Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
{
"name": "stash",
"source": "./adapters/claude-code",
"description": "Search and load local Agent Skills from a separate SKILL.md library on explicit request.",
"version": "0.1.1",
"description": "Search read-only Agent Skills catalogs and manage an explicit local inactive store.",
"version": "0.2.0",
"license": "MIT",
"strict": true
}
Expand Down
13 changes: 7 additions & 6 deletions .codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "stash",
"version": "0.1.1",
"description": "One explicit doorway to a local Agent Skills library—search by name or task and load only the selected SKILL.md.",
"version": "0.2.0",
"description": "Search read-only Agent Skills catalogs and explicitly manage a local inactive standalone skill store.",
"author": {
"name": "dd3ok",
"url": "https://github.com/dd3ok"
Expand All @@ -24,18 +24,19 @@
"skills": "./skills/",
"interface": {
"displayName": "Stash",
"shortDescription": "Open local Agent Skills only when requested.",
"longDescription": "Keep a large local Agent Skills library behind one explicit entry point. Search by exact name or task, then load only the selected SKILL.md instructions and required resources.",
"shortDescription": "Search and manage inactive local Agent Skills.",
"longDescription": "Keep a large local Agent Skills library behind one explicit entry point. Search external read-only catalogs, import standalone skills into an inactive managed store, and deploy only explicitly selected copies.",
"developerName": "dd3ok",
"category": "Productivity",
"capabilities": [
"Local skill discovery",
"Progressive disclosure",
"Read-only"
"Managed inactive skills"
],
"defaultPrompt": [
"Use $stash design-system to load that exact stored skill.",
"Use $stash to find every stored skill relevant to this task."
"Use $stash to find every stored skill relevant to this task.",
"Use $stash to install this local skill as inactive."
]
}
}
13 changes: 10 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
# Repository guidance

- Keep `StashCatalog` as the only public core Module Interface.
- Keep vendor behavior inside `adapters/` generation and contract tests.
- Treat configured catalogs as read-only; write only regenerable cache data.
- Keep `StashCatalog` as the only public read Module Interface; keep explicit
writes behind the separate `StashLifecycle` Interface.
- Keep vendor packaging and skill metadata inside `adapters/` generation. Keep
audited lifecycle discovery-root and reload policy in
`src/internal/lifecycle-host-policy.ts` with contract tests; never leak vendor
behavior into catalog search or safe-read path handling.
- Treat configured catalogs as read-only in every catalog operation. Only an
explicit lifecycle target may mutate its exact standalone child, even when
that target root is also registered for search; catalog registration alone
never grants write authority.
- Preserve exact lookup as a deterministic path before discovery search.
- Never impose a fixed cap on total relevant results; pagination is transport only.
- Do not add vector search, an LLM router, a daemon, telemetry, or catalog mutation without measured evidence and an explicit scope decision.
Expand Down
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,26 @@

## Unreleased

- Add a separate `StashLifecycle` Module with a local managed inactive store.
- Add explicit local `install`/`archive`/`activate`/`deactivate`/`status`
commands with provenance, tree hashes, tracked deployments, and drift guards.
- Add stable skill/deployment identities, explicit ownership and target records,
orthogonal status fields, archive journals, guarded dead-owner lock recovery,
and fail-closed malformed lock handling.
- Fold hash-matching catalog sources and Stash-owned deployments into the
managed canonical search result while preserving scoped lookup and raw reads.
- Reject workspace lifecycle and Antigravity CLI's flat standalone skill shapes.
- Restrict lifecycle deployment roots to documented vendor user directories;
arbitrary custom roots are no longer part of the public contract.
- Reject managed-store overlap with configured catalogs, including canonical
aliases, and fail closed when a lock owner's process state is unknown.
- Make archiving a verified tracked deployment deactivate it coherently while
preserving the managed canonical copy.
- Harden portable path validation and managed-record projection validation.
- Keep external catalogs, plugins, and vendor settings outside lifecycle write
authority; reject links, overwrites, detached removals, and remote sources.
- Make a fresh Stash installation useful without catalog configuration by
auto-discovering its managed store after the first import.
- Unify the public brand, package, repository, and marketplace identifiers as Stash.
- Reject partial-word compact-name matches that promoted unrelated short queries.
- Restore material routing for dense three-term descriptions at a regression-tested threshold.
Expand Down
11 changes: 8 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,17 @@ Validate the Codex skill and plugin with the commands and prerequisites in

