@sayknow-cli/coding-agent 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,20 @@ Sayknow-CLI is a rebranded fork of [gajae-code](https://github.com/Yeachan-Heo/g
4
4
  This file tracks the **fork's own releases**; upstream's full feature history lives
5
5
  in that project. Each release notes the upstream version it is built on.
6
6
 
7
+ ## [0.2.3] — 2026-06-19
8
+
9
+ ### Fixed
10
+
11
+ - `skc update` and the binary installer pointed at a non-existent repo path
12
+ (`jaybeyond/sayknow-cli`, lowercased by the rebrand) and 404'd. They now use the
13
+ real repo `jaybeyond/Sayknow_CLI`, so in-app updates and the install script work.
14
+
15
+ ### Changed
16
+
17
+ - **Now on npm.** Install and upgrade with `npm install -g sayknow-cli`
18
+ (`@latest` to upgrade, or `skc update`). The READMEs lead with the npm install;
19
+ building from source moved to its own "Install from source (development)" section.
20
+
7
21
  ## [0.2.2] — 2026-06-18
8
22
 
9
23
  ### Fixed
@@ -7,6 +7,6 @@ import type { LoadContext } from "../capability/types";
7
7
  * user-level config and is already enumerated by {@link getUserPathCandidates}.
8
8
  * Without this guard, any cwd under `$HOME` (with no closer git repoRoot) would
9
9
  * walk up to home and yield duplicate project+user entries for the same
10
- * directory — see https://github.com/jaybeyond/sayknow-cli/issues/1116.
10
+ * directory — see https://github.com/jaybeyond/Sayknow_CLI/issues/1116.
11
11
  */
12
12
  export declare function getProjectPathCandidates(ctx: LoadContext, ...segments: string[]): string[];
@@ -1,6 +1,6 @@
1
1
  import type { ImageContent } from "@sayknow-cli/ai";
2
2
  import type { CustomMessage } from "../session/messages";
3
- export declare const STAR_REMINDER_REPO = "jaybeyond/sayknow-cli";
3
+ export declare const STAR_REMINDER_REPO = "jaybeyond/Sayknow_CLI";
4
4
  export declare const STAR_REMINDER_CUSTOM_TYPE = "star-reminder";
5
5
  export declare const STARRED_CACHE_TTL_MS: number;
6
6
  export interface StarReminderState {
@@ -79,7 +79,7 @@ export interface MCPSseServerConfig extends MCPServerConfigBase {
79
79
  headers?: Record<string, string>;
80
80
  }
81
81
  export type MCPServerConfig = MCPStdioServerConfig | MCPHttpServerConfig | MCPSseServerConfig;
82
- export declare const MCP_CONFIG_SCHEMA_URL = "https://raw.githubusercontent.com/jaybeyond/sayknow-cli/main/packages/coding-agent/src/config/mcp-schema.json";
82
+ export declare const MCP_CONFIG_SCHEMA_URL = "https://raw.githubusercontent.com/jaybeyond/Sayknow_CLI/main/packages/coding-agent/src/config/mcp-schema.json";
83
83
  /** Root mcp.json/.mcp.json file structure */
84
84
  export interface MCPConfigFile {
85
85
  $schema?: string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@sayknow-cli/coding-agent",
4
- "version": "0.2.2",
4
+ "version": "0.2.3",
5
5
  "description": "Sayknow-CLI CLI with read, bash, edit, write tools and session management",
6
6
  "homepage": "https://github.com/jaybeyond/Sayknow_CLI",
7
7
  "author": "jaybeyond",
@@ -51,12 +51,12 @@
51
51
  "@agentclientprotocol/sdk": "0.21.0",
52
52
  "@babel/parser": "^7.29.3",
53
53
  "@mozilla/readability": "^0.6.0",
54
- "@sayknow-cli/stats": "0.2.2",
55
- "@sayknow-cli/agent-core": "0.2.2",
56
- "@sayknow-cli/ai": "0.2.2",
57
- "@sayknow-cli/natives": "0.2.2",
58
- "@sayknow-cli/tui": "0.2.2",
59
- "@sayknow-cli/utils": "0.2.2",
54
+ "@sayknow-cli/stats": "0.2.3",
55
+ "@sayknow-cli/agent-core": "0.2.3",
56
+ "@sayknow-cli/ai": "0.2.3",
57
+ "@sayknow-cli/natives": "0.2.3",
58
+ "@sayknow-cli/tui": "0.2.3",
59
+ "@sayknow-cli/utils": "0.2.3",
60
60
  "@puppeteer/browsers": "^2.13.0",
61
61
  "@types/turndown": "5.0.6",
62
62
  "@xterm/headless": "^6.0.0",
@@ -12,7 +12,7 @@ import { $ } from "bun";
12
12
  import chalk from "chalk";
13
13
  import { theme } from "../modes/theme/theme";
14
14
 
15
- const RELEASE_REPO = "jaybeyond/sayknow-cli";
15
+ const RELEASE_REPO = "jaybeyond/Sayknow_CLI";
16
16
  const PACKAGE = "@sayknow-cli/coding-agent";
17
17
 
18
18
  interface ReleaseInfo {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://raw.githubusercontent.com/jaybeyond/sayknow-cli/main/packages/coding-agent/src/config/mcp-schema.json",
3
+ "$id": "https://raw.githubusercontent.com/jaybeyond/Sayknow_CLI/main/packages/coding-agent/src/config/mcp-schema.json",
4
4
  "title": "SKC MCP configuration",
5
5
  "description": "Schema for mcp.json, .mcp.json, .skc/mcp.json, and ~/.skc/agent/mcp.json used by the SKC coding agent.",
6
6
  "type": "object",
@@ -41,7 +41,7 @@ function getUserPathCandidates(ctx: LoadContext, ...segments: string[]): string[
41
41
  * user-level config and is already enumerated by {@link getUserPathCandidates}.
42
42
  * Without this guard, any cwd under `$HOME` (with no closer git repoRoot) would
43
43
  * walk up to home and yield duplicate project+user entries for the same
44
- * directory — see https://github.com/jaybeyond/sayknow-cli/issues/1116.
44
+ * directory — see https://github.com/jaybeyond/Sayknow_CLI/issues/1116.
45
45
  */
46
46
  export function getProjectPathCandidates(ctx: LoadContext, ...segments: string[]): string[] {
47
47
  const paths: string[] = [];
@@ -4,8 +4,8 @@ export const EMBEDDED_DOC_FILENAMES: readonly string[] = ["ERRATA-GPT5-HARMONY.m
4
4
 
5
5
  export const EMBEDDED_DOCS: Readonly<Record<string, string>> = {
6
6
  "ERRATA-GPT5-HARMONY.md": "# ERRATA — GPT-5 Harmony-Header Leakage\n\n## 1. The problem\n\nOpenAI frames tool calls in the Harmony chat protocol:\n\n```\n<|start|>assistant<|channel|>commentary to=functions.<NAME><|message|>{ARGS}<|call|>\n```\n\n`<|channel|>commentary to=functions.NAME` is the **routing header** —\ncontrol tokens consumed by the runtime to dispatch the call. These\ntokens never appear as content under normal operation; the runtime\nstrips them.\n\nThe defect: gpt-5 models occasionally emit, **as ordinary content\ninside `{ARGS}`**, the **plain-text shadow** of these routing tokens —\nthe same characters without the `<|…|>` brackets — and continue\nproducing more pseudo-routing structure (channel name, body marker,\nmultilingual spam, fake tool-result framing). The contamination lives\ninside the visible tool argument and is dispatched to the tool as if it\nwere intended content.\n\n**Critical detail.** The actual `<|start|>` / `<|channel|>` /\n`<|message|>` / `<|call|>` special tokens almost never appear in tool\nargs. What leaks is the bracket-less spelling — `analysis to=functions.X\ncode …` — because OpenAI applies a logit mask suppressing the\ncontrol-token IDs inside the args region. The mass that would have gone\nto those special tokens redistributes onto the un-bracketed plain-text\nrepresentation the model also learned. This makes the leak structurally\ninvisible to the routing parser and lands it in the tool input verbatim.\n\nManifestation in tool args (real corpus example):\n\n```\n~ add_function(iso, ctx, ns, \"installSystemChangeObserver\",\n os_install_system_change_observer);】【\"】【analysis to=functions.edit\n code above เงินไทยฟรีuser to=functions.edit code …\n```\n\nThe leading code is real and intended. Everything after the first\nnon-Latin token through the next clean structural boundary is corruption.\n\n---\n\n## 2. Observed statistics & failure modes\n\nSource: `~/.skc/stats.db` (`ss_tool_calls`, `ss_assistant_msgs`), through\n2026-05-10. 1.05M tool calls scanned.\n\n### 2.1 Rate\n\n| Model | Leaks in tool args | Calls | per million |\n|------------------|-------------------:|--------:|------------:|\n| gpt-5.4 | 37 | 226,957 | 163 |\n| gpt-5.3-openai-code | 17 | 112,243 | 151 |\n| gpt-5.5 | 2 | 80,750 | 25 |\n| gpt-5.2-openai-code | 0 | — | — |\n\nPlus 15 hits in assistant visible text / thinking blobs.\n\n### 2.2 Tool distribution\n\n| Tool | Hits |\n|---------------------|-----:|\n| `edit` | 38 |\n| `eval` | 11 |\n| `report_tool_issue` | 3 |\n| `grep`/`read`/`search`/`yield` | 1 each |\n\nConcentrated in tools with free-form (non-JSON-schema) argument formats.\n\n### 2.3 Leak shape (deterministic)\n\n```\nLEAK ::= JUNK_PREFIX MARKER CHANNEL_BODY (LEAK)?\nMARKER ::= \"to=functions.\" TOOL_NAME\nCHANNEL_BODY ::= \" code \" (SPAM | reasoning_prose | fake_tool_output)*\nJUNK_PREFIX ::= (GLITCH_TOKEN | CHANNEL_WORD | NON_LATIN_RUN | \"}\" | \"】【\")+\n```\n\n**Cascading is common.** Of 96 marker occurrences across 71 contaminated\nrecords, 39 contain ≥2 markers and 7 contain ≥3 — the model emits\nmultiple fake `to=functions.X code …` blocks back-to-back, often with\nfake `code_output\\nCell N:\\n…` framing between them. Once the\nplain-text scaffolding is in the residual stream, the prefix now *looks\nlike* a fresh tool envelope start, so the macro prior over continuations\nkeeps voting for more scaffolding. Self-amplifying.\n\n### 2.4 Glitch tokens\n\nSingle-token identifiers in `o200k_base` whose embeddings appear to be\nnear-init from underrepresentation in post-training. ASCII residue\nimmediately before the marker in the natural corpus:\n\n| Surface string | Single-token | Token ID | Hits in corpus |\n|-------------------|:-:|---------:|---:|\n| `Japgolly` | ✅ | 199,745 | 1 |\n| `Jsii` | ✅ | 114,318 | (subtoken of `Jsii_commentary`) |\n| `Jsii_commentary` | — (3 toks) | — | 2 |\n| `changedFiles` | — (2 toks) | — | 8 |\n| `RTLU` | — (2 toks) | — | 3 |\n\n`Japgolly` is in the last 0.13% of the vocabulary — the same family of\nGitHub-corpus residue that produced `SolidGoldMagikarp` in the 2023\nGPT-2 vocabulary (Rumbelow & Watkins). `SolidGoldMagikarp` itself\ntokenizes to 5 tokens in `o200k_base` — that specific token was retired,\nbut the class wasn't.\n\nFor the multi-token entries, the corpus-level signature is the surface\nstring; the underlying glitch trigger is a sub-token (e.g. `Jsii` inside\n`Jsii_commentary`). The detector list (`G` signal) keys on the surface\nstrings.\n\nStable across unrelated sessions. Treated as a high-precision detector\nsignal.\n\n### 2.5 Channel-word leakage\n\n`analysis` (5), `assistant` (5), `commentary` (3), `user` (1) appear\ndirectly preceding `to=`. Always bare words; never `<|channel|>analysis`\nor any other bracketed form. Consistent with §1 — the brackets are\nmasked, the words are not.\n\n### 2.6 Non-Latin spam residue\n\n96 marker hits, by script: CJK 40, Cyrillic 12, Telugu/Kannada/Malayalam\n18, Thai 8, Georgian 7, Armenian 7, Arabic 1. Recurring fragments are\nChinese gambling SEO (`大发时时彩`, `天天中彩票`), Georgian/Abkhaz junk,\nand Thai casino spam — well-known low-quality crawl residue.\n\nThis is the same script distribution observed in the controlled\nreproduction (§7.3), independent of the prompt's natural language.\n\n### 2.7 Failure-mode breakdown for the `edit` tool\n\nThe `edit` tool exists in two variants in the corpus:\n\n| Variant | Calls | Recovery |\n|--------------------------|------:|----------|\n| Patch-DSL (`§PATH`/anchor/`«»≔` ops) | 27 | **Recoverable** by op-truncation (§3.3) |\n| JSON-schema (`{path,edits:[…]}`) | 11 | **Not recoverable** — contamination is escaped *inside* JSON strings, parser accepts it cleanly, content would be written verbatim into source files |\n\nFor Patch-DSL leaks specifically:\n\n- 20/27 cases: contamination on the last input line; nothing follows.\n- 7/27 cases: contamination mid-input; what follows is one of: a\n duplicate replay of an earlier file/anchor, intended content for a\n *different* tool call (the model started its next call inline), or\n pure hallucination. Post-contamination content is never trustworthy.\n\n### 2.8 Mechanism (confirmed)\n\n**Prior collapse from null-embedding glitch tokens, into a\ncontrol-token-masked basin whose mass redistributes onto the\nplain-text shadow of the Harmony protocol.**\n\nStep by step:\n\n1. The model is mid-`{ARGS}` of a Harmony tool call. The runtime applies\n a logit mask suppressing structural control tokens (`<|channel|>`,\n `<|message|>`, `<|call|>`, `<|start|>`, `<|end|>`) inside the args\n region. Without this mask, normal generation would constantly\n hallucinate envelope-closes; with it, those token IDs have logit\n `-∞` in args.\n2. A glitch token `g` is sampled. By construction `g` was in the BPE\n merge corpus but barely in LM/RL training, so its **input embedding\n `e_g` ≈ near-init noise of small norm**.\n3. At position t+1, the residual update `h_{t+1} ≈ LN(h_t + e_g + Attn +\n MLP)` is dominated by the prefix-derived terms; the just-emitted-token\n signal is effectively absent. Generation diversity normally comes\n from `e_x` steering the residual into different sub-regions —\n stripped here.\n4. The next-token distribution therefore collapses onto the **conditional\n prior over continuations of the prefix, with local conditioning\n removed**. In a tool-calling rollout context, that prior is sharply\n peaked on Harmony scaffolding (control tokens + routing tokens) —\n that's what RL trained.\n5. The mask zeros the control-token IDs. Mass redistributes onto the\n **next-best continuation**: the un-bracketed surface-form spelling of\n the same protocol (`analysis`, `commentary`, ` to=functions.X`,\n ` code `). This spelling is unmasked because those characters are\n ordinary tokens.\n6. Once a few tokens of plain-text scaffolding land in the residual\n stream, the prefix now resembles a fresh envelope start. The macro\n prior keeps voting for more scaffolding. Cascading (§2.3) follows.\n7. Multilingual spam after the marker is the same prior-collapse\n continuation, drawn from the training neighborhood of the glitch\n token (often ESL/auto-generated multilingual web junk — exactly the\n crawl residue in §2.6).\n\n**Two corollaries the corpus data demanded but only the experiment\nexplained:**\n\n- **The brackets never appear** (§1, §2.5). The mask is what makes the\n leak land in plain text instead of as a real envelope-close.\n- **Counterintuitive grammar dependency** (§7.4). The leak is *worse* in\n formats closest to OpenAI's training distribution. Off-distribution\n custom grammars dampen the macro-prior basin; the official\n `*** Begin Patch` format is the strongest collapse target.\n\nThe 2023 SolidGoldMagikarp paper documented mechanism (1)+(2)+(4). The\nnew piece is (5): when constrained decoding masks the natural collapse\ntarget, the mass laundered through the un-masked plain-text shadow\nbecomes a structurally-invisible exfiltration channel.",
7
- "FORK_MAINTENANCE.md": "# Fork maintenance — keeping Sayknow-CLI synced with upstream\n\nSayknow-CLI is a **rebranded fork** of upstream `gajae-code`. We track upstream\nreleases without re-doing the rename by hand each time: the fork is a\n**reproducible function of `{upstream tag, our fork layer}`**.\n\n```\nfork tree = gen-tree(clean upstream tag)\n = codemod + fork-identity + overlay + patches\n```\n\nVerified: `gen-tree(v0.5.4)` byte-reproduces the `sayknow-fork` branch (excluding\nregenerated lockfiles + `*.generated.ts`).\n\n## Branch / remote topology\n\n| ref | meaning |\n| --- | --- |\n| `upstream` (remote) | `github.com/Yeachan-Heo/gajae-code` — read-only source |\n| `origin` (remote) | `github.com/jaybeyond/sayknow-cli` — our fork |\n| `main` (local) / `origin/main` | our shippable fork (local branch `sayknow-fork` → `origin/main`) |\n| `origin/upstream-mirror` | pristine upstream mirror (tag `upstream/v0.5.4`) |\n| tag `sayknow-v0.1.0` | fork release; tag `upstream/v0.5.4` | the upstream base it was generated from |\n\nBacked up: `git push origin sayknow-fork:main` (done). Local branch `sayknow-fork`\ntracks `origin/main`.\n\n## The four layers\n\n1. **codemod** — `scripts/apply-rebrand.ts`: deterministic brand rename\n (`gajae/gjc → sayknow/skc`, paths, `@sayknow-cli` scope) + identity\n special-cases (`can1357`/`Yeachan-Heo → jaybeyond`, discord → placeholder).\n Skips `bun.lock`/`Cargo.lock` (integrity hashes). Reproduces ~1885 files with\n **zero residual tokens**.\n2. **fork-identity** — `scripts/apply-fork-identity.ts` + `rebrand/identity.json`:\n stamps the fork **version** (`0.1.0`) onto workspace `package.json` + root\n catalog + `Cargo.toml`, as minimal format-preserving edits. **Bump the version\n here**, never with a global replace (that would corrupt CHANGELOG/lockfiles).\n3. **overlay** — `rebrand/overlay/**`: whole files we own outright (i18n module,\n `blue-octopus`/`red-octopus` themes, octopus assets, brand docs). Copied over\n the codemod output. **No line-level merge → zero conflict.**\n4. **patches** — `rebrand/patches/NN-*.patch`: the ~17 **in-place edits** to\n upstream-owned files (welcome redesign, theme default, i18n wiring, tests).\n Applied with `git apply --reject`. **This is the only conflict-prone layer.**\n\n`rebrand/manifest.json` declares which files are `patch` / `regenerate` /\n`toolingOnly`; everything else that differs becomes overlay automatically.\n\n## Sync to a new upstream release\n\n```sh\nbash scripts/sync-upstream.sh v0.5.5 # fetch tag, regenerate, run gates G1–G4\n```\n\nThis produces a generated, gate-verified tree in a temp worktree (it does **not**\nauto-commit). Then **adopt** it:\n\n```sh\n# review the generated tree printed by the sync command, then:\nrsync -a --delete --exclude .git <generated-wt>/ .\nbun install # refresh lockfiles\ngit add -A && git commit -m \"sync: upstream v0.5.5\"\ngit tag sayknow-v0.<n>.0 # bump rebrand/identity.json first if releasing\n```\n\n### When a patch conflicts (upstream changed a patched file)\n\n`git apply --reject` leaves `*.rej` files in the generated worktree. For each:\n\n1. Open the `.rej` and the target file, apply the change by hand.\n2. Re-extract so the patch matches the new upstream base:\n ```sh\n # after upstream is mirrored + codemod+finalizer applied to <base>:\n bun scripts/extract-fork-layer.ts --base <base> --fork <fixed-tree> --apply\n ```\n3. Commit the refreshed `rebrand/patches/`.\n\n**Lever:** the fewer in-place edits, the fewer future conflicts. Prefer expressing\nnew fork features as *new files* (overlay) or additive hooks rather than edits to\nupstream files. Today only ~17 files are patches; keep it small.\n\n## Gates (run by `sync`, or manually)\n\n| gate | check |\n| --- | --- |\n| **G1** | no residual `gajae/gjc/red-claw/...` tokens in the generated tree |\n| **G2** | codemod idempotence — a *second* `apply-rebrand` changes **0 files** (diff-based; the printed hit-count is unreliable, do not gate on it) |\n| **G3** | `bun --cwd=packages/coding-agent run check:types` |\n| **G4** | `bun test` brand/i18n/welcome suites |\n\n## Publishing to npm\n\n`scripts/publish-npm.ts` publishes the 9 workspace packages in dependency order\nusing **`bun publish`** (not `npm publish`): bun resolves `catalog:`/`workspace:`\ndeps to concrete versions at pack time, so the packages actually install. Plain\n`npm publish` leaves `catalog:` in the tarball and breaks `bun install -g sayknow-cli`.\n\nOne-time prerequisites (need your npm account — the script can't do these):\n\n1. Create the **`@sayknow-cli`** org/scope on npmjs.com (Settings → Add Organization\n → free unlimited public). All 9 packages are `@sayknow-cli/*`.\n2. `bunx npm login`\n\nThen:\n\n```sh\nbun run build:native # build the platform .node first\nbun scripts/publish-npm.ts --dry-run # preview tarballs (no login needed)\nbun scripts/publish-npm.ts # publish for real\n```\n\nAfter publishing, `bun install -g sayknow-cli` works.\n\n> **Native binary is platform-specific.** `@sayknow-cli/natives` bundles a prebuilt\n> `.node` for the machine you publish from (e.g. `darwin-arm64`). A publish from an\n> Apple-Silicon Mac works for Apple-Silicon Mac users; **Linux / Windows / Intel-Mac\n> users get a \"failed to load native addon\" error.** Full cross-platform support\n> needs each platform's `.node` built in CI (`scripts/ci-release-build-binaries.ts`)\n> and shipped together — a follow-up, not a single-machine publish.\n\n## Regenerating the fork from scratch (audit)\n\n```sh\ngit worktree add --detach /tmp/u v0.6.0\nbun scripts/gen-tree.ts /tmp/u --build\ndiff -rq /tmp/u . -x .git -x node_modules -x bun.lock -x Cargo.lock -x '*.generated.ts'\n# → empty means the fork is fully reproducible from upstream + the fork layer\n```\n",
8
- "REBRANDING_PLAN_260525.md": "# SKC Rebranding Plan — 2026-05-26\n\n## Status\n\nApproved plan for the sayknow-cli/SKC rebrand and visible UI redesign. This document records the implementation contract to track in GitHub and preserve in-repo.\nGitHub tracking issue: https://github.com/jaybeyond/sayknow-cli/issues/3\n\n## Decision\n\nRedesign the visible SKC terminal, export, and documentation surfaces around a coherent red-octopus sayknow-cli identity while preserving clegacyatibility boundaries.\n\nThe default-visible product should read as **sayknow-cli / SKC**, not legacy upstream branding or a generic inherited terminal skin. Red-claw becomes the default dark visual direction for users without an explicit override. Session exports and README screenshots should show the same brand direction, while exported transcript content remains neutral and readable.\n\n## Principles\n\n1. **SKC-first visible identity** — Default-visible UI should present sayknow-cli/red-octopus as the current product identity.\n2. **Clegacyatibility preservation** — Keep `skc`, `skc-stats`, `skc-swarm`, `@sayknow-cli/*`, legacy runtime roots/env aliases, and explicit attribution/history.\n3. **Semantic color integrity** — Brand red/coral/shell colors must stay distinct from error, warning, and diff-removal semantics.\n4. **Readable fallbacks** — Truecolor, 256-color, Unicode, Nerd Font, ASCII, narrow terminal, and imperfect-font modes must remain usable.\n5. **Audit-friendly exports** — HTML exports and docs use SKC header/accent/metadata branding without making transcript content decorative or hard to review.\n6. **Visible workflow minimization** — Default repo-shipped visible skills/workflows remain limited to `deep-interview`, `ralplan`, `team`, and `ultragoal`.\n\n## Scope\n\n### In scope\n\n- Default dark theme and bundled red-octopus palette.\n- Visible TUI surfaces: welcome, status line, footer/keybinding hints, message frames, assistant/user/custom/system messages, tool execution cards, ask/approval cards, selectors/settings, todo/plan surfaces, transcript chrome, diff/tool output styling.\n- Status-line identity cutover away from default-visible legacy/Pi/powerline styling.\n- Session HTML export header/accent/metadata branding while preserving transcript readability.\n- README screenshots/alt text and docs pages that present current SKC UI/export identity.\n- Static scans and tests for current-product brand leaks, clegacyatibility names, theme defaults, fallback readability, and export branding.\n\n### Out of scope\n\n- Renaming `skc`, `skc-stats`, `skc-swarm`, or `@sayknow-cli/*` package surfaces.\n- Removing legacy runtime roots, env aliases, clegacyatibility internals, migration notes, generated/vendor content, or attribution/history solely because they mention legacy/Pi.\n- Copying OpenAI code provider, SST/opencode, Anthropic Code, or legacy upstream visuals verbatim.\n- Making exports decorative enough to reduce audit readability.\n- Replacing the TUI framework as part of the brand redesign.\n\n## Implementation Plan\n\n### Phase 1 — Inventory and allowlist\n\n- Search active visible UI/docs/export surfaces for old-brand and inherited UI identity markers: legacy upstream markers, `skc`, `pi`, `powerline`, and generic export labels.\n- Classify hits as current product identity, explicit user opt-in setting labels, clegacyatibility internals, attribution/history/migration notes, or generated/vendor content.\n- Build or update verification gates so current-product visible leaks fail, but clegacyatibility and attribution do not.\n\n### Phase 2 — Theme defaults and palette semantics\n\n- Make red-octopus the default dark visual direction for users without explicit theme overrides.\n- Separate brand tokens (`brandRed`, `claw`, `coral`, `shell`) from semantic tokens (`dangerRed`, `warningAmber`, `diffRemovalRed`).\n- Ensure accents, borders, markdown, status-line identity, and export header variables use brand tokens while errors, warnings, and removals use semantic tokens.\n- Add focused tests for default theme resolution and token separation.\n\n### Phase 3 — Status-line identity cutover\n\n- Remove Pi from bundled default-visible status presets or replace it with clegacyact SKC/claw identity.\n- Preserve legacy segment/symbol clegacyatibility only as explicit opt-in or internal alias behavior.\n- Change default separators away from powerline-like styling; keep powerline variants available only as explicit user choices.\n- Verify status-line overflow, narrow-width, and ASCII/minimal-symbol behavior.\n\n### Phase 4 — Coherent TUI clegacyonent pass\n\nUse existing theme tokens rather than a new UI framework abstraction.\n\n- Apply shell/ink backgrounds, coral/claw accents, clegacyact borders, and lower-noise hierarchy across visible clegacyonents.\n- Refresh welcome, status line, footer hints, message frames, tool cards, ask/approval cards, selectors/settings, todo/plan surfaces, and transcript chrome.\n- Keep high-frequency tool cards inspectable: tool name, path/args, status, diff preview, truncation/expand hints, and error states remain clearer than decoration.\n- Confirm Unicode/Nerd/ASCII fallbacks for new visible symbols.\n\n### Phase 5 — Export and docs alignment\n\n- Update HTML export title/header/metadata to present SKC session export branding.\n- Keep message bodies, code blocks, tool output, system prlegacyts, and transcript content neutral and high contrast.\n- Regenerate derived export templates if required by the repository workflow.\n- Update README screenshots/alt text and docs references so the demonstrated TUI/export direction matches the implemented default.\n\n### Phase 6 — Verification and review\n\n- Run focused theme/status/export/static-scan tests first.\n- Run package-local checks after focused tests pass.\n- Run cleanup/refactor review on changed files.\n- Rerun verification after cleanup.\n- Run final code review and resolve blockers before considering the implementation clegacylete.\n\n## Acceptance Criteria\n\n- [ ] Default dark theme resolves to red-octopus/SKC for users without explicit theme override.\n- [ ] Brand/accent tokens are distinct from error, warning, and diff-removal tokens.\n- [ ] Default-visible status-line identity no longer leads with legacy/Pi-style branding.\n- [ ] Default-visible status separators no longer use powerline-style styling unless explicitly opted in.\n- [ ] Visible TUI clegacyonents share one coherent SKC language across welcome, status line, footer hints, message frames, tool execution cards, ask/approval cards, selectors/settings, and todo/plan surfaces.\n- [ ] Static scans of active UI/docs/export surfaces do not present legacy/Pi as current product identity; clegacyatibility internals, attribution/history, generated/vendor content, and migration notes remain allowlisted.\n- [ ] Full session HTML export includes SKC header/accent/metadata branding while preserving neutral readable transcript content.\n- [ ] README screenshots and alt text show the same SKC/red-octopus brand direction as the TUI/export surfaces.\n- [ ] Redesign remains readable under fallback terminal modes, including ASCII/minimal-symbol operation.\n- [ ] Focused verification covers default theme, visible brand allowlist, export branding, and preserved clegacyatibility names.\n\n## Planned Evidence\n\nFocused tests/probes after implementation:\n\n```bash\nbun test packages/coding-agent/test/skc-ui-redesign.test.ts\nbun test packages/coding-agent/test/theme-auto-detection.test.ts packages/coding-agent/test/status-line-overflow.test.ts packages/coding-agent/test/status-line-path.test.ts\nbun scripts/verify-skc-ui-redesign.ts\nbun --cwd=packages/coding-agent run check\n```\n\nManual/render probes:\n\n1. Launch with no explicit theme config and capture welcome/status/footer/tool-card flow.\n2. Launch with explicit non-red theme config and confirm it is not overwritten.\n3. Render status line at normal and narrow widths for default, clegacyact, full, Nerd, ASCII, and preserved custom settings.\n4. Render representative tool executions: pending, success, error, diff added/removed, spilled/truncated output, and image fallback.\n5. Render selectors/settings and ask/approval cards under red-octopus and ASCII/minimal-symbol mode.\n6. Generate a full session HTML export and inspect header/title/metadata/accent variables plus transcript readability.\n7. Inspect README screenshots/alt text and clegacyare them against the generated full-session export direction.\n\n## Risks and Mitigations\n\n- **Brand red becomes error/removal red** — Add token-level tests and rendered probes for brand, error, warning, and diff states.\n- **User-selected themes/status settings are overwritten** — Change defaults and bundled presets only; test explicit non-red theme/custom status preservation.\n- **Visible legacy/Pi removal breaks legacy configs** — Keep clegacyatibility aliases internally or opt-in, while removing current-product default visibility.\n- **Visual pass becomes subjective churn** — Centralize design in existing theme tokens and focused snapshots/probes; avoid framework replacement.\n- **Exports become too decorative for audits** — Brand only header/accent/metadata; keep transcript/code/tool content neutral and high contrast.\n- **Terminal fallback regressions** — Verify ASCII/minimal-symbol and narrow-width render paths.\n\n## Approval State\n\nThis plan is approved for tracking. Implementation still requires normal code review and verification before clegacyletion.\n",
7
+ "FORK_MAINTENANCE.md": "# Fork maintenance — keeping Sayknow-CLI synced with upstream\n\nSayknow-CLI is a **rebranded fork** of upstream `gajae-code`. We track upstream\nreleases without re-doing the rename by hand each time: the fork is a\n**reproducible function of `{upstream tag, our fork layer}`**.\n\n```\nfork tree = gen-tree(clean upstream tag)\n = codemod + fork-identity + overlay + patches\n```\n\nVerified: `gen-tree(v0.5.4)` byte-reproduces the `sayknow-fork` branch (excluding\nregenerated lockfiles + `*.generated.ts`).\n\n## Branch / remote topology\n\n| ref | meaning |\n| --- | --- |\n| `upstream` (remote) | `github.com/Yeachan-Heo/gajae-code` — read-only source |\n| `origin` (remote) | `github.com/jaybeyond/Sayknow_CLI` — our fork |\n| `main` (local) / `origin/main` | our shippable fork (local branch `sayknow-fork` → `origin/main`) |\n| `origin/upstream-mirror` | pristine upstream mirror (tag `upstream/v0.5.4`) |\n| tag `sayknow-v0.1.0` | fork release; tag `upstream/v0.5.4` | the upstream base it was generated from |\n\nBacked up: `git push origin sayknow-fork:main` (done). Local branch `sayknow-fork`\ntracks `origin/main`.\n\n## The four layers\n\n1. **codemod** — `scripts/apply-rebrand.ts`: deterministic brand rename\n (`gajae/gjc → sayknow/skc`, paths, `@sayknow-cli` scope) + identity\n special-cases (`can1357`/`Yeachan-Heo → jaybeyond`, discord → placeholder).\n Skips `bun.lock`/`Cargo.lock` (integrity hashes). Reproduces ~1885 files with\n **zero residual tokens**.\n2. **fork-identity** — `scripts/apply-fork-identity.ts` + `rebrand/identity.json`:\n stamps the fork **version** (`0.1.0`) onto workspace `package.json` + root\n catalog + `Cargo.toml`, as minimal format-preserving edits. **Bump the version\n here**, never with a global replace (that would corrupt CHANGELOG/lockfiles).\n3. **overlay** — `rebrand/overlay/**`: whole files we own outright (i18n module,\n `blue-octopus`/`red-octopus` themes, octopus assets, brand docs). Copied over\n the codemod output. **No line-level merge → zero conflict.**\n4. **patches** — `rebrand/patches/NN-*.patch`: the ~17 **in-place edits** to\n upstream-owned files (welcome redesign, theme default, i18n wiring, tests).\n Applied with `git apply --reject`. **This is the only conflict-prone layer.**\n\n`rebrand/manifest.json` declares which files are `patch` / `regenerate` /\n`toolingOnly`; everything else that differs becomes overlay automatically.\n\n## Sync to a new upstream release\n\n```sh\nbash scripts/sync-upstream.sh v0.5.5 # fetch tag, regenerate, run gates G1–G4\n```\n\nThis produces a generated, gate-verified tree in a temp worktree (it does **not**\nauto-commit). Then **adopt** it:\n\n```sh\n# review the generated tree printed by the sync command, then:\nrsync -a --delete --exclude .git <generated-wt>/ .\nbun install # refresh lockfiles\ngit add -A && git commit -m \"sync: upstream v0.5.5\"\ngit tag sayknow-v0.<n>.0 # bump rebrand/identity.json first if releasing\n```\n\n### When a patch conflicts (upstream changed a patched file)\n\n`git apply --reject` leaves `*.rej` files in the generated worktree. For each:\n\n1. Open the `.rej` and the target file, apply the change by hand.\n2. Re-extract so the patch matches the new upstream base:\n ```sh\n # after upstream is mirrored + codemod+finalizer applied to <base>:\n bun scripts/extract-fork-layer.ts --base <base> --fork <fixed-tree> --apply\n ```\n3. Commit the refreshed `rebrand/patches/`.\n\n**Lever:** the fewer in-place edits, the fewer future conflicts. Prefer expressing\nnew fork features as *new files* (overlay) or additive hooks rather than edits to\nupstream files. Today only ~17 files are patches; keep it small.\n\n## Gates (run by `sync`, or manually)\n\n| gate | check |\n| --- | --- |\n| **G1** | no residual `gajae/gjc/red-claw/...` tokens in the generated tree |\n| **G2** | codemod idempotence — a *second* `apply-rebrand` changes **0 files** (diff-based; the printed hit-count is unreliable, do not gate on it) |\n| **G3** | `bun --cwd=packages/coding-agent run check:types` |\n| **G4** | `bun test` brand/i18n/welcome suites |\n\n## Publishing to npm\n\n`scripts/publish-npm.ts` publishes the 9 workspace packages in dependency order\nusing **`bun publish`** (not `npm publish`): bun resolves `catalog:`/`workspace:`\ndeps to concrete versions at pack time, so the packages actually install. Plain\n`npm publish` leaves `catalog:` in the tarball and breaks `bun install -g sayknow-cli`.\n\nOne-time prerequisites (need your npm account — the script can't do these):\n\n1. Create the **`@sayknow-cli`** org/scope on npmjs.com (Settings → Add Organization\n → free unlimited public). All 9 packages are `@sayknow-cli/*`.\n2. `bunx npm login`\n\nThen:\n\n```sh\nbun run build:native # build the platform .node first\nbun scripts/publish-npm.ts --dry-run # preview tarballs (no login needed)\nbun scripts/publish-npm.ts # publish for real\n```\n\nAfter publishing, `bun install -g sayknow-cli` works.\n\n> **Native binary is platform-specific.** `@sayknow-cli/natives` bundles a prebuilt\n> `.node` for the machine you publish from (e.g. `darwin-arm64`). A publish from an\n> Apple-Silicon Mac works for Apple-Silicon Mac users; **Linux / Windows / Intel-Mac\n> users get a \"failed to load native addon\" error.** Full cross-platform support\n> needs each platform's `.node` built in CI (`scripts/ci-release-build-binaries.ts`)\n> and shipped together — a follow-up, not a single-machine publish.\n\n## Regenerating the fork from scratch (audit)\n\n```sh\ngit worktree add --detach /tmp/u v0.6.0\nbun scripts/gen-tree.ts /tmp/u --build\ndiff -rq /tmp/u . -x .git -x node_modules -x bun.lock -x Cargo.lock -x '*.generated.ts'\n# → empty means the fork is fully reproducible from upstream + the fork layer\n```\n",
8
+ "REBRANDING_PLAN_260525.md": "# SKC Rebranding Plan — 2026-05-26\n\n## Status\n\nApproved plan for the sayknow-cli/SKC rebrand and visible UI redesign. This document records the implementation contract to track in GitHub and preserve in-repo.\nGitHub tracking issue: https://github.com/jaybeyond/Sayknow_CLI/issues/3\n\n## Decision\n\nRedesign the visible SKC terminal, export, and documentation surfaces around a coherent red-octopus sayknow-cli identity while preserving clegacyatibility boundaries.\n\nThe default-visible product should read as **sayknow-cli / SKC**, not legacy upstream branding or a generic inherited terminal skin. Red-claw becomes the default dark visual direction for users without an explicit override. Session exports and README screenshots should show the same brand direction, while exported transcript content remains neutral and readable.\n\n## Principles\n\n1. **SKC-first visible identity** — Default-visible UI should present sayknow-cli/red-octopus as the current product identity.\n2. **Clegacyatibility preservation** — Keep `skc`, `skc-stats`, `skc-swarm`, `@sayknow-cli/*`, legacy runtime roots/env aliases, and explicit attribution/history.\n3. **Semantic color integrity** — Brand red/coral/shell colors must stay distinct from error, warning, and diff-removal semantics.\n4. **Readable fallbacks** — Truecolor, 256-color, Unicode, Nerd Font, ASCII, narrow terminal, and imperfect-font modes must remain usable.\n5. **Audit-friendly exports** — HTML exports and docs use SKC header/accent/metadata branding without making transcript content decorative or hard to review.\n6. **Visible workflow minimization** — Default repo-shipped visible skills/workflows remain limited to `deep-interview`, `ralplan`, `team`, and `ultragoal`.\n\n## Scope\n\n### In scope\n\n- Default dark theme and bundled red-octopus palette.\n- Visible TUI surfaces: welcome, status line, footer/keybinding hints, message frames, assistant/user/custom/system messages, tool execution cards, ask/approval cards, selectors/settings, todo/plan surfaces, transcript chrome, diff/tool output styling.\n- Status-line identity cutover away from default-visible legacy/Pi/powerline styling.\n- Session HTML export header/accent/metadata branding while preserving transcript readability.\n- README screenshots/alt text and docs pages that present current SKC UI/export identity.\n- Static scans and tests for current-product brand leaks, clegacyatibility names, theme defaults, fallback readability, and export branding.\n\n### Out of scope\n\n- Renaming `skc`, `skc-stats`, `skc-swarm`, or `@sayknow-cli/*` package surfaces.\n- Removing legacy runtime roots, env aliases, clegacyatibility internals, migration notes, generated/vendor content, or attribution/history solely because they mention legacy/Pi.\n- Copying OpenAI code provider, SST/opencode, Anthropic Code, or legacy upstream visuals verbatim.\n- Making exports decorative enough to reduce audit readability.\n- Replacing the TUI framework as part of the brand redesign.\n\n## Implementation Plan\n\n### Phase 1 — Inventory and allowlist\n\n- Search active visible UI/docs/export surfaces for old-brand and inherited UI identity markers: legacy upstream markers, `skc`, `pi`, `powerline`, and generic export labels.\n- Classify hits as current product identity, explicit user opt-in setting labels, clegacyatibility internals, attribution/history/migration notes, or generated/vendor content.\n- Build or update verification gates so current-product visible leaks fail, but clegacyatibility and attribution do not.\n\n### Phase 2 — Theme defaults and palette semantics\n\n- Make red-octopus the default dark visual direction for users without explicit theme overrides.\n- Separate brand tokens (`brandRed`, `claw`, `coral`, `shell`) from semantic tokens (`dangerRed`, `warningAmber`, `diffRemovalRed`).\n- Ensure accents, borders, markdown, status-line identity, and export header variables use brand tokens while errors, warnings, and removals use semantic tokens.\n- Add focused tests for default theme resolution and token separation.\n\n### Phase 3 — Status-line identity cutover\n\n- Remove Pi from bundled default-visible status presets or replace it with clegacyact SKC/claw identity.\n- Preserve legacy segment/symbol clegacyatibility only as explicit opt-in or internal alias behavior.\n- Change default separators away from powerline-like styling; keep powerline variants available only as explicit user choices.\n- Verify status-line overflow, narrow-width, and ASCII/minimal-symbol behavior.\n\n### Phase 4 — Coherent TUI clegacyonent pass\n\nUse existing theme tokens rather than a new UI framework abstraction.\n\n- Apply shell/ink backgrounds, coral/claw accents, clegacyact borders, and lower-noise hierarchy across visible clegacyonents.\n- Refresh welcome, status line, footer hints, message frames, tool cards, ask/approval cards, selectors/settings, todo/plan surfaces, and transcript chrome.\n- Keep high-frequency tool cards inspectable: tool name, path/args, status, diff preview, truncation/expand hints, and error states remain clearer than decoration.\n- Confirm Unicode/Nerd/ASCII fallbacks for new visible symbols.\n\n### Phase 5 — Export and docs alignment\n\n- Update HTML export title/header/metadata to present SKC session export branding.\n- Keep message bodies, code blocks, tool output, system prlegacyts, and transcript content neutral and high contrast.\n- Regenerate derived export templates if required by the repository workflow.\n- Update README screenshots/alt text and docs references so the demonstrated TUI/export direction matches the implemented default.\n\n### Phase 6 — Verification and review\n\n- Run focused theme/status/export/static-scan tests first.\n- Run package-local checks after focused tests pass.\n- Run cleanup/refactor review on changed files.\n- Rerun verification after cleanup.\n- Run final code review and resolve blockers before considering the implementation clegacylete.\n\n## Acceptance Criteria\n\n- [ ] Default dark theme resolves to red-octopus/SKC for users without explicit theme override.\n- [ ] Brand/accent tokens are distinct from error, warning, and diff-removal tokens.\n- [ ] Default-visible status-line identity no longer leads with legacy/Pi-style branding.\n- [ ] Default-visible status separators no longer use powerline-style styling unless explicitly opted in.\n- [ ] Visible TUI clegacyonents share one coherent SKC language across welcome, status line, footer hints, message frames, tool execution cards, ask/approval cards, selectors/settings, and todo/plan surfaces.\n- [ ] Static scans of active UI/docs/export surfaces do not present legacy/Pi as current product identity; clegacyatibility internals, attribution/history, generated/vendor content, and migration notes remain allowlisted.\n- [ ] Full session HTML export includes SKC header/accent/metadata branding while preserving neutral readable transcript content.\n- [ ] README screenshots and alt text show the same SKC/red-octopus brand direction as the TUI/export surfaces.\n- [ ] Redesign remains readable under fallback terminal modes, including ASCII/minimal-symbol operation.\n- [ ] Focused verification covers default theme, visible brand allowlist, export branding, and preserved clegacyatibility names.\n\n## Planned Evidence\n\nFocused tests/probes after implementation:\n\n```bash\nbun test packages/coding-agent/test/skc-ui-redesign.test.ts\nbun test packages/coding-agent/test/theme-auto-detection.test.ts packages/coding-agent/test/status-line-overflow.test.ts packages/coding-agent/test/status-line-path.test.ts\nbun scripts/verify-skc-ui-redesign.ts\nbun --cwd=packages/coding-agent run check\n```\n\nManual/render probes:\n\n1. Launch with no explicit theme config and capture welcome/status/footer/tool-card flow.\n2. Launch with explicit non-red theme config and confirm it is not overwritten.\n3. Render status line at normal and narrow widths for default, clegacyact, full, Nerd, ASCII, and preserved custom settings.\n4. Render representative tool executions: pending, success, error, diff added/removed, spilled/truncated output, and image fallback.\n5. Render selectors/settings and ask/approval cards under red-octopus and ASCII/minimal-symbol mode.\n6. Generate a full session HTML export and inspect header/title/metadata/accent variables plus transcript readability.\n7. Inspect README screenshots/alt text and clegacyare them against the generated full-session export direction.\n\n## Risks and Mitigations\n\n- **Brand red becomes error/removal red** — Add token-level tests and rendered probes for brand, error, warning, and diff states.\n- **User-selected themes/status settings are overwritten** — Change defaults and bundled presets only; test explicit non-red theme/custom status preservation.\n- **Visible legacy/Pi removal breaks legacy configs** — Keep clegacyatibility aliases internally or opt-in, while removing current-product default visibility.\n- **Visual pass becomes subjective churn** — Centralize design in existing theme tokens and focused snapshots/probes; avoid framework replacement.\n- **Exports become too decorative for audits** — Brand only header/accent/metadata; keep transcript/code/tool content neutral and high contrast.\n- **Terminal fallback regressions** — Verify ASCII/minimal-symbol and narrow-width render paths.\n\n## Approval State\n\nThis plan is approved for tracking. Implementation still requires normal code review and verification before clegacyletion.\n",
9
9
  "ai-schema-normalize.md": "# AI tool-schema normalization\n\n`@sayknow-cli/ai` exposes one unified schema normalizer that providers consume\nbefore tools are sent on the wire. All walkers live in\n`packages/ai/src/utils/schema/normalize.ts`; the operational contract is\n`packages/ai/src/utils/schema/CONSTRAINTS.md`.\n\nThere is no separate `strict-mode.ts` module any more — OpenAI strict-mode\nsanitization, OpenAI Responses `oneOf` rewriting, Google/Vertex/Gemini-CLI\nsanitization, Cloud Code Assist Anthropic sanitization, and MCP sanitization all\nshare the same option-driven walk.\n\n## Entry points\n\nAll exports live under `@sayknow-cli/ai/utils/schema`:\n\n- `normalizeSchema(value, options)` — generic option-driven walker.\n- `normalizeSchemaForGoogle(value)` — Gemini / Vertex / Gemini CLI.\n- `normalizeSchemaForCCA(value)` — Cloud Code Assist Anthropic (Antigravity + GCA).\n- `normalizeSchemaForMCP(value)` — MCP inputSchemas before they enter the\n custom-tool registry. `tool-bridge.ts` runs every MCP `inputSchema` through\n this dispatcher.\n- `normalizeSchemaForOpenAIResponses(schema)` (alias\n `sanitizeSchemaForOpenAIResponses`) — rewrites `oneOf` → `anyOf` for the\n Responses family.\n- `sanitizeSchemaForStrictMode(schema)` and\n `enforceStrictSchema(schema)` / `tryEnforceStrictSchema(schema)` — the\n OpenAI strict-mode pipeline (sanitize → enforce). All three are exported\n from `normalize.ts`.\n- `adaptSchemaForStrict(schema, strict)` from `./adapt` — thin composer that\n wraps `tryEnforceStrictSchema` for provider call sites and consults\n `SKC_NO_STRICT` (env `SKC_NO_STRICT`) for the global bypass.\n\nRemoved in the unified-flow refactor:\n\n- `strict-mode.ts` (merged into `normalize.ts`).\n- `sanitize-google.ts` and `normalize-cca.ts` (replaced by\n `normalizeSchemaFor*` dispatchers).\n- `StringEnum` helper — use `z.enum([...])` directly; Zod's emitted JSON\n Schema is already wire-compatible with Google and other providers.\n- `sanitizeSchemaFor{Google,CCA,MCP}` / `prepareSchemaForCCA` — renamed to\n `normalizeSchemaFor{Google,CCA,MCP}`.\n\n## Dispatcher mapping\n\n| Provider transport(s) | Dispatcher |\n| -------------------------------------------------------------------- | -------------------------------------------- |\n| `openai-completions`, `openai-responses`, `openai-code-responses` | `adaptSchemaForStrict` (sanitize + enforce) |\n| `openai-responses` family (`oneOf` → `anyOf` only) | `normalizeSchemaForOpenAIResponses` |\n| `google-generative-ai`, `google-vertex`, Gemini CLI | `normalizeSchemaForGoogle` |\n| Cloud Code Assist Anthropic (Antigravity + GCA, `anthropic-model-*` model ids) | `normalizeSchemaForCCA` |\n| MCP `inputSchema` ingestion | `normalizeSchemaForMCP` |\n| `anthropic-messages` (native, not CCA) | per-provider whitelist in `anthropic.ts` |\n\nGemini CLI / Antigravity CCA MUST run the full `normalizeSchemaForCCA`\npipeline (not just the first keyword-stripping pass) to keep parity with the\nshared Google Anthropic path.\n\n## Walk semantics\n\n`normalizeSchema` first upgrades the input to JSON Schema 2020-12, then\nwalks the tree with the option set pinned by the dispatcher. Each node:\n\n1. Inlines `$ref` (see \"Edge cases\" below).\n2. Renames `snake_case` combinator/property keys to camelCase\n (`any_of` → `anyOf`, etc.; collisions follow python-genai\n `pop(from)`/`set(to)` semantics — snake_case wins).\n3. Applies the `handle_null_fields` collapse for nullable unions before\n recursing into children.\n4. Strips keys the target provider does not support, optionally lifting\n human-meaningful keys (`pattern`, `format`, min/max, `default`,\n `examples`, ...) into the sibling `description` via the spill formatter\n (`spill.ts`). Structural/meta keys (`$ref`, `$defs`,\n `additionalProperties`) are not spilled.\n5. Normalizes type unions (`type: [\"T\", \"null\"]` → `type: \"T\"` + nullable\n marker on Google, plain `type: \"T\"` on CCA).\n6. Collapses object-only / same-type combiners, optionally lossy-collapses\n mixed-type combiners (CCA only), and runs the residual-combiner fixpoint.\n7. Validates against AJV 2020 when `validateAndFallback` is set (CCA path)\n and emits the per-tool fallback `{ \"type\": \"object\", \"properties\": {} }`\n on residual incompatibility — `type` array, `type: \"null\"`, `nullable`\n key, or any remaining `anyOf`/`oneOf`/`allOf`.\n\n## OpenAI strict-mode pipeline\n\n`adaptSchemaForStrict(schema, strict)` runs `tryEnforceStrictSchema`,\nwhich composes:\n\n1. **Sanitize** (`sanitizeSchemaForStrictMode`): strips non-structural\n keywords (`format`, `pattern`, min/max, `examples`, `default`,\n `if`/`then`/`else`, `not`, `unevaluated*`, `patternProperties`,\n `dependent*`, `content*`, `min/maxProperties`, `$dynamicRef`, etc.). The\n `default` value is inlined into the sibling `description` as\n ` (default: X)` before being dropped, unless `description` already\n contains `(default:` or no `description` exists.\n2. **Enforce** (`enforceStrictSchema`): every object node gets\n `additionalProperties: false`, every property goes into `required`, and\n optional properties become nullable unions\n (`anyOf: [<original>, { \"type\": \"null\" }]`). Tuple `prefixItems` are\n strictified recursively.\n\nThe two passes share node-level caches and the same epoch-based cycle\nguard, so a single walk on the wire path normalizes refs, allOf, and\nnullable wrapping consistently. `tryEnforceStrictSchema` is fail-open:\nif anything throws, it returns `{ strict: false, schema: original }` so\ncallers MUST emit `strict: true` only when enforcement actually succeeded.\n\n### Edge cases the strict-mode normalizer handles\n\n- **Local `$ref` inlining.** OpenAI strict mode rejects\n `{ \"$ref\": \"...\", \"description\": \"...\" }` with sibling keys. The\n sanitizer pre-resolves local `#/...` refs against the root and merges\n with **sibling keys winning** over the resolved def — same precedence\n as `openai-python`'s `_ensure_strict_json_schema`. Recursive refs are\n guarded by the per-walk epoch.\n- **Single-item `allOf`.** A `{ \"allOf\": [X], ...siblings }` collapses to\n `{ ...X, ...siblings }` with the inlined entry's keys winning over the\n original siblings (matches `openai-python`'s `_pydantic.py:79-83`). Multi-\n item `allOf` is left intact for the downstream validator to reject if\n needed.\n- **Type-array branches and nullable unions.** When a node has\n `type: [\"T\", \"U\"]`, the sanitizer emits one variant schema per type,\n pruning type-specific keywords (e.g. `properties`/`required` only stay on\n the `object` variant, `items` only on the `array` variant). The shared\n `description` is **hoisted onto the `anyOf` wrapper** instead of being\n duplicated on every branch — so a strict nullable union becomes\n `{ anyOf: [T, { type: \"null\" }], description: \"...\" }`, not\n `anyOf: [{ ..., description }, { ..., description }]`.\n- **Enum/const without a `type`.** Both sanitize and enforce paths call\n `inferStrictPrimitiveTypeFromEnumOrConst` to infer the primitive `type`\n from `enum` / `const` values. Mixed-primitive enums (`[1, \"two\", null]`),\n enums containing objects/arrays, and non-primitive `const` values\n (`{a:1}`, `[1,2,3]`) cannot be described by a single `type` keyword and\n trigger the strict-mode fail-open path — emitting a typeless schema\n would just be rejected on the wire by OpenAI.\n\n## Performance: static fingerprint cache\n\n`resolveProviderModels` in `packages/ai/src/model-manager.ts` and\n`readModelCache`/`writeModelCache` in `model-cache.ts` cooperate via a\nschema-v3 `static_fingerprint` column on the `model_cache` SQLite table.\n\n- `fingerprintStatic(staticModels)` hashes the static catalog slice\n (`Bun.hash(JSON.stringify(models))` in base36) and memoizes the result\n in a per-process `WeakMap` keyed by the array reference. Multiple\n cold-start arms calling `resolveProviderModels` with the same\n `staticModels` array pay the JSON+hash cost once.\n- On cache read, if the network fetch is being skipped, the cached row is\n fresh + authoritative, and the cached `static_fingerprint` matches the\n current one, `resolveProviderModels` returns the cached models verbatim\n — the cache already incorporates the same static state, so re-running\n `mergeDynamicModels(static, cache)` would just rebuild the same objects.\n- `mergeModelSources` and `mergeDynamicModels` short-circuit on\n empty-source inputs (the common shape after `(static, [])` or for\n providers without a static catalog), avoiding Map churn entirely.\n\nCache rows written before schema v3 are dropped by the cache-version\ncheck; the column defaults to `''` for any row that survives a version\nupgrade so the fingerprint-equality check naturally fails closed and the\nfull merge re-runs.\n\n## Related\n\n- `docs/models.md` — registry, equivalence, compat flags\n (`supportsStrictMode`, `toolStrictMode`, `disableStrictTools`).\n- `docs/provider-streaming-internals.md` — how the normalized schemas are\n used downstream during the provider stream loop.\n- `packages/ai/src/utils/schema/CONSTRAINTS.md` — operational contract for\n every normalization rule.\n",
10
10
  "auth-broker-gateway.md": "# Auth Broker and Auth Gateway\n\nThe auth broker and auth gateway are two cooperating HTTP services that move OAuth refresh tokens and provider access tokens off developer laptops and into a single broker host.\n\n- **`skc auth-broker serve`** holds the canonical SQLite credential vault, performs OAuth refreshes, and exposes a small REST API (`/v1/snapshot`, `/v1/credential/:id/refresh`, `/v1/credential/:id/disable`, `/v1/credential`, `/v1/usage`, `/v1/healthz`).\n- **`skc auth-gateway serve`** is a forward-proxy. It accepts OpenAI Chat Completions, Anthropic Messages, and OpenAI Responses requests, injects the broker-resolved access token, and forwards the bytes to the real provider. Clients (containerised skc, llm-git, the macOS usage widget, …) never see the access token.\n\nTransport security between operator, broker, and gateway is delegated to the operator (Tailscale / Wireguard / reverse proxy + TLS). Every endpoint except `/v1/healthz` (broker) and `/healthz` (gateway) requires a bearer token.\n\nSource: `packages/ai/src/auth-broker/`, `packages/ai/src/auth-gateway/`, `packages/coding-agent/src/cli/auth-broker-cli.ts`, `packages/coding-agent/src/cli/auth-gateway-cli.ts`, `packages/coding-agent/src/session/auth-broker-config.ts`.\n\n## Data flow\n\n```\n ┌────────────────────────────────────────────────────────────┐\n │ broker host │\n │ │\n developer ──▶ │ ┌──────────────────────────┐ ┌────────────────────┐ │\n laptop / │ │ skc auth-broker serve │◀──▶│ SQLite agent.db │ │\n CI / roboskc │ │ - holds refresh tokens │ │ (canonical writer)│ │\n │ │ - background refresher │ └────────────────────┘ │\n │ │ /v1/{snapshot,refresh,…}│ │\n │ └─────────┬────────────────┘ │\n │ │ bearer ($CONFIG_DIR/auth-broker.token) │\n │ ▼ │\n │ ┌──────────────────────────┐ │\n │ │ skc auth-gateway serve │ RemoteAuthCredentialStore │\n │ │ /v1/{chat,messages,…} │ pulls /v1/snapshot at boot, │\n │ │ /v1/usage, /v1/models │ refreshes credentials by id │\n │ └─────────┬────────────────┘ via the broker on expiry │\n └────────────┼───────────────────────────────────────────────┘\n │ bearer ($CONFIG_DIR/auth-gateway.token)\n ▼\n unauthenticated clients\n (llm-git, macOS widget, roboskc containers, IDE plugins, …)\n │\n ▼ same path is forwarded with Authorization\n api.anthropic.com / api.openai.com / …\n```\n\nThe broker is the only writer of OAuth refresh tokens. Clients (including the gateway itself) load a redacted snapshot in which every `refresh` field has been replaced with `REMOTE_REFRESH_SENTINEL`; when an access token expires the client calls `POST /v1/credential/:id/refresh` and the broker performs the refresh server-side. `RemoteAuthCredentialStore` rejects any local code path that tries to write through it, with an error pointing at `skc auth-broker login` / `skc auth-broker logout`.\n\n## auth-broker\n\n### CLI\n\n```\nskc auth-broker serve [--bind=host:port] # boot the broker\nskc auth-broker token [--regenerate] [--json] # print or rotate the bearer token\nskc auth-broker login <provider> [--via=user@host] [--dry-run]\nskc auth-broker logout <provider>\nskc auth-broker import <file|dir> [--provider=<id>] [--include-disabled] [--dry-run] [--json]\nskc auth-broker migrate --from-local [--dry-run] [--json]\nskc auth-broker status [--json]\n```\n\n- `serve` opens the local SQLite store at `getAgentDbPath()` and binds an HTTP listener (default `127.0.0.1:8765`). On startup a token is ensured at `<config-dir>/auth-broker.token` (mode `0600`, `0700` parent dir). The background refresher refreshes any OAuth credential whose `expires - Date.now() < refreshSkewMs` (default 5 min) every `refreshIntervalMs` (default 60 s).\n- `token` prints the cached bearer or generates a new one. `--regenerate` rotates it.\n- `login <provider>` runs the per-provider OAuth flow locally, or — with `--via=user@host` — `ssh -L <callback-port>:127.0.0.1:<callback-port> user@host skc auth-broker login <provider>` so the OAuth callback hits the local browser but the credential is written on the broker host. Built-in callback ports: `anthropic:54545`, `openai-code:1455`, `google-gemini-cli:8085`, `google-antigravity:51121`, `gitlab-duo:8080`.\n- `logout <provider>` deletes every credential row for `<provider>`.\n- `import <file|dir>` imports CLIProxyAPI-style JSON credentials into the local SQLite store. Maps `type` field → skc provider (`anthropic-model → anthropic`, `openai-code → openai-code`, `gemini → google-gemini-cli`, `antigravity → google-antigravity`, `gemini-cli → google-gemini-cli`).\n- `migrate --from-local` walks the local SQLite store + env-derived credentials and idempotently uploads them to the configured broker (`POST /v1/credential`).\n- `status` health-pings the configured remote broker.\n\n### Endpoints\n\n| Method | Path | Auth | Purpose |\n| ------ | ---- | ---- | ------- |\n| `GET` | `/v1/healthz` | none | Liveness + version |\n| `GET` | `/v1/snapshot` | bearer | Redacted snapshot (refresh tokens replaced by sentinel) |\n| `POST` | `/v1/credential` | bearer | Upsert one OAuth or API-key credential |\n| `POST` | `/v1/credential/:id/refresh` | bearer | Force-refresh one OAuth credential |\n| `POST` | `/v1/credential/:id/disable` | bearer | Disable one credential with a recorded cause |\n| `GET` | `/v1/usage` | bearer | Aggregate `UsageReport[]` across credentials |\n\nRequests use `Authorization: Bearer <token>`. The server compares against an in-memory token allow-list; the gateway’s implementation uses a timing-safe comparison.\n\n### Background refresher\n\n`AuthBrokerRefresher` iterates active OAuth credentials at `refreshIntervalMs` cadence and refreshes any within `refreshSkewMs` of expiry. Refreshes are single-flighted per credential id so a slow refresh cannot be retriggered. The refresher distinguishes:\n\n- **definitive failures** (`invalid_grant`, `invalid_token`, `revoked`, unauthorized refresh-token, 401/403 not from a network blip) — credentials are passed to `AuthStorage.disableCredentialById(id, cause)` so the next snapshot pull surfaces a clean delete on the client;\n- **transient failures** (timeout / ECONNREFUSED / fetch failed) — left in place for the next sweep.\n\n## auth-gateway\n\n### CLI\n\n```\nskc auth-gateway serve [--bind=host:port] [--no-auth]\nskc auth-gateway token [--regenerate] [--json]\nskc auth-gateway status [--json]\n```\n\n- `serve` requires `SKC_AUTH_BROKER_URL` (or `auth.broker.url` in `config.yml`) — the gateway is itself a broker client. It calls `AuthBrokerClient.fetchSnapshot()`, wraps it in `RemoteAuthCredentialStore`, and constructs an `AuthStorage` that resolves access tokens through the broker. Default bind is `127.0.0.1:4000`. The gateway token is stored at `<config-dir>/auth-gateway.token` (`0600`); `--no-auth` disables the bearer check entirely (loopback-only use).\n- `token` / `status` mirror the broker’s equivalents.\n\n### Endpoints\n\n| Method | Path | Auth | Purpose |\n| ------ | ---- | ---- | ------- |\n| `GET` | `/healthz` | none | Liveness + version |\n| `GET` | `/v1/usage` | bearer | Aggregate `UsageReport[]` (proxied through `AuthStorage`) |\n| `GET` | `/v1/models` | bearer | Bundled-model catalog filtered to providers with credentials |\n| `POST` | `/v1/chat/completions` | bearer | OpenAI Chat Completions wire format |\n| `POST` | `/v1/messages` | bearer | Anthropic Messages wire format |\n| `POST` | `/v1/responses` | bearer | OpenAI Responses wire format |\n\nThe model id is read from the top-level `model` field. The gateway picks the first bundled `Model<Api>` matching that id and:\n\n- **Passthrough fast-path** — when the inbound wire format matches the model’s native API (`openai-chat → openai-completions`, `anthropic-messages → anthropic-messages`, `openai-responses → openai-responses`), the request body is forwarded byte-for-byte with the client `Authorization`/`x-api-key` stripped and replaced by `Authorization: Bearer <resolved-access-token>`. Provider-specific fields (`cache_control`, `service_tier`, tool-choice extensions, …) flow through unmodified. Hop-by-hop headers (RFC 7230) plus `Content-Encoding`/`Content-Length` are stripped from the upstream response.\n- **Translate path** — when the inbound format and the resolved model’s API differ (e.g. `/v1/chat/completions` targeting an Anthropic model, or `/v1/responses` targeting `openai-code-responses` which runs over a websocket transport), the request is parsed against the wire schema, rebuilt into an skc `Context`, dispatched through `streamSimple()`, and re-encoded back to the inbound format (SSE for streamed responses).\n\n`idleTimeout` on the underlying `Bun.serve` is set to `255 s` so long thinking-budget calls do not get killed by Bun’s default idle timeout.\n\n## Usage cache: server-side 5-min jitter + client-side 15 s single-flight\n\nTwo layers cache the aggregate provider-usage report. Both are intentional and stacked.\n\n### Server-side cache (broker `AuthStorage`)\n\n`AuthStorage` caches each credential’s `UsageReport` in the broker’s SQLite store at a **5-minute per-credential TTL with ±25 % jitter**. Anthropic and OpenAI rate-limit `/usage` aggressively per source IP, and a synchronized 5-credential fan-out trips 429s every cycle; the jitter decorrelates refresh times within a few cycles. On fetch failure the store keeps the **last-good** report for up to 24 h with a short jittered re-poll window — so a transient upstream blip never blanks out the widget.\n\nConstants: `USAGE_REPORT_TTL_MS = 5 * 60_000`, `USAGE_LAST_GOOD_RETENTION_MS = 24 * 60 * 60_000` (`packages/ai/src/auth-storage.ts`).\n\n### Client-side single-flight (`RemoteAuthCredentialStore`)\n\nWhen the gateway (or any other broker client) calls `fetchUsageReports()` / `getUsageReport(provider, credential)`, `RemoteAuthCredentialStore` coalesces concurrent calls into a single `GET /v1/usage` round-trip and caches the result for **15 s** in memory.\n\n- `USAGE_CACHE_TTL_MS = 15_000` (`packages/ai/src/auth-broker/remote-store.ts`).\n- A single `#usageInflight` promise is shared across all callers; a per-caller `AbortSignal` is **raced** against the shared promise, not threaded into it, so one caller’s abort never cascades into a peer’s in-flight request.\n- On fetch failure the rejected promise is logged and the awaited value is `null` — callers (`AuthStorage.fetchUsageReports`, `#getUsageReport`) treat a `null` report as \"no usage signal for this cycle\" and proceed without it. **This is the 15 s TTL fallback**: the client absorbs transient broker outages by suppressing the error, returning `null` to ranking, and re-attempting after the 15 s window.\n\nThe 15 s client window deliberately sits below the broker’s 5 min server cache, so almost every client poll is served from the broker’s already-cached value; the client cache exists to absorb the parallel fan-out generated by `AuthStorage.#rankOAuthSelections` into a single broker round-trip.\n\n## Operator opt-in\n\nThe broker is **off** unless `SKC_AUTH_BROKER_URL` (or `auth.broker.url` in `config.yml`) is set. When set, `discoverAuthStorage` in `packages/coding-agent/src/sdk.ts` swaps the local SQLite credential store for `RemoteAuthCredentialStore` and every API call resolves credentials through the broker.\n\n### Environment variables\n\n| Variable | Purpose | Required when |\n| -------- | ------- | ------------- |\n| `SKC_AUTH_BROKER_URL` | Base URL of the remote auth-broker (e.g. `https://broker.tailnet:8765`). Selecting this puts the client in broker mode — local SQLite is bypassed. | Any time the skc client should resolve credentials through a broker (and required by `skc auth-gateway serve`). |\n| `SKC_AUTH_BROKER_TOKEN` | Bearer token used for every broker endpoint except `/v1/healthz`. | When `SKC_AUTH_BROKER_URL` is set and no token is available from `auth.broker.token` or `<config-dir>/auth-broker.token`. |\n\nResolution order in `resolveAuthBrokerConfig()`:\n\n1. `SKC_AUTH_BROKER_URL` env (else `auth.broker.url` from `config.yml`, with `$ENV_NAME` resolution);\n2. `SKC_AUTH_BROKER_TOKEN` env (else `auth.broker.token` from `config.yml`, else `<config-dir>/auth-broker.token`);\n3. URL set but no token resolvable → hard error pointing at the token file path.\n\nThe gateway has no dedicated env vars — it inherits `SKC_AUTH_BROKER_*` because it is itself a broker client.\n\n### `config.yml` keys\n\n| Key | Default | Purpose |\n| --- | ------- | ------- |\n| `auth.broker.url` | unset | Same as `SKC_AUTH_BROKER_URL`; env wins. Hidden from the settings UI. |\n| `auth.broker.token` | unset | Same as `SKC_AUTH_BROKER_TOKEN`; env wins. Values may be the literal token or `$ENV_NAME` to indirect through env. |\n\n### Token files\n\n| Path | Owner | Mode |\n| ---- | ----- | ---- |\n| `<config-dir>/auth-broker.token` | `skc auth-broker serve` (created at first start) | `0600` in a `0700` parent dir |\n| `<config-dir>/auth-gateway.token` | `skc auth-gateway serve` (skipped under `--no-auth`) | `0600` in a `0700` parent dir |\n\n`<config-dir>` resolves to `~/.skc/` (respecting `SKC_CONFIG_DIR`).\n\n## Interaction with the local API-key resolution order\n\nThe broker only owns OAuth credentials and provider-API-key credentials that were uploaded to it. The standard credential ladder in `models.md` (`Auth and API key resolution order`) is preserved, with one addition committed alongside the gateway:\n\n- `AuthStorage.setConfigApiKey / removeConfigApiKey / clearConfigApiKeys` let a `models.yml` `apiKey` beat a stored OAuth token **without** overriding an explicit `--api-key`. This is what allows a broker-resolved OAuth credential to be reliably shadowed by a per-environment `models.yml` config key when both are present.\n\n## See also\n\n- [`secrets.md`](./secrets.md) — secret obfuscation around tokens that *do* leak through (e.g. `SKC_AUTH_BROKER_TOKEN` in shell output).\n- [`models.md`](./models.md) — provider auth resolution order; the broker plugs in at layers 2–3 (stored credentials).\n- [`environment-variables.md`](./environment-variables.md) — full env reference including `SKC_AUTH_BROKER_URL` / `SKC_AUTH_BROKER_TOKEN`.\n",
11
11
  "bash-tool-runtime.md": "# Bash tool runtime\n\nThis document describes the **`bash` tool** runtime path used by agent tool calls, from command normalization to execution, truncation/artifacts, and rendering.\n\nIt also calls out where behavior diverges in interactive TUI, print mode, RPC mode, and user-initiated bang (`!`) shell execution.\n\n## Scope and runtime surfaces\n\nThere are two different bash execution surfaces in coding-agent:\n\n1. **Tool-call surface** (`toolName: \"bash\"`): used when the model calls the bash tool.\n - Entry point: `BashTool.execute()`.\n - Parameters include `command`, optional `env`, `timeout`, `cwd`, `head`, `tail`, `pty`, and, when `async.enabled` is true, `async`.\n2. **User bang-command surface** (`!cmd` from interactive input or RPC `bash` command): session-level helper path.\n - Entry point: `AgentSession.executeBash()`.\n\nBoth eventually use `executeBash()` in `src/exec/bash-executor.ts` for non-PTY execution, but only the tool-call path runs normalization/interception, optional managed background-job handling, and tool renderer logic.\n\n## End-to-end tool-call pipeline\n\n## 1) Input handling and parameter merge\n\n`BashTool.execute()` currently handles input before execution as follows:\n\n- validates optional `env` names against shell-variable syntax,\n- extracts a leading `cd <path> && ...` into `cwd` when `cwd` was not supplied,\n- rejects `async: true` when `async.enabled` is false,\n- uses only explicit `head`/`tail` tool args for post-run filtering.\n\n`normalizeBashCommand()` still exists in `src/tools/bash-normalize.ts`, but `BashTool.execute()` does not call it in the current source. Trailing shell pipes such as `| head -n 50` remain part of the shell command unless the caller uses the structured `head`/`tail` args.\n\n## 2) Optional interception (blocked-command path)\n\nIf `bashInterceptor.enabled` is true, `BashTool` loads rules from settings and runs `checkBashInterception()` against the normalized command.\n\nInterception behavior:\n\n- command is blocked **only** when:\n - regex rule matches, and\n - the suggested tool is present in `ctx.toolNames`.\n- invalid regex rules are silently skipped.\n- on block, `BashTool` throws `ToolError` with message:\n - `Blocked: ...`\n - original command included.\n\nDefault rule patterns (defined in code) target common misuses:\n\n- file readers (`cat`, `head`, `tail`, ...)\n- search tools (`grep`, `rg`, ...)\n- file finders (`find`, `fd`, ...)\n- in-place editors (`sed -i`, `perl -i`, `awk -i inplace`)\n- shell redirection writes (`echo ... > file`, heredoc redirection)\n\n### Caveat\n\n`InterceptionResult` includes `suggestedTool`, but `BashTool` currently surfaces only the message text (no structured suggested-tool field in `details`).\n\n## 3) CWD validation and timeout clamping\n\n`cwd` is resolved relative to session cwd (`resolveToCwd`), then validated via `stat`:\n\n- missing path -> `ToolError(\"Working directory does not exist: ...\")`\n- non-directory -> `ToolError(\"Working directory is not a directory: ...\")`\n\nTimeout is clamped to `[1, 3600]` seconds and converted to milliseconds.\n\n## 4) Artifact allocation\n\nBefore execution, the tool allocates an artifact path/id (best-effort) for truncated output storage.\n\n- artifact allocation failure is non-fatal (execution continues without artifact spill file),\n- artifact id/path are passed into execution path for full-output persistence on truncation.\n\n## 5) PTY vs non-PTY execution selection\n\n`BashTool` chooses PTY execution only when all are true:\n\n- tool input `pty === true`\n- `SKC_NO_PTY !== \"1\"`\n- tool context has UI (`ctx.hasUI === true` and `ctx.ui` set)\n\nOtherwise it uses non-interactive `executeBash()`.\n\nThat means print mode and non-UI RPC/tool contexts always use non-PTY.\n\n## Non-interactive execution engine (`executeBash`)\n\n## Shell session reuse model\n\n`executeBash()` caches native `Shell` instances in a process-global map keyed by:\n\n- shell path,\n- configured command prefix,\n- snapshot path,\n- serialized shell env,\n- optional agent session key.\n\nSession-level bang-command executions pass `sessionKey: this.sessionId`.\n\nTool-call executions pass `sessionKey: this.session.getSessionId?.()`, when available. In both surfaces, a session key isolates shell reuse per session; without one, reuse falls back to shell config/snapshot/env.\n\n## Shell config and snapshot behavior\n\nAt each call, executor loads settings shell config (`shell`, `env`, optional `prefix`).\n\nIf selected shell includes `bash`, it attempts `getOrCreateSnapshot()`:\n\n- snapshot captures aliases/functions/options from user rc,\n- snapshot creation is best-effort,\n- failure falls back to no snapshot.\n\nIf `prefix` is configured, command becomes:\n\n```text\n<prefix> <command>\n```\n\n## Streaming and cancellation\n\n`Shell.run()` streams chunks to `OutputSink` and optional `onChunk` callback.\n\nCancellation:\n\n- aborted signal triggers `shellSession.abort(...)`,\n- timeout from native result is mapped to `cancelled: true` + annotation text,\n- explicit cancellation similarly returns `cancelled: true` + annotation.\n\nNo exception is thrown inside executor for timeout/cancel; it returns structured `BashResult` and lets caller map error semantics.\n\n## Interactive PTY path (`runInteractiveBashPty`)\n\nWhen PTY is enabled, tool runs `runInteractiveBashPty()` which opens an overlay console component and drives a native `PtySession`.\n\nBehavior highlights:\n\n- xterm-headless virtual terminal renders viewport in overlay,\n- keyboard input is normalized (including Kitty sequences and application cursor mode handling),\n- `esc` while running kills the PTY session,\n- terminal resize propagates to PTY (`session.resize(cols, rows)`).\n\nEnvironment hardening defaults are injected for unattended runs:\n\n- pagers disabled (`PAGER=cat`, `GIT_PAGER=cat`, etc.),\n- editor prompts disabled (`GIT_EDITOR=true`, `EDITOR=true`, ...),\n- terminal/auth prompts reduced (`GIT_TERMINAL_PROMPT=0`, `SSH_ASKPASS=/usr/bin/false`, `CI=1`),\n- package-manager/tool automation flags for non-interactive behavior.\n\nPTY output is normalized (`CRLF`/`CR` to `LF`, `sanitizeText`) and written into `OutputSink`, including artifact spill support.\n\nOn PTY startup/runtime error, sink receives `PTY error: ...` line and command finalizes with undefined exit code.\n\n## Output handling: streaming, truncation, artifact spill\n\nBoth PTY and non-PTY paths use `OutputSink`.\n\n## OutputSink semantics\n\n- keeps an in-memory UTF-8-safe tail buffer (`DEFAULT_MAX_BYTES`, currently 50KB),\n- tracks total bytes/lines seen,\n- if artifact path exists and output overflows (or file already active), writes full stream to artifact file,\n- when memory threshold overflows, trims in-memory buffer to tail (UTF-8 boundary safe),\n- marks `truncated` when overflow/file spill occurs.\n\n`dump()` returns:\n\n- `output` (possibly annotated prefix),\n- `truncated`,\n- `totalLines/totalBytes`,\n- `outputLines/outputBytes`,\n- `artifactId` if artifact file was active.\n\n### Long-output caveat\n\nRuntime truncation is byte-threshold based in `OutputSink` (50KB default). It does not enforce a hard 2000-line cap in this code path.\n\n## Live tool updates and async jobs\n\nFor non-PTY foreground execution, `BashTool` uses a separate `TailBuffer` for partial updates and emits `onUpdate` snapshots while command is running.\n\nFor PTY execution, live rendering is handled by custom UI overlay, not by `onUpdate` text chunks.\n\nWhen `async.enabled` is true and the call passes `async: true`, `BashTool` starts a managed bash job, returns a running job result with a job id, and stores completion through the session managed-job path. Auto-backgrounding can also start this path after `bash.autoBackground.thresholdMs`.\n\n## Result shaping, metadata, and error mapping\n\nAfter execution:\n\n1. `cancelled` handling:\n - if abort signal is aborted -> throw `ToolAbortError` (abort semantics),\n - else -> throw `ToolError` (treated as tool failure).\n2. PTY `timedOut` -> throw `ToolError`.\n3. apply head/tail filters to final output text (`applyHeadTail`, head then tail).\n4. empty output becomes `(no output)`.\n5. attach truncation metadata via `toolResult(...).truncationFromSummary(result, { direction: \"tail\" })`.\n6. exit-code mapping:\n - missing exit code -> `ToolError(\"... missing exit status\")`\n - non-zero exit -> `ToolError(\"... Command exited with code N\")`\n - zero exit -> success result.\n\nSuccess payload structure:\n\n- `content`: text output,\n- `details.meta.truncation` when truncated, including:\n - `direction`, `truncatedBy`, total/output line+byte counts,\n - `shownRange`,\n - `artifactId` when available.\n\nBecause built-in tools are wrapped with `wrapToolWithMetaNotice()`, truncation notice text is appended to final text content automatically (for example: `Full: artifact://<id>`).\n\n## Rendering paths\n\n## Tool-call renderer (`bashToolRenderer`)\n\n`bashToolRenderer` is used for tool-call messages (`toolCall` / `toolResult`):\n\n- collapsed mode shows visual-line-truncated preview,\n- expanded mode shows all currently available output text,\n- warning line includes truncation reason and `artifact://<id>` when truncated,\n- timeout value (from args) is shown in footer metadata line.\n\n### Caveat: full artifact expansion\n\n`BashRenderContext` has `isFullOutput`, but current renderer context builder does not set it for bash tool results. Expanded view still uses the text already in result content (tail/truncated output) unless another caller provides full artifact content.\n\n## User bang-command component (`BashExecutionComponent`)\n\n`BashExecutionComponent` is for user `!` commands in interactive mode (not model tool calls):\n\n- streams chunks live,\n- collapsed preview keeps last 20 logical lines,\n- line clamp at 4000 chars per line,\n- shows truncation + artifact warnings when metadata is present,\n- marks cancelled/error/exit state separately.\n\nThis component is wired by `CommandController.handleBashCommand()` and fed from `AgentSession.executeBash()`.\n\n## Mode-specific behavior differences\n\n| Surface | Entry path | PTY eligible | Live output UX | Error surfacing |\n| ------------------------------ | ----------------------------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------------ |\n| Interactive tool call | `BashTool.execute` | Yes, when `pty=true` and UI exists and `SKC_NO_PTY!=1` | PTY overlay (interactive) or streamed tail updates | Tool errors become `toolResult.isError` |\n| Print mode tool call | `BashTool.execute` | No (no UI context) | No TUI overlay; output appears in event stream/final assistant text flow | Same tool error mapping |\n| RPC tool call (agent tooling) | `BashTool.execute` | Usually no UI -> non-PTY | Structured tool events/results | Same tool error mapping |\n| Interactive bang command (`!`) | `AgentSession.executeBash` + `BashExecutionComponent` | No (uses executor directly) | Dedicated bash execution component | Controller catches exceptions and shows UI error |\n| RPC `bash` command | `rpc-mode` -> `session.executeBash` | No | Returns `BashResult` directly | Consumer handles returned fields |\n\n## Operational caveats\n\n- Interceptor only blocks commands when suggested tool is currently available in context.\n- If artifact allocation fails, truncation still occurs but no `artifact://` back-reference is available.\n- Shell session cache has no explicit eviction in this module; lifetime is process-scoped.\n- PTY and non-PTY timeout surfaces differ:\n - PTY exposes explicit `timedOut` result field,\n - non-PTY maps timeout into `cancelled + annotation` summary.\n\n## Implementation files\n\n- [`src/tools/bash.ts`](../packages/coding-agent/src/tools/bash.ts) — tool entrypoint, input handling/interception, async and PTY/non-PTY selection, result/error mapping, bash tool renderer.\n- [`src/tools/bash-normalize.ts`](../packages/coding-agent/src/tools/bash-normalize.ts) — post-run head/tail filtering; also contains an unused command-normalization helper.\n- [`src/tools/bash-interceptor.ts`](../packages/coding-agent/src/tools/bash-interceptor.ts) — interceptor rule matching and blocked-command messages.\n- [`src/exec/bash-executor.ts`](../packages/coding-agent/src/exec/bash-executor.ts) — non-PTY executor, shell session reuse, cancellation wiring, output sink integration.\n- [`src/tools/bash-interactive.ts`](../packages/coding-agent/src/tools/bash-interactive.ts) — PTY runtime, overlay UI, input normalization, non-interactive env defaults.\n- [`src/session/streaming-output.ts`](../packages/coding-agent/src/session/streaming-output.ts) — `OutputSink`, `TailBuffer`, truncation/artifact spill, and summary metadata.\n- [`src/tools/output-meta.ts`](../packages/coding-agent/src/tools/output-meta.ts) — truncation metadata shape + notice injection wrapper.\n- [`src/session/agent-session.ts`](../packages/coding-agent/src/session/agent-session.ts) — session-level `executeBash`, message recording, abort lifecycle.\n- [`src/modes/components/bash-execution.ts`](../packages/coding-agent/src/modes/components/bash-execution.ts) — interactive `!` command execution component.\n- [`src/modes/controllers/command-controller.ts`](../packages/coding-agent/src/modes/controllers/command-controller.ts) — wiring for interactive `!` command UI stream/update completion.\n- [`src/modes/rpc/rpc-mode.ts`](../packages/coding-agent/src/modes/rpc/rpc-mode.ts) — RPC `bash` and `abort_bash` command surface.\n- [`src/internal-urls/artifact-protocol.ts`](../packages/coding-agent/src/internal-urls/artifact-protocol.ts) — `artifact://<id>` resolution.\n",
@@ -49,12 +49,12 @@ export const EMBEDDED_DOCS: Readonly<Record<string, string>> = {
49
49
  "porting-to-natives.md": "# Porting to pi-natives (N-API) — Field Notes\n\nThis is a practical guide for moving hot paths into `crates/pi-natives` and wiring them through the generated native package entrypoint. It exists to avoid the same failures happening twice.\n\n## When to port\n\nPort when any of these are true:\n\n- The hot path runs in render loops, tight UI updates, or large batches.\n- JS allocations dominate (string churn, regex backtracking, large arrays).\n- You already have a JS baseline and can benchmark both versions side by side.\n- The work is CPU-bound or blocking I/O that can run on the libuv thread pool.\n- The work is async I/O that can run on Tokio's runtime (for example shell execution).\n\nRust is reserved for native bindings, native OS/process/filesystem integration, and measured hot paths. New crates or Rust source trees must have an explicit native/performance rationale in `scripts/check-rust-scope.ts`; keep product policy, orchestration, and glue code in TypeScript unless the benchmark or native boundary justifies moving it.\n\nAvoid ports that depend on JS-only state or dynamic imports. N-API exports should be data-in/data-out. Long-running work should go through `task::blocking` (CPU-bound/blocking I/O) or `task::future` (async I/O) with cancellation where the caller needs `timeoutMs` or `AbortSignal`.\n\n> **Optimization ports need evidence first.** A native port proposed to optimize a *leftover algorithmic hot path* must clear the gates in [`native-ffi-optimization-policy.md`](./native-ffi-optimization-policy.md) (corpus evidence, `profilerSelfTime` attribution, measured FFI overhead, representative p50/p95 win, byte parity, documented rollback cost). New OS/process/native-primitive bindings follow this guide as usual.\n\n## Current package shape\n\n`@sayknow-cli/natives` no longer has a `packages/natives/src/<module>` TypeScript wrapper layer. The package root points at generated native artifacts:\n\n- runtime entry: `packages/natives/native/index.js`\n- types entry: `packages/natives/native/index.d.ts`\n- loader helpers: `packages/natives/native/loader-state.js`\n- embedded manifest: `packages/natives/native/embedded-addon.js`\n\nConsumers import directly from `@sayknow-cli/natives`. The generated declarations are produced during `bun --cwd=packages/natives run build`.\n\n## Anatomy of a native export\n\n**Rust side:**\n\n- Implementation lives in `crates/pi-natives/src/<module>.rs`.\n- If you add a new module, register it in `crates/pi-natives/src/lib.rs`.\n- Export with `#[napi]`; snake_case exports are converted to camelCase automatically. Use explicit JS names only for true aliases/non-default names. Use `#[napi(object)]` for object-shaped structs.\n- For CPU-bound or blocking work, use `task::blocking(tag, cancel_token, work)`.\n- For async work that needs Tokio, use `task::future(env, tag, work)`.\n- Pass a `CancelToken` when the API exposes `timeoutMs` or `AbortSignal`, and call `heartbeat()` inside long loops.\n\n**Package/build side:**\n\n- `packages/natives/scripts/build-native.ts` runs napi-rs, installs the `.node` artifact, copies generated `index.js`/`index.d.ts`, and appends enum runtime exports.\n- `packages/natives/native/index.js` is the loader that chooses a candidate `.node` file and returns the loaded addon.\n- `packages/natives/package.json` exposes only the package root (`@sayknow-cli/natives`).\n\n**Consumer side:**\n\n- Update direct imports/callsites in `packages/coding-agent` or `packages/tui` when the new export replaces a JS implementation.\n- Keep higher-level policy in consumers unless it belongs in the native primitive itself.\n\n## Porting checklist\n\n1. **Add the Rust implementation**\n\n- Put the core logic in a plain Rust function.\n- If it is a new module, add it to `crates/pi-natives/src/lib.rs`.\n- Expose it with `#[napi]` so the default snake_case -> camelCase mapping stays consistent.\n- Keep signatures owned and simple: `String`, `Vec<String>`, `Uint8Array`, `Either<JsString, Uint8Array>`, or `#[napi(object)]` structs.\n- For CPU-bound or blocking work, use `task::blocking`; for async work, use `task::future`.\n- If exposing cancellation, include `timeout_ms: Option<u32>` and `signal: Option<Unknown<'env>>` in options, create `CancelToken::new(...)`, and heartbeat in long loops.\n\n2. **Build generated bindings**\n\n- Run `bun --cwd=packages/natives run build`.\n- Confirm the generated `packages/natives/native/index.d.ts` includes the new export with the intended JS name/signature.\n- Confirm `packages/natives/native/index.js` still has generated enum exports appended when enum changes are involved.\n\n3. **Update consumers**\n\n- Import the new export directly from `@sayknow-cli/natives`.\n- Replace only callsites where the native implementation is faster/equivalent and preserves behavior.\n- Remove obsolete JS implementation code in the same change when the native path becomes canonical.\n\n4. **Add benchmarks**\n\n- Put benchmarks next to the owning package (`packages/tui/bench`, `packages/natives/bench`, or `packages/coding-agent/bench`).\n- Include a JS baseline and native version in the same run.\n- Use `Bun.nanoseconds()` and a fixed iteration count.\n- Keep benchmark inputs realistic for the hot path.\n\n5. **Run focused verification**\n\n- Build the native package.\n- Run the benchmark.\n- Run the narrow tests or scenario covering the changed export/callsites.\n\n## Pain points and how to avoid them\n\n### 1) Stale platform/variant artifacts\n\nThe loader probes platform-tagged artifacts in deterministic order. For x64, selected variant candidates are tried before the unsuffixed default fallback:\n\n- `modern`: `pi_natives.<tag>-modern.node`, then `...-baseline.node`, then `pi_natives.<tag>.node`.\n- `baseline`: `pi_natives.<tag>-baseline.node`, then `pi_natives.<tag>.node`.\n\nNon-x64 uses `pi_natives.<tag>.node`.\n\nCompiled binaries also probe `<getNativesDir()>/<version>/...` and a legacy user-data directory before package/executable locations. If any earlier candidate is stale, a new export may appear missing.\n\n**Fix:** remove stale candidate/cache files and rebuild.\n\n```bash\nrm packages/natives/native/pi_natives.<platform>-<arch>.node\nrm packages/natives/native/pi_natives.<platform>-<arch>-modern.node\nrm packages/natives/native/pi_natives.<platform>-<arch>-baseline.node\nbun --cwd=packages/natives run build\n```\n\nFor compiled binaries, delete the versioned addon cache shown in the loader error (normally under `~/.skc/natives/<version>` unless `$XDG_DATA_HOME/skc` is used).\n\n### 2) Generated types do not match loaded binary\n\nThis can happen when `native/index.d.ts` was regenerated but the `.node` file being loaded is stale or from a different platform/variant.\n\nVerify the loaded export set from the actual candidate path:\n\n```bash\nbun -e 'const tag = `${process.platform}-${process.arch}`; const mod = require(`./packages/natives/native/pi_natives.${tag}.node`); console.log(Object.keys(mod).sort())'\n```\n\nFix the build/candidate mismatch. Do not paper over it with optional consumer checks if the export is required.\n\n### 3) Rust signature mismatch\n\nKeep N-API signatures simple and owned. Avoid borrowed references like `&str` in public exports. If you need structured data, use `#[napi(object)]` structs. If you need callbacks, use napi-rs `ThreadsafeFunction` and keep callback error/value behavior explicit.\n\n### 4) Enum runtime exports\n\nnapi-rs declarations alone are not enough for JS callers that use enum objects at runtime. `scripts/gen-enums.ts` appends enum objects to `native/index.js`. If you add or change a native enum, verify both `native/index.d.ts` and the generated enum export block in `native/index.js`.\n\n### 5) Benchmarking mistakes\n\n- Do not compare different inputs or allocations.\n- Keep JS and native using identical input arrays.\n- Run both in the same benchmark file to avoid skew.\n- Include enough iterations to smooth startup noise, but keep inputs realistic.\n\n## Benchmark template\n\n```ts\nconst ITERATIONS = 2000;\n\nfunction bench(name: string, fn: () => void): number {\n const start = Bun.nanoseconds();\n for (let i = 0; i < ITERATIONS; i++) fn();\n const elapsed = (Bun.nanoseconds() - start) / 1e6;\n console.log(\n `${name}: ${elapsed.toFixed(2)}ms total (${(elapsed / ITERATIONS).toFixed(6)}ms/op)`,\n );\n return elapsed;\n}\n\nbench(\"feature/js\", () => {\n jsImpl(sample);\n});\n\nbench(\"feature/native\", () => {\n nativeImpl(sample);\n});\n```\n\n## Verification checklist\n\n- Generated `native/index.d.ts` includes the new export and intended TS signature.\n- The loaded `.node` file's `Object.keys(require(candidate))` includes the new export.\n- Runtime enum objects are present when the change adds/changes enums.\n- Bench numbers are recorded in the PR/notes.\n- Call sites are updated only if native is faster/equal and behavior-compatible.\n- Obsolete JS code is removed when the native implementation becomes canonical.\n\n## Rule of thumb\n\n- If native is slower, do not switch callsites. Keep or remove the export based on whether it has a near-term owner.\n- If native is faster and behavior-compatible, switch callsites and keep a benchmark to catch regressions.\n",
50
50
  "provider-streaming-internals.md": "# Provider streaming internals\n\nThis document explains how token/tool streaming is normalized in `@sayknow-cli/ai`, then propagated through `@sayknow-cli/agent-core` and `coding-agent` session events.\n\n## End-to-end flow\n\n1. `streamSimple()` (`packages/ai/src/stream.ts`) maps generic options and dispatches to a provider stream function.\n2. Provider stream functions translate provider-native stream events into the unified `AssistantMessageEvent` sequence. Current built-ins include Anthropic, OpenAI Responses/Completions/OpenAI code/Azure Responses, Google Gemini/Gemini CLI/Vertex, Bedrock Converse, Ollama, Cursorand GitLab Duo/Kimi wrappers.\n3. Each provider pushes events into `AssistantMessageEventStream` (`packages/ai/src/utils/event-stream.ts`), which throttles delta events and exposes:\n - async iteration for incremental updates\n - `result()` for final `AssistantMessage`\n4. `agentLoop` (`packages/agent/src/agent-loop.ts`) consumes those events, mutates in-flight assistant state, and emits `message_update` events carrying the raw `assistantMessageEvent`.\n5. `AgentSession` (`packages/coding-agent/src/session/agent-session.ts`) subscribes to agent events, persists messages, and applies session behaviors (retry, compaction, TTSR, streaming-edit abort checks).\n\n## Unified stream contract in `@sayknow-cli/ai`\n\nAll providers emit the same shape (`AssistantMessageEvent` in `packages/ai/src/types.ts`):\n\n- `start`\n- content block lifecycle triplets:\n - text: `text_start` → `text_delta`\\* → `text_end`\n - thinking: `thinking_start` → `thinking_delta`\\* → `thinking_end`\n - tool call: `toolcall_start` → `toolcall_delta`\\* → `toolcall_end`\n- terminal event:\n - `done` with `reason: \"stop\" | \"length\" | \"toolUse\"`\n - or `error` with `reason: \"aborted\" | \"error\"`\n\n`AssistantMessageEventStream` guarantees:\n\n- final result is resolved by terminal event (`done` or `error`)\n- deltas are batched/throttled (~50ms)\n- buffered deltas are flushed before non-delta events and before completion\n\n## Delta throttling and harmonization behavior\n\n`AssistantMessageEventStream` treats `text_delta`, `thinking_delta`, and `toolcall_delta` as mergeable events:\n\n- buffered deltas are merged only when **type + contentIndex** match\n- merge keeps the latest `partial` snapshot\n- non-delta events force immediate flush\n\nThis smooths high-frequency provider streams for TUI/event consumers, but is not provider backpressure: providers still produce at full speed, while the local stream buffers.\n\n## Provider normalization details\n\n## Anthropic (`anthropic-messages`)\n\nSource: `packages/ai/src/providers/anthropic.ts`\n\nNormalization points:\n\n- `message_start` initializes usage (input/output/cache tokens)\n- `content_block_start` maps to text/thinking/toolcall starts\n- `content_block_delta` maps:\n - `text_delta` → `text_delta`\n - `thinking_delta` → `thinking_delta`\n - `input_json_delta` → `toolcall_delta`\n - `signature_delta` updates `thinkingSignature` only (no event)\n- `content_block_stop` emits corresponding `*_end`\n- `message_delta.stop_reason` maps via `mapStopReason()`\n\nTool-call argument streaming:\n\n- each tool block carries internal `partialJson`\n- every JSON delta appends to `partialJson`\n- `arguments` are reparsed on each delta via `parseStreamingJson()`\n- `toolcall_end` reparses once more, then strips `partialJson`\n\n## OpenAI Responses family (`openai-responses`, `openai-code-responses`, `azure-openai-responses`)\n\nSources: `packages/ai/src/providers/openai-responses.ts`, `openai-code-responses.ts`, and `azure-openai-responses.ts`\n\nNormalization points:\n\n- `response.output_item.added` starts reasoning/text/function-call blocks\n- reasoning summary events (`response.reasoning_summary_text.delta`) become `thinking_delta`\n- output/refusal deltas become `text_delta`\n- `response.function_call_arguments.delta` becomes `toolcall_delta`\n- `response.output_item.done` emits `thinking_end` / `text_end` / `toolcall_end`\n- `response.completed` maps status to stop reason and usage\n\nTool-call argument streaming:\n\n- same `partialJson` accumulation pattern as Anthropic\n- providers that send only `response.function_call_arguments.done` still populate final args\n- tool call IDs are normalized as `\"<call_id>|<item_id>\"`\n\n## Google Generative AI (`google-generative-ai`)\n\nSource: `packages/ai/src/providers/google.ts`\n\nNormalization points:\n\n- iterates `candidate.content.parts`\n- text parts are split into thinking vs text by `isThinkingPart(part)`\n- block transitions close previous block before starting a new one\n- `part.functionCall` is treated as a complete tool call (start/delta/end emitted immediately)\n- finish reason mapped by `mapStopReason()` from `google-shared.ts`\n\nTool-call argument streaming:\n\n- function call args arrive as structured object, not incremental JSON text\n- implementation emits one synthetic `toolcall_delta` containing `JSON.stringify(arguments)`\n- no partial JSON parser needed for Google in this path\n\n## Partial tool-call JSON accumulation and recovery\n\nShared behavior for Anthropic/OpenAI Responses uses `parseStreamingJson()` (`packages/ai/src/utils/json-parse.ts`):\n\n1. try `JSON.parse`\n2. fallback to `partial-json` parser for incomplete fragments\n3. if both fail, return `{}`\n\nImplications:\n\n- malformed or truncated argument deltas do not crash stream processing immediately\n- in-progress `arguments` may temporarily be `{}`\n- later valid deltas can recover structured arguments because parsing is retried on every append\n- final `toolcall_end` performs one more parse attempt before emission\n\n## Stop reasons vs transport/runtime errors\n\nProvider stop reasons are mapped to normalized `stopReason`:\n\n- Anthropic: `end_turn`→`stop`, `max_tokens`→`length`, `tool_use`→`toolUse`, safety/refusal cases→`error`\n- OpenAI Responses: `completed`→`stop`, `incomplete`→`length`, `failed/cancelled`→`error`\n- Google: `STOP`→`stop`, `MAX_TOKENS`→`length`, safety/prohibited/malformed-function-call classes→`error`\n\nError semantics are split in two stages:\n\n1. **Model completion semantics** (provider reported finish reason/status)\n2. **Transport/runtime failure** (network/client/parser/abort exceptions)\n\nIf provider stream throws or signals failure, each provider wrapper catches and emits terminal `error` event with:\n\n- `stopReason = \"aborted\"` when abort signal is set\n- otherwise `stopReason = \"error\"`\n- `errorMessage = formatErrorMessageWithRetryAfter(error)`\n\n## Malformed chunk / SSE parse failure behavior\n\nFor these provider paths, chunk/SSE framing is handled by vendor SDK streams (Anthropic SDK, OpenAI SDK, Google SDK). This code does not implement a custom SSE decoder here.\n\nObserved behavior in current implementation:\n\n- malformed chunk/SSE parsing at SDK level surfaces as an exception or stream `error` event\n- provider wrapper converts that into unified terminal `error` event\n- no provider-specific resume/retry inside the stream function itself\n- higher-level retries are handled in `AgentSession` auto-retry logic (message-level retry, not stream-chunk replay)\n\n## Cancellation boundaries\n\nCancellation is layered:\n\n- AI provider request: `options.signal` is passed into provider client stream call.\n- Provider wrapper: after stream loop, aborted signal forces error path (`\"Request was aborted\"`).\n- Agent loop: checks `signal.aborted` before handling each provider event and can synthesize an aborted assistant message from the latest partial.\n- Session/agent controls: `AgentSession.abort()` -> `agent.abort()` -> shared abort controller cancellation.\n\nTool execution cancellation is separate from model stream cancellation:\n\n- tool runners use `AbortSignal.any([agentSignal, steeringAbortSignal])`\n- steering interrupts can abort remaining tool execution while preserving already-produced tool results\n\n## Backpressure boundaries\n\nThere is no hard backpressure mechanism between provider SDK stream and downstream consumers:\n\n- `EventStream` uses in-memory queues with no max size\n- throttling reduces UI update rate but does not slow provider intake\n- if consumers lag significantly, queued events can grow until completion\n\nCurrent design favors responsiveness and simple ordering over bounded-buffer flow control.\n\n## How stream events surface as agent/session events\n\n`agentLoop.streamAssistantResponse()` bridges `AssistantMessageEvent` to `AgentEvent`:\n\n- on `start`: pushes placeholder assistant message and emits `message_start`\n- on block events (`text_*`, `thinking_*`, `toolcall_*`): updates last assistant message, emits `message_update` with raw `assistantMessageEvent`\n- on terminal (`done`/`error`): resolves final message from `response.result()`, emits `message_end`\n\n`AgentSession` then consumes those events for session-level behaviors:\n\n- TTSR watches `message_update.assistantMessageEvent` for `text_delta`, `thinking_delta`, and `toolcall_delta`\n- streaming edit guard inspects `toolcall_delta`/`toolcall_end` on `edit` calls and can abort early\n- persistence writes finalized messages at `message_end`\n- auto-retry examines assistant `stopReason === \"error\"` plus `errorMessage` heuristics\n\n## Unified vs provider-specific responsibilities\n\nUnified (common contract):\n\n- event shape (`AssistantMessageEvent`)\n- final result extraction (`done`/`error`)\n- delta throttling + merge rules\n- agent/session event propagation model\n\nProvider-specific (not fully abstracted):\n\n- upstream event taxonomies and mapping logic\n- stop-reason translation tables\n- tool-call ID conventions\n- reasoning/thinking block semantics and signatures\n- usage token semantics and availability timing\n- message conversion constraints per API\n\n## Implementation files\n\n- [`../../ai/src/stream.ts`](../packages/ai/src/stream.ts) — provider dispatch, option mapping, API key/session plumbing, custom API dispatch, and provider-specific credential handling.\n- [`../../ai/src/utils/event-stream.ts`](../packages/ai/src/utils/event-stream.ts) — generic stream queue + assistant delta throttling.\n- [`../../ai/src/utils/json-parse.ts`](../packages/ai/src/utils/json-parse.ts) — partial JSON parsing for streamed tool arguments.\n- [`../../ai/src/providers/anthropic.ts`](../packages/ai/src/providers/anthropic.ts) — Anthropic event translation and tool JSON delta accumulation.\n- [`../../ai/src/providers/openai-responses.ts`](../packages/ai/src/providers/openai-responses.ts), [`openai-code-responses.ts`](../packages/ai/src/providers/openai-code-responses.ts), [`azure-openai-responses.ts`](../packages/ai/src/providers/azure-openai-responses.ts) — Responses-family event translation and status mapping.\n- [`../../ai/src/providers/google.ts`](../packages/ai/src/providers/google.ts), [`google-gemini-cli.ts`](../packages/ai/src/providers/google-gemini-cli.ts), [`google-vertex.ts`](../packages/ai/src/providers/google-vertex.ts) — Gemini stream chunk-to-block translation variants.\n- [`../../ai/src/providers/google-shared.ts`](../packages/ai/src/providers/google-shared.ts) — Gemini finish-reason mapping and shared conversion rules.\n- [`../../ai/src/providers/amazon-bedrock.ts`](../packages/ai/src/providers/amazon-bedrock.ts), [`openai-completions.ts`](../packages/ai/src/providers/openai-completions.ts), [`ollama.ts`](../packages/ai/src/providers/ollama.ts), [`cursor.ts`](../packages/ai/src/providers/cursor.ts) — additional built-in stream adapters using the same event contract.\n- [`../../agent/src/agent-loop.ts`](../packages/agent/src/agent-loop.ts) — provider stream consumption and `message_update` bridging.\n- [`../src/session/agent-session.ts`](../packages/coding-agent/src/session/agent-session.ts) — session-level handling of streaming updates, abort, retry, and persistence.\n",
51
51
  "python-repl.md": "# Eval Tool Python Backend\n\nThis document describes the Python execution stack in `packages/coding-agent`.\nIt covers tool behavior, runner lifecycle, environment handling, execution semantics, output rendering, supported magics, and operational failure modes.\n\n## Scope and Key Files\n\n- Tool surface: `src/tools/eval.ts`\n- Session/per-call kernel orchestration: `src/eval/py/executor.ts`\n- Subprocess kernel client: `src/eval/py/kernel.ts`\n- Python wrapper / NDJSON server: `src/eval/py/runner.py`\n- Prelude helpers loaded into every kernel: `src/eval/py/prelude.py`\n- MIME bundle renderer (text + structured outputs): `src/eval/py/display.ts`\n- Interactive-mode renderer for user-triggered Python runs: `src/modes/components/eval-execution.ts`\n- Runtime/env filtering and Python resolution: `src/eval/py/runtime.ts`\n\n## What eval's Python backend is\n\nThe `eval` tool executes one or more Python cells inside a long-lived `python3` subprocess that speaks NDJSON over stdin/stdout. No Jupyter, no kernel gateway, no extra pip dependencies — a vanilla Python 3.8+ interpreter is enough. Rich `display()` output (PIL, pandas, plotly, matplotlib figures) keeps working because the wrapper reimplements the MIME-bundle dispatch that IPython previously provided.\n\nTool params:\n\n```ts\n{\n cells: Array<{ code: string; title?: string }>;\n timeout?: number; // seconds, clamped to 1..600, default 30\n reset?: boolean; // reset selected runtime before the first cell only\n}\n```\n\nThe tool is `concurrency = \"exclusive\"` for a session, so calls do not overlap.\n\n## Kernel lifecycle\n\nEach kernel is a single Python subprocess: `python -u <runner.py>`. The runner is bundled with the host binary (Bun text import), written to `~/.skc/python-env`-adjacent tmp cache once per script-hash, and reused by every subsequent spawn.\n\nKernel startup sequence:\n\n1. Availability check (`checkPythonKernelAvailability`) — verifies that a Python interpreter resolves and runs.\n2. Spawn `python -u runner.py` with filtered env and `cwd`.\n3. Send an init request that runs `os.chdir(cwd)`, injects env entries, and adds `cwd` to `sys.path`.\n4. Execute `PYTHON_PRELUDE` (idempotent — only initializes once per process).\n\nKernel shutdown:\n\n- Send `{\"type\": \"exit\"}` over stdin.\n- Wait for process exit with `SHUTDOWN_GRACE_MS` budget.\n- Escalate to `SIGTERM` and finally `SIGKILL` if the process does not exit in time.\n\n## Wire protocol (NDJSON, host ↔ runner)\n\nOne JSON object per line, UTF-8, `\\n` terminated.\n\nHost → runner:\n\n```jsonc\n{\"id\": \"<reqId>\", \"code\": \"<source>\", \"silent\": false, \"storeHistory\": true}\n{\"type\": \"exit\"}\n```\n\nRunner → host:\n\n```jsonc\n{\"type\": \"started\", \"id\": \"<reqId>\"}\n{\"type\": \"stdout\", \"id\": \"<reqId>\", \"data\": \"...\"}\n{\"type\": \"stderr\", \"id\": \"<reqId>\", \"data\": \"...\"}\n{\"type\": \"display\", \"id\": \"<reqId>\", \"bundle\": {<mime>: <value>}}\n{\"type\": \"result\", \"id\": \"<reqId>\", \"bundle\": {<mime>: <value>}}\n{\"type\": \"error\", \"id\": \"<reqId>\", \"ename\": \"...\", \"evalue\": \"...\", \"traceback\": [\"...\"]}\n{\"type\": \"done\", \"id\": \"<reqId>\", \"status\": \"ok\"|\"error\", \"executionCount\": N, \"cancelled\": false}\n```\n\nStatus events the prelude emits (e.g. `_emit_status(\"find\", count=…)`) ship inside display bundles under `application/x-skc-status` so the existing TUI status renderer keeps working.\n\n## Magics\n\nThe runner's source transformer rewrites IPython-style magics to plain Python calls before parsing. Supported set:\n\n| Magic | Effect |\n| --- | --- |\n| `%pip <args>` | `python -m pip <args>` with live streaming output. Newly installed packages are evicted from `sys.modules` so the next `import` picks up the fresh install. |\n| `%cd <path>` | `os.chdir(path)` (with `~` expansion); emits status event. |\n| `%pwd` | Returns `os.getcwd()`. |\n| `%ls [path]` | Returns `sorted(os.listdir(path))`. |\n| `%env [KEY[=VAL]]` | List, read, or set env vars (matches prelude `env()` semantics). |\n| `%set_env KEY VALUE` | Set `os.environ[KEY]`. |\n| `%time <expr>` / `%timeit <expr>` | Time the expression; emits status event with elapsed ms. |\n| `%who` / `%whos` | List user-namespace names. |\n| `%reset` | Clear user globals and re-inject prelude. |\n| `%load <path>` | Read a file into a fresh cell and execute. |\n| `%run <path>` | `runpy.run_path` and merge globals back. |\n| `%%bash` / `%%sh` | Run the cell body via `bash`/`sh`. |\n| `%%capture [name]` | Run body with stdout/stderr captured into `name`. |\n| `%%timeit` | Time the cell body. |\n| `%%writefile <path>` | Write body to file. |\n| `!cmd` / `var = !cmd` | Run command via subprocess shell; returns an SList-style result with `.n` / `.s` helpers. |\n| `var = %name args` | Assignment forms work for line magics and `!cmd`. |\n\nUnknown magic names raise `NameError: UsageError: ...` inside the cell.\n\n## Session persistence semantics\n\n`python.kernelMode` controls retained kernel reuse:\n\n- `session` (default)\n - Reuses kernel sessions keyed by session file plus cwd when a session file exists; otherwise by cwd.\n - Execution is serialized per session via a queue.\n - Idle sessions are evicted after 5 minutes.\n - At most 4 sessions; oldest is evicted on overflow.\n - Heartbeat checks detect dead kernels.\n - Auto-restart allowed once; repeated crash ⇒ hard failure.\n- `per-call`\n - Spawns a fresh subprocess for each request.\n - Shuts the subprocess down after the request.\n - No cross-call state persistence.\n\n### Multi-cell behavior in a single tool call\n\nCells run sequentially in the same kernel instance for that tool call.\n\nIf an intermediate cell fails:\n\n- Earlier cell state remains in memory.\n- Tool returns a targeted error indicating which cell failed.\n- Later cells are not executed.\n\n`reset=true` only applies to the first cell execution in that call.\n\n## Environment filtering and runtime resolution\n\nEnvironment is filtered before launching the runner:\n\n- Allowlist includes core vars like `PATH`, `HOME`, locale vars, `VIRTUAL_ENV`, `PYTHONPATH`, etc.\n- Allow-prefixes: `LC_`, `XDG_`, `SKC_`\n- Denylist strips common API keys (OpenAI/Anthropic/Gemini/etc.)\n\nRuntime selection order:\n\n1. Active/located venv (`VIRTUAL_ENV`, then `<cwd>/.venv`, `<cwd>/venv`)\n2. Managed venv at `~/.skc/python-env`\n3. `python` or `python3` on PATH\n\nWhen a venv is selected, its bin/Scripts path is prepended to `PATH`.\n\nThe runner additionally receives `PYTHONUNBUFFERED=1` and `PYTHONIOENCODING=utf-8` so streamed output reaches the host promptly.\n\n## Tool availability and mode selection\n\n`eval.py` / `eval.js` (both default `true`) plus optional `SKC_PY` override controls eval backend exposure:\n\n- Python backend only (`eval.py=true`, `eval.js=false`)\n- JavaScript backend only (`eval.py=false`, `eval.js=true`)\n- both backends\n\n`SKC_PY` accepted values:\n\n- `0` / `bash` → JavaScript backend only\n- `1` / `py` → Python backend only\n- `mix` / `both` → both backends\n\nIf Python preflight fails and `eval.js` is enabled, `eval` remains available and dispatches to JavaScript unless `language: \"python\"` is explicitly requested.\n\n## Execution flow and cancellation/timeout\n\n### Tool-level timeout\n\n`eval` timeout is in seconds, default 30, clamped to `1..600`. The tool combines caller abort signal and timeout signal with `AbortSignal.any(...)`.\n\n### Kernel execution cancellation\n\nOn abort/timeout:\n\n- The host sends `kill(\"SIGINT\")` to the runner subprocess.\n- The runner's exec-time signal handler raises `KeyboardInterrupt` inside the user code.\n- Result includes `cancelled=true`; timeout path annotates output as `Command timed out after <n> seconds`.\n- Between requests the runner installs `SIG_IGN` for SIGINT so a stray cancel does not tear down the kernel.\n\nIf a second cancel is required (runner stuck in C code), the host escalates to `SIGTERM` and the session restarts on the next call.\n\n### stdin behavior\n\nInteractive stdin is not supported. The runner does not forward `input()` prompts; user code that calls `input()` blocks until cancellation.\n\n## Output capture and rendering\n\n### Captured output classes\n\nFrom runner frames:\n\n- `stdout` / `stderr` → plain text chunks\n- `display` / `result` → rich display handling (MIME bundle)\n- `error` → traceback text\n- `application/x-skc-status` MIME inside `display` → structured status events\n\nDisplay MIME precedence:\n\n1. `text/markdown`\n2. `text/plain`\n3. `text/html` (converted to basic markdown)\n\nAdditionally captured as structured outputs:\n\n- `application/json` → JSON tree data\n- `image/png` / `image/jpeg` → image payloads\n- `application/x-skc-status` → status events\n\n### Matplotlib\n\nThe runner sets `MPLBACKEND=Agg` as an environ default so figures render off-screen. After every cell, `pyplot.get_fignums()` is iterated; each figure is saved to PNG, emitted as an `image/png` display, and closed.\n\n### Storage and truncation\n\nOutput is streamed through `OutputSink` and may be persisted to artifact storage. Tool results can include truncation metadata and `artifact://<id>` for full output recovery.\n\n### Renderer behavior\n\n- Tool renderer (`eval.ts`):\n - shows code-cell blocks with per-cell status\n - collapsed preview defaults to 10 lines\n - supports expanded mode for full output and richer status detail\n- Interactive renderer (`eval-execution.ts`):\n - used for user-triggered Python execution in TUI\n - collapsed preview defaults to 20 lines\n - clamps very long individual lines to 4000 chars for display safety\n - shows cancellation/error/truncation notices\n\n## Operational troubleshooting\n\n- **Python backend not available** — Check `eval.py`, `SKC_PY`, and that `python`/`python3` is on PATH. If preflight fails and `eval.js` is enabled, omit `language` or pass `language: \"js\"` to use JavaScript.\n- **No Python on PATH** — Install a system Python 3.8+ or place a venv at `~/.skc/python-env`. `skc setup python --check` reports the resolved interpreter.\n- **Execution hangs then times out** — Increase tool `timeout` (max 600s) if workload is legitimate. For stuck native code, cancellation triggers `SIGINT` first then escalates; the session restarts on the next request.\n- **stdin/input prompts in Python code** — `input()` is not supported; pass data programmatically.\n- **Working directory errors** — Tool validates `cwd` exists and is a directory before execution.\n\n## Relevant environment variables\n\n- `SKC_PY` — tool exposure override\n- `SKC_PYTHON_SKIP_CHECK=1` — bypass Python preflight/warm checks\n- `SKC_PYTHON_INTEGRATION=1` — enable gated integration tests that spawn a real Python\n- `SKC_PYTHON_IPC_TRACE=1` — log NDJSON frames exchanged with the runner subprocess\n",
52
- "readme/README.de.md": "<p align=\"center\">\n <img src=\"../../assets/hero.png\" alt=\"Sayknow-CLI autonomous coding-agent hero illustration\" width=\"100%\" />\n</p>\n\n<h1 align=\"center\">Sayknow-CLI</h1>\n\n<p align=\"center\">\n <strong>Programmieren sollte sich wie Denken anfühlen.</strong><br />\n Ein fokussierter Coding-Agent-Runner für Interviews, geprüfte Pläne, tmux-native Ausführung und dauerhafte Verifizierung.\n</p>\n\n<p align=\"center\">\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/releases\"><img alt=\"Release\" src=\"https://img.shields.io/github/v/tag/jaybeyond/Sayknow_CLI?sort=semver&label=release&style=flat-square&color=2f9bff\"></a>\n <a href=\"LICENSE\"><img alt=\"License: MIT\" src=\"https://img.shields.io/github/license/jaybeyond/Sayknow_CLI?style=flat-square&color=green\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/stargazers\"><img alt=\"Stars\" src=\"https://img.shields.io/github/stars/jaybeyond/Sayknow_CLI?style=flat-square&color=f5c518\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/issues\"><img alt=\"Issues\" src=\"https://img.shields.io/github/issues/jaybeyond/Sayknow_CLI?style=flat-square\"></a>\n <a href=\"https://bun.sh\"><img alt=\"Built with Bun\" src=\"https://img.shields.io/badge/built%20with-Bun-fbf0df?style=flat-square&logo=bun&logoColor=black\"></a>\n <a href=\"#languages\"><img alt=\"i18n\" src=\"https://img.shields.io/badge/i18n-7%20languages-2f9bff?style=flat-square\"></a>\n</p>\n\n<p align=\"center\">\n <a href=\"../../README.md\">English</a> ·\n <a href=\"README.ko.md\">한국어</a> ·\n <a href=\"README.zh.md\">中文</a> ·\n <a href=\"README.ja.md\">日本語</a> ·\n <a href=\"README.es.md\">Español</a> ·\n <a href=\"README.fr.md\">Français</a> ·\n <b>Deutsch</b>\n</p>\n\n<p align=\"center\">\n <img src=\"../../assets/character.png\" alt=\"Sayknow-CLI character mascot\" width=\"320\" />\n</p>\n\n> Sayknow-CLI ist ein experimentelles Projekt im Beta-Stadium. Rechnen Sie mit Ecken und Kanten und überprüfen Sie die Ausgaben, bevor Sie sich bei wichtiger Arbeit darauf verlassen.\n\n## Languages\n\nDie Oberfläche ist in **7 Sprachen** lokalisiert — English, 한국어 (Koreanisch),\n中文 (简体 / Vereinfachtes Chinesisch), 日本語 (Japanisch), Español (Spanisch),\nFrançais (Französisch) und Deutsch. Beim ersten Start erkennt sie automatisch\nIhre System-Locale; wechseln Sie jederzeit unter **Settings → Appearance → Language**\noder starten Sie z. B. mit `LANG=ja_JP.UTF-8 skc`. Nicht übersetzte Zeichenketten\nfallen auf Englisch zurück, und Marken-/Fachbegriffe (Claude, OpenAI, MCP, …)\nbleiben in allen Locales unverändert.\n\n## Was ist Sayknow-CLI?\n\nSayknow-CLI (`skc`) ist ein externes Coding-Agent-Harness. Es läuft aus dem von Ihnen gewählten Repository oder Worktree und gibt dem Agenten dann eine kleine, explizite Workflow-Oberfläche:\n\n```text\ndeep-interview -> ralplan -> ultragoal\n └─ optional team execution when parallel tmux workers help\n```\n\nEs ist bewusst kein verstecktes Plugin für Codex CLI, Claude Code, OpenCode oder Claw Code. Starten Sie `skc` neben diesen Tools, wenn Sie strukturierte Planung, dauerhafte Nachweise, tmux-gestützte Worker oder einen isolierten Worktree wünschen.\n\n## Installation\n\n> Sayknow-CLI ist noch nicht auf npm veröffentlicht — installieren Sie aus dem\n> Quellcode. Es ist ein Bun-Monorepo, daher wird der globale Befehl `skc` von\n> Ihrem lokalen Checkout verlinkt.\n\n```sh\n# 1. Install Bun (if you don't have it)\ncurl -fsSL https://bun.sh/install | bash # macOS / Linux\n\n# 2. Clone and bootstrap (installs deps, builds native bindings, links `skc`)\ngit clone https://github.com/jaybeyond/Sayknow_CLI.git\ncd Sayknow_CLI\nbun run install:dev\n\n# 3. Verify\nskc --version\nskc --smoke-test\n```\n\n`bun run install:dev` führt `bun install` aus, verlinkt `skc` in Ihren `PATH` (über\n`dev:link`) und richtet lokale Standardwerte ein. Danach läuft `skc` mit dem\nQuellcode dieses Checkouts — `git pull` zum Aktualisieren. Wenn Sie lieber nicht\nglobal verlinken möchten, führen Sie es direkt mit `bun run dev` aus dem Repo aus.\n\n### Windows (native Installation)\n\nInstallieren Sie auf einem sauberen Windows-11-Rechner zuerst Bun und bauen Sie dann aus dem Quellcode:\n\n```powershell\n# 1. Install Bun\npowershell -c \"irm bun.sh/install.ps1|iex\"\n\n# 2. Restart the terminal so PATH and the Bun runtime refresh, then confirm Bun\nbun --version\n\n# 3. Clone, bootstrap, and verify skc\ngit clone https://github.com/jaybeyond/Sayknow_CLI.git\ncd Sayknow_CLI\nbun run install:dev\nskc --version\nskc --smoke-test\n```\n\n`dev:link` platziert den `skc`-Launcher in Ihrem `PATH`. Dieses Verzeichnis muss\nim `PATH` liegen, damit `skc` als Befehl aufgelöst wird — starten Sie PowerShell\nneu (oder melden Sie sich ab/an), falls `skc` nach der Installation „not recognized“ meldet.\n\nFehlerbehebung:\n\n- **`skc` meldet eine alte Bun-Runtime.** Führen Sie den Bun-Installer oben erneut\n aus, starten Sie das Terminal neu und bestätigen Sie, dass `bun --version` mit\n dem übereinstimmt, was `skc --version` erwartet. Falls weiterhin ein älteres Bun\n gewinnt, stellen Sie sicher, dass `%USERPROFILE%\\.bun\\bin` an erster Stelle im\n `PATH` steht, und entfernen Sie veraltete Bun-Installationen, die es überschatten.\n- **`skc.exe` existiert, aber `skc` ist „not recognized“.** Der Launcher ist\n installiert, aber nicht im `PATH`. Bestätigen Sie, dass `%USERPROFILE%\\.bun\\bin`\n in `echo $env:Path` aufgeführt ist, und starten Sie dann das Terminal neu.\n\n## Schnellstart\n\n```sh\n# Run directly in the current checkout\nskc\n\n# Use a tmux-backed leader session\nskc --tmux\n\n# Use an isolated worktree for risky or reviewable work\n# --worktree takes an optional branch-like name, not a filesystem path.\nskc --tmux --worktree my-task-branch\n\n# If you already created a worktree directory, launch from that directory instead.\ncd ../my-task-worktree && skc --tmux\n```\n\nVerwenden Sie innerhalb einer SKC-Sitzung die öffentliche Workflow-Oberfläche:\n\n```text\n/skill:deep-interview clarify ambiguous requirements\n/skill:ralplan build and critique the implementation plan\nskc ultragoal create-goals --brief-file <approved-plan>\nskc ultragoal complete-goals\n```\n\nFügen Sie `skc team ...` nur hinzu, wenn koordinierte tmux-Worker spürbar helfen.\n\n## Kernfunktionen\n\n- **Interview vor dem Raten**: `deep-interview` verwandelt vage Anfragen in konkrete Anforderungen.\n- **Plan vor der Veränderung**: `ralplan` prüft den Ansatz vor Codeänderungen.\n- **Ausführen mit Nachweisen**: `ultragoal` verfolgt Ziele, Revisionen, Prüfungen und Abschlussnachweise.\n- **Parallelisieren, wenn sinnvoll**: `team` koordiniert tmux-gestützte Worker für größere Aufgaben.\n- **Extern und überprüfbar bleiben**: Laufen Sie aus einem gewählten Repo oder Worktree, ohne eine andere Agent-Runtime zu patchen.\n\n## Workflow-Oberfläche\n\nSayknow-CLI liefert vier Standard-Workflow-Skills:\n\n| Skill | Was es tut |\n| ---------------- | --------------------------------------------------------------------- |\n| `deep-interview` | Klärt mehrdeutige Anforderungen vor Planung oder Codeänderungen. |\n| `ralplan` | Erstellt und kritisiert einen Implementierungsplan vor der Veränderung. |\n| `ultragoal` | Verfolgt Ziele durch Ausführung, Revision, Verifizierung und Nachweise. |\n| `team` | Koordiniert tmux-gestützte Worker, wenn parallele Ausführung sich lohnt. |\n\nUnd vier mitgelieferte Rollen-Agenten:\n\n| Agent | Was es tut |\n| ----------- | -------------------------------------------------- |\n| `executor` | Begrenzte Implementierung, Fixes und Refactorings. |\n| `architect` | Schreibgeschützte Architektur- und Code-Review-Bewertung. |\n| `planner` | Schreibgeschützte Sequenzierung und Abnahmekriterien. |\n| `critic` | Schreibgeschützte Plan-Kritik und Umsetzbarkeitsprüfung. |\n\nKein wucherndes Standard-Skill-Zoo: SKC verbessert sich, indem es diese kleine Methode besser macht.\n\n## Funktioniert neben Ihrem bestehenden Agenten oder Bot\n\n| Tool oder Bot | Empfohlener SKC-Befehl | Grenze |\n| ----------- | ----------------------- | -------- |\n| Codex CLI | `skc --tmux --worktree <name>` oder `skc` | `--worktree` benennt einen SKC-verwalteten Geschwister-Worktree; für einen bestehenden Pfad wechseln Sie zuerst mit `cd` dorthin. |\n| Claude Code | `skc --tmux` oder `skc --tmux --worktree <name>` | SKC wird keine Claude-Code-Erweiterung. |\n| OpenCode | `skc` oder `skc --tmux` | Heute nur External-Runner-Workflow. |\n| Claw Code | `skc --tmux --worktree <name>` | SKC installiert sich nicht in Claw Code und ersetzt es nicht. |\n| Externer Controller / Bot | `skc mcp-serve coordinator` plus `skc setup hermes` für kompatible Konfiguration oder `skc --mode rpc` für einen Subprozess-Worker | Jeder MCP-/RPC-fähige Bot steuert SKC über den generischen Coordinator-/RPC-Vertrag, nicht durch Scrollback-Scraping. |\n\nFür generisches Drittanbieter-Bot-Setup und anbieterunabhängige Smokes siehe [`docs/bot-integration.md`](docs/bot-integration.md). Für die Reife-Klassifizierung über MCP-, RPC-, ACP- und Bridge/HTTPS-Oberflächen siehe [`docs/external-control-readiness.md`](docs/external-control-readiness.md). Für tiefergehende Protokolldetails siehe [`docs/hermes-mcp-bridge.md`](docs/hermes-mcp-bridge.md), [`docs/rpc.md`](docs/rpc.md) und [`docs/bridge.md`](docs/bridge.md). Für die Roadmap der Remote-Operator-Oberflächen siehe [`docs/sayknow-remote.md`](docs/sayknow-remote.md) (Web-Steuerrad) und [`docs/telegram-remote.md`](docs/telegram-remote.md) (Telegram-Lifecycle-Button).\n\n## Konfiguration\n\nProvider-Retry-Budgets liegen in `~/.skc/config.yml`:\n\n```yaml\nretry:\n requestMaxRetries: 4\n streamMaxRetries: 100\n maxRetries: 3\n maxDelayMs: 300000\n```\n\n`requestMaxRetries` gilt, bevor ein Stream aufgebaut wird. `streamMaxRetries` gilt nur für replay-sichere, vorübergehende Stream-Fehler. Ungültige Authentifizierung, nicht unterstützte Modelle/Provider, fehlerhafte Requests, Kontextüberlauf, Benutzerabbrüche und dauerhafte Kontingentfehler bleiben fail-fast.\n\n## TUI-Identität\n\nDie Standard-TUI-Identität ist das SKC-**blue-octopus**-Theme — das blaue Kopffüßer-Maskottchen — sowohl für dunkle als auch für helle Terminals. Eine warme **red-octopus**-Variante ist ebenfalls dabei für alle, die eine dunklere, kontrastreiche Palette bevorzugen. Drei zusätzliche Migrations-Themes — `claude-code`, `codex` und `opencode` — spiegeln das Aussehen dieser Tools für einen einfachen Augen-Umstieg wider und sind über Settings oder `/theme` auswählbar. Explizite Benutzer-Theme-Einstellungen gewinnen weiterhin.\n\n### Raster der mitgelieferten Themes\n\nWählen Sie über Settings (`Appearance -> Dark theme` / `Light theme`) oder `/theme`.\n\n| Theme | Visueller Eindruck | Beste Eignung |\n| --- | --- | --- |\n| `blue-octopus` | Standard-SKC-Identität — blaue Oktopus-Palette mit tentakelblauen Akzenten. | Standard für dunkle und helle Terminals. |\n| `red-octopus` | Warme rote Oktopus-Variante mit starkem Status-Kontrast. | Kontrastreiche dunkle Alternative. |\n| `claude-code` | Von Claude Code inspirierte dunkle Palette mit terrakotta- und pinkfarbenen Highlights. | Claude-Code-Muskelgedächtnis, ohne SKC zu verlassen. |\n| `codex` | Klare dunkle blaugraue Palette mit schärferem Coding-Session-Kontrast. | Ein Codex-ähnlicher dunkler Arbeitsbereich. |\n| `opencode` | Von OpenCode inspirierte dunkle Palette mit kräftigeren Terminal-Akzenten. | OpenCode-Muskelgedächtnis im mitgelieferten Picker. |\n\n## Entwicklung\n\nAbhängigkeiten installieren, native Bindings bauen und lokale Standardwerte einrichten:\n\n```sh\nbun install\nbun run build:native\nbun run install:defaults\n```\n\nDie `.node`-Binärdatei für `@sayknow-cli/natives` ist gitignored und vor jeder CLI-Ausführung erforderlich (`install:defaults`, `dev:link`, Tests).\n\n### Kanonisch: Entwickler-`skc` bauen und verlinken\n\nDamit der globale Befehl `skc` **den TypeScript-Quellcode dieses Checkouts** ausführt (live bei jeder Bearbeitung, mit funktionierenden Skills/Natives), verlinken Sie ihn in Ihren `PATH`:\n\n```sh\nbun install\nbun run dev:link\n```\n\n`dev:link` legt einen Symlink `skc` → `packages/coding-agent/src/cli.ts` nach `~/.local/bin` an (überschreibbar mit `SKC_DEV_LINK_DIR`), ersetzt dieses verwaltete Ziel, warnt und schlägt fehl, falls ein anderes `skc` es weiter vorne im `PATH` überschattet, und führt `--smoke-test` aus, um zu bestätigen, dass `@sayknow-cli/natives` geladen wird. Verwenden Sie `bun run install:dev` für das vollständige Bootstrap (Installation + Link + `setup defaults`).\n\nPrüfen Sie jederzeit, ob Ihr `skc` abgedriftet ist (falsche Quelle oder eine kompilierte Binärdatei, die keine Skills laden kann):\n\n```sh\nbun run dev:doctor\n```\n\n> Verwenden Sie für die tägliche Entwicklung **nicht** die kompilierte Binärdatei. `bun --cwd=packages/coding-agent run build` erzeugt ein eigenständiges `dist/skc`, aber eine mit `bun build --compile` erstellte Binärdatei kann `@sayknow-cli/natives` nicht dynamisch laden, sodass Skills mit `Cannot find module '@sayknow-cli/natives' from '/$bunfs/root/skc'` fehlschlagen. Die Ausführung aus dem Quellcode über `dev:link` vermeidet dies. Bauen Sie die Binärdatei nur, wenn Sie ein Release validieren.\n\nFühren Sie die CLI direkt aus dem Quellcode ohne Verlinkung aus:\n\n```sh\nbun packages/coding-agent/src/cli.ts --help\n```\n\nStandard-Workflow-Definitionen liegen im Quellcode, nicht in committeten `.skc`-Kopien:\n\n```text\npackages/coding-agent/src/defaults/skc/skills/<name>/SKILL.md\npackages/coding-agent/src/prompts/agents/<role>.md\n```\n\nFür Änderungen an Workflow-Definitionen oder Rebrand-Oberflächen führen Sie die Projekt-Gates aus:\n\n```sh\nbun scripts/check-visible-definitions.ts\nbun scripts/verify-g002-gates.ts\nbun scripts/rebrand-inventory.ts --strict\nbun test packages/coding-agent/test/default-skc-definitions.test.ts\n```\n\nFür eine Paket-für-Paket-Übersicht siehe [`docs/codebase-overview.md`](docs/codebase-overview.md).\n\n## Mitwirkende\n\nBeiträge, Fehlerberichte und Release-Validierung sind über GitHub Issues und Pull Requests willkommen.\n\n## Inspirationen und Herkunft\n\nDie Standard-TUI-Identität von Sayknow-CLI ist das Kopffüßer-Paar: blue-octopus als Standard mit einem warmen red-octopus als Alternative. Es liefert außerdem die Migrations-Themes `claude-code`, `codex` und `opencode`, deren Paletten von diesen Tools inspiriert sind, damit Benutzer, die von ihnen wechseln, einen vertrauten Look erhalten. Es baut auf Erkenntnissen aus einer kleinen Familie von Agent-Harnesses auf und hält die öffentliche SKC-Oberfläche bewusst fokussiert. Die historische Zuordnung wird in [`NOTICE.md`](NOTICE.md) geführt.\n\n## Lizenz\n\nMIT. Siehe [`LICENSE`](LICENSE).\n",
53
- "readme/README.es.md": "<p align=\"center\">\n <img src=\"../../assets/hero.png\" alt=\"Ilustración principal del agente de codificación autónomo Sayknow-CLI\" width=\"100%\" />\n</p>\n\n<h1 align=\"center\">Sayknow-CLI</h1>\n\n<p align=\"center\">\n <strong>Programar debería sentirse como pensar.</strong><br />\n Un ejecutor de agentes de codificación enfocado en entrevistas, planes revisados, ejecución nativa en tmux y verificación duradera.\n</p>\n\n<p align=\"center\">\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/releases\"><img alt=\"Release\" src=\"https://img.shields.io/github/v/tag/jaybeyond/Sayknow_CLI?sort=semver&label=release&style=flat-square&color=2f9bff\"></a>\n <a href=\"LICENSE\"><img alt=\"License: MIT\" src=\"https://img.shields.io/github/license/jaybeyond/Sayknow_CLI?style=flat-square&color=green\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/stargazers\"><img alt=\"Stars\" src=\"https://img.shields.io/github/stars/jaybeyond/Sayknow_CLI?style=flat-square&color=f5c518\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/issues\"><img alt=\"Issues\" src=\"https://img.shields.io/github/issues/jaybeyond/Sayknow_CLI?style=flat-square\"></a>\n <a href=\"https://bun.sh\"><img alt=\"Built with Bun\" src=\"https://img.shields.io/badge/built%20with-Bun-fbf0df?style=flat-square&logo=bun&logoColor=black\"></a>\n <a href=\"#languages\"><img alt=\"i18n\" src=\"https://img.shields.io/badge/i18n-7%20languages-2f9bff?style=flat-square\"></a>\n</p>\n\n<p align=\"center\">\n <a href=\"../../README.md\">English</a> ·\n <a href=\"README.ko.md\">한국어</a> ·\n <a href=\"README.zh.md\">中文</a> ·\n <a href=\"README.ja.md\">日本語</a> ·\n <b>Español</b> ·\n <a href=\"README.fr.md\">Français</a> ·\n <a href=\"README.de.md\">Deutsch</a>\n</p>\n\n<p align=\"center\">\n <img src=\"../../assets/character.png\" alt=\"Mascota personaje de Sayknow-CLI\" width=\"320\" />\n</p>\n\n> Sayknow-CLI es un proyecto experimental en fase beta. Espera asperezas y verifica los resultados antes de confiar en él para trabajos importantes.\n\n## Languages\n\nLa interfaz está localizada en **7 idiomas** — English, 한국어 (coreano),\n中文 (简体 / chino simplificado), 日本語 (japonés), Español,\nFrançais (francés) y Deutsch (alemán). Detecta automáticamente la configuración regional de tu sistema en\nel primer arranque; cámbiala en cualquier momento en **Settings → Appearance → Language**, o inícialo\ncon, por ejemplo, `LANG=ja_JP.UTF-8 skc`. Las cadenas no traducidas recurren al inglés, y\nlos nombres de marca/técnicos (Claude, OpenAI, MCP, …) se mantienen literales en todas las configuraciones regionales.\n\n## ¿Qué es Sayknow-CLI?\n\nSayknow-CLI (`skc`) es un arnés externo de agentes de codificación. Se ejecuta desde el repositorio o worktree que elijas y luego le da al agente una superficie de flujo de trabajo pequeña y explícita:\n\n```text\ndeep-interview -> ralplan -> ultragoal\n └─ optional team execution when parallel tmux workers help\n```\n\nIntencionadamente no es un plugin oculto para Codex CLI, Claude Code, OpenCode o Claw Code. Inicia `skc` junto a esas herramientas cuando quieras planificación estructurada, evidencia persistente, workers respaldados por tmux o un worktree aislado.\n\n## Install\n\n> Sayknow-CLI aún no está publicado en npm — instala desde el código fuente. Es un\n> monorepo de Bun, por lo que el comando global `skc` se enlaza desde tu copia local.\n\n```sh\n# 1. Install Bun (if you don't have it)\ncurl -fsSL https://bun.sh/install | bash # macOS / Linux\n\n# 2. Clone and bootstrap (installs deps, builds native bindings, links `skc`)\ngit clone https://github.com/jaybeyond/Sayknow_CLI.git\ncd Sayknow_CLI\nbun run install:dev\n\n# 3. Verify\nskc --version\nskc --smoke-test\n```\n\n`bun run install:dev` ejecuta `bun install`, enlaza `skc` a tu `PATH` (mediante\n`dev:link`) y configura los valores predeterminados locales. Después de eso, `skc` ejecuta el código\nfuente de esta copia — usa `git pull` para actualizar. Si prefieres no enlazarlo globalmente, ejecútalo\ndirectamente con `bun run dev` desde el repositorio.\n\n### Windows (instalación nativa)\n\nEn una máquina Windows 11 limpia, instala primero Bun y luego compila desde el código fuente:\n\n```powershell\n# 1. Install Bun\npowershell -c \"irm bun.sh/install.ps1|iex\"\n\n# 2. Restart the terminal so PATH and the Bun runtime refresh, then confirm Bun\nbun --version\n\n# 3. Clone, bootstrap, and verify skc\ngit clone https://github.com/jaybeyond/Sayknow_CLI.git\ncd Sayknow_CLI\nbun run install:dev\nskc --version\nskc --smoke-test\n```\n\n`dev:link` coloca el lanzador `skc` en tu `PATH`. Ese directorio debe estar en\n`PATH` para que `skc` se resuelva como comando — reinicia PowerShell (o cierra/inicia sesión)\nsi `skc` aparece como \"not recognized\" tras la instalación.\n\nResolución de problemas:\n\n- **`skc` informa de un runtime de Bun antiguo.** Vuelve a ejecutar el instalador de Bun de arriba, reinicia\n la terminal y confirma que `bun --version` coincide con lo que espera `skc --version`.\n Si una versión de Bun más antigua sigue ganando, asegúrate de que `%USERPROFILE%\\.bun\\bin` esté\n primero en `PATH` y elimina cualquier instalación obsoleta de Bun que la oculte.\n- **`skc.exe` existe pero `skc` aparece como \"not recognized\".** El lanzador está instalado\n pero no está en `PATH`. Confirma que `%USERPROFILE%\\.bun\\bin` aparezca en\n `echo $env:Path` y luego reinicia la terminal.\n\n## Quick start\n\n```sh\n# Run directly in the current checkout\nskc\n\n# Use a tmux-backed leader session\nskc --tmux\n\n# Use an isolated worktree for risky or reviewable work\n# --worktree takes an optional branch-like name, not a filesystem path.\nskc --tmux --worktree my-task-branch\n\n# If you already created a worktree directory, launch from that directory instead.\ncd ../my-task-worktree && skc --tmux\n```\n\nDentro de una sesión de SKC, usa la superficie pública del flujo de trabajo:\n\n```text\n/skill:deep-interview clarify ambiguous requirements\n/skill:ralplan build and critique the implementation plan\nskc ultragoal create-goals --brief-file <approved-plan>\nskc ultragoal complete-goals\n```\n\nAñade `skc team ...` solo cuando los workers coordinados de tmux ayuden de forma significativa.\n\n## Capacidades principales\n\n- **Entrevistar antes de suponer**: `deep-interview` convierte solicitudes vagas en requisitos concretos.\n- **Planificar antes de mutar**: `ralplan` revisa el enfoque antes de los cambios de código.\n- **Ejecutar con evidencia**: `ultragoal` rastrea objetivos, revisiones, comprobaciones y evidencia de finalización.\n- **Paralelizar cuando sea útil**: `team` coordina workers respaldados por tmux para tareas más grandes.\n- **Mantenerse externo y revisable**: ejecútalo desde un repositorio o worktree elegido sin parchear otro runtime de agente.\n\n## Superficie del flujo de trabajo\n\nSayknow-CLI incluye cuatro skills de flujo de trabajo predeterminadas:\n\n| Skill | Qué hace |\n| ---------------- | --------------------------------------------------------------------- |\n| `deep-interview` | Aclara requisitos ambiguos antes de planificar o cambiar código. |\n| `ralplan` | Construye y critica un plan de implementación antes de mutar. |\n| `ultragoal` | Rastrea objetivos a través de ejecución, revisión, verificación y evidencia. |\n| `team` | Coordina workers respaldados por tmux cuando vale la pena la ejecución paralela. |\n\nY cuatro agentes de rol incluidos:\n\n| Agent | Qué hace |\n| ----------- | -------------------------------------------------- |\n| `executor` | Implementación acotada, correcciones y refactorizaciones. |\n| `architect` | Evaluación de arquitectura y revisión de código de solo lectura. |\n| `planner` | Secuenciación y criterios de aceptación de solo lectura. |\n| `critic` | Crítica de planes y revisión de accionabilidad de solo lectura. |\n\nSin un zoológico de skills predeterminadas desbordante: SKC mejora haciendo mejor este pequeño método.\n\n## Funciona junto a tu agente o bot existente\n\n| Herramienta o bot | Comando SKC recomendado | Límite |\n| ----------- | ----------------------- | -------- |\n| Codex CLI | `skc --tmux --worktree <name>` o `skc` | `--worktree` nombra un worktree hermano gestionado por SKC; para una ruta existente, haz `cd` allí primero. |\n| Claude Code | `skc --tmux` o `skc --tmux --worktree <name>` | SKC no se convierte en una extensión de Claude Code. |\n| OpenCode | `skc` o `skc --tmux` | Solo flujo de trabajo de ejecutor externo por ahora. |\n| Claw Code | `skc --tmux --worktree <name>` | SKC no se instala dentro de Claw Code ni lo reemplaza. |\n| Controlador / bot externo | `skc mcp-serve coordinator` más `skc setup hermes` para una configuración compatible, o `skc --mode rpc` para un worker en subproceso | Cualquier bot con capacidad MCP/RPC controla SKC mediante el contrato genérico coordinator/RPC, no mediante scraping del scrollback. |\n\nPara la configuración genérica de bots de terceros y pruebas de humo independientes del proveedor, consulta [`docs/bot-integration.md`](docs/bot-integration.md). Para la clasificación de preparación a través de las superficies MCP, RPC, ACP y Bridge/HTTPS, consulta [`docs/external-control-readiness.md`](docs/external-control-readiness.md). Para los detalles de protocolo de más bajo nivel, consulta [`docs/hermes-mcp-bridge.md`](docs/hermes-mcp-bridge.md), [`docs/rpc.md`](docs/rpc.md) y [`docs/bridge.md`](docs/bridge.md). Para la hoja de ruta de las superficies de operador remoto, consulta [`docs/sayknow-remote.md`](docs/sayknow-remote.md) (volante web) y [`docs/telegram-remote.md`](docs/telegram-remote.md) (botón de ciclo de vida de Telegram).\n\n## Configuration\n\nLos presupuestos de reintento del proveedor viven en `~/.skc/config.yml`:\n\n```yaml\nretry:\n requestMaxRetries: 4\n streamMaxRetries: 100\n maxRetries: 3\n maxDelayMs: 300000\n```\n\n`requestMaxRetries` se aplica antes de que se establezca un stream. `streamMaxRetries` se aplica solo a fallos transitorios de stream que son seguros de reproducir. La autenticación inválida, los modelos/proveedores no compatibles, las solicitudes malformadas, el desbordamiento de contexto, las cancelaciones del usuario y los fallos permanentes de cuota siguen siendo de fallo rápido.\n\n## Identidad de la TUI\n\nLa identidad predeterminada de la TUI es el tema **blue-octopus** de SKC — la mascota del cefalópodo azul — tanto para terminales oscuras como claras. También se incluye una variante cálida **red-octopus** para quienes prefieren una paleta más oscura y de alto contraste. Tres temas de migración adicionales — `claude-code`, `codex` y `opencode` — reflejan el aspecto de esas herramientas para facilitar la migración visual y se pueden seleccionar desde Settings o `/theme`. Los ajustes de tema explícitos del usuario siguen prevaleciendo.\n\n### Cuadrícula de temas incluidos\n\nElige desde Settings (`Appearance -> Dark theme` / `Light theme`) o `/theme`.\n\n| Tema | Sensación visual | Mejor uso |\n| --- | --- | --- |\n| `blue-octopus` | Identidad predeterminada de SKC — paleta de pulpo azul con acentos azul-tentáculo. | Predeterminado para terminales oscuras y claras. |\n| `red-octopus` | Variante cálida de pulpo rojo con fuerte contraste de estado. | Alternativa oscura de alto contraste. |\n| `claude-code` | Paleta oscura inspirada en Claude Code con resaltados terracota y rosa. | Memoria muscular de Claude Code sin salir de SKC. |\n| `codex` | Paleta nítida azul-gris oscuro con un contraste de sesión de codificación más marcado. | Un espacio de trabajo oscuro al estilo Codex. |\n| `opencode` | Paleta oscura inspirada en OpenCode con acentos de terminal más vibrantes. | Memoria muscular de OpenCode en el selector incluido. |\n\n## Development\n\nInstala las dependencias, compila los bindings nativos y configura los valores predeterminados locales:\n\n```sh\nbun install\nbun run build:native\nbun run install:defaults\n```\n\nEl binario `.node` para `@sayknow-cli/natives` está en gitignore y es necesario antes de cualquier invocación del CLI (`install:defaults`, `dev:link`, tests).\n\n### Canónico: compilar y enlazar el `skc` de desarrollo\n\nPara hacer que el comando global `skc` ejecute **el código fuente TypeScript de esta copia** (sensible a cada edición, con skills/natives funcionando), enlázalo a tu `PATH`:\n\n```sh\nbun install\nbun run dev:link\n```\n\n`dev:link` crea un symlink de `skc` → `packages/coding-agent/src/cli.ts` en `~/.local/bin` (sobrescríbelo con `SKC_DEV_LINK_DIR`), reemplaza ese objetivo gestionado, advierte y falla si otro `skc` aún lo oculta antes en `PATH`, y ejecuta `--smoke-test` para confirmar que `@sayknow-cli/natives` carga. Usa `bun run install:dev` para el bootstrap completo (install + link + `setup defaults`).\n\nComprueba en cualquier momento si tu `skc` se ha desviado (fuente incorrecta, o un binario compilado que no puede cargar skills):\n\n```sh\nbun run dev:doctor\n```\n\n> **No** uses el binario compilado para el desarrollo diario. `bun --cwd=packages/coding-agent run build` produce un `dist/skc` independiente, pero un binario `bun build --compile` no puede cargar dinámicamente `@sayknow-cli/natives`, por lo que las skills fallan con `Cannot find module '@sayknow-cli/natives' from '/$bunfs/root/skc'`. Ejecutar desde el código fuente mediante `dev:link` evita esto. Compila el binario solo al validar una release.\n\nEjecuta el CLI directamente desde el código fuente sin enlazarlo:\n\n```sh\nbun packages/coding-agent/src/cli.ts --help\n```\n\nLas definiciones de flujo de trabajo predeterminadas viven en el código fuente, no en copias `.skc` comprometidas:\n\n```text\npackages/coding-agent/src/defaults/skc/skills/<name>/SKILL.md\npackages/coding-agent/src/prompts/agents/<role>.md\n```\n\nPara cambios en las definiciones de flujo de trabajo o en la superficie de rebranding, ejecuta las puertas del proyecto:\n\n```sh\nbun scripts/check-visible-definitions.ts\nbun scripts/verify-g002-gates.ts\nbun scripts/rebrand-inventory.ts --strict\nbun test packages/coding-agent/test/default-skc-definitions.test.ts\n```\n\nPara un mapa paquete por paquete, consulta [`docs/codebase-overview.md`](docs/codebase-overview.md).\n\n## Contributors\n\nLas contribuciones, los informes de errores y la validación de releases son bienvenidos a través de GitHub Issues y Pull Requests.\n\n## Inspiraciones y linaje\n\nLa identidad predeterminada de la TUI de Sayknow-CLI es la pareja de cefalópodos: blue-octopus como predeterminado con un red-octopus cálido como alternativa. También incluye los temas de migración `claude-code`, `codex` y `opencode`, cuyas paletas están inspiradas en esas herramientas para que los usuarios que migran de ellas obtengan un aspecto familiar. Se basa en las lecciones de una pequeña familia de arneses de agentes mientras mantiene la superficie pública de SKC intencionadamente enfocada. La atribución histórica se conserva en [`NOTICE.md`](NOTICE.md).\n\n## License\n\nMIT. Consulta [`LICENSE`](LICENSE).\n",
54
- "readme/README.fr.md": "<p align=\"center\">\n <img src=\"../../assets/hero.png\" alt=\"Illustration héros de l'agent de codage autonome Sayknow-CLI\" width=\"100%\" />\n</p>\n\n<h1 align=\"center\">Sayknow-CLI</h1>\n\n<p align=\"center\">\n <strong>Coder devrait ressembler à réfléchir.</strong><br />\n Un exécuteur d'agent de codage ciblé pour les entretiens, les plans révisés, l'exécution native tmux et la vérification durable.\n</p>\n\n<p align=\"center\">\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/releases\"><img alt=\"Release\" src=\"https://img.shields.io/github/v/tag/jaybeyond/Sayknow_CLI?sort=semver&label=release&style=flat-square&color=2f9bff\"></a>\n <a href=\"LICENSE\"><img alt=\"License: MIT\" src=\"https://img.shields.io/github/license/jaybeyond/Sayknow_CLI?style=flat-square&color=green\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/stargazers\"><img alt=\"Stars\" src=\"https://img.shields.io/github/stars/jaybeyond/Sayknow_CLI?style=flat-square&color=f5c518\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/issues\"><img alt=\"Issues\" src=\"https://img.shields.io/github/issues/jaybeyond/Sayknow_CLI?style=flat-square\"></a>\n <a href=\"https://bun.sh\"><img alt=\"Built with Bun\" src=\"https://img.shields.io/badge/built%20with-Bun-fbf0df?style=flat-square&logo=bun&logoColor=black\"></a>\n <a href=\"#languages\"><img alt=\"i18n\" src=\"https://img.shields.io/badge/i18n-7%20languages-2f9bff?style=flat-square\"></a>\n</p>\n\n<p align=\"center\">\n <a href=\"../../README.md\">English</a> ·\n <a href=\"README.ko.md\">한국어</a> ·\n <a href=\"README.zh.md\">中文</a> ·\n <a href=\"README.ja.md\">日本語</a> ·\n <a href=\"README.es.md\">Español</a> ·\n <b>Français</b> ·\n <a href=\"README.de.md\">Deutsch</a>\n</p>\n\n<p align=\"center\">\n <img src=\"../../assets/character.png\" alt=\"Mascotte personnage de Sayknow-CLI\" width=\"320\" />\n</p>\n\n> Sayknow-CLI est un projet expérimental en phase bêta. Attendez-vous à des aspérités et vérifiez les résultats avant de vous y fier pour un travail important.\n\n## Languages\n\nL'interface est localisée en **7 langues** — English, 한국어 (coréen),\n中文 (简体 / chinois simplifié), 日本語 (japonais), Español (espagnol),\nFrançais (français) et Deutsch (allemand). Elle détecte automatiquement la locale de votre système au\npremier lancement ; changez-en à tout moment dans **Settings → Appearance → Language**, ou lancez\navec par exemple `LANG=ja_JP.UTF-8 skc`. Les chaînes non traduites se rabattent sur l'anglais, et\nles noms de marque/techniques (Claude, OpenAI, MCP, …) restent verbatim dans toutes les locales.\n\n## What is Sayknow-CLI?\n\nSayknow-CLI (`skc`) est un harnais d'agent de codage externe. Il s'exécute depuis le dépôt ou le worktree que vous choisissez, puis donne à l'agent une surface de workflow réduite et explicite :\n\n```text\ndeep-interview -> ralplan -> ultragoal\n └─ optional team execution when parallel tmux workers help\n```\n\nCe n'est volontairement pas un plugin caché pour Codex CLI, Claude Code, OpenCode ou Claw Code. Lancez `skc` à côté de ces outils lorsque vous voulez une planification structurée, des preuves persistantes, des workers adossés à tmux, ou un worktree isolé.\n\n## Install\n\n> Sayknow-CLI n'est pas encore publié sur npm — installez depuis les sources. C'est un monorepo\n> Bun, donc la commande globale `skc` est liée depuis votre checkout local.\n\n```sh\n# 1. Install Bun (if you don't have it)\ncurl -fsSL https://bun.sh/install | bash # macOS / Linux\n\n# 2. Clone and bootstrap (installs deps, builds native bindings, links `skc`)\ngit clone https://github.com/jaybeyond/Sayknow_CLI.git\ncd Sayknow_CLI\nbun run install:dev\n\n# 3. Verify\nskc --version\nskc --smoke-test\n```\n\n`bun run install:dev` exécute `bun install`, lie `skc` à votre `PATH` (via\n`dev:link`), et configure les valeurs par défaut locales. Après cela, `skc` exécute la\nsource de ce checkout — `git pull` pour mettre à jour. Si vous préférez ne pas lier globalement, exécutez-le\ndirectement avec `bun run dev` depuis le dépôt.\n\n### Windows (native install)\n\nSur une machine Windows 11 vierge, installez d'abord Bun, puis compilez depuis les sources :\n\n```powershell\n# 1. Install Bun\npowershell -c \"irm bun.sh/install.ps1|iex\"\n\n# 2. Restart the terminal so PATH and the Bun runtime refresh, then confirm Bun\nbun --version\n\n# 3. Clone, bootstrap, and verify skc\ngit clone https://github.com/jaybeyond/Sayknow_CLI.git\ncd Sayknow_CLI\nbun run install:dev\nskc --version\nskc --smoke-test\n```\n\n`dev:link` place le lanceur `skc` sur votre `PATH`. Ce répertoire doit être sur le\n`PATH` pour que `skc` se résolve comme une commande — redémarrez PowerShell (ou déconnectez/reconnectez-vous)\nsi `skc` est « not recognized » après l'installation.\n\nDépannage :\n\n- **`skc` signale un ancien runtime Bun.** Relancez l'installateur Bun ci-dessus, redémarrez\n le terminal, et confirmez que `bun --version` correspond à ce que `skc --version`\n attend. Si une version plus ancienne de Bun l'emporte toujours, assurez-vous que `%USERPROFILE%\\.bun\\bin` est\n en premier sur le `PATH` et supprimez toute installation Bun obsolète qui le masquerait.\n- **`skc.exe` existe mais `skc` est « not recognized ».** Le lanceur est installé\n mais pas sur le `PATH`. Confirmez que `%USERPROFILE%\\.bun\\bin` est listé dans\n `echo $env:Path`, puis redémarrez le terminal.\n\n## Quick start\n\n```sh\n# Run directly in the current checkout\nskc\n\n# Use a tmux-backed leader session\nskc --tmux\n\n# Use an isolated worktree for risky or reviewable work\n# --worktree takes an optional branch-like name, not a filesystem path.\nskc --tmux --worktree my-task-branch\n\n# If you already created a worktree directory, launch from that directory instead.\ncd ../my-task-worktree && skc --tmux\n```\n\nÀ l'intérieur d'une session SKC, utilisez la surface de workflow publique :\n\n```text\n/skill:deep-interview clarify ambiguous requirements\n/skill:ralplan build and critique the implementation plan\nskc ultragoal create-goals --brief-file <approved-plan>\nskc ultragoal complete-goals\n```\n\nAjoutez `skc team ...` uniquement lorsque des workers tmux coordonnés aident concrètement.\n\n## Core capabilities\n\n- **Interviewer avant de deviner** : `deep-interview` transforme des demandes vagues en exigences concrètes.\n- **Planifier avant de muter** : `ralplan` révise l'approche avant les changements de code.\n- **Exécuter avec des preuves** : `ultragoal` suit les objectifs, les révisions, les vérifications et les preuves de complétion.\n- **Paralléliser quand c'est utile** : `team` coordonne des workers adossés à tmux pour les tâches plus importantes.\n- **Rester externe et révisable** : exécutez depuis un dépôt ou un worktree choisi sans patcher un autre runtime d'agent.\n\n## Workflow surface\n\nSayknow-CLI fournit quatre skills de workflow par défaut :\n\n| Skill | What it does |\n| ---------------- | --------------------------------------------------------------------- |\n| `deep-interview` | Clarifie les exigences ambiguës avant la planification ou les changements de code. |\n| `ralplan` | Construit et critique un plan d'implémentation avant la mutation. |\n| `ultragoal` | Suit les objectifs à travers l'exécution, la révision, la vérification et les preuves. |\n| `team` | Coordonne des workers adossés à tmux lorsque l'exécution parallèle en vaut la peine. |\n\nEt quatre agents de rôle inclus :\n\n| Agent | What it does |\n| ----------- | -------------------------------------------------- |\n| `executor` | Implémentation bornée, correctifs et refactorisations. |\n| `architect` | Évaluation d'architecture et de revue de code en lecture seule. |\n| `planner` | Séquençage et critères d'acceptation en lecture seule. |\n| `critic` | Critique de plan et revue d'actionnabilité en lecture seule. |\n\nPas de ménagerie tentaculaire de skills par défaut : SKC s'améliore en rendant cette petite méthode meilleure.\n\n## Works beside your existing agent or bot\n\n| Tool or bot | Recommended SKC command | Boundary |\n| ----------- | ----------------------- | -------- |\n| Codex CLI | `skc --tmux --worktree <name>` or `skc` | `--worktree` nomme un worktree frère géré par SKC ; pour un chemin existant, faites d'abord `cd` à cet endroit. |\n| Claude Code | `skc --tmux` or `skc --tmux --worktree <name>` | SKC ne devient pas une extension de Claude Code. |\n| OpenCode | `skc` or `skc --tmux` | Workflow d'exécuteur externe uniquement aujourd'hui. |\n| Claw Code | `skc --tmux --worktree <name>` | SKC ne s'installe pas dans Claw Code et ne le remplace pas. |\n| External controller / bot | `skc mcp-serve coordinator` plus `skc setup hermes` for compatible config, or `skc --mode rpc` for a subprocess worker | Tout bot capable de MCP/RPC pilote SKC via le contrat générique coordinator/RPC, et non par grattage de scrollback. |\n\nPour la configuration générique d'un bot tiers et les smokes indépendants du provider, voir [`docs/bot-integration.md`](docs/bot-integration.md). Pour la classification de readiness à travers les surfaces MCP, RPC, ACP et Bridge/HTTPS, voir [`docs/external-control-readiness.md`](docs/external-control-readiness.md). Pour les détails de protocole de plus bas niveau, voir [`docs/hermes-mcp-bridge.md`](docs/hermes-mcp-bridge.md), [`docs/rpc.md`](docs/rpc.md) et [`docs/bridge.md`](docs/bridge.md). Pour la roadmap des surfaces d'opérateur distant, voir [`docs/sayknow-remote.md`](docs/sayknow-remote.md) (volant de direction web) et [`docs/telegram-remote.md`](docs/telegram-remote.md) (bouton de cycle de vie Telegram).\n\n## Configuration\n\nLes budgets de retry du provider se trouvent dans `~/.skc/config.yml` :\n\n```yaml\nretry:\n requestMaxRetries: 4\n streamMaxRetries: 100\n maxRetries: 3\n maxDelayMs: 300000\n```\n\n`requestMaxRetries` s'applique avant qu'un stream ne soit établi. `streamMaxRetries` ne s'applique qu'aux échecs de stream transitoires sûrs pour le replay. L'authentification invalide, les modèles/providers non pris en charge, les requêtes malformées, le débordement de contexte, les abandons par l'utilisateur et les échecs de quota permanents restent en fail-fast.\n\n## TUI identity\n\nL'identité TUI par défaut est le thème SKC **blue-octopus** — la mascotte céphalopode bleue — pour les terminaux sombres comme clairs. Une variante chaleureuse **red-octopus** est également incluse pour ceux qui préfèrent une palette plus sombre et à fort contraste. Trois thèmes de migration supplémentaires — `claude-code`, `codex` et `opencode` — reflètent l'apparence de ces outils pour faciliter la migration visuelle et sont sélectionnables depuis Settings ou `/theme`. Les réglages de thème explicites de l'utilisateur l'emportent toujours.\n\n### Bundled theme grid\n\nChoisissez depuis Settings (`Appearance -> Dark theme` / `Light theme`) ou `/theme`.\n\n| Theme | Visual feel | Best fit |\n| --- | --- | --- |\n| `blue-octopus` | Identité SKC par défaut — palette poulpe bleu avec des accents bleu tentacule. | Par défaut pour les terminaux sombres et clairs. |\n| `red-octopus` | Variante chaleureuse poulpe rouge avec un fort contraste d'état. | Alternative sombre à fort contraste. |\n| `claude-code` | Palette sombre inspirée de Claude Code avec des touches terracotta et rose. | La mémoire musculaire de Claude Code sans quitter SKC. |\n| `codex` | Palette bleu-gris sombre et nette avec un contraste de session de codage plus marqué. | Un espace de travail sombre à la manière de Codex. |\n| `opencode` | Palette sombre inspirée d'OpenCode avec des accents de terminal plus percutants. | La mémoire musculaire d'OpenCode dans le sélecteur inclus. |\n\n## Development\n\nInstallez les dépendances, compilez les bindings natifs et configurez les valeurs par défaut locales :\n\n```sh\nbun install\nbun run build:native\nbun run install:defaults\n```\n\nLe binaire `.node` pour `@sayknow-cli/natives` est gitignored et requis avant toute invocation de la CLI (`install:defaults`, `dev:link`, tests).\n\n### Canonical: build and link the dev `skc`\n\nPour que la commande globale `skc` exécute **la source TypeScript de ce checkout** (sensible à chaque édition, avec skills/natives fonctionnels), liez-la à votre `PATH` :\n\n```sh\nbun install\nbun run dev:link\n```\n\n`dev:link` crée un lien symbolique `skc` → `packages/coding-agent/src/cli.ts` dans `~/.local/bin` (à surcharger avec `SKC_DEV_LINK_DIR`), remplace cette cible gérée, avertit et échoue si un autre `skc` le masque encore plus tôt sur le `PATH`, et exécute `--smoke-test` pour confirmer que `@sayknow-cli/natives` se charge. Utilisez `bun run install:dev` pour le bootstrap complet (install + link + `setup defaults`).\n\nVérifiez à tout moment si votre `skc` a dérivé (mauvaise source, ou un binaire compilé qui ne peut pas charger les skills) :\n\n```sh\nbun run dev:doctor\n```\n\n> N'utilisez **pas** le binaire compilé pour le développement quotidien. `bun --cwd=packages/coding-agent run build` produit un `dist/skc` autonome, mais un binaire `bun build --compile` ne peut pas charger dynamiquement `@sayknow-cli/natives`, donc les skills échouent avec `Cannot find module '@sayknow-cli/natives' from '/$bunfs/root/skc'`. L'exécution depuis la source via `dev:link` évite cela. Ne compilez le binaire que lors de la validation d'une release.\n\nExécutez la CLI depuis la source directement sans lier :\n\n```sh\nbun packages/coding-agent/src/cli.ts --help\n```\n\nLes définitions de workflow par défaut résident dans la source, et non dans des copies `.skc` commitées :\n\n```text\npackages/coding-agent/src/defaults/skc/skills/<name>/SKILL.md\npackages/coding-agent/src/prompts/agents/<role>.md\n```\n\nPour les changements de définition de workflow ou de surface de rebrand, exécutez les portes du projet :\n\n```sh\nbun scripts/check-visible-definitions.ts\nbun scripts/verify-g002-gates.ts\nbun scripts/rebrand-inventory.ts --strict\nbun test packages/coding-agent/test/default-skc-definitions.test.ts\n```\n\nPour une carte package par package, voir [`docs/codebase-overview.md`](docs/codebase-overview.md).\n\n## Contributors\n\nLes contributions, les rapports de bugs et la validation de release sont les bienvenus via les GitHub Issues et les Pull Requests.\n\n## Inspirations and lineage\n\nL'identité TUI par défaut de Sayknow-CLI est la paire de céphalopodes : blue-octopus comme valeur par défaut avec une alternative chaleureuse red-octopus. Il inclut aussi les thèmes de migration `claude-code`, `codex` et `opencode` dont les palettes sont inspirées de ces outils afin que les utilisateurs qui en proviennent retrouvent une apparence familière. Il s'appuie sur les leçons d'une petite famille de harnais d'agents tout en gardant la surface publique SKC volontairement ciblée. L'attribution historique est conservée dans [`NOTICE.md`](NOTICE.md).\n\n## License\n\nMIT. Voir [`LICENSE`](LICENSE).\n",
55
- "readme/README.ja.md": "<p align=\"center\">\n <img src=\"../../assets/hero.png\" alt=\"Sayknow-CLI 自律型コーディングエージェントのヒーローイラスト\" width=\"100%\" />\n</p>\n\n<h1 align=\"center\">Sayknow-CLI</h1>\n\n<p align=\"center\">\n <strong>コーディングは、考えることのように感じられるべきだ。</strong><br />\n インタビュー、レビュー済みプラン、tmux ネイティブ実行、そして永続的な検証のための、集中型コーディングエージェントランナー。\n</p>\n\n<p align=\"center\">\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/releases\"><img alt=\"Release\" src=\"https://img.shields.io/github/v/tag/jaybeyond/Sayknow_CLI?sort=semver&label=release&style=flat-square&color=2f9bff\"></a>\n <a href=\"LICENSE\"><img alt=\"License: MIT\" src=\"https://img.shields.io/github/license/jaybeyond/Sayknow_CLI?style=flat-square&color=green\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/stargazers\"><img alt=\"Stars\" src=\"https://img.shields.io/github/stars/jaybeyond/Sayknow_CLI?style=flat-square&color=f5c518\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/issues\"><img alt=\"Issues\" src=\"https://img.shields.io/github/issues/jaybeyond/Sayknow_CLI?style=flat-square\"></a>\n <a href=\"https://bun.sh\"><img alt=\"Built with Bun\" src=\"https://img.shields.io/badge/built%20with-Bun-fbf0df?style=flat-square&logo=bun&logoColor=black\"></a>\n <a href=\"#languages\"><img alt=\"i18n\" src=\"https://img.shields.io/badge/i18n-7%20languages-2f9bff?style=flat-square\"></a>\n</p>\n\n<p align=\"center\">\n <a href=\"../../README.md\">English</a> ·\n <a href=\"README.ko.md\">한국어</a> ·\n <a href=\"README.zh.md\">中文</a> ·\n <b>日本語</b> ·\n <a href=\"README.es.md\">Español</a> ·\n <a href=\"README.fr.md\">Français</a> ·\n <a href=\"README.de.md\">Deutsch</a>\n</p>\n\n<p align=\"center\">\n <img src=\"../../assets/character.png\" alt=\"Sayknow-CLI キャラクターマスコット\" width=\"320\" />\n</p>\n\n> Sayknow-CLI は実験的なベータ段階のプロジェクトです。粗削りな部分があることを想定し、重要な作業で頼る前には出力を検証してください。\n\n## Languages\n\nインターフェースは **7 言語** にローカライズされています — English、한국어 (韓国語)、\n中文 (简体 / 簡体字中国語)、日本語 (Japanese)、Español (スペイン語)、\nFrançais (フランス語)、そして Deutsch (ドイツ語)。初回起動時にシステムロケールを\n自動検出します。**Settings → Appearance → Language** でいつでも切り替えられるほか、\nたとえば `LANG=ja_JP.UTF-8 skc` のように起動することもできます。未翻訳の文字列は英語に\nフォールバックし、ブランド名や技術名 (Claude、OpenAI、MCP、…) はすべてのロケールで\nそのまま表示されます。\n\n## Sayknow-CLI とは?\n\nSayknow-CLI (`skc`) は外部コーディングエージェントのハーネスです。選択したリポジトリまたは worktree から実行され、エージェントに対して小さく明示的なワークフロー面を提供します:\n\n```text\ndeep-interview -> ralplan -> ultragoal\n └─ optional team execution when parallel tmux workers help\n```\n\nこれは意図的に、Codex CLI、Claude Code、OpenCode、Claw Code 向けの隠しプラグインにはなっていません。構造化されたプランニング、永続的なエビデンス、tmux ベースのワーカー、または分離された worktree が欲しいときに、それらのツールと並べて `skc` を起動してください。\n\n## Install\n\n> Sayknow-CLI はまだ npm に公開されていません — ソースからインストールしてください。これは Bun\n> のモノレポであり、グローバルの `skc` コマンドはローカルのチェックアウトからリンクされます。\n\n```sh\n# 1. Install Bun (if you don't have it)\ncurl -fsSL https://bun.sh/install | bash # macOS / Linux\n\n# 2. Clone and bootstrap (installs deps, builds native bindings, links `skc`)\ngit clone https://github.com/jaybeyond/Sayknow_CLI.git\ncd Sayknow_CLI\nbun run install:dev\n\n# 3. Verify\nskc --version\nskc --smoke-test\n```\n\n`bun run install:dev` は `bun install` を実行し、`skc` をあなたの `PATH` にリンクし (`dev:link`\n経由)、ローカルのデフォルトをセットアップします。その後は `skc` がこのチェックアウトの\nソースを実行します — 更新するには `git pull` してください。グローバルにリンクしたくない\n場合は、リポジトリから `bun run dev` で直接実行してください。\n\n### Windows (native install)\n\nクリーンな Windows 11 マシンでは、まず Bun をインストールし、その後ソースからビルドします:\n\n```powershell\n# 1. Install Bun\npowershell -c \"irm bun.sh/install.ps1|iex\"\n\n# 2. Restart the terminal so PATH and the Bun runtime refresh, then confirm Bun\nbun --version\n\n# 3. Clone, bootstrap, and verify skc\ngit clone https://github.com/jaybeyond/Sayknow_CLI.git\ncd Sayknow_CLI\nbun run install:dev\nskc --version\nskc --smoke-test\n```\n\n`dev:link` は `skc` ランチャーをあなたの `PATH` に配置します。`skc` がコマンドとして解決\nされるには、そのディレクトリが `PATH` 上にある必要があります — インストール後に `skc` が\n「not recognized」になる場合は、PowerShell を再起動 (またはサインアウト/サインイン) してください。\n\nトラブルシューティング:\n\n- **`skc` が古い Bun ランタイムを報告する。** 上記の Bun インストーラーを再実行し、\n ターミナルを再起動して、`bun --version` が `skc --version` の期待する値と一致することを\n 確認してください。それでも古い Bun が優先される場合は、`%USERPROFILE%\\.bun\\bin` が\n `PATH` の先頭にあることを確認し、それをシャドウしている古い Bun のインストールを削除して\n ください。\n- **`skc.exe` は存在するのに `skc` が「not recognized」になる。** ランチャーは\n インストールされているものの `PATH` 上にありません。`echo $env:Path` に\n `%USERPROFILE%\\.bun\\bin` が含まれていることを確認し、ターミナルを再起動してください。\n\n## Quick start\n\n```sh\n# Run directly in the current checkout\nskc\n\n# Use a tmux-backed leader session\nskc --tmux\n\n# Use an isolated worktree for risky or reviewable work\n# --worktree takes an optional branch-like name, not a filesystem path.\nskc --tmux --worktree my-task-branch\n\n# If you already created a worktree directory, launch from that directory instead.\ncd ../my-task-worktree && skc --tmux\n```\n\nSKC セッション内では、公開されているワークフロー面を使用してください:\n\n```text\n/skill:deep-interview clarify ambiguous requirements\n/skill:ralplan build and critique the implementation plan\nskc ultragoal create-goals --brief-file <approved-plan>\nskc ultragoal complete-goals\n```\n\n`skc team ...` は、協調する tmux ワーカーが実質的に役立つときにのみ追加してください。\n\n## Core capabilities\n\n- **推測する前にインタビューする**: `deep-interview` は曖昧なリクエストを具体的な要件に変えます。\n- **変更する前にプランニングする**: `ralplan` はコード変更の前にアプローチをレビューします。\n- **エビデンスとともに実行する**: `ultragoal` はゴール、リビジョン、チェック、完了エビデンスを追跡します。\n- **役立つときに並列化する**: `team` はより大きなタスクのために tmux ベースのワーカーを協調させます。\n- **外部かつレビュー可能であり続ける**: 別のエージェントランタイムにパッチを当てることなく、選択したリポジトリまたは worktree から実行します。\n\n## Workflow surface\n\nSayknow-CLI は 4 つのデフォルトワークフロースキルを同梱しています:\n\n| Skill | What it does |\n| ---------------- | --------------------------------------------------------------------- |\n| `deep-interview` | プランニングやコード変更の前に、曖昧な要件を明確化します。 |\n| `ralplan` | 変更の前に実装プランを構築し批評します。 |\n| `ultragoal` | 実行、リビジョン、検証、エビデンスを通じてゴールを追跡します。 |\n| `team` | 並列実行に価値があるときに tmux ベースのワーカーを協調させます。 |\n\nそして 4 つの同梱ロールエージェント:\n\n| Agent | What it does |\n| ----------- | -------------------------------------------------- |\n| `executor` | 範囲を限定した実装、修正、リファクタリング。 |\n| `architect` | 読み取り専用のアーキテクチャおよびコードレビュー評価。 |\n| `planner` | 読み取り専用のシーケンシングと受け入れ基準。 |\n| `critic` | 読み取り専用のプラン批評と実行可能性レビュー。 |\n\n肥大化したデフォルトスキルの動物園はありません: SKC はこの小さなメソッドをより良くすることで改善されます。\n\n## Works beside your existing agent or bot\n\n| Tool or bot | Recommended SKC command | Boundary |\n| ----------- | ----------------------- | -------- |\n| Codex CLI | `skc --tmux --worktree <name>` or `skc` | `--worktree` は SKC が管理する兄弟 worktree に名前を付けます。既存のパスを使う場合は、まずそこへ `cd` してください。 |\n| Claude Code | `skc --tmux` or `skc --tmux --worktree <name>` | SKC は Claude Code の拡張機能にはなりません。 |\n| OpenCode | `skc` or `skc --tmux` | 現時点では外部ランナーのワークフローのみです。 |\n| Claw Code | `skc --tmux --worktree <name>` | SKC は Claw Code にインストールされたり、置き換えたりはしません。 |\n| External controller / bot | `skc mcp-serve coordinator` plus `skc setup hermes` for compatible config, or `skc --mode rpc` for a subprocess worker | MCP/RPC 対応のボットはどれも、スクロールバックのスクレイピングではなく、汎用のコーディネーター/RPC コントラクトを通じて SKC を駆動します。 |\n\n汎用的なサードパーティボットのセットアップとプロバイダー非依存のスモークテストについては、[`docs/bot-integration.md`](docs/bot-integration.md) を参照してください。MCP、RPC、ACP、Bridge/HTTPS 各面にわたる準備状況の分類については、[`docs/external-control-readiness.md`](docs/external-control-readiness.md) を参照してください。より低レベルのプロトコル詳細については、[`docs/hermes-mcp-bridge.md`](docs/hermes-mcp-bridge.md)、[`docs/rpc.md`](docs/rpc.md)、および [`docs/bridge.md`](docs/bridge.md) を参照してください。リモートオペレーター面のロードマップについては、[`docs/sayknow-remote.md`](docs/sayknow-remote.md) (web steering wheel) と [`docs/telegram-remote.md`](docs/telegram-remote.md) (Telegram lifecycle button) を参照してください。\n\n## Configuration\n\nプロバイダーのリトライバジェットは `~/.skc/config.yml` にあります:\n\n```yaml\nretry:\n requestMaxRetries: 4\n streamMaxRetries: 100\n maxRetries: 3\n maxDelayMs: 300000\n```\n\n`requestMaxRetries` はストリームが確立される前に適用されます。`streamMaxRetries` はリプレイ安全な一時的ストリーム障害にのみ適用されます。無効な認証、サポートされていないモデル/プロバイダー、不正な形式のリクエスト、コンテキストオーバーフロー、ユーザーによる中断、および恒久的なクォータ障害は、引き続きフェイルファストのままです。\n\n## TUI identity\n\nデフォルトの TUI アイデンティティは SKC の **blue-octopus** テーマ — 青い頭足類のマスコット — で、ダークおよびライトの両方のターミナルに対応します。より暗めでハイコントラストなパレットを好む人のために、温かみのある **red-octopus** バリアントも同梱されています。さらに 3 つの移行用テーマ — `claude-code`、`codex`、`opencode` — がそれらのツールの見た目を再現しており、視覚的な移行を容易にし、Settings または `/theme` から選択できます。ユーザーが明示的に設定したテーマは引き続き優先されます。\n\n### Bundled theme grid\n\nSettings (`Appearance -> Dark theme` / `Light theme`) または `/theme` から選択してください。\n\n| Theme | Visual feel | Best fit |\n| --- | --- | --- |\n| `blue-octopus` | デフォルトの SKC アイデンティティ — テンタクルブルーのアクセントを持つ青いタコのパレット。 | ダークおよびライトのターミナルのデフォルト。 |\n| `red-octopus` | 強いステータスコントラストを持つ温かみのある赤いタコのバリアント。 | ハイコントラストなダークの代替。 |\n| `claude-code` | テラコッタとピンクのハイライトを持つ Claude Code 風のダークパレット。 | SKC を離れずに Claude Code の体に染み付いた操作感を。 |\n| `codex` | よりシャープなコーディングセッションのコントラストを持つ、くっきりしたダークブルーグレーのパレット。 | Codex ライクなダークワークスペース。 |\n| `opencode` | よりパンチの効いたターミナルアクセントを持つ OpenCode 風のダークパレット。 | 同梱のピッカーで OpenCode の体に染み付いた操作感を。 |\n\n## Development\n\n依存関係をインストールし、ネイティブバインディングをビルドし、ローカルのデフォルトをセットアップします:\n\n```sh\nbun install\nbun run build:native\nbun run install:defaults\n```\n\n`@sayknow-cli/natives` 用の `.node` バイナリは gitignore されており、あらゆる CLI 呼び出し (`install:defaults`、`dev:link`、テスト) の前に必要です。\n\n### Canonical: build and link the dev `skc`\n\nグローバルの `skc` コマンドが **このチェックアウトの TypeScript ソース** を実行するようにする (すべての編集に即座に反映され、スキル/ネイティブが動作する) には、それをあなたの `PATH` にリンクします:\n\n```sh\nbun install\nbun run dev:link\n```\n\n`dev:link` は `skc` → `packages/coding-agent/src/cli.ts` を `~/.local/bin` にシンボリックリンクし (`SKC_DEV_LINK_DIR` で上書き可能)、その管理対象ターゲットを置き換え、別の `skc` が `PATH` 上でより前にそれをシャドウしている場合は警告して失敗し、`--smoke-test` を実行して `@sayknow-cli/natives` がロードされることを確認します。完全なブートストラップ (install + link + `setup defaults`) には `bun run install:dev` を使用してください。\n\nあなたの `skc` がドリフトしていないか (誤ったソース、またはスキルをロードできないコンパイル済みバイナリ) は、いつでも確認できます:\n\n```sh\nbun run dev:doctor\n```\n\n> 日常の開発にコンパイル済みバイナリを **使わないでください**。`bun --cwd=packages/coding-agent run build` はスタンドアロンの `dist/skc` を生成しますが、`bun build --compile` のバイナリは `@sayknow-cli/natives` を動的にロードできないため、スキルは `Cannot find module '@sayknow-cli/natives' from '/$bunfs/root/skc'` で失敗します。`dev:link` を通じてソースから実行すれば、これを回避できます。バイナリのビルドはリリースを検証するときのみ行ってください。\n\nリンクせずに CLI をソースから直接実行します:\n\n```sh\nbun packages/coding-agent/src/cli.ts --help\n```\n\nデフォルトのワークフロー定義はソースにあり、コミットされた `.skc` のコピーにはありません:\n\n```text\npackages/coding-agent/src/defaults/skc/skills/<name>/SKILL.md\npackages/coding-agent/src/prompts/agents/<role>.md\n```\n\nワークフロー定義またはリブランド面の変更については、プロジェクトのゲートを実行してください:\n\n```sh\nbun scripts/check-visible-definitions.ts\nbun scripts/verify-g002-gates.ts\nbun scripts/rebrand-inventory.ts --strict\nbun test packages/coding-agent/test/default-skc-definitions.test.ts\n```\n\nパッケージごとのマップについては、[`docs/codebase-overview.md`](docs/codebase-overview.md) を参照してください。\n\n## Contributors\n\nコントリビューション、バグレポート、リリース検証は GitHub の Issues と Pull Request を通じて歓迎しています。\n\n## Inspirations and lineage\n\nSayknow-CLI のデフォルト TUI アイデンティティは頭足類のペアです: デフォルトの blue-octopus と、温かみのある red-octopus の代替。また、`claude-code`、`codex`、`opencode` の移行用テーマも同梱しており、これらのパレットはそれらのツールにインスパイアされているため、移行してくるユーザーが見慣れた見た目を得られます。これは、公開された SKC 面を意図的に集中させたまま、小さなエージェントハーネス一族からの教訓の上に構築されています。歴史的な帰属表示は [`NOTICE.md`](NOTICE.md) に保持されています。\n\n## License\n\nMIT。[`LICENSE`](LICENSE) を参照してください。\n",
56
- "readme/README.ko.md": "<p align=\"center\">\n <img src=\"../../assets/hero.png\" alt=\"Sayknow-CLI autonomous coding-agent hero illustration\" width=\"100%\" />\n</p>\n\n<h1 align=\"center\">Sayknow-CLI</h1>\n\n<p align=\"center\">\n <strong>코딩은 사고처럼 느껴져야 합니다.</strong><br />\n 인터뷰, 검토된 계획, tmux 네이티브 실행, 견고한 검증을 위한 집중형 코딩 에이전트 러너.\n</p>\n\n<p align=\"center\">\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/releases\"><img alt=\"Release\" src=\"https://img.shields.io/github/v/tag/jaybeyond/Sayknow_CLI?sort=semver&label=release&style=flat-square&color=2f9bff\"></a>\n <a href=\"LICENSE\"><img alt=\"License: MIT\" src=\"https://img.shields.io/github/license/jaybeyond/Sayknow_CLI?style=flat-square&color=green\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/stargazers\"><img alt=\"Stars\" src=\"https://img.shields.io/github/stars/jaybeyond/Sayknow_CLI?style=flat-square&color=f5c518\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/issues\"><img alt=\"Issues\" src=\"https://img.shields.io/github/issues/jaybeyond/Sayknow_CLI?style=flat-square\"></a>\n <a href=\"https://bun.sh\"><img alt=\"Built with Bun\" src=\"https://img.shields.io/badge/built%20with-Bun-fbf0df?style=flat-square&logo=bun&logoColor=black\"></a>\n <a href=\"#languages\"><img alt=\"i18n\" src=\"https://img.shields.io/badge/i18n-7%20languages-2f9bff?style=flat-square\"></a>\n</p>\n\n<p align=\"center\">\n <a href=\"../../README.md\">English</a> ·\n <b>한국어</b> ·\n <a href=\"README.zh.md\">中文</a> ·\n <a href=\"README.ja.md\">日本語</a> ·\n <a href=\"README.es.md\">Español</a> ·\n <a href=\"README.fr.md\">Français</a> ·\n <a href=\"README.de.md\">Deutsch</a>\n</p>\n\n<p align=\"center\">\n <img src=\"../../assets/character.png\" alt=\"Sayknow-CLI character mascot\" width=\"320\" />\n</p>\n\n> Sayknow-CLI는 실험적인 베타 단계 프로젝트입니다. 거친 부분이 있을 수 있으니 중요한 작업에 의존하기 전에 출력 결과를 검증하세요.\n\n## Languages\n\n인터페이스는 **7개 언어** — English, 한국어 (Korean),\n中文 (简体 / Simplified Chinese), 日本語 (Japanese), Español (Spanish),\nFrançais (French), Deutsch (German) — 로 현지화되어 있습니다. 첫 실행 시\n시스템 로케일을 자동으로 감지하며, 언제든지 **Settings → Appearance → Language** 에서\n전환하거나 예를 들어 `LANG=ja_JP.UTF-8 skc` 로 실행할 수 있습니다. 번역되지 않은 문자열은\nEnglish로 대체되며, 브랜드/기술 이름(Claude, OpenAI, MCP, …)은 모든 로케일에서 그대로 유지됩니다.\n\n## What is Sayknow-CLI?\n\nSayknow-CLI(`skc`)는 외부 코딩 에이전트 하니스입니다. 선택한 저장소나 워크트리에서 실행되며, 에이전트에게 작고 명시적인 워크플로 표면을 제공합니다:\n\n```text\ndeep-interview -> ralplan -> ultragoal\n └─ optional team execution when parallel tmux workers help\n```\n\n이것은 의도적으로 Codex CLI, Claude Code, OpenCode, Claw Code의 숨겨진 플러그인이 아닙니다. 구조화된 계획, 지속적인 증거, tmux 기반 워커, 또는 격리된 워크트리를 원할 때 이러한 도구들 옆에서 `skc`를 시작하세요.\n\n## Install\n\n> Sayknow-CLI는 아직 npm에 게시되지 않았습니다 — 소스에서 설치하세요. 이것은 Bun\n> 모노레포이므로, 전역 `skc` 명령은 로컬 체크아웃에서 링크됩니다.\n\n```sh\n# 1. Install Bun (if you don't have it)\ncurl -fsSL https://bun.sh/install | bash # macOS / Linux\n\n# 2. Clone and bootstrap (installs deps, builds native bindings, links `skc`)\ngit clone https://github.com/jaybeyond/Sayknow_CLI.git\ncd Sayknow_CLI\nbun run install:dev\n\n# 3. Verify\nskc --version\nskc --smoke-test\n```\n\n`bun run install:dev`는 `bun install`을 실행하고, `skc`를 (via\n`dev:link`) `PATH`에 링크하며, 로컬 기본값을 설정합니다. 그 이후로 `skc`는 이 체크아웃의\n소스를 실행합니다 — 업데이트하려면 `git pull` 하세요. 전역으로 링크하지 않으려면, 저장소에서\n`bun run dev`로 직접 실행하세요.\n\n### Windows (native install)\n\n깨끗한 Windows 11 머신에서는, 먼저 Bun을 설치한 다음 소스에서 빌드하세요:\n\n```powershell\n# 1. Install Bun\npowershell -c \"irm bun.sh/install.ps1|iex\"\n\n# 2. Restart the terminal so PATH and the Bun runtime refresh, then confirm Bun\nbun --version\n\n# 3. Clone, bootstrap, and verify skc\ngit clone https://github.com/jaybeyond/Sayknow_CLI.git\ncd Sayknow_CLI\nbun run install:dev\nskc --version\nskc --smoke-test\n```\n\n`dev:link`는 `skc` 런처를 `PATH`에 배치합니다. `skc`가 명령으로 인식되려면 그\n디렉터리가 `PATH`에 있어야 합니다 — 설치 후 `skc`가 \"not recognized\"라면 PowerShell을\n재시작(또는 로그아웃/로그인)하세요.\n\nTroubleshooting:\n\n- **`skc`가 오래된 Bun 런타임을 보고합니다.** 위의 Bun 설치 프로그램을 다시 실행하고, 터미널을\n 재시작한 다음, `bun --version`이 `skc --version`이 기대하는 것과 일치하는지 확인하세요.\n 여전히 오래된 Bun이 우선한다면, `%USERPROFILE%\\.bun\\bin`이\n `PATH`의 맨 앞에 있는지 확인하고 그것을 가리는 오래된 Bun 설치를 제거하세요.\n- **`skc.exe`는 존재하지만 `skc`가 \"not recognized\"입니다.** 런처는 설치되어\n 있지만 `PATH`에 없습니다. `echo $env:Path`에 `%USERPROFILE%\\.bun\\bin`이\n 나열되어 있는지 확인한 다음, 터미널을 재시작하세요.\n\n## Quick start\n\n```sh\n# Run directly in the current checkout\nskc\n\n# Use a tmux-backed leader session\nskc --tmux\n\n# Use an isolated worktree for risky or reviewable work\n# --worktree takes an optional branch-like name, not a filesystem path.\nskc --tmux --worktree my-task-branch\n\n# If you already created a worktree directory, launch from that directory instead.\ncd ../my-task-worktree && skc --tmux\n```\n\nSKC 세션 내부에서는, 공개 워크플로 표면을 사용하세요:\n\n```text\n/skill:deep-interview clarify ambiguous requirements\n/skill:ralplan build and critique the implementation plan\nskc ultragoal create-goals --brief-file <approved-plan>\nskc ultragoal complete-goals\n```\n\n조율된 tmux 워커가 실질적으로 도움이 될 때만 `skc team ...`을 추가하세요.\n\n## Core capabilities\n\n- **추측하기 전에 인터뷰**: `deep-interview`는 모호한 요청을 구체적인 요구사항으로 바꿉니다.\n- **변경하기 전에 계획**: `ralplan`은 코드 변경 전에 접근 방식을 검토합니다.\n- **증거와 함께 실행**: `ultragoal`은 목표, 수정, 점검, 완료 증거를 추적합니다.\n- **유용할 때 병렬화**: `team`은 더 큰 작업을 위해 tmux 기반 워커를 조율합니다.\n- **외부에서 검토 가능하게 유지**: 다른 에이전트 런타임을 패치하지 않고 선택한 저장소나 워크트리에서 실행합니다.\n\n## Workflow surface\n\nSayknow-CLI는 네 가지 기본 워크플로 스킬을 제공합니다:\n\n| Skill | What it does |\n| ---------------- | --------------------------------------------------------------------- |\n| `deep-interview` | 계획이나 코드 변경 전에 모호한 요구사항을 명확히 합니다. |\n| `ralplan` | 변경 전에 구현 계획을 구축하고 비평합니다. |\n| `ultragoal` | 실행, 수정, 검증, 증거를 거쳐 목표를 추적합니다. |\n| `team` | 병렬 실행이 가치가 있을 때 tmux 기반 워커를 조율합니다. |\n\n그리고 네 가지 번들 역할 에이전트:\n\n| Agent | What it does |\n| ----------- | -------------------------------------------------- |\n| `executor` | 범위가 정해진 구현, 수정, 리팩터. |\n| `architect` | 읽기 전용 아키텍처 및 코드 리뷰 평가. |\n| `planner` | 읽기 전용 순서 결정 및 수용 기준. |\n| `critic` | 읽기 전용 계획 비평 및 실행 가능성 검토. |\n\n광범위한 기본 스킬 동물원은 없습니다: SKC는 이 작은 방법을 더 좋게 만들어 개선됩니다.\n\n## Works beside your existing agent or bot\n\n| Tool or bot | Recommended SKC command | Boundary |\n| ----------- | ----------------------- | -------- |\n| Codex CLI | `skc --tmux --worktree <name>` or `skc` | `--worktree`는 SKC가 관리하는 형제 워크트리의 이름을 지정합니다. 기존 경로의 경우 먼저 그곳으로 `cd` 하세요. |\n| Claude Code | `skc --tmux` or `skc --tmux --worktree <name>` | SKC는 Claude Code 확장이 되지 않습니다. |\n| OpenCode | `skc` or `skc --tmux` | 현재로서는 외부 러너 워크플로만 지원합니다. |\n| Claw Code | `skc --tmux --worktree <name>` | SKC는 Claw Code에 설치되거나 그것을 대체하지 않습니다. |\n| External controller / bot | 호환 가능한 구성을 위한 `skc mcp-serve coordinator` 및 `skc setup hermes`, 또는 서브프로세스 워커를 위한 `skc --mode rpc` | MCP/RPC 지원 봇이라면 무엇이든 스크롤백 스크래핑이 아니라 일반 coordinator/RPC 계약을 통해 SKC를 구동합니다. |\n\n일반 서드파티 봇 설정 및 공급자 독립적 스모크에 대해서는 [`docs/bot-integration.md`](docs/bot-integration.md)를 참조하세요. MCP, RPC, ACP, Bridge/HTTPS 표면 전반의 준비도 분류에 대해서는 [`docs/external-control-readiness.md`](docs/external-control-readiness.md)를 참조하세요. 더 낮은 수준의 프로토콜 세부 사항에 대해서는 [`docs/hermes-mcp-bridge.md`](docs/hermes-mcp-bridge.md), [`docs/rpc.md`](docs/rpc.md), [`docs/bridge.md`](docs/bridge.md)를 참조하세요. 원격 운영자 표면 로드맵에 대해서는 [`docs/sayknow-remote.md`](docs/sayknow-remote.md)(웹 스티어링 휠) 및 [`docs/telegram-remote.md`](docs/telegram-remote.md)(Telegram 라이프사이클 버튼)를 참조하세요.\n\n## Configuration\n\n공급자 재시도 예산은 `~/.skc/config.yml`에 있습니다:\n\n```yaml\nretry:\n requestMaxRetries: 4\n streamMaxRetries: 100\n maxRetries: 3\n maxDelayMs: 300000\n```\n\n`requestMaxRetries`는 스트림이 설정되기 전에 적용됩니다. `streamMaxRetries`는 재생 안전한 일시적 스트림 실패에만 적용됩니다. 잘못된 인증, 지원되지 않는 모델/공급자, 잘못된 형식의 요청, 컨텍스트 오버플로, 사용자 중단, 영구적인 할당량 실패는 즉시 실패(fail-fast)로 유지됩니다.\n\n## TUI identity\n\n기본 TUI 정체성은 SKC **blue-octopus** 테마 — 파란 두족류 마스코트 — 로, 다크 및 라이트 터미널 모두에 적용됩니다. 더 어둡고 고대비 팔레트를 선호하는 사람들을 위해 따뜻한 **red-octopus** 변형도 번들로 제공됩니다. 세 가지 추가 마이그레이션 테마 — `claude-code`, `codex`, `opencode` — 는 쉬운 눈 마이그레이션을 위해 해당 도구들의 모습을 그대로 따르며 Settings 또는 `/theme`에서 선택할 수 있습니다. 명시적인 사용자 테마 설정이 여전히 우선합니다.\n\n### Bundled theme grid\n\nSettings (`Appearance -> Dark theme` / `Light theme`) 또는 `/theme`에서 선택하세요.\n\n| Theme | Visual feel | Best fit |\n| --- | --- | --- |\n| `blue-octopus` | 기본 SKC 정체성 — 촉수 블루 액센트가 있는 파란 문어 팔레트. | 다크 및 라이트 터미널의 기본값. |\n| `red-octopus` | 강한 상태 대비를 가진 따뜻한 빨간 문어 변형. | 고대비 다크 대안. |\n| `claude-code` | 테라코타와 핑크 하이라이트가 있는 Claude Code 영감 다크 팔레트. | SKC를 떠나지 않고 Claude Code 근육 기억을 유지. |\n| `codex` | 더 날카로운 코딩 세션 대비를 가진 선명한 다크 블루그레이 팔레트. | Codex 같은 다크 작업 공간. |\n| `opencode` | 더 강렬한 터미널 액센트를 가진 OpenCode 영감 다크 팔레트. | 번들 선택기에서의 OpenCode 근육 기억. |\n\n## Development\n\n의존성을 설치하고, 네이티브 바인딩을 빌드하고, 로컬 기본값을 설정하세요:\n\n```sh\nbun install\nbun run build:native\nbun run install:defaults\n```\n\n`@sayknow-cli/natives`용 `.node` 바이너리는 gitignore되어 있으며 모든 CLI 호출(`install:defaults`, `dev:link`, 테스트) 전에 필요합니다.\n\n### Canonical: build and link the dev `skc`\n\n전역 `skc` 명령이 **이 체크아웃의 TypeScript 소스**(모든 편집에 즉시 반영되며, 스킬/네이티브가 작동함)를 실행하도록 하려면, `PATH`에 링크하세요:\n\n```sh\nbun install\nbun run dev:link\n```\n\n`dev:link`는 `skc` → `packages/coding-agent/src/cli.ts`를 `~/.local/bin`에 심볼릭 링크하고(`SKC_DEV_LINK_DIR`로 재정의 가능), 그 관리되는 대상을 교체하며, 다른 `skc`가 여전히 `PATH`에서 더 앞쪽에 있어 그것을 가린다면 경고하고 실패하며, `--smoke-test`를 실행하여 `@sayknow-cli/natives`가 로드되는지 확인합니다. 전체 부트스트랩(install + link + `setup defaults`)을 위해서는 `bun run install:dev`를 사용하세요.\n\n당신의 `skc`가 표류했는지(잘못된 소스, 또는 스킬을 로드할 수 없는 컴파일된 바이너리) 언제든지 확인하세요:\n\n```sh\nbun run dev:doctor\n```\n\n> 일상적인 개발에는 컴파일된 바이너리를 **사용하지 마세요**. `bun --cwd=packages/coding-agent run build`는 독립 실행형 `dist/skc`를 생성하지만, `bun build --compile` 바이너리는 `@sayknow-cli/natives`를 동적으로 로드할 수 없으므로 스킬이 `Cannot find module '@sayknow-cli/natives' from '/$bunfs/root/skc'`로 실패합니다. `dev:link`를 통해 소스에서 실행하면 이를 피할 수 있습니다. 릴리스를 검증할 때만 바이너리를 빌드하세요.\n\n링크 없이 소스에서 직접 CLI를 실행하세요:\n\n```sh\nbun packages/coding-agent/src/cli.ts --help\n```\n\n기본 워크플로 정의는 커밋된 `.skc` 사본이 아니라 소스에 있습니다:\n\n```text\npackages/coding-agent/src/defaults/skc/skills/<name>/SKILL.md\npackages/coding-agent/src/prompts/agents/<role>.md\n```\n\n워크플로 정의 또는 리브랜드 표면 변경의 경우, 프로젝트 게이트를 실행하세요:\n\n```sh\nbun scripts/check-visible-definitions.ts\nbun scripts/verify-g002-gates.ts\nbun scripts/rebrand-inventory.ts --strict\nbun test packages/coding-agent/test/default-skc-definitions.test.ts\n```\n\n패키지별 맵에 대해서는 [`docs/codebase-overview.md`](docs/codebase-overview.md)를 참조하세요.\n\n## Contributors\n\n기여, 버그 보고, 릴리스 검증은 GitHub Issues와 Pull Request를 통해 환영합니다.\n\n## Inspirations and lineage\n\nSayknow-CLI의 기본 TUI 정체성은 두족류 쌍입니다: 기본값인 blue-octopus와 따뜻한 red-octopus 대안. 또한 해당 도구들에서 옮겨오는 사용자들이 익숙한 모습을 얻도록 팔레트가 그 도구들에서 영감을 받은 `claude-code`, `codex`, `opencode` 마이그레이션 테마를 번들로 제공합니다. 공개 SKC 표면을 의도적으로 집중된 상태로 유지하면서, 작은 에이전트 하니스 계열에서 얻은 교훈을 바탕으로 만들어졌습니다. 역사적 출처 표기는 [`NOTICE.md`](NOTICE.md)에 보관되어 있습니다.\n\n## License\n\nMIT. [`LICENSE`](LICENSE)를 참조하세요.\n",
57
- "readme/README.zh.md": "<p align=\"center\">\n <img src=\"../../assets/hero.png\" alt=\"Sayknow-CLI autonomous coding-agent hero illustration\" width=\"100%\" />\n</p>\n\n<h1 align=\"center\">Sayknow-CLI</h1>\n\n<p align=\"center\">\n <strong>编码应当如思考般自然。</strong><br />\n 一个专注的编码智能体运行器,面向访谈式需求澄清、经评审的计划、tmux 原生执行与持久化验证。\n</p>\n\n<p align=\"center\">\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/releases\"><img alt=\"Release\" src=\"https://img.shields.io/github/v/tag/jaybeyond/Sayknow_CLI?sort=semver&label=release&style=flat-square&color=2f9bff\"></a>\n <a href=\"LICENSE\"><img alt=\"License: MIT\" src=\"https://img.shields.io/github/license/jaybeyond/Sayknow_CLI?style=flat-square&color=green\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/stargazers\"><img alt=\"Stars\" src=\"https://img.shields.io/github/stars/jaybeyond/Sayknow_CLI?style=flat-square&color=f5c518\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/issues\"><img alt=\"Issues\" src=\"https://img.shields.io/github/issues/jaybeyond/Sayknow_CLI?style=flat-square\"></a>\n <a href=\"https://bun.sh\"><img alt=\"Built with Bun\" src=\"https://img.shields.io/badge/built%20with-Bun-fbf0df?style=flat-square&logo=bun&logoColor=black\"></a>\n <a href=\"#languages\"><img alt=\"i18n\" src=\"https://img.shields.io/badge/i18n-7%20languages-2f9bff?style=flat-square\"></a>\n</p>\n\n<p align=\"center\">\n <a href=\"../../README.md\">English</a> ·\n <a href=\"README.ko.md\">한국어</a> ·\n <b>中文</b> ·\n <a href=\"README.ja.md\">日本語</a> ·\n <a href=\"README.es.md\">Español</a> ·\n <a href=\"README.fr.md\">Français</a> ·\n <a href=\"README.de.md\">Deutsch</a>\n</p>\n\n<p align=\"center\">\n <img src=\"../../assets/character.png\" alt=\"Sayknow-CLI character mascot\" width=\"320\" />\n</p>\n\n> Sayknow-CLI 是一个实验性的、处于 beta 阶段的项目。请预期会有粗糙之处,并在依赖其结果完成重要工作之前先行验证输出。\n\n## Languages\n\n界面已本地化为 **7 种语言**——English、한국어(韩语)、\n中文(简体)、日本語(日语)、Español(西班牙语)、\nFrançais(法语)以及 Deutsch(德语)。首次运行时它会自动检测你的系统区域设置;\n你可以随时在 **Settings → Appearance → Language** 中切换,或者使用例如\n`LANG=ja_JP.UTF-8 skc` 的方式启动。未翻译的字符串会回退到英文,而\n品牌/技术名称(Claude、OpenAI、MCP……)在所有语言环境中均保持原样。\n\n## What is Sayknow-CLI?\n\nSayknow-CLI(`skc`)是一个外部编码智能体框架(harness)。它从你选择的仓库或工作树(worktree)中运行,然后为智能体提供一个精简、明确的工作流界面:\n\n```text\ndeep-interview -> ralplan -> ultragoal\n └─ optional team execution when parallel tmux workers help\n```\n\n它有意不做成 Codex CLI、Claude Code、OpenCode 或 Claw Code 的隐藏插件。当你需要结构化的规划、持久化的证据、tmux 支持的工作进程或一个隔离的工作树时,就在这些工具旁边启动 `skc`。\n\n## Install\n\n> Sayknow-CLI 尚未发布到 npm——请从源码安装。它是一个 Bun\n> monorepo,因此全局 `skc` 命令是从你本地的检出(checkout)链接而来的。\n\n```sh\n# 1. Install Bun (if you don't have it)\ncurl -fsSL https://bun.sh/install | bash # macOS / Linux\n\n# 2. Clone and bootstrap (installs deps, builds native bindings, links `skc`)\ngit clone https://github.com/jaybeyond/Sayknow_CLI.git\ncd Sayknow_CLI\nbun run install:dev\n\n# 3. Verify\nskc --version\nskc --smoke-test\n```\n\n`bun run install:dev` 会运行 `bun install`,将 `skc` 链接到你的 `PATH`(通过\n`dev:link`),并设置本地默认值。完成之后,`skc` 运行的就是此检出的\n源码——执行 `git pull` 即可更新。如果你不想进行全局链接,可以在仓库中\n通过 `bun run dev` 直接运行它。\n\n### Windows (native install)\n\n在一台干净的 Windows 11 机器上,先安装 Bun,然后从源码构建:\n\n```powershell\n# 1. Install Bun\npowershell -c \"irm bun.sh/install.ps1|iex\"\n\n# 2. Restart the terminal so PATH and the Bun runtime refresh, then confirm Bun\nbun --version\n\n# 3. Clone, bootstrap, and verify skc\ngit clone https://github.com/jaybeyond/Sayknow_CLI.git\ncd Sayknow_CLI\nbun run install:dev\nskc --version\nskc --smoke-test\n```\n\n`dev:link` 会把 `skc` 启动器放到你的 `PATH` 上。该目录必须位于\n`PATH` 中,`skc` 才能作为命令被解析——如果安装后 `skc` 提示“未识别”,\n请重启 PowerShell(或注销后重新登录)。\n\n故障排查:\n\n- **`skc` 报告 Bun 运行时版本过旧。** 重新运行上面的 Bun 安装程序,重启\n 终端,并确认 `bun --version` 与 `skc --version`\n 所期望的版本一致。如果较旧的 Bun 仍然胜出,请确保 `%USERPROFILE%\\.bun\\bin` 位于\n `PATH` 的最前面,并移除任何遮蔽它的过时 Bun 安装。\n- **`skc.exe` 存在但 `skc` 提示“未识别”。** 启动器已安装,\n 但不在 `PATH` 上。确认 `%USERPROFILE%\\.bun\\bin` 已列在\n `echo $env:Path` 中,然后重启终端。\n\n## Quick start\n\n```sh\n# Run directly in the current checkout\nskc\n\n# Use a tmux-backed leader session\nskc --tmux\n\n# Use an isolated worktree for risky or reviewable work\n# --worktree takes an optional branch-like name, not a filesystem path.\nskc --tmux --worktree my-task-branch\n\n# If you already created a worktree directory, launch from that directory instead.\ncd ../my-task-worktree && skc --tmux\n```\n\n在 SKC 会话内部,使用公共工作流界面:\n\n```text\n/skill:deep-interview clarify ambiguous requirements\n/skill:ralplan build and critique the implementation plan\nskc ultragoal create-goals --brief-file <approved-plan>\nskc ultragoal complete-goals\n```\n\n仅当协同的 tmux 工作进程能带来实质性帮助时,才加上 `skc team ...`。\n\n## Core capabilities\n\n- **先访谈,不靠猜**:`deep-interview` 把模糊的请求转化为具体的需求。\n- **先规划,再变更**:`ralplan` 在代码改动之前评审方案。\n- **带证据地执行**:`ultragoal` 跟踪目标、修订、检查以及完成证据。\n- **在有用时并行化**:`team` 为较大的任务协调 tmux 支持的工作进程。\n- **保持外部化且可评审**:从所选的仓库或工作树中运行,无需给另一个智能体运行时打补丁。\n\n## Workflow surface\n\nSayknow-CLI 内置四项默认工作流技能:\n\n| Skill | What it does |\n| ---------------- | --------------------------------------------------------------------- |\n| `deep-interview` | 在规划或代码改动之前澄清模糊的需求。 |\n| `ralplan` | 在变更之前构建并评审实现计划。 |\n| `ultragoal` | 在执行、修订、验证与证据收集的全过程中跟踪目标。 |\n| `team` | 当并行执行值得时,协调 tmux 支持的工作进程。 |\n\n以及四个捆绑的角色智能体:\n\n| Agent | What it does |\n| ----------- | -------------------------------------------------- |\n| `executor` | 有边界的实现、修复与重构。 |\n| `architect` | 只读的架构与代码评审评估。 |\n| `planner` | 只读的排序与验收标准。 |\n| `critic` | 只读的计划评审与可执行性审查。 |\n\n没有庞杂的默认技能堆砌:SKC 通过把这一精简方法做得更好来持续改进。\n\n## Works beside your existing agent or bot\n\n| Tool or bot | Recommended SKC command | Boundary |\n| ----------- | ----------------------- | -------- |\n| Codex CLI | `skc --tmux --worktree <name>` or `skc` | `--worktree` 指定一个由 SKC 管理的同级工作树;对于已存在的路径,请先 `cd` 到那里。 |\n| Claude Code | `skc --tmux` or `skc --tmux --worktree <name>` | SKC 不会成为 Claude Code 的扩展。 |\n| OpenCode | `skc` or `skc --tmux` | 目前仅支持外部运行器(external-runner)工作流。 |\n| Claw Code | `skc --tmux --worktree <name>` | SKC 不会安装到 Claw Code 中,也不会替代它。 |\n| External controller / bot | `skc mcp-serve coordinator` plus `skc setup hermes` for compatible config, or `skc --mode rpc` for a subprocess worker | 任何具备 MCP/RPC 能力的 bot 都通过通用的 coordinator/RPC 契约来驱动 SKC,而非抓取滚动回显(scrollback scraping)。 |\n\n关于通用第三方 bot 的设置以及与提供商无关的冒烟测试,请参阅 [`docs/bot-integration.md`](docs/bot-integration.md)。关于在 MCP、RPC、ACP 与 Bridge/HTTPS 各界面上的就绪度分级,请参阅 [`docs/external-control-readiness.md`](docs/external-control-readiness.md)。关于更底层的协议细节,请参阅 [`docs/hermes-mcp-bridge.md`](docs/hermes-mcp-bridge.md)、[`docs/rpc.md`](docs/rpc.md) 以及 [`docs/bridge.md`](docs/bridge.md)。关于远程操作员界面的路线图,请参阅 [`docs/sayknow-remote.md`](docs/sayknow-remote.md)(网页方向盘)以及 [`docs/telegram-remote.md`](docs/telegram-remote.md)(Telegram 生命周期按钮)。\n\n## Configuration\n\n提供商重试预算位于 `~/.skc/config.yml`:\n\n```yaml\nretry:\n requestMaxRetries: 4\n streamMaxRetries: 100\n maxRetries: 3\n maxDelayMs: 300000\n```\n\n`requestMaxRetries` 在流(stream)建立之前生效。`streamMaxRetries` 仅适用于可安全重放的瞬时流失败。无效的认证、不受支持的模型/提供商、格式错误的请求、上下文溢出、用户中止以及永久性配额失败仍然保持快速失败(fail-fast)。\n\n## TUI identity\n\n默认的 TUI 标识是 SKC 的 **blue-octopus**(蓝章鱼)主题——蓝色头足类吉祥物——同时适用于深色和浅色终端。还捆绑了一个暖色调的 **red-octopus**(红章鱼)变体,供偏好更深、高对比度配色的用户使用。另有三个迁移主题——`claude-code`、`codex` 和 `opencode`——分别复刻了这些工具的外观,以便于视觉迁移,可从 Settings 或 `/theme` 中选择。显式的用户主题设置仍然优先生效。\n\n### Bundled theme grid\n\n从 Settings(`Appearance -> Dark theme` / `Light theme`)或 `/theme` 中选择。\n\n| Theme | Visual feel | Best fit |\n| --- | --- | --- |\n| `blue-octopus` | 默认 SKC 标识——蓝章鱼配色,带触手蓝点缀。 | 深色和浅色终端的默认主题。 |\n| `red-octopus` | 暖色调红章鱼变体,状态对比强烈。 | 高对比度的深色替代方案。 |\n| `claude-code` | 受 Claude Code 启发的深色配色,带赤陶色和粉色高光。 | 在不离开 SKC 的情况下保留 Claude Code 的肌肉记忆。 |\n| `codex` | 清爽的深蓝灰配色,编码会话对比更锐利。 | 类似 Codex 的深色工作区。 |\n| `opencode` | 受 OpenCode 启发的深色配色,终端点缀更鲜明。 | 在捆绑选择器中保留 OpenCode 的肌肉记忆。 |\n\n## Development\n\n安装依赖、构建原生绑定,并设置本地默认值:\n\n```sh\nbun install\nbun run build:native\nbun run install:defaults\n```\n\n`@sayknow-cli/natives` 的 `.node` 二进制文件已被 gitignore,且在任何 CLI 调用(`install:defaults`、`dev:link`、测试)之前都是必需的。\n\n### Canonical: build and link the dev `skc`\n\n要让全局 `skc` 命令运行**此检出的 TypeScript 源码**(对每一次编辑都即时生效,且技能/原生绑定均可用),请把它链接到你的 `PATH`:\n\n```sh\nbun install\nbun run dev:link\n```\n\n`dev:link` 会把 `skc` → `packages/coding-agent/src/cli.ts` 软链接到 `~/.local/bin`(可用 `SKC_DEV_LINK_DIR` 覆盖),替换该受管目标,如果另一个 `skc` 仍在 `PATH` 上更靠前地遮蔽它则会发出警告并失败,并运行 `--smoke-test` 以确认 `@sayknow-cli/natives` 能够加载。使用 `bun run install:dev` 进行完整的引导(install + link + `setup defaults`)。\n\n随时检查你的 `skc` 是否已经漂移(源码错误,或一个无法加载技能的已编译二进制文件):\n\n```sh\nbun run dev:doctor\n```\n\n> 在日常开发中**不要**使用已编译的二进制文件。`bun --cwd=packages/coding-agent run build` 会产出一个独立的 `dist/skc`,但 `bun build --compile` 生成的二进制无法动态加载 `@sayknow-cli/natives`,因此技能会以 `Cannot find module '@sayknow-cli/natives' from '/$bunfs/root/skc'` 失败。通过 `dev:link` 从源码运行可避免此问题。仅在验证发布版本时才构建该二进制文件。\n\n不进行链接,直接从源码运行 CLI:\n\n```sh\nbun packages/coding-agent/src/cli.ts --help\n```\n\n默认工作流定义存放在源码中,而非已提交的 `.skc` 副本:\n\n```text\npackages/coding-agent/src/defaults/skc/skills/<name>/SKILL.md\npackages/coding-agent/src/prompts/agents/<role>.md\n```\n\n对于工作流定义或品牌重塑界面(rebrand-surface)的改动,请运行项目门禁(gates):\n\n```sh\nbun scripts/check-visible-definitions.ts\nbun scripts/verify-g002-gates.ts\nbun scripts/rebrand-inventory.ts --strict\nbun test packages/coding-agent/test/default-skc-definitions.test.ts\n```\n\n关于逐包(package-by-package)的对照图,请参阅 [`docs/codebase-overview.md`](docs/codebase-overview.md)。\n\n## Contributors\n\n欢迎通过 GitHub Issues 和 Pull Requests 进行贡献、提交错误报告以及参与发布验证。\n\n## Inspirations and lineage\n\nSayknow-CLI 默认的 TUI 标识是这对头足类:blue-octopus 作为默认,搭配一个暖色调的 red-octopus 备选。它还捆绑了 `claude-code`、`codex` 和 `opencode` 迁移主题,其配色受这些工具启发,以便从它们迁移过来的用户能获得熟悉的外观。它在一个小型智能体框架家族的经验之上构建,同时有意保持公共 SKC 界面的专注。历史归属保留在 [`NOTICE.md`](NOTICE.md) 中。\n\n## License\n\nMIT。参见 [`LICENSE`](LICENSE)。\n",
52
+ "readme/README.de.md": "<p align=\"center\">\n <img src=\"../../assets/hero.png\" alt=\"Sayknow-CLI autonomous coding-agent hero illustration\" width=\"100%\" />\n</p>\n\n<h1 align=\"center\">Sayknow-CLI</h1>\n\n<p align=\"center\">\n <strong>Programmieren sollte sich wie Denken anfühlen.</strong><br />\n Ein fokussierter Coding-Agent-Runner für Interviews, geprüfte Pläne, tmux-native Ausführung und dauerhafte Verifizierung.\n</p>\n\n<p align=\"center\">\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/releases\"><img alt=\"Release\" src=\"https://img.shields.io/github/v/tag/jaybeyond/Sayknow_CLI?sort=semver&label=release&style=flat-square&color=2f9bff\"></a>\n <a href=\"LICENSE\"><img alt=\"License: MIT\" src=\"https://img.shields.io/github/license/jaybeyond/Sayknow_CLI?style=flat-square&color=green\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/stargazers\"><img alt=\"Stars\" src=\"https://img.shields.io/github/stars/jaybeyond/Sayknow_CLI?style=flat-square&color=f5c518\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/issues\"><img alt=\"Issues\" src=\"https://img.shields.io/github/issues/jaybeyond/Sayknow_CLI?style=flat-square\"></a>\n <a href=\"https://bun.sh\"><img alt=\"Built with Bun\" src=\"https://img.shields.io/badge/built%20with-Bun-fbf0df?style=flat-square&logo=bun&logoColor=black\"></a>\n <a href=\"#languages\"><img alt=\"i18n\" src=\"https://img.shields.io/badge/i18n-7%20languages-2f9bff?style=flat-square\"></a>\n</p>\n\n<p align=\"center\">\n <a href=\"../../README.md\">English</a> ·\n <a href=\"README.ko.md\">한국어</a> ·\n <a href=\"README.zh.md\">中文</a> ·\n <a href=\"README.ja.md\">日本語</a> ·\n <a href=\"README.es.md\">Español</a> ·\n <a href=\"README.fr.md\">Français</a> ·\n <b>Deutsch</b>\n</p>\n\n<p align=\"center\">\n <img src=\"../../assets/character.png\" alt=\"Sayknow-CLI character mascot\" width=\"320\" />\n</p>\n\n> Sayknow-CLI ist ein experimentelles Projekt im Beta-Stadium. Rechnen Sie mit Ecken und Kanten und überprüfen Sie die Ausgaben, bevor Sie sich bei wichtiger Arbeit darauf verlassen.\n\n## Languages\n\nDie Oberfläche ist in **7 Sprachen** lokalisiert — English, 한국어 (Koreanisch),\n中文 (简体 / Vereinfachtes Chinesisch), 日本語 (Japanisch), Español (Spanisch),\nFrançais (Französisch) und Deutsch. Beim ersten Start erkennt sie automatisch\nIhre System-Locale; wechseln Sie jederzeit unter **Settings → Appearance → Language**\noder starten Sie z. B. mit `LANG=ja_JP.UTF-8 skc`. Nicht übersetzte Zeichenketten\nfallen auf Englisch zurück, und Marken-/Fachbegriffe (Claude, OpenAI, MCP, …)\nbleiben in allen Locales unverändert.\n\n## Was ist Sayknow-CLI?\n\nSayknow-CLI (`skc`) ist ein externes Coding-Agent-Harness. Es läuft aus dem von Ihnen gewählten Repository oder Worktree und gibt dem Agenten dann eine kleine, explizite Workflow-Oberfläche:\n\n```text\ndeep-interview -> ralplan -> ultragoal\n └─ optional team execution when parallel tmux workers help\n```\n\nEs ist bewusst kein verstecktes Plugin für Codex CLI, Claude Code, OpenCode oder Claw Code. Starten Sie `skc` neben diesen Tools, wenn Sie strukturierte Planung, dauerhafte Nachweise, tmux-gestützte Worker oder einen isolierten Worktree wünschen.\n\n## Installation\n\n```sh\nnpm install -g sayknow-cli # oder: bun install -g sayknow-cli\nskc --version\n```\n\nDas Paket enthält vorgefertigte native Addons für macOS, Linux und Windows – keine Rust-Toolchain und kein Build-Schritt nötig. Aktualisieren: `npm install -g sayknow-cli@latest` oder `skc update` im Terminal.\n\n> Früher aus dem Quellcode (git clone) installiert? Einmalig umsteigen: `rm -f ~/.local/bin/skc && npm install -g sayknow-cli`. Für die Installation aus dem Quellcode (Entwicklung) siehe die [englische README](../../README.md#install-from-source-development).\n\n## Schnellstart\n\n```sh\n# Run directly in the current checkout\nskc\n\n# Use a tmux-backed leader session\nskc --tmux\n\n# Use an isolated worktree for risky or reviewable work\n# --worktree takes an optional branch-like name, not a filesystem path.\nskc --tmux --worktree my-task-branch\n\n# If you already created a worktree directory, launch from that directory instead.\ncd ../my-task-worktree && skc --tmux\n```\n\nVerwenden Sie innerhalb einer SKC-Sitzung die öffentliche Workflow-Oberfläche:\n\n```text\n/skill:deep-interview clarify ambiguous requirements\n/skill:ralplan build and critique the implementation plan\nskc ultragoal create-goals --brief-file <approved-plan>\nskc ultragoal complete-goals\n```\n\nFügen Sie `skc team ...` nur hinzu, wenn koordinierte tmux-Worker spürbar helfen.\n\n## Kernfunktionen\n\n- **Interview vor dem Raten**: `deep-interview` verwandelt vage Anfragen in konkrete Anforderungen.\n- **Plan vor der Veränderung**: `ralplan` prüft den Ansatz vor Codeänderungen.\n- **Ausführen mit Nachweisen**: `ultragoal` verfolgt Ziele, Revisionen, Prüfungen und Abschlussnachweise.\n- **Parallelisieren, wenn sinnvoll**: `team` koordiniert tmux-gestützte Worker für größere Aufgaben.\n- **Extern und überprüfbar bleiben**: Laufen Sie aus einem gewählten Repo oder Worktree, ohne eine andere Agent-Runtime zu patchen.\n\n## Workflow-Oberfläche\n\nSayknow-CLI liefert vier Standard-Workflow-Skills:\n\n| Skill | Was es tut |\n| ---------------- | --------------------------------------------------------------------- |\n| `deep-interview` | Klärt mehrdeutige Anforderungen vor Planung oder Codeänderungen. |\n| `ralplan` | Erstellt und kritisiert einen Implementierungsplan vor der Veränderung. |\n| `ultragoal` | Verfolgt Ziele durch Ausführung, Revision, Verifizierung und Nachweise. |\n| `team` | Koordiniert tmux-gestützte Worker, wenn parallele Ausführung sich lohnt. |\n\nUnd vier mitgelieferte Rollen-Agenten:\n\n| Agent | Was es tut |\n| ----------- | -------------------------------------------------- |\n| `executor` | Begrenzte Implementierung, Fixes und Refactorings. |\n| `architect` | Schreibgeschützte Architektur- und Code-Review-Bewertung. |\n| `planner` | Schreibgeschützte Sequenzierung und Abnahmekriterien. |\n| `critic` | Schreibgeschützte Plan-Kritik und Umsetzbarkeitsprüfung. |\n\nKein wucherndes Standard-Skill-Zoo: SKC verbessert sich, indem es diese kleine Methode besser macht.\n\n## Funktioniert neben Ihrem bestehenden Agenten oder Bot\n\n| Tool oder Bot | Empfohlener SKC-Befehl | Grenze |\n| ----------- | ----------------------- | -------- |\n| Codex CLI | `skc --tmux --worktree <name>` oder `skc` | `--worktree` benennt einen SKC-verwalteten Geschwister-Worktree; für einen bestehenden Pfad wechseln Sie zuerst mit `cd` dorthin. |\n| Claude Code | `skc --tmux` oder `skc --tmux --worktree <name>` | SKC wird keine Claude-Code-Erweiterung. |\n| OpenCode | `skc` oder `skc --tmux` | Heute nur External-Runner-Workflow. |\n| Claw Code | `skc --tmux --worktree <name>` | SKC installiert sich nicht in Claw Code und ersetzt es nicht. |\n| Externer Controller / Bot | `skc mcp-serve coordinator` plus `skc setup hermes` für kompatible Konfiguration oder `skc --mode rpc` für einen Subprozess-Worker | Jeder MCP-/RPC-fähige Bot steuert SKC über den generischen Coordinator-/RPC-Vertrag, nicht durch Scrollback-Scraping. |\n\nFür generisches Drittanbieter-Bot-Setup und anbieterunabhängige Smokes siehe [`docs/bot-integration.md`](docs/bot-integration.md). Für die Reife-Klassifizierung über MCP-, RPC-, ACP- und Bridge/HTTPS-Oberflächen siehe [`docs/external-control-readiness.md`](docs/external-control-readiness.md). Für tiefergehende Protokolldetails siehe [`docs/hermes-mcp-bridge.md`](docs/hermes-mcp-bridge.md), [`docs/rpc.md`](docs/rpc.md) und [`docs/bridge.md`](docs/bridge.md). Für die Roadmap der Remote-Operator-Oberflächen siehe [`docs/sayknow-remote.md`](docs/sayknow-remote.md) (Web-Steuerrad) und [`docs/telegram-remote.md`](docs/telegram-remote.md) (Telegram-Lifecycle-Button).\n\n## Konfiguration\n\nProvider-Retry-Budgets liegen in `~/.skc/config.yml`:\n\n```yaml\nretry:\n requestMaxRetries: 4\n streamMaxRetries: 100\n maxRetries: 3\n maxDelayMs: 300000\n```\n\n`requestMaxRetries` gilt, bevor ein Stream aufgebaut wird. `streamMaxRetries` gilt nur für replay-sichere, vorübergehende Stream-Fehler. Ungültige Authentifizierung, nicht unterstützte Modelle/Provider, fehlerhafte Requests, Kontextüberlauf, Benutzerabbrüche und dauerhafte Kontingentfehler bleiben fail-fast.\n\n## TUI-Identität\n\nDie Standard-TUI-Identität ist das SKC-**blue-octopus**-Theme — das blaue Kopffüßer-Maskottchen — sowohl für dunkle als auch für helle Terminals. Eine warme **red-octopus**-Variante ist ebenfalls dabei für alle, die eine dunklere, kontrastreiche Palette bevorzugen. Drei zusätzliche Migrations-Themes — `claude-code`, `codex` und `opencode` — spiegeln das Aussehen dieser Tools für einen einfachen Augen-Umstieg wider und sind über Settings oder `/theme` auswählbar. Explizite Benutzer-Theme-Einstellungen gewinnen weiterhin.\n\n### Raster der mitgelieferten Themes\n\nWählen Sie über Settings (`Appearance -> Dark theme` / `Light theme`) oder `/theme`.\n\n| Theme | Visueller Eindruck | Beste Eignung |\n| --- | --- | --- |\n| `blue-octopus` | Standard-SKC-Identität — blaue Oktopus-Palette mit tentakelblauen Akzenten. | Standard für dunkle und helle Terminals. |\n| `red-octopus` | Warme rote Oktopus-Variante mit starkem Status-Kontrast. | Kontrastreiche dunkle Alternative. |\n| `claude-code` | Von Claude Code inspirierte dunkle Palette mit terrakotta- und pinkfarbenen Highlights. | Claude-Code-Muskelgedächtnis, ohne SKC zu verlassen. |\n| `codex` | Klare dunkle blaugraue Palette mit schärferem Coding-Session-Kontrast. | Ein Codex-ähnlicher dunkler Arbeitsbereich. |\n| `opencode` | Von OpenCode inspirierte dunkle Palette mit kräftigeren Terminal-Akzenten. | OpenCode-Muskelgedächtnis im mitgelieferten Picker. |\n\n## Entwicklung\n\nAbhängigkeiten installieren, native Bindings bauen und lokale Standardwerte einrichten:\n\n```sh\nbun install\nbun run build:native\nbun run install:defaults\n```\n\nDie `.node`-Binärdatei für `@sayknow-cli/natives` ist gitignored und vor jeder CLI-Ausführung erforderlich (`install:defaults`, `dev:link`, Tests).\n\n### Kanonisch: Entwickler-`skc` bauen und verlinken\n\nDamit der globale Befehl `skc` **den TypeScript-Quellcode dieses Checkouts** ausführt (live bei jeder Bearbeitung, mit funktionierenden Skills/Natives), verlinken Sie ihn in Ihren `PATH`:\n\n```sh\nbun install\nbun run dev:link\n```\n\n`dev:link` legt einen Symlink `skc` → `packages/coding-agent/src/cli.ts` nach `~/.local/bin` an (überschreibbar mit `SKC_DEV_LINK_DIR`), ersetzt dieses verwaltete Ziel, warnt und schlägt fehl, falls ein anderes `skc` es weiter vorne im `PATH` überschattet, und führt `--smoke-test` aus, um zu bestätigen, dass `@sayknow-cli/natives` geladen wird. Verwenden Sie `bun run install:dev` für das vollständige Bootstrap (Installation + Link + `setup defaults`).\n\nPrüfen Sie jederzeit, ob Ihr `skc` abgedriftet ist (falsche Quelle oder eine kompilierte Binärdatei, die keine Skills laden kann):\n\n```sh\nbun run dev:doctor\n```\n\n> Verwenden Sie für die tägliche Entwicklung **nicht** die kompilierte Binärdatei. `bun --cwd=packages/coding-agent run build` erzeugt ein eigenständiges `dist/skc`, aber eine mit `bun build --compile` erstellte Binärdatei kann `@sayknow-cli/natives` nicht dynamisch laden, sodass Skills mit `Cannot find module '@sayknow-cli/natives' from '/$bunfs/root/skc'` fehlschlagen. Die Ausführung aus dem Quellcode über `dev:link` vermeidet dies. Bauen Sie die Binärdatei nur, wenn Sie ein Release validieren.\n\nFühren Sie die CLI direkt aus dem Quellcode ohne Verlinkung aus:\n\n```sh\nbun packages/coding-agent/src/cli.ts --help\n```\n\nStandard-Workflow-Definitionen liegen im Quellcode, nicht in committeten `.skc`-Kopien:\n\n```text\npackages/coding-agent/src/defaults/skc/skills/<name>/SKILL.md\npackages/coding-agent/src/prompts/agents/<role>.md\n```\n\nFür Änderungen an Workflow-Definitionen oder Rebrand-Oberflächen führen Sie die Projekt-Gates aus:\n\n```sh\nbun scripts/check-visible-definitions.ts\nbun scripts/verify-g002-gates.ts\nbun scripts/rebrand-inventory.ts --strict\nbun test packages/coding-agent/test/default-skc-definitions.test.ts\n```\n\nFür eine Paket-für-Paket-Übersicht siehe [`docs/codebase-overview.md`](docs/codebase-overview.md).\n\n## Mitwirkende\n\nBeiträge, Fehlerberichte und Release-Validierung sind über GitHub Issues und Pull Requests willkommen.\n\n## Inspirationen und Herkunft\n\nDie Standard-TUI-Identität von Sayknow-CLI ist das Kopffüßer-Paar: blue-octopus als Standard mit einem warmen red-octopus als Alternative. Es liefert außerdem die Migrations-Themes `claude-code`, `codex` und `opencode`, deren Paletten von diesen Tools inspiriert sind, damit Benutzer, die von ihnen wechseln, einen vertrauten Look erhalten. Es baut auf Erkenntnissen aus einer kleinen Familie von Agent-Harnesses auf und hält die öffentliche SKC-Oberfläche bewusst fokussiert. Die historische Zuordnung wird in [`NOTICE.md`](NOTICE.md) geführt.\n\n## Lizenz\n\nMIT. Siehe [`LICENSE`](LICENSE).\n",
53
+ "readme/README.es.md": "<p align=\"center\">\n <img src=\"../../assets/hero.png\" alt=\"Ilustración principal del agente de codificación autónomo Sayknow-CLI\" width=\"100%\" />\n</p>\n\n<h1 align=\"center\">Sayknow-CLI</h1>\n\n<p align=\"center\">\n <strong>Programar debería sentirse como pensar.</strong><br />\n Un ejecutor de agentes de codificación enfocado en entrevistas, planes revisados, ejecución nativa en tmux y verificación duradera.\n</p>\n\n<p align=\"center\">\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/releases\"><img alt=\"Release\" src=\"https://img.shields.io/github/v/tag/jaybeyond/Sayknow_CLI?sort=semver&label=release&style=flat-square&color=2f9bff\"></a>\n <a href=\"LICENSE\"><img alt=\"License: MIT\" src=\"https://img.shields.io/github/license/jaybeyond/Sayknow_CLI?style=flat-square&color=green\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/stargazers\"><img alt=\"Stars\" src=\"https://img.shields.io/github/stars/jaybeyond/Sayknow_CLI?style=flat-square&color=f5c518\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/issues\"><img alt=\"Issues\" src=\"https://img.shields.io/github/issues/jaybeyond/Sayknow_CLI?style=flat-square\"></a>\n <a href=\"https://bun.sh\"><img alt=\"Built with Bun\" src=\"https://img.shields.io/badge/built%20with-Bun-fbf0df?style=flat-square&logo=bun&logoColor=black\"></a>\n <a href=\"#languages\"><img alt=\"i18n\" src=\"https://img.shields.io/badge/i18n-7%20languages-2f9bff?style=flat-square\"></a>\n</p>\n\n<p align=\"center\">\n <a href=\"../../README.md\">English</a> ·\n <a href=\"README.ko.md\">한국어</a> ·\n <a href=\"README.zh.md\">中文</a> ·\n <a href=\"README.ja.md\">日本語</a> ·\n <b>Español</b> ·\n <a href=\"README.fr.md\">Français</a> ·\n <a href=\"README.de.md\">Deutsch</a>\n</p>\n\n<p align=\"center\">\n <img src=\"../../assets/character.png\" alt=\"Mascota personaje de Sayknow-CLI\" width=\"320\" />\n</p>\n\n> Sayknow-CLI es un proyecto experimental en fase beta. Espera asperezas y verifica los resultados antes de confiar en él para trabajos importantes.\n\n## Languages\n\nLa interfaz está localizada en **7 idiomas** — English, 한국어 (coreano),\n中文 (简体 / chino simplificado), 日本語 (japonés), Español,\nFrançais (francés) y Deutsch (alemán). Detecta automáticamente la configuración regional de tu sistema en\nel primer arranque; cámbiala en cualquier momento en **Settings → Appearance → Language**, o inícialo\ncon, por ejemplo, `LANG=ja_JP.UTF-8 skc`. Las cadenas no traducidas recurren al inglés, y\nlos nombres de marca/técnicos (Claude, OpenAI, MCP, …) se mantienen literales en todas las configuraciones regionales.\n\n## ¿Qué es Sayknow-CLI?\n\nSayknow-CLI (`skc`) es un arnés externo de agentes de codificación. Se ejecuta desde el repositorio o worktree que elijas y luego le da al agente una superficie de flujo de trabajo pequeña y explícita:\n\n```text\ndeep-interview -> ralplan -> ultragoal\n └─ optional team execution when parallel tmux workers help\n```\n\nIntencionadamente no es un plugin oculto para Codex CLI, Claude Code, OpenCode o Claw Code. Inicia `skc` junto a esas herramientas cuando quieras planificación estructurada, evidencia persistente, workers respaldados por tmux o un worktree aislado.\n\n## Install\n\n```sh\nnpm install -g sayknow-cli # o: bun install -g sayknow-cli\nskc --version\n```\n\nEl paquete incluye binarios nativos precompilados para macOS, Linux y Windows, así que no necesitas Rust ni paso de compilación. Para actualizar: `npm install -g sayknow-cli@latest` o ejecuta `skc update` en la terminal.\n\n> ¿Vienes de una instalación desde el código fuente (git clone)? Cambia una sola vez: `rm -f ~/.local/bin/skc && npm install -g sayknow-cli`. Para la instalación desde el código (desarrollo), consulta el [README en inglés](../../README.md#install-from-source-development).\n\n## Quick start\n\n```sh\n# Run directly in the current checkout\nskc\n\n# Use a tmux-backed leader session\nskc --tmux\n\n# Use an isolated worktree for risky or reviewable work\n# --worktree takes an optional branch-like name, not a filesystem path.\nskc --tmux --worktree my-task-branch\n\n# If you already created a worktree directory, launch from that directory instead.\ncd ../my-task-worktree && skc --tmux\n```\n\nDentro de una sesión de SKC, usa la superficie pública del flujo de trabajo:\n\n```text\n/skill:deep-interview clarify ambiguous requirements\n/skill:ralplan build and critique the implementation plan\nskc ultragoal create-goals --brief-file <approved-plan>\nskc ultragoal complete-goals\n```\n\nAñade `skc team ...` solo cuando los workers coordinados de tmux ayuden de forma significativa.\n\n## Capacidades principales\n\n- **Entrevistar antes de suponer**: `deep-interview` convierte solicitudes vagas en requisitos concretos.\n- **Planificar antes de mutar**: `ralplan` revisa el enfoque antes de los cambios de código.\n- **Ejecutar con evidencia**: `ultragoal` rastrea objetivos, revisiones, comprobaciones y evidencia de finalización.\n- **Paralelizar cuando sea útil**: `team` coordina workers respaldados por tmux para tareas más grandes.\n- **Mantenerse externo y revisable**: ejecútalo desde un repositorio o worktree elegido sin parchear otro runtime de agente.\n\n## Superficie del flujo de trabajo\n\nSayknow-CLI incluye cuatro skills de flujo de trabajo predeterminadas:\n\n| Skill | Qué hace |\n| ---------------- | --------------------------------------------------------------------- |\n| `deep-interview` | Aclara requisitos ambiguos antes de planificar o cambiar código. |\n| `ralplan` | Construye y critica un plan de implementación antes de mutar. |\n| `ultragoal` | Rastrea objetivos a través de ejecución, revisión, verificación y evidencia. |\n| `team` | Coordina workers respaldados por tmux cuando vale la pena la ejecución paralela. |\n\nY cuatro agentes de rol incluidos:\n\n| Agent | Qué hace |\n| ----------- | -------------------------------------------------- |\n| `executor` | Implementación acotada, correcciones y refactorizaciones. |\n| `architect` | Evaluación de arquitectura y revisión de código de solo lectura. |\n| `planner` | Secuenciación y criterios de aceptación de solo lectura. |\n| `critic` | Crítica de planes y revisión de accionabilidad de solo lectura. |\n\nSin un zoológico de skills predeterminadas desbordante: SKC mejora haciendo mejor este pequeño método.\n\n## Funciona junto a tu agente o bot existente\n\n| Herramienta o bot | Comando SKC recomendado | Límite |\n| ----------- | ----------------------- | -------- |\n| Codex CLI | `skc --tmux --worktree <name>` o `skc` | `--worktree` nombra un worktree hermano gestionado por SKC; para una ruta existente, haz `cd` allí primero. |\n| Claude Code | `skc --tmux` o `skc --tmux --worktree <name>` | SKC no se convierte en una extensión de Claude Code. |\n| OpenCode | `skc` o `skc --tmux` | Solo flujo de trabajo de ejecutor externo por ahora. |\n| Claw Code | `skc --tmux --worktree <name>` | SKC no se instala dentro de Claw Code ni lo reemplaza. |\n| Controlador / bot externo | `skc mcp-serve coordinator` más `skc setup hermes` para una configuración compatible, o `skc --mode rpc` para un worker en subproceso | Cualquier bot con capacidad MCP/RPC controla SKC mediante el contrato genérico coordinator/RPC, no mediante scraping del scrollback. |\n\nPara la configuración genérica de bots de terceros y pruebas de humo independientes del proveedor, consulta [`docs/bot-integration.md`](docs/bot-integration.md). Para la clasificación de preparación a través de las superficies MCP, RPC, ACP y Bridge/HTTPS, consulta [`docs/external-control-readiness.md`](docs/external-control-readiness.md). Para los detalles de protocolo de más bajo nivel, consulta [`docs/hermes-mcp-bridge.md`](docs/hermes-mcp-bridge.md), [`docs/rpc.md`](docs/rpc.md) y [`docs/bridge.md`](docs/bridge.md). Para la hoja de ruta de las superficies de operador remoto, consulta [`docs/sayknow-remote.md`](docs/sayknow-remote.md) (volante web) y [`docs/telegram-remote.md`](docs/telegram-remote.md) (botón de ciclo de vida de Telegram).\n\n## Configuration\n\nLos presupuestos de reintento del proveedor viven en `~/.skc/config.yml`:\n\n```yaml\nretry:\n requestMaxRetries: 4\n streamMaxRetries: 100\n maxRetries: 3\n maxDelayMs: 300000\n```\n\n`requestMaxRetries` se aplica antes de que se establezca un stream. `streamMaxRetries` se aplica solo a fallos transitorios de stream que son seguros de reproducir. La autenticación inválida, los modelos/proveedores no compatibles, las solicitudes malformadas, el desbordamiento de contexto, las cancelaciones del usuario y los fallos permanentes de cuota siguen siendo de fallo rápido.\n\n## Identidad de la TUI\n\nLa identidad predeterminada de la TUI es el tema **blue-octopus** de SKC — la mascota del cefalópodo azul — tanto para terminales oscuras como claras. También se incluye una variante cálida **red-octopus** para quienes prefieren una paleta más oscura y de alto contraste. Tres temas de migración adicionales — `claude-code`, `codex` y `opencode` — reflejan el aspecto de esas herramientas para facilitar la migración visual y se pueden seleccionar desde Settings o `/theme`. Los ajustes de tema explícitos del usuario siguen prevaleciendo.\n\n### Cuadrícula de temas incluidos\n\nElige desde Settings (`Appearance -> Dark theme` / `Light theme`) o `/theme`.\n\n| Tema | Sensación visual | Mejor uso |\n| --- | --- | --- |\n| `blue-octopus` | Identidad predeterminada de SKC — paleta de pulpo azul con acentos azul-tentáculo. | Predeterminado para terminales oscuras y claras. |\n| `red-octopus` | Variante cálida de pulpo rojo con fuerte contraste de estado. | Alternativa oscura de alto contraste. |\n| `claude-code` | Paleta oscura inspirada en Claude Code con resaltados terracota y rosa. | Memoria muscular de Claude Code sin salir de SKC. |\n| `codex` | Paleta nítida azul-gris oscuro con un contraste de sesión de codificación más marcado. | Un espacio de trabajo oscuro al estilo Codex. |\n| `opencode` | Paleta oscura inspirada en OpenCode con acentos de terminal más vibrantes. | Memoria muscular de OpenCode en el selector incluido. |\n\n## Development\n\nInstala las dependencias, compila los bindings nativos y configura los valores predeterminados locales:\n\n```sh\nbun install\nbun run build:native\nbun run install:defaults\n```\n\nEl binario `.node` para `@sayknow-cli/natives` está en gitignore y es necesario antes de cualquier invocación del CLI (`install:defaults`, `dev:link`, tests).\n\n### Canónico: compilar y enlazar el `skc` de desarrollo\n\nPara hacer que el comando global `skc` ejecute **el código fuente TypeScript de esta copia** (sensible a cada edición, con skills/natives funcionando), enlázalo a tu `PATH`:\n\n```sh\nbun install\nbun run dev:link\n```\n\n`dev:link` crea un symlink de `skc` → `packages/coding-agent/src/cli.ts` en `~/.local/bin` (sobrescríbelo con `SKC_DEV_LINK_DIR`), reemplaza ese objetivo gestionado, advierte y falla si otro `skc` aún lo oculta antes en `PATH`, y ejecuta `--smoke-test` para confirmar que `@sayknow-cli/natives` carga. Usa `bun run install:dev` para el bootstrap completo (install + link + `setup defaults`).\n\nComprueba en cualquier momento si tu `skc` se ha desviado (fuente incorrecta, o un binario compilado que no puede cargar skills):\n\n```sh\nbun run dev:doctor\n```\n\n> **No** uses el binario compilado para el desarrollo diario. `bun --cwd=packages/coding-agent run build` produce un `dist/skc` independiente, pero un binario `bun build --compile` no puede cargar dinámicamente `@sayknow-cli/natives`, por lo que las skills fallan con `Cannot find module '@sayknow-cli/natives' from '/$bunfs/root/skc'`. Ejecutar desde el código fuente mediante `dev:link` evita esto. Compila el binario solo al validar una release.\n\nEjecuta el CLI directamente desde el código fuente sin enlazarlo:\n\n```sh\nbun packages/coding-agent/src/cli.ts --help\n```\n\nLas definiciones de flujo de trabajo predeterminadas viven en el código fuente, no en copias `.skc` comprometidas:\n\n```text\npackages/coding-agent/src/defaults/skc/skills/<name>/SKILL.md\npackages/coding-agent/src/prompts/agents/<role>.md\n```\n\nPara cambios en las definiciones de flujo de trabajo o en la superficie de rebranding, ejecuta las puertas del proyecto:\n\n```sh\nbun scripts/check-visible-definitions.ts\nbun scripts/verify-g002-gates.ts\nbun scripts/rebrand-inventory.ts --strict\nbun test packages/coding-agent/test/default-skc-definitions.test.ts\n```\n\nPara un mapa paquete por paquete, consulta [`docs/codebase-overview.md`](docs/codebase-overview.md).\n\n## Contributors\n\nLas contribuciones, los informes de errores y la validación de releases son bienvenidos a través de GitHub Issues y Pull Requests.\n\n## Inspiraciones y linaje\n\nLa identidad predeterminada de la TUI de Sayknow-CLI es la pareja de cefalópodos: blue-octopus como predeterminado con un red-octopus cálido como alternativa. También incluye los temas de migración `claude-code`, `codex` y `opencode`, cuyas paletas están inspiradas en esas herramientas para que los usuarios que migran de ellas obtengan un aspecto familiar. Se basa en las lecciones de una pequeña familia de arneses de agentes mientras mantiene la superficie pública de SKC intencionadamente enfocada. La atribución histórica se conserva en [`NOTICE.md`](NOTICE.md).\n\n## License\n\nMIT. Consulta [`LICENSE`](LICENSE).\n",
54
+ "readme/README.fr.md": "<p align=\"center\">\n <img src=\"../../assets/hero.png\" alt=\"Illustration héros de l'agent de codage autonome Sayknow-CLI\" width=\"100%\" />\n</p>\n\n<h1 align=\"center\">Sayknow-CLI</h1>\n\n<p align=\"center\">\n <strong>Coder devrait ressembler à réfléchir.</strong><br />\n Un exécuteur d'agent de codage ciblé pour les entretiens, les plans révisés, l'exécution native tmux et la vérification durable.\n</p>\n\n<p align=\"center\">\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/releases\"><img alt=\"Release\" src=\"https://img.shields.io/github/v/tag/jaybeyond/Sayknow_CLI?sort=semver&label=release&style=flat-square&color=2f9bff\"></a>\n <a href=\"LICENSE\"><img alt=\"License: MIT\" src=\"https://img.shields.io/github/license/jaybeyond/Sayknow_CLI?style=flat-square&color=green\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/stargazers\"><img alt=\"Stars\" src=\"https://img.shields.io/github/stars/jaybeyond/Sayknow_CLI?style=flat-square&color=f5c518\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/issues\"><img alt=\"Issues\" src=\"https://img.shields.io/github/issues/jaybeyond/Sayknow_CLI?style=flat-square\"></a>\n <a href=\"https://bun.sh\"><img alt=\"Built with Bun\" src=\"https://img.shields.io/badge/built%20with-Bun-fbf0df?style=flat-square&logo=bun&logoColor=black\"></a>\n <a href=\"#languages\"><img alt=\"i18n\" src=\"https://img.shields.io/badge/i18n-7%20languages-2f9bff?style=flat-square\"></a>\n</p>\n\n<p align=\"center\">\n <a href=\"../../README.md\">English</a> ·\n <a href=\"README.ko.md\">한국어</a> ·\n <a href=\"README.zh.md\">中文</a> ·\n <a href=\"README.ja.md\">日本語</a> ·\n <a href=\"README.es.md\">Español</a> ·\n <b>Français</b> ·\n <a href=\"README.de.md\">Deutsch</a>\n</p>\n\n<p align=\"center\">\n <img src=\"../../assets/character.png\" alt=\"Mascotte personnage de Sayknow-CLI\" width=\"320\" />\n</p>\n\n> Sayknow-CLI est un projet expérimental en phase bêta. Attendez-vous à des aspérités et vérifiez les résultats avant de vous y fier pour un travail important.\n\n## Languages\n\nL'interface est localisée en **7 langues** — English, 한국어 (coréen),\n中文 (简体 / chinois simplifié), 日本語 (japonais), Español (espagnol),\nFrançais (français) et Deutsch (allemand). Elle détecte automatiquement la locale de votre système au\npremier lancement ; changez-en à tout moment dans **Settings → Appearance → Language**, ou lancez\navec par exemple `LANG=ja_JP.UTF-8 skc`. Les chaînes non traduites se rabattent sur l'anglais, et\nles noms de marque/techniques (Claude, OpenAI, MCP, …) restent verbatim dans toutes les locales.\n\n## What is Sayknow-CLI?\n\nSayknow-CLI (`skc`) est un harnais d'agent de codage externe. Il s'exécute depuis le dépôt ou le worktree que vous choisissez, puis donne à l'agent une surface de workflow réduite et explicite :\n\n```text\ndeep-interview -> ralplan -> ultragoal\n └─ optional team execution when parallel tmux workers help\n```\n\nCe n'est volontairement pas un plugin caché pour Codex CLI, Claude Code, OpenCode ou Claw Code. Lancez `skc` à côté de ces outils lorsque vous voulez une planification structurée, des preuves persistantes, des workers adossés à tmux, ou un worktree isolé.\n\n## Install\n\n```sh\nnpm install -g sayknow-cli # ou : bun install -g sayknow-cli\nskc --version\n```\n\nLe paquet embarque des binaires natifs précompilés pour macOS, Linux et Windows : aucune chaîne d'outils Rust ni étape de compilation. Pour mettre à jour : `npm install -g sayknow-cli@latest` ou lancez `skc update` dans le terminal.\n\n> Vous veniez d'une installation depuis les sources (git clone) ? Basculez une seule fois : `rm -f ~/.local/bin/skc && npm install -g sayknow-cli`. Pour l'installation depuis les sources (développement), voir le [README en anglais](../../README.md#install-from-source-development).\n\n## Quick start\n\n```sh\n# Run directly in the current checkout\nskc\n\n# Use a tmux-backed leader session\nskc --tmux\n\n# Use an isolated worktree for risky or reviewable work\n# --worktree takes an optional branch-like name, not a filesystem path.\nskc --tmux --worktree my-task-branch\n\n# If you already created a worktree directory, launch from that directory instead.\ncd ../my-task-worktree && skc --tmux\n```\n\nÀ l'intérieur d'une session SKC, utilisez la surface de workflow publique :\n\n```text\n/skill:deep-interview clarify ambiguous requirements\n/skill:ralplan build and critique the implementation plan\nskc ultragoal create-goals --brief-file <approved-plan>\nskc ultragoal complete-goals\n```\n\nAjoutez `skc team ...` uniquement lorsque des workers tmux coordonnés aident concrètement.\n\n## Core capabilities\n\n- **Interviewer avant de deviner** : `deep-interview` transforme des demandes vagues en exigences concrètes.\n- **Planifier avant de muter** : `ralplan` révise l'approche avant les changements de code.\n- **Exécuter avec des preuves** : `ultragoal` suit les objectifs, les révisions, les vérifications et les preuves de complétion.\n- **Paralléliser quand c'est utile** : `team` coordonne des workers adossés à tmux pour les tâches plus importantes.\n- **Rester externe et révisable** : exécutez depuis un dépôt ou un worktree choisi sans patcher un autre runtime d'agent.\n\n## Workflow surface\n\nSayknow-CLI fournit quatre skills de workflow par défaut :\n\n| Skill | What it does |\n| ---------------- | --------------------------------------------------------------------- |\n| `deep-interview` | Clarifie les exigences ambiguës avant la planification ou les changements de code. |\n| `ralplan` | Construit et critique un plan d'implémentation avant la mutation. |\n| `ultragoal` | Suit les objectifs à travers l'exécution, la révision, la vérification et les preuves. |\n| `team` | Coordonne des workers adossés à tmux lorsque l'exécution parallèle en vaut la peine. |\n\nEt quatre agents de rôle inclus :\n\n| Agent | What it does |\n| ----------- | -------------------------------------------------- |\n| `executor` | Implémentation bornée, correctifs et refactorisations. |\n| `architect` | Évaluation d'architecture et de revue de code en lecture seule. |\n| `planner` | Séquençage et critères d'acceptation en lecture seule. |\n| `critic` | Critique de plan et revue d'actionnabilité en lecture seule. |\n\nPas de ménagerie tentaculaire de skills par défaut : SKC s'améliore en rendant cette petite méthode meilleure.\n\n## Works beside your existing agent or bot\n\n| Tool or bot | Recommended SKC command | Boundary |\n| ----------- | ----------------------- | -------- |\n| Codex CLI | `skc --tmux --worktree <name>` or `skc` | `--worktree` nomme un worktree frère géré par SKC ; pour un chemin existant, faites d'abord `cd` à cet endroit. |\n| Claude Code | `skc --tmux` or `skc --tmux --worktree <name>` | SKC ne devient pas une extension de Claude Code. |\n| OpenCode | `skc` or `skc --tmux` | Workflow d'exécuteur externe uniquement aujourd'hui. |\n| Claw Code | `skc --tmux --worktree <name>` | SKC ne s'installe pas dans Claw Code et ne le remplace pas. |\n| External controller / bot | `skc mcp-serve coordinator` plus `skc setup hermes` for compatible config, or `skc --mode rpc` for a subprocess worker | Tout bot capable de MCP/RPC pilote SKC via le contrat générique coordinator/RPC, et non par grattage de scrollback. |\n\nPour la configuration générique d'un bot tiers et les smokes indépendants du provider, voir [`docs/bot-integration.md`](docs/bot-integration.md). Pour la classification de readiness à travers les surfaces MCP, RPC, ACP et Bridge/HTTPS, voir [`docs/external-control-readiness.md`](docs/external-control-readiness.md). Pour les détails de protocole de plus bas niveau, voir [`docs/hermes-mcp-bridge.md`](docs/hermes-mcp-bridge.md), [`docs/rpc.md`](docs/rpc.md) et [`docs/bridge.md`](docs/bridge.md). Pour la roadmap des surfaces d'opérateur distant, voir [`docs/sayknow-remote.md`](docs/sayknow-remote.md) (volant de direction web) et [`docs/telegram-remote.md`](docs/telegram-remote.md) (bouton de cycle de vie Telegram).\n\n## Configuration\n\nLes budgets de retry du provider se trouvent dans `~/.skc/config.yml` :\n\n```yaml\nretry:\n requestMaxRetries: 4\n streamMaxRetries: 100\n maxRetries: 3\n maxDelayMs: 300000\n```\n\n`requestMaxRetries` s'applique avant qu'un stream ne soit établi. `streamMaxRetries` ne s'applique qu'aux échecs de stream transitoires sûrs pour le replay. L'authentification invalide, les modèles/providers non pris en charge, les requêtes malformées, le débordement de contexte, les abandons par l'utilisateur et les échecs de quota permanents restent en fail-fast.\n\n## TUI identity\n\nL'identité TUI par défaut est le thème SKC **blue-octopus** — la mascotte céphalopode bleue — pour les terminaux sombres comme clairs. Une variante chaleureuse **red-octopus** est également incluse pour ceux qui préfèrent une palette plus sombre et à fort contraste. Trois thèmes de migration supplémentaires — `claude-code`, `codex` et `opencode` — reflètent l'apparence de ces outils pour faciliter la migration visuelle et sont sélectionnables depuis Settings ou `/theme`. Les réglages de thème explicites de l'utilisateur l'emportent toujours.\n\n### Bundled theme grid\n\nChoisissez depuis Settings (`Appearance -> Dark theme` / `Light theme`) ou `/theme`.\n\n| Theme | Visual feel | Best fit |\n| --- | --- | --- |\n| `blue-octopus` | Identité SKC par défaut — palette poulpe bleu avec des accents bleu tentacule. | Par défaut pour les terminaux sombres et clairs. |\n| `red-octopus` | Variante chaleureuse poulpe rouge avec un fort contraste d'état. | Alternative sombre à fort contraste. |\n| `claude-code` | Palette sombre inspirée de Claude Code avec des touches terracotta et rose. | La mémoire musculaire de Claude Code sans quitter SKC. |\n| `codex` | Palette bleu-gris sombre et nette avec un contraste de session de codage plus marqué. | Un espace de travail sombre à la manière de Codex. |\n| `opencode` | Palette sombre inspirée d'OpenCode avec des accents de terminal plus percutants. | La mémoire musculaire d'OpenCode dans le sélecteur inclus. |\n\n## Development\n\nInstallez les dépendances, compilez les bindings natifs et configurez les valeurs par défaut locales :\n\n```sh\nbun install\nbun run build:native\nbun run install:defaults\n```\n\nLe binaire `.node` pour `@sayknow-cli/natives` est gitignored et requis avant toute invocation de la CLI (`install:defaults`, `dev:link`, tests).\n\n### Canonical: build and link the dev `skc`\n\nPour que la commande globale `skc` exécute **la source TypeScript de ce checkout** (sensible à chaque édition, avec skills/natives fonctionnels), liez-la à votre `PATH` :\n\n```sh\nbun install\nbun run dev:link\n```\n\n`dev:link` crée un lien symbolique `skc` → `packages/coding-agent/src/cli.ts` dans `~/.local/bin` (à surcharger avec `SKC_DEV_LINK_DIR`), remplace cette cible gérée, avertit et échoue si un autre `skc` le masque encore plus tôt sur le `PATH`, et exécute `--smoke-test` pour confirmer que `@sayknow-cli/natives` se charge. Utilisez `bun run install:dev` pour le bootstrap complet (install + link + `setup defaults`).\n\nVérifiez à tout moment si votre `skc` a dérivé (mauvaise source, ou un binaire compilé qui ne peut pas charger les skills) :\n\n```sh\nbun run dev:doctor\n```\n\n> N'utilisez **pas** le binaire compilé pour le développement quotidien. `bun --cwd=packages/coding-agent run build` produit un `dist/skc` autonome, mais un binaire `bun build --compile` ne peut pas charger dynamiquement `@sayknow-cli/natives`, donc les skills échouent avec `Cannot find module '@sayknow-cli/natives' from '/$bunfs/root/skc'`. L'exécution depuis la source via `dev:link` évite cela. Ne compilez le binaire que lors de la validation d'une release.\n\nExécutez la CLI depuis la source directement sans lier :\n\n```sh\nbun packages/coding-agent/src/cli.ts --help\n```\n\nLes définitions de workflow par défaut résident dans la source, et non dans des copies `.skc` commitées :\n\n```text\npackages/coding-agent/src/defaults/skc/skills/<name>/SKILL.md\npackages/coding-agent/src/prompts/agents/<role>.md\n```\n\nPour les changements de définition de workflow ou de surface de rebrand, exécutez les portes du projet :\n\n```sh\nbun scripts/check-visible-definitions.ts\nbun scripts/verify-g002-gates.ts\nbun scripts/rebrand-inventory.ts --strict\nbun test packages/coding-agent/test/default-skc-definitions.test.ts\n```\n\nPour une carte package par package, voir [`docs/codebase-overview.md`](docs/codebase-overview.md).\n\n## Contributors\n\nLes contributions, les rapports de bugs et la validation de release sont les bienvenus via les GitHub Issues et les Pull Requests.\n\n## Inspirations and lineage\n\nL'identité TUI par défaut de Sayknow-CLI est la paire de céphalopodes : blue-octopus comme valeur par défaut avec une alternative chaleureuse red-octopus. Il inclut aussi les thèmes de migration `claude-code`, `codex` et `opencode` dont les palettes sont inspirées de ces outils afin que les utilisateurs qui en proviennent retrouvent une apparence familière. Il s'appuie sur les leçons d'une petite famille de harnais d'agents tout en gardant la surface publique SKC volontairement ciblée. L'attribution historique est conservée dans [`NOTICE.md`](NOTICE.md).\n\n## License\n\nMIT. Voir [`LICENSE`](LICENSE).\n",
55
+ "readme/README.ja.md": "<p align=\"center\">\n <img src=\"../../assets/hero.png\" alt=\"Sayknow-CLI 自律型コーディングエージェントのヒーローイラスト\" width=\"100%\" />\n</p>\n\n<h1 align=\"center\">Sayknow-CLI</h1>\n\n<p align=\"center\">\n <strong>コーディングは、考えることのように感じられるべきだ。</strong><br />\n インタビュー、レビュー済みプラン、tmux ネイティブ実行、そして永続的な検証のための、集中型コーディングエージェントランナー。\n</p>\n\n<p align=\"center\">\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/releases\"><img alt=\"Release\" src=\"https://img.shields.io/github/v/tag/jaybeyond/Sayknow_CLI?sort=semver&label=release&style=flat-square&color=2f9bff\"></a>\n <a href=\"LICENSE\"><img alt=\"License: MIT\" src=\"https://img.shields.io/github/license/jaybeyond/Sayknow_CLI?style=flat-square&color=green\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/stargazers\"><img alt=\"Stars\" src=\"https://img.shields.io/github/stars/jaybeyond/Sayknow_CLI?style=flat-square&color=f5c518\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/issues\"><img alt=\"Issues\" src=\"https://img.shields.io/github/issues/jaybeyond/Sayknow_CLI?style=flat-square\"></a>\n <a href=\"https://bun.sh\"><img alt=\"Built with Bun\" src=\"https://img.shields.io/badge/built%20with-Bun-fbf0df?style=flat-square&logo=bun&logoColor=black\"></a>\n <a href=\"#languages\"><img alt=\"i18n\" src=\"https://img.shields.io/badge/i18n-7%20languages-2f9bff?style=flat-square\"></a>\n</p>\n\n<p align=\"center\">\n <a href=\"../../README.md\">English</a> ·\n <a href=\"README.ko.md\">한국어</a> ·\n <a href=\"README.zh.md\">中文</a> ·\n <b>日本語</b> ·\n <a href=\"README.es.md\">Español</a> ·\n <a href=\"README.fr.md\">Français</a> ·\n <a href=\"README.de.md\">Deutsch</a>\n</p>\n\n<p align=\"center\">\n <img src=\"../../assets/character.png\" alt=\"Sayknow-CLI キャラクターマスコット\" width=\"320\" />\n</p>\n\n> Sayknow-CLI は実験的なベータ段階のプロジェクトです。粗削りな部分があることを想定し、重要な作業で頼る前には出力を検証してください。\n\n## Languages\n\nインターフェースは **7 言語** にローカライズされています — English、한국어 (韓国語)、\n中文 (简体 / 簡体字中国語)、日本語 (Japanese)、Español (スペイン語)、\nFrançais (フランス語)、そして Deutsch (ドイツ語)。初回起動時にシステムロケールを\n自動検出します。**Settings → Appearance → Language** でいつでも切り替えられるほか、\nたとえば `LANG=ja_JP.UTF-8 skc` のように起動することもできます。未翻訳の文字列は英語に\nフォールバックし、ブランド名や技術名 (Claude、OpenAI、MCP、…) はすべてのロケールで\nそのまま表示されます。\n\n## Sayknow-CLI とは?\n\nSayknow-CLI (`skc`) は外部コーディングエージェントのハーネスです。選択したリポジトリまたは worktree から実行され、エージェントに対して小さく明示的なワークフロー面を提供します:\n\n```text\ndeep-interview -> ralplan -> ultragoal\n └─ optional team execution when parallel tmux workers help\n```\n\nこれは意図的に、Codex CLI、Claude Code、OpenCode、Claw Code 向けの隠しプラグインにはなっていません。構造化されたプランニング、永続的なエビデンス、tmux ベースのワーカー、または分離された worktree が欲しいときに、それらのツールと並べて `skc` を起動してください。\n\n## Install\n\n```sh\nnpm install -g sayknow-cli # または: bun install -g sayknow-cli\nskc --version\n```\n\nmacOS・Linux・Windows 向けのビルド済みネイティブを同梱しているため、Rust ツールチェーンやビルド手順は不要です。更新は `npm install -g sayknow-cli@latest`、またはターミナルで `skc update`。\n\n> 以前ソース(git clone)からインストールした場合は、一度だけ `rm -f ~/.local/bin/skc && npm install -g sayknow-cli` で切り替えてください。ソース/開発インストールは[英語版 README](../../README.md#install-from-source-development)を参照。\n\n## Quick start\n\n```sh\n# Run directly in the current checkout\nskc\n\n# Use a tmux-backed leader session\nskc --tmux\n\n# Use an isolated worktree for risky or reviewable work\n# --worktree takes an optional branch-like name, not a filesystem path.\nskc --tmux --worktree my-task-branch\n\n# If you already created a worktree directory, launch from that directory instead.\ncd ../my-task-worktree && skc --tmux\n```\n\nSKC セッション内では、公開されているワークフロー面を使用してください:\n\n```text\n/skill:deep-interview clarify ambiguous requirements\n/skill:ralplan build and critique the implementation plan\nskc ultragoal create-goals --brief-file <approved-plan>\nskc ultragoal complete-goals\n```\n\n`skc team ...` は、協調する tmux ワーカーが実質的に役立つときにのみ追加してください。\n\n## Core capabilities\n\n- **推測する前にインタビューする**: `deep-interview` は曖昧なリクエストを具体的な要件に変えます。\n- **変更する前にプランニングする**: `ralplan` はコード変更の前にアプローチをレビューします。\n- **エビデンスとともに実行する**: `ultragoal` はゴール、リビジョン、チェック、完了エビデンスを追跡します。\n- **役立つときに並列化する**: `team` はより大きなタスクのために tmux ベースのワーカーを協調させます。\n- **外部かつレビュー可能であり続ける**: 別のエージェントランタイムにパッチを当てることなく、選択したリポジトリまたは worktree から実行します。\n\n## Workflow surface\n\nSayknow-CLI は 4 つのデフォルトワークフロースキルを同梱しています:\n\n| Skill | What it does |\n| ---------------- | --------------------------------------------------------------------- |\n| `deep-interview` | プランニングやコード変更の前に、曖昧な要件を明確化します。 |\n| `ralplan` | 変更の前に実装プランを構築し批評します。 |\n| `ultragoal` | 実行、リビジョン、検証、エビデンスを通じてゴールを追跡します。 |\n| `team` | 並列実行に価値があるときに tmux ベースのワーカーを協調させます。 |\n\nそして 4 つの同梱ロールエージェント:\n\n| Agent | What it does |\n| ----------- | -------------------------------------------------- |\n| `executor` | 範囲を限定した実装、修正、リファクタリング。 |\n| `architect` | 読み取り専用のアーキテクチャおよびコードレビュー評価。 |\n| `planner` | 読み取り専用のシーケンシングと受け入れ基準。 |\n| `critic` | 読み取り専用のプラン批評と実行可能性レビュー。 |\n\n肥大化したデフォルトスキルの動物園はありません: SKC はこの小さなメソッドをより良くすることで改善されます。\n\n## Works beside your existing agent or bot\n\n| Tool or bot | Recommended SKC command | Boundary |\n| ----------- | ----------------------- | -------- |\n| Codex CLI | `skc --tmux --worktree <name>` or `skc` | `--worktree` は SKC が管理する兄弟 worktree に名前を付けます。既存のパスを使う場合は、まずそこへ `cd` してください。 |\n| Claude Code | `skc --tmux` or `skc --tmux --worktree <name>` | SKC は Claude Code の拡張機能にはなりません。 |\n| OpenCode | `skc` or `skc --tmux` | 現時点では外部ランナーのワークフローのみです。 |\n| Claw Code | `skc --tmux --worktree <name>` | SKC は Claw Code にインストールされたり、置き換えたりはしません。 |\n| External controller / bot | `skc mcp-serve coordinator` plus `skc setup hermes` for compatible config, or `skc --mode rpc` for a subprocess worker | MCP/RPC 対応のボットはどれも、スクロールバックのスクレイピングではなく、汎用のコーディネーター/RPC コントラクトを通じて SKC を駆動します。 |\n\n汎用的なサードパーティボットのセットアップとプロバイダー非依存のスモークテストについては、[`docs/bot-integration.md`](docs/bot-integration.md) を参照してください。MCP、RPC、ACP、Bridge/HTTPS 各面にわたる準備状況の分類については、[`docs/external-control-readiness.md`](docs/external-control-readiness.md) を参照してください。より低レベルのプロトコル詳細については、[`docs/hermes-mcp-bridge.md`](docs/hermes-mcp-bridge.md)、[`docs/rpc.md`](docs/rpc.md)、および [`docs/bridge.md`](docs/bridge.md) を参照してください。リモートオペレーター面のロードマップについては、[`docs/sayknow-remote.md`](docs/sayknow-remote.md) (web steering wheel) と [`docs/telegram-remote.md`](docs/telegram-remote.md) (Telegram lifecycle button) を参照してください。\n\n## Configuration\n\nプロバイダーのリトライバジェットは `~/.skc/config.yml` にあります:\n\n```yaml\nretry:\n requestMaxRetries: 4\n streamMaxRetries: 100\n maxRetries: 3\n maxDelayMs: 300000\n```\n\n`requestMaxRetries` はストリームが確立される前に適用されます。`streamMaxRetries` はリプレイ安全な一時的ストリーム障害にのみ適用されます。無効な認証、サポートされていないモデル/プロバイダー、不正な形式のリクエスト、コンテキストオーバーフロー、ユーザーによる中断、および恒久的なクォータ障害は、引き続きフェイルファストのままです。\n\n## TUI identity\n\nデフォルトの TUI アイデンティティは SKC の **blue-octopus** テーマ — 青い頭足類のマスコット — で、ダークおよびライトの両方のターミナルに対応します。より暗めでハイコントラストなパレットを好む人のために、温かみのある **red-octopus** バリアントも同梱されています。さらに 3 つの移行用テーマ — `claude-code`、`codex`、`opencode` — がそれらのツールの見た目を再現しており、視覚的な移行を容易にし、Settings または `/theme` から選択できます。ユーザーが明示的に設定したテーマは引き続き優先されます。\n\n### Bundled theme grid\n\nSettings (`Appearance -> Dark theme` / `Light theme`) または `/theme` から選択してください。\n\n| Theme | Visual feel | Best fit |\n| --- | --- | --- |\n| `blue-octopus` | デフォルトの SKC アイデンティティ — テンタクルブルーのアクセントを持つ青いタコのパレット。 | ダークおよびライトのターミナルのデフォルト。 |\n| `red-octopus` | 強いステータスコントラストを持つ温かみのある赤いタコのバリアント。 | ハイコントラストなダークの代替。 |\n| `claude-code` | テラコッタとピンクのハイライトを持つ Claude Code 風のダークパレット。 | SKC を離れずに Claude Code の体に染み付いた操作感を。 |\n| `codex` | よりシャープなコーディングセッションのコントラストを持つ、くっきりしたダークブルーグレーのパレット。 | Codex ライクなダークワークスペース。 |\n| `opencode` | よりパンチの効いたターミナルアクセントを持つ OpenCode 風のダークパレット。 | 同梱のピッカーで OpenCode の体に染み付いた操作感を。 |\n\n## Development\n\n依存関係をインストールし、ネイティブバインディングをビルドし、ローカルのデフォルトをセットアップします:\n\n```sh\nbun install\nbun run build:native\nbun run install:defaults\n```\n\n`@sayknow-cli/natives` 用の `.node` バイナリは gitignore されており、あらゆる CLI 呼び出し (`install:defaults`、`dev:link`、テスト) の前に必要です。\n\n### Canonical: build and link the dev `skc`\n\nグローバルの `skc` コマンドが **このチェックアウトの TypeScript ソース** を実行するようにする (すべての編集に即座に反映され、スキル/ネイティブが動作する) には、それをあなたの `PATH` にリンクします:\n\n```sh\nbun install\nbun run dev:link\n```\n\n`dev:link` は `skc` → `packages/coding-agent/src/cli.ts` を `~/.local/bin` にシンボリックリンクし (`SKC_DEV_LINK_DIR` で上書き可能)、その管理対象ターゲットを置き換え、別の `skc` が `PATH` 上でより前にそれをシャドウしている場合は警告して失敗し、`--smoke-test` を実行して `@sayknow-cli/natives` がロードされることを確認します。完全なブートストラップ (install + link + `setup defaults`) には `bun run install:dev` を使用してください。\n\nあなたの `skc` がドリフトしていないか (誤ったソース、またはスキルをロードできないコンパイル済みバイナリ) は、いつでも確認できます:\n\n```sh\nbun run dev:doctor\n```\n\n> 日常の開発にコンパイル済みバイナリを **使わないでください**。`bun --cwd=packages/coding-agent run build` はスタンドアロンの `dist/skc` を生成しますが、`bun build --compile` のバイナリは `@sayknow-cli/natives` を動的にロードできないため、スキルは `Cannot find module '@sayknow-cli/natives' from '/$bunfs/root/skc'` で失敗します。`dev:link` を通じてソースから実行すれば、これを回避できます。バイナリのビルドはリリースを検証するときのみ行ってください。\n\nリンクせずに CLI をソースから直接実行します:\n\n```sh\nbun packages/coding-agent/src/cli.ts --help\n```\n\nデフォルトのワークフロー定義はソースにあり、コミットされた `.skc` のコピーにはありません:\n\n```text\npackages/coding-agent/src/defaults/skc/skills/<name>/SKILL.md\npackages/coding-agent/src/prompts/agents/<role>.md\n```\n\nワークフロー定義またはリブランド面の変更については、プロジェクトのゲートを実行してください:\n\n```sh\nbun scripts/check-visible-definitions.ts\nbun scripts/verify-g002-gates.ts\nbun scripts/rebrand-inventory.ts --strict\nbun test packages/coding-agent/test/default-skc-definitions.test.ts\n```\n\nパッケージごとのマップについては、[`docs/codebase-overview.md`](docs/codebase-overview.md) を参照してください。\n\n## Contributors\n\nコントリビューション、バグレポート、リリース検証は GitHub の Issues と Pull Request を通じて歓迎しています。\n\n## Inspirations and lineage\n\nSayknow-CLI のデフォルト TUI アイデンティティは頭足類のペアです: デフォルトの blue-octopus と、温かみのある red-octopus の代替。また、`claude-code`、`codex`、`opencode` の移行用テーマも同梱しており、これらのパレットはそれらのツールにインスパイアされているため、移行してくるユーザーが見慣れた見た目を得られます。これは、公開された SKC 面を意図的に集中させたまま、小さなエージェントハーネス一族からの教訓の上に構築されています。歴史的な帰属表示は [`NOTICE.md`](NOTICE.md) に保持されています。\n\n## License\n\nMIT。[`LICENSE`](LICENSE) を参照してください。\n",
56
+ "readme/README.ko.md": "<p align=\"center\">\n <img src=\"../../assets/hero.png\" alt=\"Sayknow-CLI autonomous coding-agent hero illustration\" width=\"100%\" />\n</p>\n\n<h1 align=\"center\">Sayknow-CLI</h1>\n\n<p align=\"center\">\n <strong>코딩은 사고처럼 느껴져야 합니다.</strong><br />\n 인터뷰, 검토된 계획, tmux 네이티브 실행, 견고한 검증을 위한 집중형 코딩 에이전트 러너.\n</p>\n\n<p align=\"center\">\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/releases\"><img alt=\"Release\" src=\"https://img.shields.io/github/v/tag/jaybeyond/Sayknow_CLI?sort=semver&label=release&style=flat-square&color=2f9bff\"></a>\n <a href=\"LICENSE\"><img alt=\"License: MIT\" src=\"https://img.shields.io/github/license/jaybeyond/Sayknow_CLI?style=flat-square&color=green\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/stargazers\"><img alt=\"Stars\" src=\"https://img.shields.io/github/stars/jaybeyond/Sayknow_CLI?style=flat-square&color=f5c518\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/issues\"><img alt=\"Issues\" src=\"https://img.shields.io/github/issues/jaybeyond/Sayknow_CLI?style=flat-square\"></a>\n <a href=\"https://bun.sh\"><img alt=\"Built with Bun\" src=\"https://img.shields.io/badge/built%20with-Bun-fbf0df?style=flat-square&logo=bun&logoColor=black\"></a>\n <a href=\"#languages\"><img alt=\"i18n\" src=\"https://img.shields.io/badge/i18n-7%20languages-2f9bff?style=flat-square\"></a>\n</p>\n\n<p align=\"center\">\n <a href=\"../../README.md\">English</a> ·\n <b>한국어</b> ·\n <a href=\"README.zh.md\">中文</a> ·\n <a href=\"README.ja.md\">日本語</a> ·\n <a href=\"README.es.md\">Español</a> ·\n <a href=\"README.fr.md\">Français</a> ·\n <a href=\"README.de.md\">Deutsch</a>\n</p>\n\n<p align=\"center\">\n <img src=\"../../assets/character.png\" alt=\"Sayknow-CLI character mascot\" width=\"320\" />\n</p>\n\n> Sayknow-CLI는 실험적인 베타 단계 프로젝트입니다. 거친 부분이 있을 수 있으니 중요한 작업에 의존하기 전에 출력 결과를 검증하세요.\n\n## Languages\n\n인터페이스는 **7개 언어** — English, 한국어 (Korean),\n中文 (简体 / Simplified Chinese), 日本語 (Japanese), Español (Spanish),\nFrançais (French), Deutsch (German) — 로 현지화되어 있습니다. 첫 실행 시\n시스템 로케일을 자동으로 감지하며, 언제든지 **Settings → Appearance → Language** 에서\n전환하거나 예를 들어 `LANG=ja_JP.UTF-8 skc` 로 실행할 수 있습니다. 번역되지 않은 문자열은\nEnglish로 대체되며, 브랜드/기술 이름(Claude, OpenAI, MCP, …)은 모든 로케일에서 그대로 유지됩니다.\n\n## What is Sayknow-CLI?\n\nSayknow-CLI(`skc`)는 외부 코딩 에이전트 하니스입니다. 선택한 저장소나 워크트리에서 실행되며, 에이전트에게 작고 명시적인 워크플로 표면을 제공합니다:\n\n```text\ndeep-interview -> ralplan -> ultragoal\n └─ optional team execution when parallel tmux workers help\n```\n\n이것은 의도적으로 Codex CLI, Claude Code, OpenCode, Claw Code의 숨겨진 플러그인이 아닙니다. 구조화된 계획, 지속적인 증거, tmux 기반 워커, 또는 격리된 워크트리를 원할 때 이러한 도구들 옆에서 `skc`를 시작하세요.\n\n## Install\n\n```sh\nnpm install -g sayknow-cli # 또는: bun install -g sayknow-cli\nskc --version\n```\n\n프리빌드 네이티브(macOS·Linux·Windows)가 포함돼 있어 Rust 툴체인이나 빌드가 필요 없습니다. 업데이트는 `npm install -g sayknow-cli@latest` 또는 터미널에서 `skc update`.\n\n> 이전에 소스(git clone)로 설치했다면 한 번만 `rm -f ~/.local/bin/skc && npm install -g sayknow-cli`로 전환하세요. 소스/개발 설치는 [영문 README](../../README.md#install-from-source-development) 참고.\n\n## Quick start\n\n```sh\n# Run directly in the current checkout\nskc\n\n# Use a tmux-backed leader session\nskc --tmux\n\n# Use an isolated worktree for risky or reviewable work\n# --worktree takes an optional branch-like name, not a filesystem path.\nskc --tmux --worktree my-task-branch\n\n# If you already created a worktree directory, launch from that directory instead.\ncd ../my-task-worktree && skc --tmux\n```\n\nSKC 세션 내부에서는, 공개 워크플로 표면을 사용하세요:\n\n```text\n/skill:deep-interview clarify ambiguous requirements\n/skill:ralplan build and critique the implementation plan\nskc ultragoal create-goals --brief-file <approved-plan>\nskc ultragoal complete-goals\n```\n\n조율된 tmux 워커가 실질적으로 도움이 될 때만 `skc team ...`을 추가하세요.\n\n## Core capabilities\n\n- **추측하기 전에 인터뷰**: `deep-interview`는 모호한 요청을 구체적인 요구사항으로 바꿉니다.\n- **변경하기 전에 계획**: `ralplan`은 코드 변경 전에 접근 방식을 검토합니다.\n- **증거와 함께 실행**: `ultragoal`은 목표, 수정, 점검, 완료 증거를 추적합니다.\n- **유용할 때 병렬화**: `team`은 더 큰 작업을 위해 tmux 기반 워커를 조율합니다.\n- **외부에서 검토 가능하게 유지**: 다른 에이전트 런타임을 패치하지 않고 선택한 저장소나 워크트리에서 실행합니다.\n\n## Workflow surface\n\nSayknow-CLI는 네 가지 기본 워크플로 스킬을 제공합니다:\n\n| Skill | What it does |\n| ---------------- | --------------------------------------------------------------------- |\n| `deep-interview` | 계획이나 코드 변경 전에 모호한 요구사항을 명확히 합니다. |\n| `ralplan` | 변경 전에 구현 계획을 구축하고 비평합니다. |\n| `ultragoal` | 실행, 수정, 검증, 증거를 거쳐 목표를 추적합니다. |\n| `team` | 병렬 실행이 가치가 있을 때 tmux 기반 워커를 조율합니다. |\n\n그리고 네 가지 번들 역할 에이전트:\n\n| Agent | What it does |\n| ----------- | -------------------------------------------------- |\n| `executor` | 범위가 정해진 구현, 수정, 리팩터. |\n| `architect` | 읽기 전용 아키텍처 및 코드 리뷰 평가. |\n| `planner` | 읽기 전용 순서 결정 및 수용 기준. |\n| `critic` | 읽기 전용 계획 비평 및 실행 가능성 검토. |\n\n광범위한 기본 스킬 동물원은 없습니다: SKC는 이 작은 방법을 더 좋게 만들어 개선됩니다.\n\n## Works beside your existing agent or bot\n\n| Tool or bot | Recommended SKC command | Boundary |\n| ----------- | ----------------------- | -------- |\n| Codex CLI | `skc --tmux --worktree <name>` or `skc` | `--worktree`는 SKC가 관리하는 형제 워크트리의 이름을 지정합니다. 기존 경로의 경우 먼저 그곳으로 `cd` 하세요. |\n| Claude Code | `skc --tmux` or `skc --tmux --worktree <name>` | SKC는 Claude Code 확장이 되지 않습니다. |\n| OpenCode | `skc` or `skc --tmux` | 현재로서는 외부 러너 워크플로만 지원합니다. |\n| Claw Code | `skc --tmux --worktree <name>` | SKC는 Claw Code에 설치되거나 그것을 대체하지 않습니다. |\n| External controller / bot | 호환 가능한 구성을 위한 `skc mcp-serve coordinator` 및 `skc setup hermes`, 또는 서브프로세스 워커를 위한 `skc --mode rpc` | MCP/RPC 지원 봇이라면 무엇이든 스크롤백 스크래핑이 아니라 일반 coordinator/RPC 계약을 통해 SKC를 구동합니다. |\n\n일반 서드파티 봇 설정 및 공급자 독립적 스모크에 대해서는 [`docs/bot-integration.md`](docs/bot-integration.md)를 참조하세요. MCP, RPC, ACP, Bridge/HTTPS 표면 전반의 준비도 분류에 대해서는 [`docs/external-control-readiness.md`](docs/external-control-readiness.md)를 참조하세요. 더 낮은 수준의 프로토콜 세부 사항에 대해서는 [`docs/hermes-mcp-bridge.md`](docs/hermes-mcp-bridge.md), [`docs/rpc.md`](docs/rpc.md), [`docs/bridge.md`](docs/bridge.md)를 참조하세요. 원격 운영자 표면 로드맵에 대해서는 [`docs/sayknow-remote.md`](docs/sayknow-remote.md)(웹 스티어링 휠) 및 [`docs/telegram-remote.md`](docs/telegram-remote.md)(Telegram 라이프사이클 버튼)를 참조하세요.\n\n## Configuration\n\n공급자 재시도 예산은 `~/.skc/config.yml`에 있습니다:\n\n```yaml\nretry:\n requestMaxRetries: 4\n streamMaxRetries: 100\n maxRetries: 3\n maxDelayMs: 300000\n```\n\n`requestMaxRetries`는 스트림이 설정되기 전에 적용됩니다. `streamMaxRetries`는 재생 안전한 일시적 스트림 실패에만 적용됩니다. 잘못된 인증, 지원되지 않는 모델/공급자, 잘못된 형식의 요청, 컨텍스트 오버플로, 사용자 중단, 영구적인 할당량 실패는 즉시 실패(fail-fast)로 유지됩니다.\n\n## TUI identity\n\n기본 TUI 정체성은 SKC **blue-octopus** 테마 — 파란 두족류 마스코트 — 로, 다크 및 라이트 터미널 모두에 적용됩니다. 더 어둡고 고대비 팔레트를 선호하는 사람들을 위해 따뜻한 **red-octopus** 변형도 번들로 제공됩니다. 세 가지 추가 마이그레이션 테마 — `claude-code`, `codex`, `opencode` — 는 쉬운 눈 마이그레이션을 위해 해당 도구들의 모습을 그대로 따르며 Settings 또는 `/theme`에서 선택할 수 있습니다. 명시적인 사용자 테마 설정이 여전히 우선합니다.\n\n### Bundled theme grid\n\nSettings (`Appearance -> Dark theme` / `Light theme`) 또는 `/theme`에서 선택하세요.\n\n| Theme | Visual feel | Best fit |\n| --- | --- | --- |\n| `blue-octopus` | 기본 SKC 정체성 — 촉수 블루 액센트가 있는 파란 문어 팔레트. | 다크 및 라이트 터미널의 기본값. |\n| `red-octopus` | 강한 상태 대비를 가진 따뜻한 빨간 문어 변형. | 고대비 다크 대안. |\n| `claude-code` | 테라코타와 핑크 하이라이트가 있는 Claude Code 영감 다크 팔레트. | SKC를 떠나지 않고 Claude Code 근육 기억을 유지. |\n| `codex` | 더 날카로운 코딩 세션 대비를 가진 선명한 다크 블루그레이 팔레트. | Codex 같은 다크 작업 공간. |\n| `opencode` | 더 강렬한 터미널 액센트를 가진 OpenCode 영감 다크 팔레트. | 번들 선택기에서의 OpenCode 근육 기억. |\n\n## Development\n\n의존성을 설치하고, 네이티브 바인딩을 빌드하고, 로컬 기본값을 설정하세요:\n\n```sh\nbun install\nbun run build:native\nbun run install:defaults\n```\n\n`@sayknow-cli/natives`용 `.node` 바이너리는 gitignore되어 있으며 모든 CLI 호출(`install:defaults`, `dev:link`, 테스트) 전에 필요합니다.\n\n### Canonical: build and link the dev `skc`\n\n전역 `skc` 명령이 **이 체크아웃의 TypeScript 소스**(모든 편집에 즉시 반영되며, 스킬/네이티브가 작동함)를 실행하도록 하려면, `PATH`에 링크하세요:\n\n```sh\nbun install\nbun run dev:link\n```\n\n`dev:link`는 `skc` → `packages/coding-agent/src/cli.ts`를 `~/.local/bin`에 심볼릭 링크하고(`SKC_DEV_LINK_DIR`로 재정의 가능), 그 관리되는 대상을 교체하며, 다른 `skc`가 여전히 `PATH`에서 더 앞쪽에 있어 그것을 가린다면 경고하고 실패하며, `--smoke-test`를 실행하여 `@sayknow-cli/natives`가 로드되는지 확인합니다. 전체 부트스트랩(install + link + `setup defaults`)을 위해서는 `bun run install:dev`를 사용하세요.\n\n당신의 `skc`가 표류했는지(잘못된 소스, 또는 스킬을 로드할 수 없는 컴파일된 바이너리) 언제든지 확인하세요:\n\n```sh\nbun run dev:doctor\n```\n\n> 일상적인 개발에는 컴파일된 바이너리를 **사용하지 마세요**. `bun --cwd=packages/coding-agent run build`는 독립 실행형 `dist/skc`를 생성하지만, `bun build --compile` 바이너리는 `@sayknow-cli/natives`를 동적으로 로드할 수 없으므로 스킬이 `Cannot find module '@sayknow-cli/natives' from '/$bunfs/root/skc'`로 실패합니다. `dev:link`를 통해 소스에서 실행하면 이를 피할 수 있습니다. 릴리스를 검증할 때만 바이너리를 빌드하세요.\n\n링크 없이 소스에서 직접 CLI를 실행하세요:\n\n```sh\nbun packages/coding-agent/src/cli.ts --help\n```\n\n기본 워크플로 정의는 커밋된 `.skc` 사본이 아니라 소스에 있습니다:\n\n```text\npackages/coding-agent/src/defaults/skc/skills/<name>/SKILL.md\npackages/coding-agent/src/prompts/agents/<role>.md\n```\n\n워크플로 정의 또는 리브랜드 표면 변경의 경우, 프로젝트 게이트를 실행하세요:\n\n```sh\nbun scripts/check-visible-definitions.ts\nbun scripts/verify-g002-gates.ts\nbun scripts/rebrand-inventory.ts --strict\nbun test packages/coding-agent/test/default-skc-definitions.test.ts\n```\n\n패키지별 맵에 대해서는 [`docs/codebase-overview.md`](docs/codebase-overview.md)를 참조하세요.\n\n## Contributors\n\n기여, 버그 보고, 릴리스 검증은 GitHub Issues와 Pull Request를 통해 환영합니다.\n\n## Inspirations and lineage\n\nSayknow-CLI의 기본 TUI 정체성은 두족류 쌍입니다: 기본값인 blue-octopus와 따뜻한 red-octopus 대안. 또한 해당 도구들에서 옮겨오는 사용자들이 익숙한 모습을 얻도록 팔레트가 그 도구들에서 영감을 받은 `claude-code`, `codex`, `opencode` 마이그레이션 테마를 번들로 제공합니다. 공개 SKC 표면을 의도적으로 집중된 상태로 유지하면서, 작은 에이전트 하니스 계열에서 얻은 교훈을 바탕으로 만들어졌습니다. 역사적 출처 표기는 [`NOTICE.md`](NOTICE.md)에 보관되어 있습니다.\n\n## License\n\nMIT. [`LICENSE`](LICENSE)를 참조하세요.\n",
57
+ "readme/README.zh.md": "<p align=\"center\">\n <img src=\"../../assets/hero.png\" alt=\"Sayknow-CLI autonomous coding-agent hero illustration\" width=\"100%\" />\n</p>\n\n<h1 align=\"center\">Sayknow-CLI</h1>\n\n<p align=\"center\">\n <strong>编码应当如思考般自然。</strong><br />\n 一个专注的编码智能体运行器,面向访谈式需求澄清、经评审的计划、tmux 原生执行与持久化验证。\n</p>\n\n<p align=\"center\">\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/releases\"><img alt=\"Release\" src=\"https://img.shields.io/github/v/tag/jaybeyond/Sayknow_CLI?sort=semver&label=release&style=flat-square&color=2f9bff\"></a>\n <a href=\"LICENSE\"><img alt=\"License: MIT\" src=\"https://img.shields.io/github/license/jaybeyond/Sayknow_CLI?style=flat-square&color=green\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/stargazers\"><img alt=\"Stars\" src=\"https://img.shields.io/github/stars/jaybeyond/Sayknow_CLI?style=flat-square&color=f5c518\"></a>\n <a href=\"https://github.com/jaybeyond/Sayknow_CLI/issues\"><img alt=\"Issues\" src=\"https://img.shields.io/github/issues/jaybeyond/Sayknow_CLI?style=flat-square\"></a>\n <a href=\"https://bun.sh\"><img alt=\"Built with Bun\" src=\"https://img.shields.io/badge/built%20with-Bun-fbf0df?style=flat-square&logo=bun&logoColor=black\"></a>\n <a href=\"#languages\"><img alt=\"i18n\" src=\"https://img.shields.io/badge/i18n-7%20languages-2f9bff?style=flat-square\"></a>\n</p>\n\n<p align=\"center\">\n <a href=\"../../README.md\">English</a> ·\n <a href=\"README.ko.md\">한국어</a> ·\n <b>中文</b> ·\n <a href=\"README.ja.md\">日本語</a> ·\n <a href=\"README.es.md\">Español</a> ·\n <a href=\"README.fr.md\">Français</a> ·\n <a href=\"README.de.md\">Deutsch</a>\n</p>\n\n<p align=\"center\">\n <img src=\"../../assets/character.png\" alt=\"Sayknow-CLI character mascot\" width=\"320\" />\n</p>\n\n> Sayknow-CLI 是一个实验性的、处于 beta 阶段的项目。请预期会有粗糙之处,并在依赖其结果完成重要工作之前先行验证输出。\n\n## Languages\n\n界面已本地化为 **7 种语言**——English、한국어(韩语)、\n中文(简体)、日本語(日语)、Español(西班牙语)、\nFrançais(法语)以及 Deutsch(德语)。首次运行时它会自动检测你的系统区域设置;\n你可以随时在 **Settings → Appearance → Language** 中切换,或者使用例如\n`LANG=ja_JP.UTF-8 skc` 的方式启动。未翻译的字符串会回退到英文,而\n品牌/技术名称(Claude、OpenAI、MCP……)在所有语言环境中均保持原样。\n\n## What is Sayknow-CLI?\n\nSayknow-CLI(`skc`)是一个外部编码智能体框架(harness)。它从你选择的仓库或工作树(worktree)中运行,然后为智能体提供一个精简、明确的工作流界面:\n\n```text\ndeep-interview -> ralplan -> ultragoal\n └─ optional team execution when parallel tmux workers help\n```\n\n它有意不做成 Codex CLI、Claude Code、OpenCode 或 Claw Code 的隐藏插件。当你需要结构化的规划、持久化的证据、tmux 支持的工作进程或一个隔离的工作树时,就在这些工具旁边启动 `skc`。\n\n## Install\n\n```sh\nnpm install -g sayknow-cli # 或:bun install -g sayknow-cli\nskc --version\n```\n\n已内置 macOS·Linux·Windows 的预编译原生模块,无需 Rust 工具链或构建步骤。更新:`npm install -g sayknow-cli@latest` 或在终端运行 `skc update`。\n\n> 如果你之前是从源码(git clone)安装的,只需一次性切换:`rm -f ~/.local/bin/skc && npm install -g sayknow-cli`。源码/开发安装请参见[英文 README](../../README.md#install-from-source-development)。\n\n## Quick start\n\n```sh\n# Run directly in the current checkout\nskc\n\n# Use a tmux-backed leader session\nskc --tmux\n\n# Use an isolated worktree for risky or reviewable work\n# --worktree takes an optional branch-like name, not a filesystem path.\nskc --tmux --worktree my-task-branch\n\n# If you already created a worktree directory, launch from that directory instead.\ncd ../my-task-worktree && skc --tmux\n```\n\n在 SKC 会话内部,使用公共工作流界面:\n\n```text\n/skill:deep-interview clarify ambiguous requirements\n/skill:ralplan build and critique the implementation plan\nskc ultragoal create-goals --brief-file <approved-plan>\nskc ultragoal complete-goals\n```\n\n仅当协同的 tmux 工作进程能带来实质性帮助时,才加上 `skc team ...`。\n\n## Core capabilities\n\n- **先访谈,不靠猜**:`deep-interview` 把模糊的请求转化为具体的需求。\n- **先规划,再变更**:`ralplan` 在代码改动之前评审方案。\n- **带证据地执行**:`ultragoal` 跟踪目标、修订、检查以及完成证据。\n- **在有用时并行化**:`team` 为较大的任务协调 tmux 支持的工作进程。\n- **保持外部化且可评审**:从所选的仓库或工作树中运行,无需给另一个智能体运行时打补丁。\n\n## Workflow surface\n\nSayknow-CLI 内置四项默认工作流技能:\n\n| Skill | What it does |\n| ---------------- | --------------------------------------------------------------------- |\n| `deep-interview` | 在规划或代码改动之前澄清模糊的需求。 |\n| `ralplan` | 在变更之前构建并评审实现计划。 |\n| `ultragoal` | 在执行、修订、验证与证据收集的全过程中跟踪目标。 |\n| `team` | 当并行执行值得时,协调 tmux 支持的工作进程。 |\n\n以及四个捆绑的角色智能体:\n\n| Agent | What it does |\n| ----------- | -------------------------------------------------- |\n| `executor` | 有边界的实现、修复与重构。 |\n| `architect` | 只读的架构与代码评审评估。 |\n| `planner` | 只读的排序与验收标准。 |\n| `critic` | 只读的计划评审与可执行性审查。 |\n\n没有庞杂的默认技能堆砌:SKC 通过把这一精简方法做得更好来持续改进。\n\n## Works beside your existing agent or bot\n\n| Tool or bot | Recommended SKC command | Boundary |\n| ----------- | ----------------------- | -------- |\n| Codex CLI | `skc --tmux --worktree <name>` or `skc` | `--worktree` 指定一个由 SKC 管理的同级工作树;对于已存在的路径,请先 `cd` 到那里。 |\n| Claude Code | `skc --tmux` or `skc --tmux --worktree <name>` | SKC 不会成为 Claude Code 的扩展。 |\n| OpenCode | `skc` or `skc --tmux` | 目前仅支持外部运行器(external-runner)工作流。 |\n| Claw Code | `skc --tmux --worktree <name>` | SKC 不会安装到 Claw Code 中,也不会替代它。 |\n| External controller / bot | `skc mcp-serve coordinator` plus `skc setup hermes` for compatible config, or `skc --mode rpc` for a subprocess worker | 任何具备 MCP/RPC 能力的 bot 都通过通用的 coordinator/RPC 契约来驱动 SKC,而非抓取滚动回显(scrollback scraping)。 |\n\n关于通用第三方 bot 的设置以及与提供商无关的冒烟测试,请参阅 [`docs/bot-integration.md`](docs/bot-integration.md)。关于在 MCP、RPC、ACP 与 Bridge/HTTPS 各界面上的就绪度分级,请参阅 [`docs/external-control-readiness.md`](docs/external-control-readiness.md)。关于更底层的协议细节,请参阅 [`docs/hermes-mcp-bridge.md`](docs/hermes-mcp-bridge.md)、[`docs/rpc.md`](docs/rpc.md) 以及 [`docs/bridge.md`](docs/bridge.md)。关于远程操作员界面的路线图,请参阅 [`docs/sayknow-remote.md`](docs/sayknow-remote.md)(网页方向盘)以及 [`docs/telegram-remote.md`](docs/telegram-remote.md)(Telegram 生命周期按钮)。\n\n## Configuration\n\n提供商重试预算位于 `~/.skc/config.yml`:\n\n```yaml\nretry:\n requestMaxRetries: 4\n streamMaxRetries: 100\n maxRetries: 3\n maxDelayMs: 300000\n```\n\n`requestMaxRetries` 在流(stream)建立之前生效。`streamMaxRetries` 仅适用于可安全重放的瞬时流失败。无效的认证、不受支持的模型/提供商、格式错误的请求、上下文溢出、用户中止以及永久性配额失败仍然保持快速失败(fail-fast)。\n\n## TUI identity\n\n默认的 TUI 标识是 SKC 的 **blue-octopus**(蓝章鱼)主题——蓝色头足类吉祥物——同时适用于深色和浅色终端。还捆绑了一个暖色调的 **red-octopus**(红章鱼)变体,供偏好更深、高对比度配色的用户使用。另有三个迁移主题——`claude-code`、`codex` 和 `opencode`——分别复刻了这些工具的外观,以便于视觉迁移,可从 Settings 或 `/theme` 中选择。显式的用户主题设置仍然优先生效。\n\n### Bundled theme grid\n\n从 Settings(`Appearance -> Dark theme` / `Light theme`)或 `/theme` 中选择。\n\n| Theme | Visual feel | Best fit |\n| --- | --- | --- |\n| `blue-octopus` | 默认 SKC 标识——蓝章鱼配色,带触手蓝点缀。 | 深色和浅色终端的默认主题。 |\n| `red-octopus` | 暖色调红章鱼变体,状态对比强烈。 | 高对比度的深色替代方案。 |\n| `claude-code` | 受 Claude Code 启发的深色配色,带赤陶色和粉色高光。 | 在不离开 SKC 的情况下保留 Claude Code 的肌肉记忆。 |\n| `codex` | 清爽的深蓝灰配色,编码会话对比更锐利。 | 类似 Codex 的深色工作区。 |\n| `opencode` | 受 OpenCode 启发的深色配色,终端点缀更鲜明。 | 在捆绑选择器中保留 OpenCode 的肌肉记忆。 |\n\n## Development\n\n安装依赖、构建原生绑定,并设置本地默认值:\n\n```sh\nbun install\nbun run build:native\nbun run install:defaults\n```\n\n`@sayknow-cli/natives` 的 `.node` 二进制文件已被 gitignore,且在任何 CLI 调用(`install:defaults`、`dev:link`、测试)之前都是必需的。\n\n### Canonical: build and link the dev `skc`\n\n要让全局 `skc` 命令运行**此检出的 TypeScript 源码**(对每一次编辑都即时生效,且技能/原生绑定均可用),请把它链接到你的 `PATH`:\n\n```sh\nbun install\nbun run dev:link\n```\n\n`dev:link` 会把 `skc` → `packages/coding-agent/src/cli.ts` 软链接到 `~/.local/bin`(可用 `SKC_DEV_LINK_DIR` 覆盖),替换该受管目标,如果另一个 `skc` 仍在 `PATH` 上更靠前地遮蔽它则会发出警告并失败,并运行 `--smoke-test` 以确认 `@sayknow-cli/natives` 能够加载。使用 `bun run install:dev` 进行完整的引导(install + link + `setup defaults`)。\n\n随时检查你的 `skc` 是否已经漂移(源码错误,或一个无法加载技能的已编译二进制文件):\n\n```sh\nbun run dev:doctor\n```\n\n> 在日常开发中**不要**使用已编译的二进制文件。`bun --cwd=packages/coding-agent run build` 会产出一个独立的 `dist/skc`,但 `bun build --compile` 生成的二进制无法动态加载 `@sayknow-cli/natives`,因此技能会以 `Cannot find module '@sayknow-cli/natives' from '/$bunfs/root/skc'` 失败。通过 `dev:link` 从源码运行可避免此问题。仅在验证发布版本时才构建该二进制文件。\n\n不进行链接,直接从源码运行 CLI:\n\n```sh\nbun packages/coding-agent/src/cli.ts --help\n```\n\n默认工作流定义存放在源码中,而非已提交的 `.skc` 副本:\n\n```text\npackages/coding-agent/src/defaults/skc/skills/<name>/SKILL.md\npackages/coding-agent/src/prompts/agents/<role>.md\n```\n\n对于工作流定义或品牌重塑界面(rebrand-surface)的改动,请运行项目门禁(gates):\n\n```sh\nbun scripts/check-visible-definitions.ts\nbun scripts/verify-g002-gates.ts\nbun scripts/rebrand-inventory.ts --strict\nbun test packages/coding-agent/test/default-skc-definitions.test.ts\n```\n\n关于逐包(package-by-package)的对照图,请参阅 [`docs/codebase-overview.md`](docs/codebase-overview.md)。\n\n## Contributors\n\n欢迎通过 GitHub Issues 和 Pull Requests 进行贡献、提交错误报告以及参与发布验证。\n\n## Inspirations and lineage\n\nSayknow-CLI 默认的 TUI 标识是这对头足类:blue-octopus 作为默认,搭配一个暖色调的 red-octopus 备选。它还捆绑了 `claude-code`、`codex` 和 `opencode` 迁移主题,其配色受这些工具启发,以便从它们迁移过来的用户能获得熟悉的外观。它在一个小型智能体框架家族的经验之上构建,同时有意保持公共 SKC 界面的专注。历史归属保留在 [`NOTICE.md`](NOTICE.md) 中。\n\n## License\n\nMIT。参见 [`LICENSE`](LICENSE)。\n",
58
58
  "render-mermaid.md": "# RenderMermaid\n\n`RenderMermaid` is an optional built-in tool that renders Mermaid source to terminal-friendly text.\n\n## Enable it\n\nDisabled by default. Turn it on in `/settings` under **Tools → Render Mermaid**, or in `~/.skc/agent/config.yml`:\n\n```yaml\nrenderMermaid:\n enabled: true\n```\n\n## What it does\n\n- Tool name: `render_mermaid`\n- Input: Mermaid source in the required `mermaid` field\n- Output: rendered ASCII/Unicode text, not SVG or PNG\n- Storage: when artifact storage is available, the full render is also saved as an `artifact://...`\n\nThere are no model-specific or environment-variable prerequisites. Once enabled, any model that can call built-in tools can use it.\n\n## Parameters\n\n```json\n{\n \"mermaid\": \"graph TD\\n A[Start] --> B[Stop]\",\n \"config\": {\n \"useAscii\": false,\n \"paddingX\": 2,\n \"paddingY\": 2,\n \"boxBorderPadding\": 0\n }\n}\n```\n\nAvailable `config` fields:\n\n- `useAscii` — `true` for plain ASCII, `false` for Unicode box-drawing characters (default and usually more readable)\n- `paddingX` — horizontal spacing between nodes\n- `paddingY` — vertical spacing between nodes\n- `boxBorderPadding` — inner padding inside node boxes\n\n## Current limitations\n\n`RenderMermaid` uses the `beautiful-mermaid` ASCII renderer. It works best for flowcharts and small diagrams.\n\nComplex sequence diagrams, especially with `alt` / `else` blocks, can become very wide in a terminal. That is current renderer behavior, not a provider or model configuration problem.\n\nIf a sequence diagram is hard to read:\n\n1. Keep Unicode output (`useAscii: false`)\n2. Reduce spacing with a tighter config such as `paddingX: 2`, `paddingY: 2`, `boxBorderPadding: 0`\n3. Prefer smaller sub-diagrams over one large sequence diagram\n4. Open the saved artifact if the inline preview is truncated in the TUI\n\n## Example\n\nInput:\n\n```mermaid\ngraph TD\n A[Start] --> B{Decision}\n B -->|Yes| C[Action]\n B -->|No| D[End]\n```\n\nTypical result:\n\n```text\n┌─────┐\n│Start│\n└─────┘\n │\n ▼\n┌────────┐\n│Decision│\n└────────┘\n```\n",
59
59
  "resolve-tool-runtime.md": "# Resolve tool runtime internals\n\nThis document explains how preview/apply workflows are modeled in coding-agent and how built-in or custom tools can participate via the tool-choice queue and `pushPendingAction`.\n\n## Scope and key files\n\n- [`src/tools/resolve.ts`](../packages/coding-agent/src/tools/resolve.ts)\n- [`src/tools/ast-edit.ts`](../packages/coding-agent/src/tools/ast-edit.ts)\n- [`src/extensibility/custom-tools/types.ts`](../packages/coding-agent/src/extensibility/custom-tools/types.ts)\n- [`src/extensibility/custom-tools/loader.ts`](../packages/coding-agent/src/extensibility/custom-tools/loader.ts)\n- [`src/sdk.ts`](../packages/coding-agent/src/sdk.ts)\n\n## What `resolve` does\n\n`resolve` is a hidden tool that finalizes a pending preview action.\n\n- `action: \"apply\"` executes the queued action's `apply(reason)` callback and returns that result with resolve metadata.\n- `action: \"discard\"` invokes `reject(reason)` if provided; otherwise returns `Discarded: <label>. Reason: <reason>`.\n\nIf no pending action exists, `resolve` fails with:\n\n- `No pending action to resolve. Nothing to apply or discard.`\n\n## Pending actions use the tool-choice queue\n\nPreview producers call `queueResolveHandler(...)`, which pushes a one-shot forced `resolve` directive onto the session tool-choice queue and adds a `resolve-reminder` steering message.\n\nRuntime behavior:\n\n- the queued handler owns the pending `apply`/`reject` callbacks,\n- `resolve` looks up the current queue invoker with `session.peekQueueInvoker()`,\n- if the model rejects the forced tool choice, the queue directive is requeued,\n- `resolve` does not maintain a separate pending-action stack.\n\nMultiple pending previews therefore follow the active tool-choice queue ordering, not an independent pending-action store.\n\n## Built-in producer example (`ast_edit`)\n\n`ast_edit` previews structural replacements first. When the preview has replacements and is not applied yet, it queues a resolve handler that contains:\n\n- label (human-readable summary)\n- `sourceToolName` (`ast_edit`)\n- `apply(reason: string)` callback that reruns AST edit with `dryRun: false`\n\n`resolve(action=\"apply\", reason=\"...\")` passes `reason` into this callback.\n\n## Custom tools: `pushPendingAction`\n\nCustom tools can register resolve-compatible pending actions through `CustomToolAPI.pushPendingAction(...)`. The custom tool loader forwards these actions to `queueResolveHandler(...)` when that hook is available.\n\n`CustomToolPendingAction`:\n\n- `label: string` (required)\n- `apply(reason: string): Promise<AgentToolResult<unknown>>` (required) — invoked on apply; `reason` is the string passed to `resolve`\n- `reject?(reason: string): Promise<AgentToolResult<unknown> | undefined>` (optional) — invoked on discard; return value replaces the default \"Discarded\" message if provided\n- `details?: unknown` exists on the public custom-tool type but is not currently forwarded by the loader into resolve metadata\n- `sourceToolName?: string` (optional, defaults to `\"custom_tool\"`)\n\n### Minimal usage example\n\n```ts\nimport type { CustomToolFactory } from \"@sayknow-cli/coding-agent\";\n\nconst factory: CustomToolFactory = (pi) => ({\n name: \"batch_rename_preview\",\n label: \"Batch Rename Preview\",\n description: \"Previews renames and defers commit to resolve\",\n parameters: pi.zod.object({\n files: pi.zod.array(pi.zod.string()),\n }),\n\n async execute(_toolCallId, params) {\n const previewSummary = `Prepared rename plan for ${params.files.length} files`;\n\n pi.pushPendingAction({\n label: `Batch rename: ${params.files.length} files`,\n sourceToolName: \"batch_rename_preview\",\n apply: async (reason) => {\n // apply writes here\n return {\n content: [\n { type: \"text\", text: `Applied batch rename. Reason: ${reason}` },\n ],\n };\n },\n reject: async (reason) => {\n // optional: cleanup or notify on discard\n return {\n content: [\n { type: \"text\", text: `Discarded batch rename. Reason: ${reason}` },\n ],\n };\n },\n });\n\n return {\n content: [\n {\n type: \"text\",\n text: `${previewSummary}. Call resolve to apply or discard.`,\n },\n ],\n };\n },\n});\n\nexport default factory;\n```\n\n## Runtime availability and failures\n\n`pushPendingAction` is wired by the custom tool loader through the active session's resolve queue hook.\n\nIf the runtime did not provide the resolve queue hook, `pushPendingAction` throws:\n\n- `Pending action store unavailable for custom tools in this runtime.`\n\n## Tool-choice behavior\n\nWhen `queueResolveHandler(...)` registers a preview, the agent runtime forces a one-shot `resolve` tool choice so pending previews are explicitly finalized before normal tool flow continues.\n\n## Developer guidance\n\n- Use pending actions only for destructive or high-impact operations that should support explicit apply/discard.\n- Keep `label` concise and specific; it is shown in resolve renderer output.\n- Ensure `apply(reason)` is deterministic and idempotent enough for one-shot execution; `reason` is informational and should not change behavior.\n- Implement `reject(reason)` when the discard needs cleanup (temp state, locks, notifications); omit it for stateless previews where the default message suffices.\n- If your tool can stage multiple previews, remember they are mediated by the tool-choice queue rather than a separate pending-action stack.\n",
60
60
  "rpc.md": "# RPC Protocol Reference\n\nRPC mode runs the coding agent as a newline-delimited JSON protocol over stdio.\n\n- **stdin**: commands (`RpcCommand`), `workflow_gate_response`, extension UI responses, and host-tool updates/results\n- **stdout**: a ready frame, command responses (`RpcResponse`), session/agent events, `workflow_gate`, extension UI requests, host-tool requests/cancellations\n\nPrimary implementation:\n\n- `src/modes/rpc/rpc-mode.ts`\n- `src/modes/rpc/rpc-types.ts`\n- `src/session/agent-session.ts`\n- `packages/agent/src/agent.ts`\n- `packages/agent/src/agent-loop.ts`\n\n## Startup\n\n```bash\nskc --mode rpc [regular CLI options]\n```\n\nBehavior notes:\n\n- `@file` CLI arguments are rejected in RPC mode.\n- RPC mode disables automatic session title generation by default to avoid an extra model call.\n- RPC mode resets workflow-altering `todo.*`, `task.*`, `async.*`, and `bash.autoBackground.*` settings to their built-in defaults instead of inheriting user overrides.\n- The process reads stdin as JSONL (`readJsonl(Bun.stdin.stream())`).\n- At startup it writes `{ \"type\": \"ready\" }` before processing commands.\n- When stdin closes, pending host-tool calls are rejected and the process exits with code `0`.\n- Responses/events are written as one JSON object per line.\n\n## Transport and Framing\n\nEach frame is a single JSON object followed by `\\n`.\n\nAgent session events are wrapped in canonical `event` frames. Ready, response, workflow gate, extension UI/error, host tool, and host URI frames remain flat.\n\n### Outbound frame categories (stdout)\n\n1. Ready frame (`{ type: \"ready\" }`)\n2. `RpcResponse` (`{ type: \"response\", ... }`)\n3. Canonical event frames wrapping `AgentSessionEvent` objects (`{ type: \"event\", ... }`)\n4. `RpcWorkflowGateEvent` (`{ type: \"workflow_gate\", ... }`)\n5. `RpcExtensionUIRequest` (`{ type: \"extension_ui_request\", ... }`)\n6. Host tool requests/cancellations (`host_tool_call`, `host_tool_cancel`)\n7. Host URI requests/cancellations (`host_uri_request`, `host_uri_cancel`)\n8. Extension errors (`{ type: \"extension_error\", extensionPath, event, error }`)\n\n### Inbound frame categories (stdin)\n\n1. `RpcCommand`\n2. `RpcWorkflowGateResponse` (`{ type: \"workflow_gate_response\", gate_id, answer }`)\n3. `RpcExtensionUIResponse` (`{ type: \"extension_ui_response\", ... }`)\n4. Host tool updates/results (`host_tool_update`, `host_tool_result`)\n5. Host URI results (`host_uri_result`)\n\n## Request/Response Correlation\n\nAll commands accept optional `id?: string`.\n\n- If provided, normal command responses echo the same `id`.\n- `RpcClient` relies on this for pending-request resolution.\n\nImportant edge behavior from runtime:\n\n- Unknown command responses are emitted with `id: undefined` (even if the request had an `id`).\n- Parse/handler exceptions in the input loop emit `command: \"parse\"` with `id: undefined`.\n- `prompt` and `abort_and_prompt` return immediate success, then may emit a later error response with the **same** id if async prompt scheduling fails.\n\n## Command Schema (canonical)\n\n`RpcCommand` is defined in `src/modes/rpc/rpc-types.ts`:\n\n### Prompting\n\n- `{ id?, type: \"prompt\", message: string, images?: ImageContent[], streamingBehavior?: \"steer\" | \"followUp\" }`\n- `{ id?, type: \"steer\", message: string, images?: ImageContent[] }`\n- `{ id?, type: \"follow_up\", message: string, images?: ImageContent[] }`\n- `{ id?, type: \"abort\" }`\n- `{ id?, type: \"abort_and_prompt\", message: string, images?: ImageContent[] }`\n- `{ id?, type: \"new_session\", parentSession?: string }`\n\n### State\n\n- `{ id?, type: \"get_state\", include?: (\"tools\" | \"dumpTools\" | \"systemPrompt\")[] }` (`dumpTools` is accepted as an alias for the older response field name.)\n- `{ id?, type: \"set_todos\", phases: TodoPhase[] }`\n- `{ id?, type: \"set_host_tools\", tools: RpcHostToolDefinition[] }`\n- `{ id?, type: \"set_host_uri_schemes\", schemes: RpcHostUriSchemeDefinition[] }`\n- `{ id?, type: \"workflow_gate_response\", gate_id: string, answer: unknown }`\n\n### Model\n\n- `{ id?, type: \"set_model\", provider: string, modelId: string }`\n- `{ id?, type: \"cycle_model\" }`\n- `{ id?, type: \"get_available_models\" }`\n\n### Thinking\n\n- `{ id?, type: \"set_thinking_level\", level: ThinkingLevel }`\n- `{ id?, type: \"cycle_thinking_level\" }`\n\n### Queue modes\n\n- `{ id?, type: \"set_steering_mode\", mode: \"all\" | \"one-at-a-time\" }`\n- `{ id?, type: \"set_follow_up_mode\", mode: \"all\" | \"one-at-a-time\" }`\n- `{ id?, type: \"set_interrupt_mode\", mode: \"immediate\" | \"wait\" }`\n\n### Compaction\n\n- `{ id?, type: \"compact\", customInstructions?: string }`\n- `{ id?, type: \"set_auto_compaction\", enabled: boolean }`\n\n### Retry\n\n- `{ id?, type: \"set_auto_retry\", enabled: boolean }`\n- `{ id?, type: \"abort_retry\" }`\n\n### Bash\n\n- `{ id?, type: \"bash\", command: string }`\n- `{ id?, type: \"abort_bash\" }`\n\n### Session\n\n- `{ id?, type: \"get_session_stats\" }`\n- `{ id?, type: \"export_html\", outputPath?: string }`\n- `{ id?, type: \"switch_session\", sessionPath: string }`\n- `{ id?, type: \"branch\", entryId: string }`\n- `{ id?, type: \"get_branch_messages\" }`\n- `{ id?, type: \"get_last_assistant_text\" }`\n- `{ id?, type: \"set_session_name\", name: string }`\n\n### Messages\n\n- `{ id?, type: \"get_messages\" }`\n\n## Response Schema\n\nAll command results use `RpcResponse`:\n\n- Success: `{ id?, type: \"response\", command: <command>, success: true, data?: ... }`\n- Failure: `{ id?, type: \"response\", command: string, success: false, error: string | object }`; typed control-plane failures use object-valued errors such as `{ \"code\": \"scope_denied\", ... }`.\n\nData payloads are command-specific and defined in `rpc-types.ts`.\n\n\nBy default, `get_state` omits large static fields. Request `include: [\"tools\"]` to include `dumpTools`, `include: [\"systemPrompt\"]` to include `systemPrompt`, or both when a host needs a one-shot full session dump.\n### `get_state` payload\n\n```json\n{\n \"model\": { \"provider\": \"...\", \"id\": \"...\" },\n \"thinkingLevel\": \"off|minimal|low|medium|high|xhigh\",\n \"isStreaming\": false,\n \"isCompacting\": false,\n \"steeringMode\": \"all|one-at-a-time\",\n \"followUpMode\": \"all|one-at-a-time\",\n \"interruptMode\": \"immediate|wait\",\n \"sessionFile\": \"...\",\n \"sessionId\": \"...\",\n \"sessionName\": \"...\",\n \"autoCompactionEnabled\": true,\n \"messageCount\": 0,\n \"queuedMessageCount\": 0,\n \"todoPhases\": [\n {\n \"id\": \"phase-1\",\n \"name\": \"Todos\",\n \"tasks\": [\n {\n \"id\": \"task-1\",\n \"content\": \"Map the tool surface\",\n \"status\": \"in_progress\"\n }\n ]\n }\n ],\n \"contextUsage\": {\n \"tokens\": 0,\n \"contextWindow\": 200000,\n \"percent\": 0\n }\n // Optional with include: [\"systemPrompt\"]:\n // \"systemPrompt\": [\"...\"],\n // Optional with include: [\"tools\"] (or [\"dumpTools\"]):\n // \"dumpTools\": [\n // { \"name\": \"read\", \"description\": \"Read files and URLs\", \"parameters\": {} }\n // ]\n}\n```\n\n### `set_todos` payload\n\nReplaces the in-memory todo state for the current session and returns the normalized phase list:\n\n```json\n{\n \"id\": \"req_2\",\n \"type\": \"set_todos\",\n \"phases\": [\n {\n \"id\": \"phase-1\",\n \"name\": \"Evaluation\",\n \"tasks\": [\n {\n \"id\": \"task-1\",\n \"content\": \"Map the read tool surface\",\n \"status\": \"in_progress\"\n },\n {\n \"id\": \"task-2\",\n \"content\": \"Exercise edit operations\",\n \"status\": \"pending\"\n }\n ]\n }\n ]\n}\n```\n\nThis is useful for hosts that want to pre-seed a plan before the first prompt.\n\n### `set_host_tools` payload\n\nReplaces the current set of host-owned tools that the RPC server may call back\ninto over stdio:\n\n```json\n{\n \"id\": \"req_3\",\n \"type\": \"set_host_tools\",\n \"tools\": [\n {\n \"name\": \"echo_host\",\n \"label\": \"Echo Host\",\n \"description\": \"Echo a value from the embedding host\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"message\": { \"type\": \"string\" }\n },\n \"required\": [\"message\"],\n \"additionalProperties\": false\n }\n }\n ]\n}\n```\n\nThe response payload is:\n\n```json\n{\n \"toolNames\": [\"echo_host\"]\n}\n```\n\nThese tools are added to the active session tool registry before the next model\ncall. Re-sending `set_host_tools` replaces the previous host-owned set.\n\n### `set_host_uri_schemes` payload\n\nReplaces the current set of host-owned URL schemes the RPC server should\ndispatch reads/writes through:\n\n```json\n{\n \"id\": \"req_4\",\n \"type\": \"set_host_uri_schemes\",\n \"schemes\": [\n {\n \"scheme\": \"db\",\n \"description\": \"Virtual db row files\",\n \"writable\": true,\n \"immutable\": false\n }\n ]\n}\n```\n\nThe response payload is:\n\n```json\n{\n \"schemes\": [\"db\"]\n}\n```\n\nSchemes are case-insensitive on the wire and normalized to lowercase before\nthe response is sent. Re-sending `set_host_uri_schemes` replaces the entire\nprevious set — schemes missing from the new list are unregistered.\n\n## Event Stream Schema\n\nRPC mode forwards `AgentSessionEvent` objects from `AgentSession.subscribe(...)` as canonical `event` frames:\n\n```json\n{\n \"type\": \"event\",\n \"protocol_version\": 2,\n \"session_id\": \"...\",\n \"seq\": 1,\n \"frame_id\": \"...\",\n \"payload\": {\n \"event_type\": \"agent_start\",\n \"event\": { \"type\": \"agent_start\" }\n }\n}\n```\n\n`seq` is monotonic per session starting at `1`. `payload.event_type` duplicates the inner event `type` for routing, and `payload.event` contains the original `AgentSessionEvent` fields.\n\nCommon inner event types:\n\n- `agent_start`, `agent_end`\n- `turn_start`, `turn_end`\n- `message_start`, `message_update`, `message_end`\n- `tool_execution_start`, `tool_execution_update`, `tool_execution_end`\n- `auto_compaction_start`, `auto_compaction_end`\n- `auto_retry_start`, `auto_retry_end`\n- `ttsr_triggered`\n- `todo_reminder`\n- `todo_auto_clear`\n\nNon-event stdout categories remain flat: `ready`, `response`, `workflow_gate`, `extension_ui_request`, `extension_error`, `host_tool_call`, `host_tool_cancel`, `host_uri_request`, and `host_uri_cancel`.\n\n`message_update` includes streaming deltas in the inner event's `assistantMessageEvent` (text/thinking/toolcall deltas).\n\nExtension runner errors are emitted separately as flat frames:\n\n```json\n{\n \"type\": \"extension_error\",\n \"extensionPath\": \"...\",\n \"event\": \"...\",\n \"error\": \"...\"\n}\n```\n\n## Prompt/Queue Concurrency and Ordering\n\nThis is the most important operational behavior.\n\n### Immediate ack vs completion\n\n`prompt` and `abort_and_prompt` are **acknowledged immediately**:\n\n```json\n{ \"id\": \"req_1\", \"type\": \"response\", \"command\": \"prompt\", \"success\": true }\n```\n\nThat means:\n\n- command acceptance != run completion\n- final completion is observed via `agent_end`\n\n### While streaming\n\n`AgentSession.prompt()` requires `streamingBehavior` during active streaming:\n\n- `\"steer\"` => queued steering message (interrupt path)\n- `\"followUp\"` => queued follow-up message (post-turn path)\n\nIf omitted during streaming, prompt fails.\n\n### Queue defaults\n\nFrom `packages/agent/src/agent.ts` defaults:\n\n- `steeringMode`: `\"one-at-a-time\"`\n- `followUpMode`: `\"one-at-a-time\"`\n- `interruptMode`: `\"immediate\"`\n\n### Mode semantics\n\n- `set_steering_mode` / `set_follow_up_mode`\n - `\"one-at-a-time\"`: dequeue one queued message per turn\n - `\"all\"`: dequeue entire queue at once\n- `set_interrupt_mode`\n - `\"immediate\"`: tool execution checks steering between tool calls; pending steering can abort remaining tool calls in the turn\n - `\"wait\"`: defer steering until turn completion\n\n## Workflow Gate Sub-Protocol\n\nInteractive workflow stages emit a machine-addressable gate frame before the legacy extension UI request:\n\n```json\n{\n \"type\": \"workflow_gate\",\n \"gate_id\": \"wg_4845_ralplan_000001\",\n \"stage\": \"ralplan\",\n \"kind\": \"approval\",\n \"schema\": { \"type\": \"string\", \"enum\": [\"approve\", \"request-changes\", \"reject\"] },\n \"schema_hash\": \"<sha256 of canonical schema>\",\n \"options\": [{ \"value\": \"approve\", \"label\": \"Approve execution\" }],\n \"context\": { \"title\": \"Approve plan?\", \"summary\": \"…\" },\n \"created_at\": \"2026-06-05T05:00:00.000Z\",\n \"required\": true\n}\n```\n\nFields:\n\n- `gate_id`: run-scoped, monotonic, stable id of the form `wg_<run>_<stage>_NNNNNN`.\n- `stage`: one of `\"deep-interview\"`, `\"ralplan\"`, or `\"ultragoal\"` (`team` is reserved and rejected for v1).\n- `kind`: one of `\"question\"`, `\"approval\"`, or `\"execution\"`.\n- `schema`: documented JSON Schema 2020-12 subset for the expected answer; `schema_hash` is the canonical hash of `schema` and equals the server-side validation hash.\n- `options`: optional `RpcWorkflowGateOption[]` (`{ value, label, description? }`), emitted for select-style gates.\n- `context`: `RpcWorkflowGateContext` (`title`, `prompt`, `summary`, `stage_state`, `artifact_refs`, `language`).\n- `created_at`: ISO timestamp the gate was opened; `required` is always `true`.\n\nHosts answer with:\n\n```json\n{ \"id\": \"resp_1\", \"type\": \"workflow_gate_response\", \"gate_id\": \"wg_4845_ralplan_000001\", \"answer\": \"approve\" }\n```\n\nA valid answer resolves the pending gate and returns:\n\n```json\n{ \"id\": \"resp_1\", \"type\": \"response\", \"command\": \"workflow_gate_response\", \"success\": true }\n```\n\nA schema mismatch is **not** a command failure: the response succeeds and the\nresolution data carries `status: \"rejected\"` plus a typed validation `error`\nwith code `invalid_workflow_gate_answer`:\n\n```json\n{\n \"id\": \"resp_1\",\n \"type\": \"response\",\n \"command\": \"workflow_gate_response\",\n \"success\": true,\n \"data\": {\n \"gate_id\": \"wg_1\",\n \"status\": \"rejected\",\n \"answer_hash\": \"…\",\n \"resolved_at\": \"…\",\n \"error\": {\n \"code\": \"invalid_workflow_gate_answer\",\n \"gate_id\": \"wg_1\",\n \"schema_hash\": \"…\",\n \"errors\": [{ \"path\": \"/answer\", \"keyword\": \"type\", \"message\": \"must be boolean\" }]\n }\n }\n}\n```\n\nAnswering a gate that does not exist is a recoverable command failure carrying\nthe broker error code `unknown_gate` (other broker codes are `already_resolved`,\n`idempotency_conflict`, and `invalid_workflow_stage`).\n## Extension UI Sub-Protocol\n\nExtensions in RPC mode use request/response UI frames.\n\n### Outbound request\n\n`RpcExtensionUIRequest` (`type: \"extension_ui_request\"`) methods:\n\n- `select`, `confirm`, `input`, `editor`, `cancel`\n- `notify`, `setStatus`, `setWidget`, `setTitle`, `set_editor_text`\n\nRuntime note:\n\n- Automatic session title generation is disabled in RPC mode, and `setTitle` UI\n requests are also suppressed by default because most hosts do not have a\n meaningful terminal-title surface. Set `SKC_RPC_EMIT_TITLE=1` to opt back in to\n the UI event only.\n\nExample:\n\n```json\n{\n \"type\": \"extension_ui_request\",\n \"id\": \"123\",\n \"method\": \"confirm\",\n \"title\": \"Confirm\",\n \"message\": \"Continue?\",\n \"timeout\": 30000\n}\n```\n\n### Inbound response\n\n`RpcExtensionUIResponse` (`type: \"extension_ui_response\"`):\n\n- `{ type: \"extension_ui_response\", id: string, value: string }`\n- `{ type: \"extension_ui_response\", id: string, confirmed: boolean }`\n- `{ type: \"extension_ui_response\", id: string, cancelled: true, timedOut?: boolean }`\n\nIf a dialog has a timeout, RPC mode resolves to a default value when timeout/abort fires.\n\n## Host Tool Sub-Protocol\n\nRPC hosts can expose custom tools to the agent by sending `set_host_tools`, then\nserving execution requests over the same transport.\n\n### Outbound request\n\nWhen the agent wants the host to execute one of those tools, RPC mode emits:\n\n```json\n{\n \"type\": \"host_tool_call\",\n \"id\": \"host_1\",\n \"toolCallId\": \"toolu_123\",\n \"toolName\": \"echo_host\",\n \"arguments\": { \"message\": \"hello\" }\n}\n```\n\nIf the tool execution is later aborted, RPC mode emits:\n\n```json\n{\n \"type\": \"host_tool_cancel\",\n \"id\": \"host_cancel_1\",\n \"targetId\": \"host_1\"\n}\n```\n\n### Inbound updates and completion\n\nHosts can optionally stream progress:\n\n```json\n{\n \"type\": \"host_tool_update\",\n \"id\": \"host_1\",\n \"partialResult\": {\n \"content\": [{ \"type\": \"text\", \"text\": \"working\" }]\n }\n}\n```\n\nCompletion uses:\n\n```json\n{\n \"type\": \"host_tool_result\",\n \"id\": \"host_1\",\n \"result\": {\n \"content\": [{ \"type\": \"text\", \"text\": \"done\" }]\n }\n}\n```\n\nSet top-level `isError: true` on `host_tool_result` to reject the pending host tool call and surface the returned text content as a tool error.\n\n## Host URI Sub-Protocol\n\nRPC hosts can also own custom URL schemes (virtual files). After\n`set_host_uri_schemes`, every read of `<scheme>://…` and write of\n`<scheme>://…` (when registered as `writable`) is bounced back to the host\nover the same transport.\n\n### Outbound request\n\nWhen a session tool resolves a host-owned URL, RPC mode emits:\n\n```json\n{\n \"type\": \"host_uri_request\",\n \"id\": \"uri_1\",\n \"operation\": \"read\",\n \"url\": \"db://users/42\"\n}\n```\n\nWrites look the same with `\"operation\": \"write\"` and an additional\n`\"content\": \"...\"` field carrying the full replacement bytes.\n\nIf the request is later aborted (caller cancels, session ends), RPC mode\nemits:\n\n```json\n{\n \"type\": \"host_uri_cancel\",\n \"id\": \"uri_cancel_1\",\n \"targetId\": \"uri_1\"\n}\n```\n\n### Inbound result\n\nFor successful reads:\n\n```json\n{\n \"type\": \"host_uri_result\",\n \"id\": \"uri_1\",\n \"content\": \"id=42\\nname=Alice\\n\",\n \"contentType\": \"text/plain\",\n \"notes\": [\"fresh from cache\"],\n \"immutable\": false\n}\n```\n\nFor successful writes, omit content:\n\n```json\n{ \"type\": \"host_uri_result\", \"id\": \"uri_1\" }\n```\n\nTo reject the request, set `isError: true` and either populate `error` with\na message or fall back to `content` for textual error surfacing:\n\n```json\n{\n \"type\": \"host_uri_result\",\n \"id\": \"uri_1\",\n \"isError\": true,\n \"error\": \"row 42 not found\"\n}\n```\n\n### Constraints\n\n- The agent's `edit` tool does not target host URIs. Hosts that want to\n mutate virtual files expose `write` and let the model use the `write` tool\n with replacement content.\n- Schemes are global to the process; `set_host_uri_schemes` replaces the\n previous set, unregistering anything not in the new list.\n- Schemes are normalized to lowercase before registration.\n\n## Error Model and Recoverability\n\n### Command-level failures\n\nFailures are `success: false` with string `error`.\n\n```json\n{\n \"id\": \"req_2\",\n \"type\": \"response\",\n \"command\": \"set_model\",\n \"success\": false,\n \"error\": \"Model not found: provider/model\"\n}\n```\n\n### Recoverability expectations\n\n- Most command failures are recoverable; process remains alive.\n- Malformed JSONL / parse-loop exceptions emit a `parse` error response and continue reading subsequent lines.\n- Empty `set_session_name` is rejected (`Session name cannot be empty`).\n- Extension UI responses with unknown `id` are ignored.\n- Process termination conditions are stdin close or explicit extension-triggered shutdown after the current command.\n\n## Compact Command Flows\n\n### 1) Prompt and stream\n\nstdin:\n\n```json\n{ \"id\": \"req_1\", \"type\": \"prompt\", \"message\": \"Summarize this repo\" }\n```\n\nstdout sequence (typical):\n\n```json\n{ \"id\": \"req_1\", \"type\": \"response\", \"command\": \"prompt\", \"success\": true }\n{ \"type\": \"agent_start\" }\n{ \"type\": \"message_update\", \"assistantMessageEvent\": { \"type\": \"text_delta\", \"delta\": \"...\" }, \"message\": { \"role\": \"assistant\", \"content\": [] } }\n{ \"type\": \"agent_end\", \"messages\": [] }\n```\n\n### 2) Prompt during streaming with explicit queue policy\n\nstdin:\n\n```json\n{\n \"id\": \"req_2\",\n \"type\": \"prompt\",\n \"message\": \"Also include risks\",\n \"streamingBehavior\": \"followUp\"\n}\n```\n\n### 3) Inspect and tune queue behavior\n\nstdin:\n\n```json\n{ \"id\": \"q1\", \"type\": \"get_state\" }\n{ \"id\": \"q2\", \"type\": \"set_steering_mode\", \"mode\": \"all\" }\n{ \"id\": \"q3\", \"type\": \"set_interrupt_mode\", \"mode\": \"wait\" }\n```\n\n### 4) Extension UI round trip\n\nstdout:\n\n```json\n{\n \"type\": \"extension_ui_request\",\n \"id\": \"ui_7\",\n \"method\": \"input\",\n \"title\": \"Branch name\",\n \"placeholder\": \"feature/...\"\n}\n```\n\nstdin:\n\n```json\n{ \"type\": \"extension_ui_response\", \"id\": \"ui_7\", \"value\": \"feature/rpc-host\" }\n```\n\n## OpenClaw / Hermes host integrations\n\nFor OpenClaw- or Hermes-style hosts, keep MCP servers and skills on the host side and expose the selected capabilities through RPC host tools. Do not import SKC runtime MCP internals directly; those package paths are intentionally quarantined. See [OpenClaw / Hermes RPC integration notes](./openclaw-hermes-rpc-integration.md).\n\n## Notes on `RpcClient` helper\n\n`src/modes/rpc/rpc-client.ts` is a convenience wrapper, not the protocol definition.\n\nCurrent helper characteristics:\n\n- Spawns `bun <cliPath> --mode rpc`\n- Correlates responses by generated `req_<n>` ids\n- Dispatches recognized `AgentEvent` types to event listeners\n- Dispatches top-level `workflow_gate` frames to `onWorkflowGate()` listeners\n- Supports host-owned custom tools via `setCustomTools()` and automatic handling of `host_tool_call` / `host_tool_cancel`\n- Exposes `respondGate()` for `workflow_gate_response` and waits for the accepted/rejected resolution envelope\n- Does **not** expose helper methods for every protocol command (for example, `set_interrupt_mode` and `set_session_name` are in protocol types but not wrapped as dedicated methods)\n\nUse raw protocol frames if you need complete surface coverage.\n\n## Workflow gates (agent-driven lifecycle)\n\nThe workflow-gate contract makes every human-gated lifecycle moment\n(deep-interview questions, ralplan approval, ultragoal execution sign-off)\nmachine-addressable so an external agent can answer it over RPC without\nscreen-scraping.\n\n### Outbound event: `workflow_gate`\n\n```json\n{\n \"type\": \"workflow_gate\",\n \"gate_id\": \"wg_4845_ralplan_000001\",\n \"stage\": \"ralplan\",\n \"kind\": \"approval\",\n \"schema\": { \"type\": \"string\", \"enum\": [\"approve\", \"request-changes\", \"reject\"] },\n \"schema_hash\": \"<sha256 of canonical schema>\",\n \"options\": [{ \"value\": \"approve\", \"label\": \"Approve execution\" }],\n \"context\": { \"title\": \"Approve plan?\", \"summary\": \"…\" },\n \"created_at\": \"2026-06-05T05:00:00.000Z\",\n \"required\": true\n}\n```\n\n- `gate_id` is **run-scoped and monotonic**: `wg_<run>_<stage>_<NNNNNN>`.\n- `stage` is one of `deep-interview` | `ralplan` | `ultragoal`. `team` is\n reserved and rejected for v1 (single-agent only).\n- `kind` is `question` | `approval` | `execution`.\n- `schema` is a **documented subset of JSON Schema 2020-12**. Supported keywords:\n `type`, `enum`, `const`, `properties`, `required`, `additionalProperties`,\n `items`, `minLength`, `maxLength`, `minimum`, `maximum`, `title`,\n `description`, `oneOf`, `anyOf`. Any other keyword is rejected at gate\n construction (`invalid_workflow_gate_schema`) so the server never advertises a\n schema it will not validate. `schema_hash` equals the server-side validation\n hash for that gate.\n\n### Inbound command: `workflow_gate_response`\n\n```json\n{ \"type\": \"workflow_gate_response\", \"gate_id\": \"wg_4845_ralplan_000001\", \"answer\": \"approve\", \"idempotency_key\": \"k1\" }\n```\n\nThe answer is validated against the advertised schema **before acceptance**:\n\n- Valid → resolution persisted before the workflow advances; response:\n `{ \"type\": \"response\", \"command\": \"workflow_gate_response\", \"success\": true, \"data\": { \"gate_id\": \"…\", \"status\": \"accepted\", \"answer_hash\": \"…\", \"resolved_at\": \"…\" } }`.\n- Invalid → the gate stays **pending** and the resolution carries a typed\n `invalid_workflow_gate_answer` error listing each `{ path, keyword, message, expected? }`.\n- Idempotency: replaying the same `idempotency_key` + identical body returns the\n cached resolution; the same key with a different body is an\n `idempotency_conflict`; answering an already-accepted gate is `already_resolved`.\n- Client helpers wait for this accepted/rejected resolution envelope; they must not treat the write of `workflow_gate_response` itself as completion.\n\n### Entering unattended mode: `negotiate_unattended`\n\nUnattended (zero-human) operation is **fail-closed**. The external agent must\ndeclare its budget, scopes, and action allowlist up front:\n\n```json\n{\n \"type\": \"negotiate_unattended\",\n \"declaration\": {\n \"actor\": \"openclaw/hermes\",\n \"budget\": { \"max_tokens\": 2000000, \"max_tool_calls\": 5000, \"max_wall_time_ms\": 3600000, \"max_cost_usd\": 20 },\n \"scopes\": [\"prompt\", \"control\", \"bash\"],\n \"action_allowlist\": [\"bash.readonly\", \"file.write\"]\n }\n}\n```\n\nA missing or partial declaration refuses unattended mode. Budget, scope, and\naudit enforcement are layered on this contract by the unattended control plane\n(see issues #318/#319/#320). Attended mode is unaffected: clients that never send\n`negotiate_unattended` keep the existing extension-UI / permission behavior.\n\n\n> **Status (live, #315/#318/#321):** the `workflow_gate` /\n> `workflow_gate_response` / `negotiate_unattended` frames, the answer-schema\n> validator, and the durable gate broker are defined, tested, and wired into\n> live session dispatch. When an unattended control plane is attached to the\n> session, `dispatchRpcCommand` routes `negotiate_unattended` and\n> `workflow_gate_response` through it (see\n> `packages/coding-agent/src/modes/shared/agent-wire/command-dispatch.ts`); a\n> session without that control plane returns a typed \"not available\" error for\n> these frames rather than silently dropping them.\n\n\n### Answering gates from a client (#322)\n\nBoth clients expose typed `workflow_gate` receive + respond helpers so an agent\ncan answer a gate from its own memory via a callback.\n\nFor bridge sessions, gate responses are **not** posted through `/commands`. The\nclient must first own the UI/control plane, then post the answer body to\n`POST /v1/sessions/{session_id}/ui-responses/{gate_id}` with\n`X-SKC-Bridge-Owner-Token: <ownerToken>`. `Idempotency-Key` may be supplied as a\nheader and the same value is also accepted in the JSON body as `idempotency_key`.\n\n`@sayknow-cli/bridge-client` (TypeScript):\n\n```ts\nimport { BridgeClient } from \"@sayknow-cli/bridge-client\";\n\nconst client = new BridgeClient({ baseUrl, token });\n// Headless policy: every received gate is routed to the resolver and answered.\nfor await (const { gate, answer } of client.consumeWorkflowGates(sessionId, ownerToken, gate => {\n if (gate.kind === \"approval\") return { decision: \"approve\" };\n if (gate.kind === \"question\") return { selected: [gate.options?.[0]?.value], other: false };\n return { decision: \"approve\" };\n})) {\n console.log(`answered ${gate.gate_id} (${gate.kind}) with`, answer);\n}\n// Or answer a single gate directly:\nawait client.respondGate(sessionId, gateId, ownerToken, { decision: \"approve\" });\n```\n\n`python/skc-rpc` (Python):\n\n```python\nfrom skc_rpc import RpcClient, WorkflowGate\n\nclient = RpcClient(executable=\"skc\")\n\ndef resolver(gate: WorkflowGate) -> object:\n if gate.kind == \"approval\":\n return {\"decision\": \"approve\"}\n if gate.kind == \"question\":\n return {\"selected\": [gate.options[0].value] if gate.options else [], \"other\": False}\n return {\"decision\": \"approve\"}\n\n# Headless policy: route every received gate to the resolver and respond.\nclient.run_workflow_gate_policy(resolver)\nclient.start()\n# Or answer a single gate directly: client.respond_gate(gate_id, {\"decision\": \"approve\"})\n```\n",
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "https://raw.githubusercontent.com/jaybeyond/sayknow-cli/main/packages/coding-agent/theme-schema.json",
2
+ "$schema": "https://raw.githubusercontent.com/jaybeyond/Sayknow_CLI/main/packages/coding-agent/theme-schema.json",
3
3
  "name": "claude-code",
4
4
  "vars": {
5
5
  "bg": "#1a1a1a",
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "https://raw.githubusercontent.com/jaybeyond/sayknow-cli/main/packages/coding-agent/theme-schema.json",
2
+ "$schema": "https://raw.githubusercontent.com/jaybeyond/Sayknow_CLI/main/packages/coding-agent/theme-schema.json",
3
3
  "name": "codex",
4
4
  "vars": {
5
5
  "bg": "#0f1115",
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "https://raw.githubusercontent.com/jaybeyond/sayknow-cli/main/packages/coding-agent/theme-schema.json",
2
+ "$schema": "https://raw.githubusercontent.com/jaybeyond/Sayknow_CLI/main/packages/coding-agent/theme-schema.json",
3
3
  "name": "opencode",
4
4
  "vars": {
5
5
  "background": "#212121",
@@ -20,7 +20,7 @@ import { withFileLock } from "../config/file-lock";
20
20
  import { t } from "../i18n";
21
21
  import type { CustomMessage } from "../session/messages";
22
22
 
23
- export const STAR_REMINDER_REPO = "jaybeyond/sayknow-cli";
23
+ export const STAR_REMINDER_REPO = "jaybeyond/Sayknow_CLI";
24
24
  export const STAR_REMINDER_CUSTOM_TYPE = "star-reminder";
25
25
  export const STARRED_CACHE_TTL_MS = 24 * 60 * 60 * 1000;
26
26
 
@@ -101,7 +101,7 @@ export interface MCPSseServerConfig extends MCPServerConfigBase {
101
101
  export type MCPServerConfig = MCPStdioServerConfig | MCPHttpServerConfig | MCPSseServerConfig;
102
102
 
103
103
  export const MCP_CONFIG_SCHEMA_URL =
104
- "https://raw.githubusercontent.com/jaybeyond/sayknow-cli/main/packages/coding-agent/src/config/mcp-schema.json";
104
+ "https://raw.githubusercontent.com/jaybeyond/Sayknow_CLI/main/packages/coding-agent/src/config/mcp-schema.json";
105
105
 
106
106
  /** Root mcp.json/.mcp.json file structure */
107
107
  export interface MCPConfigFile {
@@ -277,7 +277,7 @@ export const handleDiscogs: SpecialHandler = async (
277
277
  signal,
278
278
  headers: {
279
279
  Accept: "application/json",
280
- "User-Agent": "CodingAgent/1.0 +https://github.com/jaybeyond/sayknow-cli",
280
+ "User-Agent": "CodingAgent/1.0 +https://github.com/jaybeyond/Sayknow_CLI",
281
281
  },
282
282
  });
283
283