@kontextmind/kxm 0.7.95 → 0.7.97

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.
Files changed (158) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.kxm/README.md +39 -9
  3. package/CHANGELOG.md +23 -1
  4. package/README.md +147 -257
  5. package/SECURITY.md +21 -12
  6. package/docs/README.md +133 -54
  7. package/docs/adr/ADR-0002-browser-automation-steel-doks.md +24 -18
  8. package/docs/adr/ADR-0003-sqlite-only-store.md +100 -0
  9. package/docs/adr/ADR-0004-edge-identity-authentik.md +99 -0
  10. package/docs/adr/README.md +33 -0
  11. package/docs/concepts/architecture.md +262 -0
  12. package/docs/concepts/data-and-storage.md +194 -0
  13. package/docs/concepts/trust-model.md +153 -0
  14. package/docs/contracts/README.md +22 -14
  15. package/docs/contracts/effects-and-recovery.md +3 -0
  16. package/docs/contracts/migration.md +2 -2
  17. package/docs/contracts/routing.md +6 -5
  18. package/docs/contributing/assignment-runner.md +388 -0
  19. package/docs/contributing/ci-and-release.md +231 -0
  20. package/docs/contributing/development.md +362 -0
  21. package/docs/contributing/harness-routing-internals.md +192 -0
  22. package/docs/{packages.md → contributing/packages.md} +13 -15
  23. package/docs/{skills → contributing}/repo-work-delivery.md +20 -21
  24. package/docs/contributing/test-matrix.md +208 -0
  25. package/docs/{tui-components.md → contributing/tui-components.md} +30 -22
  26. package/docs/contributing/writing-docs.md +340 -0
  27. package/docs/glossary.md +471 -0
  28. package/docs/guides/agent-skills.md +137 -0
  29. package/docs/guides/browser-automation.md +160 -0
  30. package/docs/guides/context-and-memory.md +352 -0
  31. package/docs/guides/continuous-improvement.md +228 -0
  32. package/docs/guides/governed-skills.md +173 -0
  33. package/docs/guides/nous-providers.md +186 -0
  34. package/docs/guides/peer-messaging.md +304 -0
  35. package/docs/guides/pi-workers.md +219 -0
  36. package/docs/guides/provenance-gates.md +313 -0
  37. package/docs/guides/webhook-workflows.md +399 -0
  38. package/docs/kb/how-credentials-retrieved-safely.md +38 -12
  39. package/docs/kb/how-to-capture-and-annotate-section.md +15 -13
  40. package/docs/kb/how-to-connect-playwright-to-steel.md +16 -11
  41. package/docs/kb/how-to-recover-expired-session-or-orphan.md +26 -16
  42. package/docs/kb/how-to-resume-after-mfa.md +19 -11
  43. package/docs/kb/how-to-take-over-session.md +17 -13
  44. package/docs/kb/why-authentication-disappeared.md +22 -14
  45. package/docs/kb/why-automation-opened-different-browser.md +23 -14
  46. package/docs/kb/why-session-viewer-cannot-control.md +13 -12
  47. package/docs/operations/backup-and-restore.md +248 -0
  48. package/docs/operations/deploy.md +307 -0
  49. package/docs/operations/monitoring.md +209 -0
  50. package/docs/operations/runtime-sync.md +192 -0
  51. package/docs/operations/troubleshooting.md +266 -0
  52. package/docs/operations/upgrade.md +124 -0
  53. package/docs/prompts/browser-annotate-feedback.md +7 -7
  54. package/docs/prompts/browser-diagnose-recover.md +11 -10
  55. package/docs/prompts/browser-explore.md +7 -7
  56. package/docs/prompts/browser-repro-fix.md +7 -7
  57. package/docs/prompts/browser-start.md +12 -11
  58. package/docs/prompts/browser-takeover.md +8 -8
  59. package/docs/{cli-reference.md → reference/cli-reference.md} +88 -46
  60. package/docs/{config-reference.md → reference/config-reference.md} +159 -148
  61. package/docs/reference/configuration.md +299 -0
  62. package/docs/reference/harness-routing.md +508 -0
  63. package/docs/reference/http-api.md +203 -0
  64. package/docs/reference/tools.md +370 -0
  65. package/docs/{workflow-guide.md → reference/workflow-catalog.md} +92 -153
  66. package/docs/reference/workflow-definitions.md +286 -0
  67. package/docs/start/first-workflow.md +287 -0
  68. package/docs/start/install.md +146 -0
  69. package/docs/start/quickstart-claude-code.md +405 -0
  70. package/docs/start/quickstart-pi.md +213 -0
  71. package/docs/templates/README.md +78 -73
  72. package/docs/templates/adr.md +13 -13
  73. package/docs/templates/architecture.md +55 -71
  74. package/docs/templates/bug-fix.md +13 -16
  75. package/docs/templates/feature.md +14 -19
  76. package/docs/templates/handoff.md +44 -46
  77. package/docs/templates/postmortem.md +30 -43
  78. package/docs/templates/research.md +15 -20
  79. package/docs/templates/review.md +49 -50
  80. package/docs/templates/runbook.md +38 -30
  81. package/docs/templates/test-plan.md +16 -23
  82. package/docs/templates/test-report.md +14 -17
  83. package/examples/README.md +9 -5
  84. package/examples/provenance-workflow.json +1 -1
  85. package/examples/webhook-workflows/jira-development.json +59 -0
  86. package/examples/webhook-workflows/jira-issue-updated.json +12 -0
  87. package/examples/workflow-signal.ts +4 -5
  88. package/package.json +1 -1
  89. package/packages/core/tui/README.md +1 -1
  90. package/plugins/kxm/.claude-plugin/plugin.json +1 -1
  91. package/plugins/kxm/README.md +31 -32
  92. package/plugins/kxm/dist/claude-hook.js +11 -1
  93. package/plugins/kxm/dist/cli.js +164 -79
  94. package/plugins/kxm/dist/client.js +3 -1
  95. package/plugins/kxm/dist/core.js +11 -1
  96. package/plugins/kxm/dist/extension.js +45 -13
  97. package/plugins/kxm/dist/mcp-server.js +20 -4
  98. package/plugins/kxm/dist/runtime-supervisor.js +1 -3
  99. package/plugins/kxm/dist/runtime.js +18 -4
  100. package/plugins/kxm/dist/server.js +115 -20
  101. package/plugins/kxm/package.json +1 -1
  102. package/plugins/kxm/skills/kxm/references/protocol.md +3 -1
  103. package/plugins/kxm/skills/kxm-browser-auth/SKILL.md +1 -1
  104. package/plugins/kxm/skills/kxm-browser-diagnostics/SKILL.md +5 -5
  105. package/plugins/kxm/skills/kxm-browser-explore/SKILL.md +2 -2
  106. package/plugins/kxm/skills/kxm-browser-session/SKILL.md +10 -13
  107. package/plugins/kxm/skills/kxm-browser-takeover/SKILL.md +1 -1
  108. package/plugins/kxm/skills/kxm-browser-verify/SKILL.md +1 -1
  109. package/plugins/kxm/skills/kxm-context-memory/SKILL.md +13 -4
  110. package/plugins/kxm/skills/kxm-hub-ops/SKILL.md +3 -1
  111. package/plugins/kxm/skills/kxm-mind-setup/SKILL.md +2 -1
  112. package/plugins/kxm/skills/kxm-project-setup/SKILL.md +31 -54
  113. package/plugins/kxm/skills/kxm-projects/SKILL.md +1 -1
  114. package/plugins/kxm/skills/kxm-protocol/SKILL.md +1 -1
  115. package/plugins/kxm/skills/kxm-routing-improve/SKILL.md +15 -7
  116. package/plugins/kxm/skills/kxm-runs/SKILL.md +11 -5
  117. package/plugins/kxm/skills/kxm-session/SKILL.md +1 -1
  118. package/plugins/kxm/skills/kxm-tasks/SKILL.md +9 -7
  119. package/plugins/kxm/skills/kxm-workflow/SKILL.md +10 -2
  120. package/plugins/kxm/src/cli/system.ts +1 -1
  121. package/plugins/kxm/src/cli/workflows.ts +12 -7
  122. package/plugins/kxm/src/cli.ts +22 -8
  123. package/plugins/kxm/src/client.ts +4 -0
  124. package/plugins/kxm/src/commands.ts +23 -1
  125. package/plugins/kxm/src/extension.ts +20 -14
  126. package/plugins/kxm/src/github-watch.ts +8 -5
  127. package/plugins/kxm/src/hub-env.ts +19 -1
  128. package/plugins/kxm/src/hub.ts +105 -21
  129. package/plugins/kxm/src/improve-sources.ts +2 -7
  130. package/plugins/kxm/src/init-guide-setup.ts +1 -1
  131. package/plugins/kxm/src/mcp-server.ts +9 -2
  132. package/plugins/kxm/src/modes.ts +1 -1
  133. package/plugins/kxm/src/runtime-store.ts +23 -0
  134. package/plugins/kxm/src/workflow.ts +70 -1
  135. package/schemas/README.md +1 -1
  136. package/scripts/smoke-multi-pi.mjs +5 -1
  137. package/docs/agent-communication-envelopes-and-gates.md +0 -553
  138. package/docs/agent-skills.md +0 -198
  139. package/docs/architecture.md +0 -245
  140. package/docs/assignment-runner.md +0 -264
  141. package/docs/browser-automation.md +0 -139
  142. package/docs/configuration.md +0 -437
  143. package/docs/continuous-improvement.md +0 -226
  144. package/docs/getting-started.md +0 -277
  145. package/docs/harness-routing.md +0 -616
  146. package/docs/kb/qa-authentik-authentication.md +0 -97
  147. package/docs/kb/qa-extension-install-and-hub-bootstrap.md +0 -85
  148. package/docs/kb/qa-hub-on-a-public-host.md +0 -48
  149. package/docs/kb/qa-sqlite-vs-duckdb.md +0 -35
  150. package/docs/kb/qa-what-the-hub-stores.md +0 -64
  151. package/docs/kxm-handbook.md +0 -1181
  152. package/docs/operations.md +0 -510
  153. package/docs/operator-pi-packages.md +0 -67
  154. package/docs/provenance-gates.md +0 -295
  155. package/docs/skills.md +0 -47
  156. package/docs/test-matrix.md +0 -132
  157. package/docs/troubleshooting.md +0 -322
  158. package/docs/webhook-workflows.md +0 -240