## Change rules

- Keep the `StashCatalog` Interface small.
- Keep vendor logic out of core search and path handling.
- Keep the `StashCatalog` read Interface and `StashLifecycle` write Interface
small and authority-separated.
- Keep vendor packaging in generated Adapters. Centralize the narrow lifecycle
host-path/reload policy in `src/internal/lifecycle-host-policy.ts`, and keep it
out of catalog search and safe-read path handling.
- Add a failing golden or Interface test before changing relevance behavior.
- Preserve no-match abstention.
- Preserve all-relevant totals independently from page size.
- Never add catalog mutation to a read path.
- Never add catalog mutation to a read path. An explicit lifecycle archive may
mutate only the exact standalone target selected by the caller; a catalog
registration never grants that authority.
- Do not add remote calls or telemetry by default.
- Update `docs/vendor-support.md` only from current first-party documentation and live contract tests.

Expand Down
51 changes: 44 additions & 7 deletions README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ $stash API 문서 검토에 필요한 스킬을 모두 찾아줘
→ 실질적으로 관련된 저장 스킬 전체 반환
```

Stash는 로컬에서 검색하고 원본 보관함을 읽기 전용으로 다루며, 선택한
지침만 불러옵니다. 검색 중 스킬을 다운로드·설치·업데이트·실행하지
않습니다.
Stash는 로컬에서 검색하고 모든 외부 보관함을 읽기 전용으로 다루며, 선택한
지침만 불러옵니다. 별도의 관리형 보관소에는 명시적으로 가져온 독립 스킬을
호스트에 배포하기 전까지 비활성 상태로 둘 수 있습니다. 검색 자체는 스킬을
다운로드·설치·업데이트·실행하지 않습니다.

## 왜 필요한가요?

Expand Down Expand Up @@ -46,7 +47,8 @@ Stash는 많은 로컬 스킬을 제품에 하나씩 등록하지 않고 이름,
## 동작 방식

1. 평소 사용하는 스킬은 제품의 기본 스킬 폴더에 둡니다.
2. 가끔 사용하는 스킬은 Stash에 설정한 별도 폴더에 둡니다.
2. 가끔 사용하는 스킬은 Stash 관리형 보관소로 가져오거나 기존 읽기 전용
보관함을 설정합니다.
3. 사용자가 Stash를 명시적으로 호출합니다.
4. 정확한 이름을 확인하거나 로컬 어휘 검색을 실행합니다.
5. 선택한 `SKILL.md`와 필요한 참고 파일만 읽습니다.
Expand Down Expand Up @@ -92,6 +94,39 @@ defaults:
`STASH_CONFIG`에 설정 파일 경로를 지정합니다. 한 번만 사용할 때는
`--root <보관함-경로>`를 사용할 수 있습니다.

### 관리형 비활성 스킬

관리형 보관소는 별도 catalog 설정 없이 바로 쓸 수 있습니다. `install`은
로컬 스킬 디렉터리를 복사하고 원본은 그대로 둡니다.

```bash
stash install D:/downloads/rare-skill
stash archive old-skill --host codex
stash status rare-skill
stash activate rare-skill --host codex
stash deactivate rare-skill --host codex
```

`install`, `import`, `add`는 같은 명령입니다. `archive`는 파괴적 변형으로,
명시적으로 선택한 독립 스킬을 검증해 보관한 뒤 호스트 검색 경로의 원본을
제거합니다. 이미 검증된 Stash 소유 배포본이면 canonical 사본을 유지한 채
`deactivate`와 같은 추적 철회를 수행합니다. 플러그인에 포함된 스킬은
관리하지 않습니다. `activate` 결과는 `deployed`로 기록하며 호스트의 별도
활성·비활성 설정까지 켜졌다고 단정하지 않습니다.

CLI는 로컬 디렉터리만 가져옵니다. 사용자가 Stash 스킬에 저장소의 특정
스킬을 명시적으로 가져오라고 요청하면, 에이전트가 호스트 검색 경로 밖에
고정 revision을 임시로 준비하고 검토한 뒤 그 로컬 경로를 `install`에
전달할 수 있습니다. 설정된 catalog 안의 스킬도 원본을 변경하지 않고
설치할 수 있습니다. 같은 원본이나 Stash 소유 배포본이 catalog 검색에도
나오면 해시가 일치할 때 관리형 canonical 결과의 관련 사본으로 접습니다.
변경되었거나 연관되지 않은 사본은 별도 결과와 경고로 남깁니다.

첫 생명주기 버전은 로컬 전용입니다. 원격 Git, 심볼릭 링크 배포, 덮어쓰기,
플러그인 변경, 벤더 설정 변경, workspace 생명주기 대상은 지원하지 않습니다.
Antigravity CLI의 독립 스킬 형식은 문서상 디렉터리가 아닌 단일 Markdown
파일이므로 생명주기 명령의 대상으로 사용할 수 없습니다.

## 제품별 지원

| 제품 | 명시 호출 | 자동 선택 |
Expand All @@ -106,12 +141,14 @@ Antigravity 어댑터는 생성되지만, 지원을 공개하기 전에 대상 `

