AGENTS.md · git:20261031.0488329 · 2026-10-31 · sha256 2557d571a3a9f364

AGENTS.md git:20261031.0488329A

Immutable. This exact content never changes and is served at /api/v1/blob/2557d571a3a9f364.

# 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`. Keep the package public; plugin index generators skip private bundles.
- `dsh/plugin-index.txt`: npm package names (Agent Stash's own bundles, then recommended third-party DSH plugins) that `.github/workflows/pages.yml` turns 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. 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.