AGENTS.md · git:20261102.2424ece · 2026-11-02 · sha256 6e8c5c5f37ffa97d

AGENTS.md git:20261102.2424eceA

Immutable. This exact content never changes and is served at /api/v1/blob/6e8c5c5f37ffa97d.

# Repository Guidelines

## Project Structure & Module Organization

- `src/init/`: shared `/init` core (preset registry, prompt rendering, agent adapters). Test fixtures live in `src/init/fixtures/`.
- `src/code-styleguide/`: converter that turns upstream style guides into the skill.
- Agent entry points: `pi/extensions/init/`, `dsh/init/`, `cline/init/`, and `cli/agent-stash.ts`.
- DSH `/init`: `dsh/cordis.patch.yml` inserts one row named after the package root, so DSH serves the package's browser half too. The Host half (`dsh/init/index.ts`, exported as `.`) registers `GET /agent-stash-init/presets` and `POST /agent-stash-init/run`; the browser half (`dsh/init/client.ts`, exported as `./client` and built to `dist/dsh/client.js`) registers the `/init` contribution with `commandUi` (title, icon, preset popup) and a `/` source in `inputTriggers` that claims `/init` followed by arguments. `dsh/init/wire.ts` holds the route paths and request schemas both halves share.
- DSH bundle metadata: `dsh/locale/*.json` (bundle and row title and description, exported as `./locale/*.json`), plus `icon`, `engines.dsh`, `dsh.manifestVersion`, and `dsh.client` in `package.json`. Every DSH bundle also repeats its `engines.dsh` range as an optional `@deepseek-ai/dsh` peer for tools that read the requirement from `peerDependencies`; the workspace `overrides` keep pnpm from installing DSH itself, and `dsh/dsh-requirement.test.ts` keeps the two in sync. Keep the package public; plugin index generators skip private bundles.
- `dsh/plugin-index.yaml`: the plugin index sources. `plugins` lists npm package names (Agent Stash's own bundles, then recommended third-party DSH plugins), each with a `category` and `labels` declared under `categories` and `labels` (titles need `en`). `.github/workflows/pages.yml` turns the list into the plugin index at `https://alice39s.github.io/agent-stash/index.json` with DSH's reference generator; `ci plugin-index` then keeps the 10 highest versions of each plugin, plus any version a `dist-tags` entry points to, and writes the declarations and each plugin's category and labels into the index metadata. The same Pages artifact carries the docs site, so the index stays at the site root. The workflow also runs after every Release run and hourly; those runs build and deploy only when `ci plugin-index-diff` finds that the generated index differs from the published one.
- `docs/` (workspace package `agent-stash-docs`): the bilingual docs site, a statically exported Fumadocs (Next.js) app published to GitHub Pages under `/agent-stash`. Pages live in `docs/content/docs/` (`*.mdx` in Chinese, `*.en.mdx` in English, with `meta.json`/`meta.en.json`); screenshots and recordings in `docs/public/media/` are registered in `docs/lib/media.ts` and shown with `<Showcase>`. Recordings and their posters carry the repository watermark from `docs/lib/watermark.ts`; `pnpm --filter agent-stash-docs media:watermark --source <dir>` writes them from the unwatermarked originals in `<dir>`. `docs/design.md` holds the site's presentation rules (the root `design.md` covers the DSH overlays); read it before changing the site's interface.
- `packages/`: further workspace packages published to npm, each with its own `bundle` script and committed `dist/`. `packages/dsh-message-edit/` is a DSH bundle with a Host half (`src/host/`) and a browser half (`src/client/`); its UI follows `packages/dsh-message-edit/design.md`. `packages/dsh-skill-scout/` (`@agent-stash/dsh-skill-scout`) uses the same layout plus `src/shared.ts` for the route schemas both halves share. Its Host half reads sessions through `ctx.sessionQuery`, lists the Skills an evidence session sees through `ctx.sessionSkillCatalog`, stores episodes and suggestions in the `skill_scout` storage domain, and calls the discovery model (summaries) and the drafting model (Skill drafts, only after the user approves a summary) through `ctx.llm`. Its browser half takes `react-dom` and `@deepseek-ai/dsh-client-ui-primitives` from the DSH module table (the third argument of `clientBundle` in `packages/dsh-message-edit/tsdown.client.ts`), so it needs DSH 0.2.1-rc.3 or later. `packages/dsh-skill-scout/architecture.md` records its design decisions, and its UI (a conversation view, a main panel page, and a header popover, with charts in `src/client/ui/charts/`) follows `packages/dsh-skill-scout/design.md`.
- `scripts/ci/`: Python CLI (uv + Typer) that every workflow step calls (`uv run --project scripts/ci ci --help`). Workflows contain no inline shell; add a CLI command instead. Check it with `uv run ruff format --check`, `uv run ruff check`, and `uv run pytest` in that directory.
- Standalone DSH bundles `dsh/recall/` (`@agent-stash/dsh-recall`), `dsh/autosuggest/` (`@agent-stash/dsh-autosuggest`), `dsh/enhance/` (`@agent-stash/dsh-enhance`), and `dsh/kit/` (`@agent-stash/dsh-stash-kit`, the Agent Stash Kit): workspace packages published to npm, each with its own `package.json`, `cordis.patch.yml`, `locale/*.json`, `icon.svg`, and `README.md`, a Host half in `src/index.ts`, and a browser half in `src/client.tsx`. Their plugin rows keep the short ids `dsh-recall`, `dsh-autosuggest`, `dsh-enhance`, and `dsh-stash-kit`, which also name their dictionaries and config. The kit's browser half provides the `stashKit` Cordis service (panel, ghost text, draft-swap motion, appearance store) and the `plugins.row.config` settings page; its Host half owns the volatile appearance `Config`. Recall and autosuggest register into the `conversation.input.overlay` slot, inject `stashKit`, import kit code only as types, and install or enable the kit bundle through `pluginManager` at Host startup (`dsh/shared/host/kit.ts`). Enhance does the same with the kit but registers a button into the `conversation.input.right` slot and its own `plugins.row.config` page; its Host half registers `POST /dsh-enhance/rewrite` and `GET /dsh-enhance/context` and calls the model through `ctx.llm`, and its volatile `Config` holds the model, timeout, session-context, shortcut, and preset settings. Its component tests mount through `dsh/enhance/src/harness.tsx`. Shared code lives in `dsh/shared/` (`prompts.ts` for pure history logic, `host/` for the prompt route and kit installation, `client/` for the composer hooks and component-test harness). The root `pnpm bundle` writes both halves to each bundle's `dist/`; the browser half is CommonJS wrapped in `window.__ModuleLoader__.load` and takes `react` and `@deepseek-ai/dsh-client-ui-primitives` from the DSH module table. Their UI follows the root `design.md`.
- `benchmark/prompts/` (private workspace package `agent-stash-prompt-benchmark`): [vieval](https://github.com/vieval-dev/vieval) benchmarks for the prompts the plugins send to models. `enhance/` runs the dsh-enhance built-in presets through the plugin's own `buildPrompt` and `runRewrite` over the golden set in `enhance/cases/*.yaml`, then scores each result with rule checks (`enhance/src/checks.ts`) and a judge model (`enhance/src/judge.ts`). Its README holds the review process for prompt changes.
- `prompts/init/`: hand-maintained presets (`claude-code*.md`).
- Generated content, never edited by hand: `vendor/init-prompts/` (from `pnpm sync:init-prompts`), `skills/code-styleguide/` (from `pnpm sync:code-styleguide`), `SKILL.md` and `agents/openai.yaml` in each `skills/self-use-*-subagent/` (from `uv run skills/self-use-haiku-subagent/scripts/render.py`, which renders that directory's `templates/` with `models.yaml`), and `dist/` plus `dsh/*/dist/` (from `pnpm bundle`).
- Plugin names and descriptions: `meta.title` and `meta.description` in each bundle's `locale/*.json` hold the wording that READMEs, the docs site (overview table, page descriptions), and changesets reuse. The Chinese titles are `/init`, Prompt 回溯, Prompt 自动补全, 提示词增强器, Agent Stash 基础核心框架, 消息编辑, and 经验提炼器. A description is one clause, without trailing punctuation, that says what the plugin does (提示词增强器: 一键润色、结构化、提炼 Prompt 草稿的核心内容); key bindings, defaults, and limits go in the README and the docs page.

## Build, Test, and Development Commands

Requires Node 24+ and pnpm 11.

- `pnpm install`: install dependencies.
- `pnpm check`: `oxfmt --check`, type-aware `oxlint`, and `vitest run`; this is what CI runs.
- `pnpm test`, `pnpm lint`, `pnpm format`: run each step on its own.
- `pnpm bundle`: rebuild `dist/` and `dsh/*/dist/` with tsdown. DSH, Cline, and the CLI load these directories directly, so commit the rebuilt output; CI fails when they differ from the sources. `uv run --project scripts/ci ci bundle` rebuilds every workspace package.

Keep the bundling script named `bundle`. A `build` script makes `npm install -g github:...` install a broken link.

- `pnpm --filter agent-stash-prompt-benchmark bench`: run the prompt benchmark with real models (needs API keys; see `benchmark/prompts/README.md`). `pnpm test` covers its loaders, checks, and adapters without network.
- `pnpm --filter agent-stash-docs dev`: serve the docs site at `http://localhost:3883/agent-stash/`.
- `pnpm --filter agent-stash-docs build`: export the docs site to `docs/out/`. The Pages workflow builds it on pull requests that touch `docs/` and deploys it from `main`.

## Coding Style & Naming Conventions

- TypeScript ESM with `strict`, `noUncheckedIndexedAccess`, `exactOptionalPropertyTypes`, and `erasableSyntaxOnly` (no enums or namespaces). Import local files with the `.ts` extension.
- oxfmt formats with a 100-column print width. oxlint denies warnings and forbids `any` and floating promises.
- Validate external input with valibot schemas (`ConfigSchema`); use `pathe` for paths.
- Constants use `UPPER_SNAKE_CASE`, schemas `PascalCaseSchema`, files `kebab-case.ts`. Write doc comments in Chinese, matching existing code.

## Testing Guidelines

Tests use Vitest and sit next to their source as `*.test.ts` (`src/init/registry.test.ts`). Browser-half component tests are `*.test.tsx` files with a `// @vitest-environment happy-dom` header that mount the overlay through `dsh/shared/client/harness.tsx`, which provides the real kit service from `dsh/kit/src/harness.tsx` (kit tests use `mountKit` and `createSettings` from there); `vitest.config.ts` aliases `@deepseek-ai/dsh-client-ui-primitives`, which the DSH module table supplies at runtime, to `dsh/kit/src/primitives-stand-in.tsx`. Write `describe`/`test` names as English behavior statements. Put on-disk config cases under `src/init/fixtures/<case>/`. Every new preset, adapter, or config path needs a test. A change to the dsh-enhance prompts (`dsh/enhance/src/presets.ts`, or how `rewrite.ts` builds the request or checks the result) needs a baseline and candidate run of `benchmark/prompts` compared as its README describes; a draft the plugin rewrote wrongly becomes a golden-set case first.

## Commit & Pull Request Guidelines

- Commits follow Conventional Commits with a scope, for example `feat(init): add Crush preset` or `ci(release): ...`. Use the body to explain why.
- For user-facing changes, add a changeset to `.tegami/<topic>.md` with `packages: { "@agent-stash/init": minor }` frontmatter (use the name of each changed workspace package) and release notes in Chinese under at least one Markdown heading; Tegami ignores changesets without a heading. Tegami opens the Version Packages PR on `main`.
- PRs must pass `pnpm check` and include the rebuilt `dist/`. Describe which agents or presets the change affects.