## 범위

- 원본 보관함은 읽기 전용으로 유지합니다.
- catalog 작업은 외부 원본 보관함을 읽기 전용으로 유지합니다. 쓰기는 외부
보관함과 겹치지 않는 Stash 관리형 보관소와, 사용자가 정확히 선택한 독립
스킬 생명주기 대상에만 허용합니다.
- 네트워크, embedding 모델, vector database, 별도 LLM 라우터를 사용하지
않습니다.
- 스킬을 읽으면서 포함된 스크립트를 실행하지 않습니다.
- 설치기, 업데이트 도구, 마켓플레이스, 권한 시스템, 샌드박스 또는 보안
검사기가 아닙니다.
- 마켓플레이스, 원격 업데이트 도구, 권한 시스템, 샌드박스 또는 보안
검사기가 아닙니다. 플러그인 생명주기는 각 호스트가 관리합니다.

## 문서

Expand Down
52 changes: 45 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ $stash find every skill for reviewing API documentation
→ return every materially relevant stored skill
```

Stash searches locally, treats source libraries as read-only, and loads only
the selected instructions. It does not download, install, update, or execute
skills while searching.
Stash searches locally, treats every external source library as read-only, and
loads only the selected instructions. Its separate managed store can also keep
an explicitly imported standalone skill inactive until you deploy it to a host.
Search never downloads, installs, updates, or executes a skill.

## Why

Expand Down Expand Up @@ -47,7 +48,8 @@ host discovery
## How it works

1. Keep everyday skills in the host's standard skill directory.
2. Keep occasional skills in a separate folder configured in Stash.
2. Import occasional skills into Stash's managed store, or configure an
existing read-only library.
3. Invoke Stash explicitly.
4. Stash resolves an exact name or runs local lexical search.
5. It reads the selected `SKILL.md` and only the required resources.
Expand Down Expand Up @@ -94,6 +96,40 @@ defaults:
Set `STASH_CONFIG` to the configuration file. You can also use
`--root <library-path>` for a one-off call.

### Managed inactive skills

No catalog configuration is required for the managed store. Import accepts a
local skill directory and leaves the source untouched:

```bash
stash install D:/downloads/rare-skill
stash archive old-skill --host codex
stash status rare-skill
stash activate rare-skill --host codex
stash deactivate rare-skill --host codex
```

`install`, `import`, and `add` are aliases. `archive` is the destructive form:
it verifies and stores an explicitly selected standalone skill before removing
that source directory from host discovery. It never manages a plugin-contained
skill. If the selected path is already a verified Stash-owned deployment,
`archive` performs the same tracked withdrawal as `deactivate` and preserves
the canonical copy. `activate` records a `deployed` copy; it does not claim that
a host-level enable/disable override is enabled.

The CLI imports local directories only. When a user explicitly asks the Stash
skill to import a repository skill, the agent may stage the pinned revision
outside host discovery, inspect it, and pass that local directory to `install`.
Install may read a selected skill inside a configured catalog but never mutates
that source. When a hash-matching source or Stash-owned deployment also appears
in an indexed catalog, search folds it into the managed canonical result as a
related copy. A drifted or unrelated copy remains separate and visible.

The first lifecycle release is intentionally local-only: no remote Git source,
symlink deployment, overwrite, plugin mutation, vendor setting mutation, or
workspace lifecycle target. Antigravity CLI lifecycle is rejected because its
documented standalone skill layouts are flat Markdown rather than directories.

## Vendor support

| Vendor | Explicit use | Automatic selection |
Expand All @@ -108,12 +144,14 @@ Antigravity adapters are generated, but should be tested against the target

## Boundaries

- Source libraries remain read-only.
- Catalog operations keep external source libraries read-only. Writes are
restricted to the non-overlapping Stash-managed root and exact standalone
lifecycle targets explicitly selected by the caller.
- Search uses no network, embedding model, vector database, or second LLM
router.
- Reading a skill does not execute its scripts.
- Stash is not an installer, updater, marketplace, permission system, sandbox,
or security scanner.
- Stash is not a marketplace, remote updater, permission system, sandbox, or
security scanner. Plugin lifecycle remains owned by each host.

## Documentation

Expand Down
25 changes: 23 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,29 @@

## Scope

Stash discovers and reads local Agent Skills. A skill can contain untrusted instructions, scripts, URLs, and assets. Treat adding a catalog like adding source code.
Stash discovers, reads, and explicitly stores local Agent Skills. A skill can contain untrusted instructions, scripts, URLs, and assets. Treat adding a catalog or importing a managed skill like adding source code.

## Guarantees

- Stash never edits configured catalog files.
- Catalog search, read, refresh, doctor, and install never edit external
configured catalog files. An explicit archive/deactivate target may share a
root with a search registration, but only that exact standalone child or a
verified Stash-owned deployment is writable.
- Managed imports reject symlinks, junctions, special files, non-portable path
names, case-insensitive collisions, oversized trees, and overwrites.
- Lifecycle copies are staged and tree-hash verified before atomic rename.
- Destructive operations apply only to explicitly selected standalone skills
or recorded deployments. Untracked and drifted deployments are preserved.
- Archive recovery is journaled. A rollback never overwrites an occupied source
path, and a committed tombstone is deleted only after its tree hash matches.
- Deactivation requires matching Stash ownership, skill/deployment identity,
target, and tree hash.
- Catalog registration grants no write authority. Hash-matching related copies
are folded only in the read projection; drifted or unrelated copies stay
visible. Managed storage itself must not equal, contain, or sit inside an
external catalog, including through a filesystem alias.
- Lifecycle lock ownership is atomically published. Proven-dead owners are
reclaimed under a separate guard; malformed or live ownership fails closed.
- Indexing does not execute scripts.
- Resource paths must stay inside the selected skill and catalog roots after `realpath`.
- Absolute paths and `..` traversal are rejected.
Expand All @@ -24,6 +42,9 @@ Stash discovers and reads local Agent Skills. A skill can contain untrusted inst
- Stash does not sandbox scripts executed later by a host agent.
- A well-formed skill can still contain malicious or misleading instructions.
- Lexical relevance is not a security classifier.
- `deployed` means present in a host discovery root; it does not prove that a
host enable/disable override is enabled.
- Plugin lifecycle and vendor setting changes are outside Stash lifecycle.

## Catalog review

Expand Down
2 changes: 1 addition & 1 deletion adapters/antigravity/cli/plugin.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://antigravity.google/schemas/v1/plugin.json",
"name": "stash",
"description": "Search and load local Agent Skills from a separate SKILL.md library on demand."
"description": "Search read-only Agent Skills catalogs and manage an explicit local inactive store."
}
Loading