@@ -0,0 +1,231 @@
1
+ # CI and release
2
+
3
+ Every pull request and every push to `main` that changes code runs a
4
+ three-minute merge-safety gate, the complete suite with coverage floors runs
5
+ nightly, every merge to `main` cuts a patch release, and every release is
6
+ verified before it reaches npm. This
7
+ page explains which checks run where, how a merge becomes a published version,
8
+ and which smoke tests stay manual. It is for contributors and maintainers.
9
+
10
+ ## The pipeline at a glance
11
+
12
+ A merged pull request flows through CI, an automatic tag, a verified GitHub
13
+ release and an npm publish; the nightly job adds the slower suites.
14
+
15
+ ```mermaid
16
+ flowchart LR
17
+ PR[Pull request] -->|"validate:pr, docs lint, plugin validation"| MERGE{Merged?}
18
+ MERGE -->|yes| MAIN[main]
19
+ MAIN -->|"same three-minute validate:pr"| PUSH[Push CI]
20
+ MAIN -->|"Auto-Release: next patch tag"| TAG[Tag vX.Y.Z]
21
+ TAG -->|dispatch| REL[Release workflow]
22
+ REL -->|"verify, stamp version, pack"| GH[GitHub release<br/>kxm-X.Y.Z.tgz]
23
+ GH -->|"sha256 verified"| NPM[npm publish]
24
+ MAIN -->|"daily 04:00 UTC"| NIGHT[Nightly<br/>complete suite]
25
+ ```
26
+
27
+ All workflows live in `.github/workflows/`. Every job runs on the organization's
28
+ ARC runner scale set, and `test/core/ci-contract.test.ts` pins the
29
+ runner selector, job names, coverage floors and release triggers. Change a
30
+ workflow and that test together.
31
+
32
+ ## What runs where
33
+
34
+ | Trigger | Workflow (job) | What it runs |
35
+ |---|---|---|
36
+ | Before you push | Local | `npm run verify` |
37
+ | Pull request and push to `main` | `ci.yml` (Validate, two Node legs) | `validate:pr`, the three-minute gate; skipped for documentation-only changes |
38
+ | Pull request and push | `ci.yml` (Docs lint) | `lint:docs` and `check:versions`, always |
39
+ | Pull request and push | `ci.yml` (Plugin validation) | `claude plugin validate --strict` on the marketplace and the plugin; skipped for documentation-only changes |
40
+ | Daily at 04:00 UTC, or manual | `nightly.yml` | `test:coverage:complete`, `check`, `check:generated`, `npm pack --dry-run` |
41
+ | Merged pull request | `auto-release.yml` | Tags the merge commit and dispatches `release.yml` |
42
+ | Tag push or dispatch | `release.yml` | Verifies, packs and publishes (see [Release flow](#release-flow)) |
43
+ | Manual only | `smoke.yml` | Real Pi smoke, currently disabled (see [Smoke tests](#smoke-tests)) |
44
+
45
+ The npm scripts behind those rows:
46
+
47
+ | Script | Composition |
48
+ |---|---|
49
+ | `verify` | `npm test` (core and package unit tests), `check`, `check:generated` |
50
+ | `validate:pr` | `build`, `typecheck`, a compact contract and smoke set of nine `test/core` files, `check:versions`, and the generated-`dist` check |
51
+ | `validate:ci` | `test:coverage` (core and package tests, 91/80/92 floors), `check`, `npm pack --dry-run`; not run by CI today, available locally |
52
+ | `test:coverage:complete` | Core, simulation and package tests with 93/80/93 floors |
53
+ | `check` | `typecheck`, `lint:docs`, `check:versions` |
54
+
55
+ Three differences matter when a check fails on one side only:
56
+
57
+ - CI runs a compact contract and smoke set, not the core suite. The full core
58
+ suite and the package unit tests under `packages/core/*/tests` run in your
59
+ local `npm run verify`; run it before every push.
60
+ - Coverage and `test/simulations` run only in the nightly complete suite, never
61
+ on a pull request or a push to `main`.
62
+ - A regression the compact set misses can reach `main` and show up in the
63
+ nightly run, so treat a nightly failure as a release blocker.
64
+
65
+ ### Validate matrix and required checks
66
+
67
+ The Validate job runs on Node 22.19.0 and Node 24, on Linux, with a
68
+ three-minute job timeout. The branch ruleset
69
+ requires the job names `Validate (linux, Node 22.19.0)` and
70
+ `Validate (linux, Node 24)`, so renaming the job or the matrix means updating
71
+ the ruleset in the same change. A newer push cancels an older pull request run;
72
+ runs on `main` are never cancelled.
73
+
74
+ ### CI jobs stay queued while a runner is online
75
+
76
+ Every Linux workflow targets the ARC runner scale set `kontextmind-doks`. That
77
+ name is the scale set, not a custom label on a repository runner. The scale set
78
+ belongs to the selected-repository runner group `KontextMind DOKS ARC`, which
79
+ must allow this public repository. The legacy repository runner `km-gh-rn01`
80
+ must not carry the `kontextmind-doks` label; adding it bypasses ARC and
81
+ serializes the build queue.
82
+
83
+ Check GitHub routing first:
84
+
85
+ ```bash
86
+ gh api repos/kontextmind/kxm/actions/runners \
87
+ --jq '.runners[] | {name, status, busy, labels: [.labels[].name]}'
88
+ gh api orgs/kontextmind/actions/runner-groups \
89
+ --jq '.runner_groups[] | select(.name == "KontextMind DOKS ARC") |
90
+ {name, visibility, allows_public_repositories}'
91
+ ```
92
+
93
+ Then check ARC in the cluster:
94
+
95
+ ```bash
96
+ kubectl -n arc-runners get autoscalingrunnerset kontextmind-doks
97
+ kubectl -n arc-runners get ephemeralrunners,pods
98
+ ```
99
+
100
+ The capacity policy keeps one warm runner, bursts to four, and requests three
101
+ CPUs per runner so the node-pool autoscaler adds capacity instead of packing
102
+ CPU-bound jobs onto busy nodes. If jobs stay queued while the listener is
103
+ assigned zero jobs, check the runner group's selected repository and public
104
+ repository access. If ARC has pending pods, check node capacity and the cluster
105
+ autoscaler. Do not relabel `km-gh-rn01` or push an empty commit as a routing
106
+ workaround.
107
+
108
+ > [!NOTE]
109
+ > Windows legs are paused, not removed. Windows stays a supported target, and
110
+ > Windows-specific fixtures (for example the `pi.cmd` worker launch in
111
+ > `test/core/worker.test.ts`) run when you test on Windows locally.
112
+
113
+ ### The docs-only classifier
114
+
115
+ The first job, Classify changes, lists the changed paths and sets `code=false`
116
+ when every path matches `*.md`, `docs/*`, `.kxm/assets/*`, `LICENSE`, the issue
117
+ and PR templates, or `dependabot.yml`. Validate and Plugin validation read it:
118
+ for a documentation-only change they report success without checking out the
119
+ code, so the required job names still pass. Docs lint always runs.
120
+ `ci-contract.test.ts` pins this behavior.
121
+
122
+ > [!WARNING]
123
+ > Several tests and code paths read documentation files by path. A pull request
124
+ > that only moves or renames a pinned doc is classified documentation-only, so
125
+ > CI does not run the tests that would catch the broken path; the next code
126
+ > change fails instead. For any docs move, update the pinned readers in the same
127
+ > pull request (see [Pinned paths](writing-docs.md#pinned-paths)) and run
128
+ > `npm run verify` locally before you push.
129
+
130
+ ## Release flow
131
+
132
+ KXM releases a patch version for every merged pull request. No one bumps
133
+ versions by hand.
134
+
135
+ 1. **Auto-Release** (`auto-release.yml`) runs when a pull request to `main` is
136
+ merged. It finds the newest `vX.Y.Z` tag, adds one to the patch number, tags
137
+ the merge commit, and dispatches the Release workflow for that tag.
138
+ 2. **Release** (`release.yml`) checks out the tag, and takes its release helper
139
+ scripts from `main`. It runs `npm run check:generated` against the tagged
140
+ tree, stamps the tag's version into every version surface, runs
141
+ `npm run validate:ci`, and packs `kxm-<version>.tgz`. The step summary records
142
+ the tarball's sha256.
143
+ 3. `scripts/kxm-release-github.mjs` creates a draft GitHub release, uploads the
144
+ tarball, and checks the digest GitHub reports against the local one. The
145
+ workflow then publishes the draft.
146
+ 4. **Publish npm** runs in the protected `npm-publish` environment. It skips a
147
+ version already on npm. Otherwise `scripts/kxm-publish-npm.mjs` confirms the
148
+ GitHub release is published, downloads the asset, verifies its sha256
149
+ against the release digest, and runs `npm publish` on that exact file.
150
+
151
+ Every step is idempotent. Rerunning the Release workflow for a tag that is
152
+ already published or already on npm reports it and changes nothing.
153
+
154
+ ### Skip a release
155
+
156
+ Auto-Release skips a merge when the pull request has the `no-release` label, or
157
+ when its head branch starts with `chore/release-`.
158
+
159
+ ### Versions
160
+
161
+ The version in the repository's `package.json` stays at its base value. The
162
+ release job stamps the tag's version into the package, the lockfile, the plugin
163
+ package and manifest, the marketplace entry, the MCP server constant, and every
164
+ workspace package, in the runner's workspace only. The stamp is never committed
165
+ back.
166
+
167
+ - Do not edit version fields in a pull request. `npm run check:versions` fails
168
+ when any surface differs from the root `package.json`.
169
+ - Auto-Release only increments the patch number. For a minor or major release,
170
+ push a `vX.Y.0` tag yourself; `release.yml` also runs on tag pushes, and
171
+ later merges continue from that tag.
172
+ - `scripts/kxm-bump-version.mjs` and `scripts/check-versions.mjs` read the same
173
+ package list from `scripts/package-surfaces.mjs`, so the gate and the writer
174
+ cannot disagree.
175
+
176
+ ### Changelog
177
+
178
+ Add user-visible changes to `CHANGELOG.md` under `## Unreleased`, in the same
179
+ pull request. Keep an entry to a few lines and link the doc page that explains
180
+ the behavior. Add an `### Upgrade note` when an operator must act.
181
+
182
+ No release step moves those entries into a dated section. Auto-Release tags a
183
+ patch for each merged pull request, but nothing cuts the changelog, so
184
+ everything released since its newest dated section is still listed under
185
+ `## Unreleased`.
186
+
187
+ ## Smoke tests
188
+
189
+ Smoke tests prove what unit tests cannot: that the packed artifact installs,
190
+ and that real harnesses complete a turn.
191
+
192
+ | Smoke | How to run | What it proves |
193
+ |---|---|---|
194
+ | Packed install | Part of the core suite: `test/core/package-install.test.ts` | The packed CLI and hub run from a clean local and global install |
195
+ | Real Pi smoke | `KXM_SMOKE=1 KXM_SMOKE_MODELS=<model-a>,<model-b> node scripts/smoke-multi-pi.mjs` | Two supervised Pi workers discover each other, exchange requests and replies, and recover across a restart |
196
+ | Container install | `just docker-install-smoke` | The tarball installs into a fresh container with a fresh Pi, and two providers complete a live turn |
197
+
198
+ The real Pi smoke calls paid models, so it never runs by default. Its workflow,
199
+ `smoke.yml`, is manual and stays skipped until the repository variable
200
+ `KXM_SMOKE_RUNNER` names a runner with Pi credentials. Both smoke models run as
201
+ long-lived Pi workers, so each must pass the Pi native-vendor brake: pick two
202
+ non-native routes such as
203
+ `openrouter/qwen/qwen3-coder-plus,openrouter/z-ai/glm-5.3-flash`, never `xai/…`
204
+ or `anthropic/…`. The container smoke needs
205
+ Docker, a `pass-cli` session and a local Pi model store. It keeps secrets in a
206
+ mode-600 file inside a temporary directory; set `KXM_SMOKE_VAULT` to read keys
207
+ from your own vault.
208
+
209
+ ### Manual checks before announcing a release
210
+
211
+ Automation cannot prove that a harness UI renders correctly. Before you
212
+ announce a release:
213
+
214
+ 1. Install the published version:
215
+ `npm install --global --omit=peer @kontextmind/kxm@<version>`.
216
+ 2. Connect two current Pi sessions, run `/kxm hub`, and complete one inbound
217
+ round trip.
218
+ 3. Install the marketplace plugin in a clean Claude Code profile and confirm
219
+ that `kxm_list` answers.
220
+ 4. Check pushed channel delivery only when the target Claude Code version
221
+ supports channels.
222
+
223
+ If a behavior can only be checked by hand, add it to this list rather than
224
+ implying automated coverage.
225
+
226
+ ## Related
227
+
228
+ - [Develop KXM](development.md): the local gate and generated artifacts
229
+ - [Test matrix](test-matrix.md): which test proves which behavior
230
+ - [Write KXM documentation](writing-docs.md): doc gates and pinned paths
231
+ - [Upgrade KXM](../operations/upgrade.md): the operator side of a new version
@@ -0,0 +1,362 @@
1
+ # Develop KXM
2
+
3
+ Set up a source checkout, learn where each part of KXM lives, and run the same
4
+ gate CI runs before you push. This page is for contributors who change the CLI,
5
+ the [hub](../glossary.md#hub), the [Runtime](../glossary.md#runtime), the Pi
6
+ extension, the Claude Code plugin, or the bundled skills.
7
+
8
+ ## Before you begin
9
+
10
+ - Node.js 22.19 or newer on the 22 line, or Node.js 24 or newer. The
11
+ `engines` field in `package.json` is the authority.
12
+ - npm and Git.
13
+ - Optional tools, needed only for the matching task:
14
+ - [Pi](https://pi.dev) to load the extension from source.
15
+ - The Claude Code CLI to validate the plugin manifests locally.
16
+ - [`just`](https://github.com/casey/just) for the
17
+ [assignment runner](assignment-runner.md).
18
+ - Docker for the clean-container install smoke.
19
+
20
+ ## Set up a checkout
21
+
22
+ ```bash
23
+ git clone https://github.com/kontextmind/kxm.git
24
+ cd kxm
25
+ npm ci
26
+ node scripts/kxm.mjs --help
27
+ ```
28
+
29
+ `node scripts/kxm.mjs` is the `kxm` binary from `package.json` `bin`. It runs the
30
+ committed bundle `plugins/kxm/dist/cli.js`, not the TypeScript source. A source
31
+ change is invisible until you rebuild:
32
+
33
+ ```bash
34
+ npm run build
35
+ ```
36
+
37
+ Use `node scripts/kxm.mjs` wherever the user docs show `kxm`.
38
+
39
+ ### Keep experiments away from real state
40
+
41
+ A source build uses the same default hub (`http://127.0.0.1:7331`), user state
42
+ root, configuration and telemetry directories as an installed `kxm`. Point every
43
+ experiment at throwaway directories and a hub you start yourself on another
44
+ port:
45
+
46
+ ```bash
47
+ # Run in a scratch Git repository, not in your KXM checkout.
48
+ export KXM_STATE_HOME="$(mktemp -d)"
49
+ export KXM_USER_CONFIG_DIR="$(mktemp -d)"
50
+ export KXM_USER_TELEMETRY_DIR="$(mktemp -d)"
51
+ export KXM_PORT=47331
52
+ export KXM_SERVER_URL="http://127.0.0.1:$KXM_PORT"
53
+ node /path/to/kxm/scripts/kxm.mjs hub start
54
+ ```
55
+
56
+ In a second terminal with the same variables:
57
+
58
+ ```bash
59
+ node /path/to/kxm/scripts/kxm.mjs hub view
60
+ node /path/to/kxm/scripts/kxm.mjs hub stop
61
+ ```
62
+
63
+ Expected output of `hub view`:
64
+
65
+ ```text
66
+ hub health=true ready=true · loopback hub
67
+ ```
68
+
69
+ `KXM_STATE_HOME` must be an absolute path. The hub writes its database and logs
70
+ under `.kxm/` in the directory where you start it.
71
+
72
+ ### Load the Pi extension from source
73
+
74
+ Pi loads the TypeScript extension directly, so it needs no build step:
75
+
76
+ ```bash
77
+ pi --no-extensions -e ./plugins/kxm/src/extension.ts
78
+ ```
79
+
80
+ `--no-extensions` turns off Pi's package discovery, so only the listed extensions
81
+ load. Add another `-e` for each provider extension your models need.
82
+
83
+ ### Validate the Claude Code plugin
84
+
85
+ With the Claude Code CLI installed, run the same strict manifest validation as
86
+ CI. Validation reads the manifests only; the plugin itself runs the committed
87
+ `plugins/kxm/dist/mcp-server.js`, so rebuild before you try it in Claude Code.
88
+
89
+ ```bash
90
+ npm run validate:claude
91
+ ```
92
+
93
+ ## Repository layout
94
+
95
+ The tree below lists what is tracked in Git. Directories marked "not shipped" are
96
+ excluded from the npm package.
97
+
98
+ ```text
99
+ .
100
+ ├── plugins/kxm/ The product: CLI, hub, Runtime, Pi extension, MCP server
101
+ │ ├── src/ TypeScript source (cli/, context/, providers/ inside)
102
+ │ ├── dist/ Generated, committed bundles (see Generated artifacts)
103
+ │ ├── skills/ Bundled Agent Skills, one <name>/SKILL.md each
104
+ │ ├── skill-suite.json Skill manifest: names, paths, owned commands
105
+ │ ├── .claude-plugin/ Claude Code plugin manifest (plugin.json)
106
+ │ └── .mcp.json MCP server launch for the plugin
107
+ ├── .claude-plugin/ Claude marketplace catalog (marketplace.json)
108
+ ├── packages/core/tui/ @kontextmind/tui workspace package
109
+ ├── scripts/ kxm.mjs, hub and worker wrappers, build, release, runners
110
+ ├── schemas/ JSON Schemas for YAML resources, events and records
111
+ ├── docs/ User, operator and contributor documentation
112
+ ├── examples/ Runnable transport examples and project fixtures
113
+ ├── test/ core/, simulations/, fixtures/, helpers/ (not shipped)
114
+ ├── .kxm/ This repository's own KXM project definition
115
+ ├── .agents/skills/ Generated mirror of the bundled skills (not shipped)
116
+ ├── .github/ CI, release, issue and PR templates (not shipped)
117
+ ├── .claude/ Developer harness notes and commands (not shipped)
118
+ ├── plans/ Internal planning and tracking (not shipped)
119
+ ├── justfile Developer recipes for the assignment runner
120
+ └── AGENTS.md, CLAUDE.md, GEMINI.md Agent instructions with generated blocks
121
+ ```
122
+
123
+ The workspace layout for `packages/` is described in
124
+ [Packages and workspaces](packages.md). The `.kxm/` layout is described in
125
+ [`.kxm/README.md`](../../.kxm/README.md).
126
+
127
+ ## Packaging standards
128
+
129
+ KXM ships one product through four native package formats. Each format reads
130
+ its own manifest, and `npm run check:versions` keeps every version field equal.
131
+
132
+ ### npm package
133
+
134
+ `@kontextmind/kxm` is published publicly.
135
+
136
+ | Field | What it declares |
137
+ |---|---|
138
+ | `bin` | `kxm` → `scripts/kxm.mjs` |
139
+ | `exports` | `./core`, `./runtime`, `./client`, `./extension`, `./mcp` from `plugins/kxm/dist`, and `./tui` |
140
+ | `files` | `plugins/kxm/{dist,src,skills}`, `scripts`, `docs`, `examples`, `schemas`, the plugin manifests, and selected `.kxm` files |
141
+ | `engines` | Node `^22.19.0 \|\| >=24.0.0` |
142
+ | `peerDependencies` | Pi and `typebox`, both optional |
143
+
144
+ Everything under `docs/` ships in the tarball, so a link from `docs/` into
145
+ `plans/` is dead for npm readers. `.npmignore` drops logs, state and generated
146
+ assets even inside listed directories. Inspect the result with
147
+ `npm pack --dry-run`.
148
+
149
+ ### Claude Code plugin and marketplace
150
+
151
+ | File | Role |
152
+ |---|---|
153
+ | `.claude-plugin/marketplace.json` | Marketplace catalog; its `kxm` entry points at `./plugins/kxm` |
154
+ | `plugins/kxm/.claude-plugin/plugin.json` | Plugin manifest: `userConfig`, the `SessionStart` hook, the channel, and `mcpServers` |
155
+ | `plugins/kxm/.mcp.json` | Launches `dist/mcp-server.js` over stdio and maps `userConfig` to `KXM_*` variables |
156
+ | `plugins/kxm/dist/claude-hook.js` | The bundled, read-only `SessionStart` hook script |
157
+
158
+ A marketplace install clones the repository, so the plugin can use only committed
159
+ files. That is why the bundles in `dist/` are tracked. For what the plugin does,
160
+ see the [plugin README](../../plugins/kxm/README.md).
161
+
162
+ ### Pi package
163
+
164
+ The root `package.json` carries the `pi-package` keyword and a `pi` block:
165
+ `pi.extensions` lists `./plugins/kxm/src/extension.ts` and `pi.skills` lists
166
+ `./plugins/kxm/skills`. Pi loads the TypeScript source itself.
167
+
168
+ ### Agent Skills
169
+
170
+ Each bundled skill is a directory `plugins/kxm/skills/<name>/` with a `SKILL.md`.
171
+ `plugins/kxm/skill-suite.json` declares every skill and the top-level `kxm`
172
+ commands it owns. `test/core/skill-suite.test.ts` enforces the rules:
173
+
174
+ - The directory name equals the frontmatter `name` and the manifest `name`.
175
+ - The frontmatter parses as strict YAML. Quote any value that contains a colon followed by a space.
176
+ - The `description` is at most 1,024 characters.
177
+ - Every top-level `kxm` command is owned by exactly one skill.
178
+ - `.agents/skills/` matches the authored skills byte for byte.
179
+
180
+ For what each skill covers, see [Agent skills](../guides/agent-skills.md).
181
+
182
+ ## The development loop
183
+
184
+ 1. Branch from `main`. Keep one concern per branch and one clear concern per
185
+ commit.
186
+ 2. Change the source and the test that proves the change. Update
187
+ [the test matrix](test-matrix.md) when you add a behavior.
188
+ 3. Rebuild with `npm run build` when you touched anything that is bundled.
189
+ 4. Run the focused test file while you iterate (see
190
+ [Test conventions](#test-conventions)).
191
+ 5. Update the user docs and `CHANGELOG.md` (under `## Unreleased`) for any
192
+ user-visible change.
193
+ 6. Stage the source change together with the regenerated files. The commit gate
194
+ compares generated files with the staged copy.
195
+ 7. Run the commit gate, `npm run verify`, fix what it reports, then commit.
196
+ 8. Push and open a pull request. The template asks for the slice issue and the
197
+ `npm run verify` result.
198
+
199
+ Maintainers who delegate work to coding agents use the
200
+ [assignment runner](assignment-runner.md) for steps 2 to 7.
201
+
202
+ ## Generated artifacts
203
+
204
+ `npm run build` regenerates the files below. They are committed because the
205
+ Claude marketplace installs from Git and npm consumers install without dev
206
+ dependencies. Neither can run a build or strip TypeScript at install time.
207
+
208
+ | Artifact | Produced by | Consumers |
209
+ |---|---|---|
210
+ | `plugins/kxm/dist/cli.js`, `server.js`, `runtime-supervisor.js`, `claude-hook.js` | `scripts/build-runtime.mjs` | `kxm`, the hub, the Runtime supervisor, the plugin hook |
211
+ | `plugins/kxm/dist/core.js`, `runtime.js`, `client.js`, `extension.js` | `scripts/build-runtime.mjs` | The package `exports` |
212
+ | `plugins/kxm/dist/mcp-server.js` | `npm run build:mcp` | The Claude plugin and `@kontextmind/kxm/mcp` |
213
+ | `packages/core/tui/dist/index.js` | `npm run build:packages` | `@kontextmind/kxm/tui` |
214
+ | `.agents/skills/<name>/…` | `scripts/emit-codex-artifacts.mjs` | Harnesses that read `.agents/skills` |
215
+ | `AGENTS.md` block between the `kxm:codex:commands` markers | `scripts/emit-codex-artifacts.mjs` | Codex and other `AGENTS.md` readers |
216
+ | `AGENTS.md`, `CLAUDE.md`, `GEMINI.md` blocks between the `kxm:memory` markers | `syncHarnessMemory` (same as `kxm memory sync`) | Every harness, from `.kxm/memory/*.md` |
217
+
218
+ Never edit a generated file by hand. Edit its source and rebuild.
219
+
220
+ `npm run check:generated` rebuilds, then fails if any artifact is missing, not
221
+ tracked, or different from the staged copy. Stage the rebuilt files
222
+ (`git add plugins/kxm/dist packages/core/tui/dist .agents AGENTS.md CLAUDE.md GEMINI.md`)
223
+ before you run it.
224
+
225
+ ## The commit gate
226
+
227
+ Run `npm run verify` before every commit you push. It is the same gate for
228
+ people and for agents.
229
+
230
+ ```bash
231
+ npm run verify
232
+ ```
233
+
234
+ It runs three scripts in order:
235
+
236
+ | Step | Script | What it checks |
237
+ |---|---|---|
238
+ | 1 | `npm test` | Build, then `test/core/*.test.ts` and `packages/core/*/tests/unit/*.test.ts` |
239
+ | 2 | `npm run check` | `tsc --noEmit`, `markdownlint-cli2`, and version surfaces |
240
+ | 3 | `npm run check:generated` | Generated artifacts are tracked and match the staged copy |
241
+
242
+ Other scripts you will use:
243
+
244
+ | Script | Use it for |
245
+ |---|---|
246
+ | `npm run test:core` | The core suite only (CI runs a smaller contract set; see [CI and release](ci-and-release.md)) |
247
+ | `npm run test:simulations` | `test/simulations/*.test.ts` |
248
+ | `npm run test:coverage` | Core suite with coverage floors |
249
+ | `npm run test:coverage:complete` | Core plus simulations with the higher nightly floors |
250
+ | `npm run lint:docs` | Markdown lint only |
251
+ | `npm run validate:pr` | The three-minute CI gate; see [CI and release](ci-and-release.md) |
252
+ | `npm run validate:ci` | Coverage suite, `check` and a package dry run (not run by CI today) |
253
+ | `npm run validate:claude` | Strict Claude plugin and marketplace validation |
254
+
255
+ Plugin validation needs the Claude Code CLI, so it is a CI job rather than part
256
+ of `verify`. Do not add a third gate script: `test/core/ci-contract.test.ts`
257
+ refuses one.
258
+
259
+ ### Coverage floors
260
+
261
+ | Run | Lines | Branches | Functions |
262
+ |---|---:|---:|---:|
263
+ | `test:coverage:core` (pushes to `main`, releases) | 91% | 80% | 92% |
264
+ | `test:coverage:complete` (nightly) | 93% | 80% | 93% |
265
+
266
+ Coverage measures `plugins/kxm/src/**/*.ts` and `packages/core/*/src/**/*.ts`.
267
+ The floors only move up. A pull request may raise a floor. No pull request may
268
+ lower one: when coverage drops, add tests.
269
+
270
+ Three files are excluded because they run only as spawned bundles, so coverage
271
+ would attribute their lines to `dist`, never to the source. Each is exercised
272
+ as a child process instead:
273
+
274
+ - `plugins/kxm/src/server.ts`, the hub entry;
275
+ - `plugins/kxm/src/mcp-server.ts`, the MCP stdio entry;
276
+ - `plugins/kxm/src/runtime-supervisor.ts`, the Runtime supervisor entry.
277
+
278
+ An exclusion needs a reason other than "hard to test".
279
+
280
+ ## Test conventions
281
+
282
+ Tests use the built-in `node:test` runner and run TypeScript through
283
+ `--experimental-strip-types`. There is no Jest or Vitest.
284
+
285
+ ### Write one focused test per behavior
286
+
287
+ - Name each test after the behavior it proves, as a sentence. For example,
288
+ `"MCP server never registers with the persisted admin token"`.
289
+ - Assert the observable contract: an exit code, a JSON field, an error code, a
290
+ file on disk. Do not assert log wording unless the wording is the contract.
291
+ - Prove the refusal as well as the success. Fail-closed paths need their own test.
292
+ - Put the test next to its peers in `test/core/<area>.test.ts`, and add a row to
293
+ [the test matrix](test-matrix.md).
294
+
295
+ ### Run one file or one test
296
+
297
+ Build once, then run the file directly:
298
+
299
+ ```bash
300
+ npm run build
301
+ node --disable-warning=ExperimentalWarning --experimental-strip-types \
302
+ --test test/core/improve.test.ts
303
+ # Narrow to tests whose names match a pattern.
304
+ node --disable-warning=ExperimentalWarning --experimental-strip-types \
305
+ --test --test-name-pattern="same-ask" test/core/improve.test.ts
306
+ ```
307
+
308
+ Several suites spawn the built bundles, so a stale `dist` fails them. Rebuild
309
+ before you trust a failure.
310
+
311
+ ### Isolate all state
312
+
313
+ A test must never read or write the operator's hub, state root, configuration or
314
+ credentials. Use the shared helpers:
315
+
316
+ | Helper | What it isolates |
317
+ |---|---|
318
+ | `isolateSessionEnvironment()` in `test/helpers/session-env.ts` | Points `KXM_STATE_HOME` and `KXM_USER_CONFIG_DIR` at a temp directory and clears session tokens |
319
+ | `createTestMesh(context)` in `test/helpers.ts` | Starts an in-memory hub on port `0` with a test token, closed when the test ends |
320
+ | `committedKxmProject(prefix, …)` in `test/helpers/project.ts` | Creates a committed KXM project and a separate state root in temp directories |
321
+ | `test/helpers/harness-fake.ts` | Fake spawns and auth fixtures for `scripts/harness-run.mjs`, so no real harness or login is needed |
322
+
323
+ Other rules:
324
+
325
+ - Create files only under `mkdtempSync(join(tmpdir(), …))` and remove them when
326
+ the test ends.
327
+ - Bind servers to port `0`. Never assume `7331` is free.
328
+ - Make no network calls outside loopback, and never call a paid model. Real-model
329
+ checks are opt-in smoke tests (see [CI and release](ci-and-release.md#smoke-tests)).
330
+ - Tests must pass on Node 22.19 and Node 24.
331
+
332
+ ## Change the protocol
333
+
334
+ Routes, request fields, status transitions, delivery modes, limits and
335
+ authentication are the protocol. A change to any of them needs:
336
+
337
+ - integration tests;
338
+ - an update to `plugins/kxm/skills/kxm/references/protocol.md`;
339
+ - an update to the matching page in `docs/`;
340
+ - a `CHANGELOG.md` entry;
341
+ - a compatibility note when existing clients could break.
342
+
343
+ Prefer additive changes. KXM does not keep backward-compatible aliases for
344
+ retired names: an old name fails closed instead.
345
+
346
+ ## Troubleshooting
347
+
348
+ | Symptom | Cause | Fix |
349
+ |---|---|---|
350
+ | `generated artifacts changed after build` | `dist`, a skill mirror or a generated block differs from the index | Run `npm run build`, stage the listed files, rerun |
351
+ | `generated artifacts are not tracked by git` | A new bundle or skill file was never added | `git add` the listed paths |
352
+ | `… version … does not match …` from `check:versions` | A version surface was edited by hand | Revert it; releases stamp versions (see [CI and release](ci-and-release.md#versions)) |
353
+ | A doc test fails after a docs move | A test or code path reads that doc | See [pinned paths](writing-docs.md#pinned-paths) |
354
+ | A CLI change has no effect | `node scripts/kxm.mjs` runs the old bundle | `npm run build` |
355
+
356
+ ## Next steps
357
+
358
+ - Understand what CI runs on your pull request: [CI and release](ci-and-release.md)
359
+ - Write or update a docs page: [Write KXM documentation](writing-docs.md)
360
+ - Find the test that proves a behavior: [Test matrix](test-matrix.md)
361
+ - Add a workspace package: [Packages and workspaces](packages.md)
362
+ - Look up a command: [CLI reference](../reference/cli-reference.md)