@kontextmind/kxm 0.7.121 → 0.7.123
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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +18 -0
- package/docs/architecture/access-schema.yaml +60 -0
- package/docs/architecture/access.md +33 -0
- package/docs/architecture/agent-path.md +36 -0
- package/docs/architecture/authentication.md +29 -0
- package/docs/architecture/hosted-direction.md +59 -0
- package/docs/architecture/index.md +19 -0
- package/docs/architecture/inventory.md +38 -0
- package/docs/architecture/platform.md +48 -0
- package/docs/assets/logo.png +0 -0
- package/docs/contributing/assignment-runner.md +25 -22
- package/docs/guides/agent-skills.md +1 -1
- package/docs/index.md +56 -0
- package/docs/javascripts/mermaid-init.js +83 -0
- package/docs/javascripts/mermaid.min.js +4376 -0
- package/docs/reference/cli-reference.md +148 -3
- package/docs/robots.txt +44 -0
- package/docs/stylesheets/extra.css +100 -0
- package/package.json +1 -1
- package/plugins/kxm/.claude-plugin/plugin.json +1 -1
- package/plugins/kxm/dist/cli.js +418 -184
- package/plugins/kxm/dist/mcp-server.js +1 -1
- package/plugins/kxm/package.json +1 -1
- package/plugins/kxm/skills/kxm/SKILL.md +1 -1
- package/plugins/kxm/skills/kxm-runs/SKILL.md +16 -1
- package/plugins/kxm/src/cli/assign.ts +144 -0
- package/plugins/kxm/src/cli/docs.ts +78 -0
- package/plugins/kxm/src/cli.ts +85 -0
- package/plugins/kxm/src/mcp-server.ts +1 -1
- package/schemas/roadmap-state.schema.json +147 -0
package/CHANGELOG.md
CHANGED
|
@@ -14,6 +14,13 @@ All notable user-facing changes are documented here. The project follows [Semant
|
|
|
14
14
|
A required review is reported. The `land` workflow in `.kxm/workflows/land.yaml`
|
|
15
15
|
runs the same gates and may be refused until gate-only workflows are supported.
|
|
16
16
|
See the [CLI reference](docs/reference/cli-reference.md#kxm-land).
|
|
17
|
+
- **`kxm assign` is the entry to the developer assignment runner.**
|
|
18
|
+
`run`, `witness`, `plan-current`, `attribute`, `observe-cost`, `accept` and
|
|
19
|
+
`change-report` spawn `scripts/assignment-run.mjs` with the same flags as the
|
|
20
|
+
just recipes. The runner still performs every check and writes every file.
|
|
21
|
+
The just recipes stay until one real unit has been accepted through
|
|
22
|
+
`kxm assign`. See the
|
|
23
|
+
[CLI reference](docs/reference/cli-reference.md#kxm-assign).
|
|
17
24
|
|
|
18
25
|
- **`kxm lane` keeps one git worktree per unit beside the control checkout.**
|
|
19
26
|
`create`, `list`, `status`, `drop` and `run` store a 0600 record in
|
|
@@ -28,6 +35,17 @@ All notable user-facing changes are documented here. The project follows [Semant
|
|
|
28
35
|
limit lands. See the
|
|
29
36
|
[CLI reference](docs/reference/cli-reference.md#kxm-lane).
|
|
30
37
|
|
|
38
|
+
- **The tailnet docs site is built and served with `kxm docs build` and `kxm docs serve`.**
|
|
39
|
+
`kxm docs build` runs `node plans/kxm-roadmap/update-dashboard.mjs` from the
|
|
40
|
+
project root and returns its exit code. `kxm docs serve` runs
|
|
41
|
+
`python3 ops/docs-site/serve.py`, streams its output, and passes `--port`
|
|
42
|
+
through when it is set. Both refuse `project_required` outside a KXM project,
|
|
43
|
+
and `docs_generator_missing` or `docs_server_missing` when the file is absent.
|
|
44
|
+
`--dry-run` prints the command and starts nothing. The header wordmark is the
|
|
45
|
+
portal mark, and the slate palette uses `#0e0d0b`, `#3068da`, and `#f2eee7`.
|
|
46
|
+
`kxm docs build` validates the roadmap state file and refuses when it does not match the schema.
|
|
47
|
+
See the [CLI reference](docs/reference/cli-reference.md#kxm-docs).
|
|
48
|
+
|
|
31
49
|
- **Claude-only workflow recommendations now fail honestly when execution is unavailable.**
|
|
32
50
|
`suggest` honors explicit harness constraints, uses flat installable IDs and verified
|
|
33
51
|
capability-appropriate routes, refuses unchecked existing definitions, and never substitutes a
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
schema: kxm.access.v1
|
|
2
|
+
objects:
|
|
3
|
+
- kind: principal
|
|
4
|
+
id: writer
|
|
5
|
+
source: .kxm/roles/writer.yaml
|
|
6
|
+
enforced: false
|
|
7
|
+
note: Roster only. This file has no tools block. role.ts counts tools.allow and does not enforce it.
|
|
8
|
+
- kind: principal
|
|
9
|
+
id: planner
|
|
10
|
+
source: .kxm/roles/planner.yaml
|
|
11
|
+
enforced: false
|
|
12
|
+
note: Roster only. This file has no tools block.
|
|
13
|
+
- kind: principal
|
|
14
|
+
id: reviewer-arch
|
|
15
|
+
source: .kxm/roles/reviewer-arch.yaml
|
|
16
|
+
enforced: false
|
|
17
|
+
note: Roster only. This file has no tools block.
|
|
18
|
+
- kind: principal
|
|
19
|
+
id: reviewer-cli
|
|
20
|
+
source: .kxm/roles/reviewer-cli.yaml
|
|
21
|
+
enforced: false
|
|
22
|
+
note: Roster only. This file has no tools block.
|
|
23
|
+
- kind: group
|
|
24
|
+
id: writer
|
|
25
|
+
members: [writer]
|
|
26
|
+
enforced: false
|
|
27
|
+
note: Naming group only. No group object is enforced in code.
|
|
28
|
+
- kind: group
|
|
29
|
+
id: critics
|
|
30
|
+
members: [reviewer-arch, reviewer-cli]
|
|
31
|
+
enforced: false
|
|
32
|
+
note: Naming group only. No group object is enforced in code.
|
|
33
|
+
- kind: claim
|
|
34
|
+
id: edit
|
|
35
|
+
enforced: true
|
|
36
|
+
note: oneShotWriterArgs in plugins/kxm/src/harness.ts for pi, omp, and grok.
|
|
37
|
+
- kind: claim
|
|
38
|
+
id: read-only
|
|
39
|
+
enforced: true
|
|
40
|
+
note: oneShotReadOnlyArgs in plugins/kxm/src/harness.ts, and isToolAllowed in plugins/kxm/src/commands.ts when preset is read-only.
|
|
41
|
+
- kind: grant
|
|
42
|
+
id: coordinator
|
|
43
|
+
source: BUILTIN_TOOL_PRESETS
|
|
44
|
+
enforced: false
|
|
45
|
+
note: Accepted preset name in plugins/kxm/src/project-config.ts. isToolAllowed does not special-case it.
|
|
46
|
+
- kind: grant
|
|
47
|
+
id: read-only
|
|
48
|
+
source: BUILTIN_TOOL_PRESETS
|
|
49
|
+
enforced: true
|
|
50
|
+
note: Same read-only claim as above.
|
|
51
|
+
- kind: grant
|
|
52
|
+
id: workspace-writer
|
|
53
|
+
source: BUILTIN_TOOL_PRESETS
|
|
54
|
+
enforced: false
|
|
55
|
+
note: Accepted preset name. init-guide-setup.ts assigns it to a writer agent. isToolAllowed does not map it to a tool list.
|
|
56
|
+
- kind: grant
|
|
57
|
+
id: tests-writer
|
|
58
|
+
source: BUILTIN_TOOL_PRESETS
|
|
59
|
+
enforced: false
|
|
60
|
+
note: Accepted preset name. isToolAllowed does not special-case it.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Access
|
|
2
|
+
|
|
3
|
+
Read from `.kxm/roles/writer.yaml`, `.kxm/roles/planner.yaml`,
|
|
4
|
+
`.kxm/roles/reviewer-arch.yaml`, `.kxm/roles/reviewer-cli.yaml`,
|
|
5
|
+
`plugins/kxm/src/role.ts`, `plugins/kxm/src/commands.ts`,
|
|
6
|
+
`plugins/kxm/src/harness.ts`, and `plugins/kxm/src/project-config.ts`.
|
|
7
|
+
|
|
8
|
+
The four principals in this checkout are the role files under `.kxm/roles/`.
|
|
9
|
+
None of those files sets `tools`. `listRoles` in `plugins/kxm/src/role.ts`
|
|
10
|
+
sets `toolsCount` from `tools.allow.length` and does not apply the list.
|
|
11
|
+
`DEFAULT_ROLES` in the same file carries preset names such as `author` and
|
|
12
|
+
`read_only`. Those defaults are not the files in `.kxm/roles/`, and those
|
|
13
|
+
preset strings are not the `BUILTIN_TOOL_PRESETS` list.
|
|
14
|
+
|
|
15
|
+
`isToolAllowed` in `plugins/kxm/src/commands.ts` enforces `preset: read-only`
|
|
16
|
+
by denying mutating `kxm_*` tools. `oneShotReadOnlyArgs` and
|
|
17
|
+
`oneShotWriterArgs` in `plugins/kxm/src/harness.ts` are the harness argument
|
|
18
|
+
sets. Edit arguments exist for `pi`, `omp`, and `grok`. Other harnesses stay
|
|
19
|
+
on the read-only set. A live write step without an edit profile hands off
|
|
20
|
+
instead of spawning unconstrained (`unsupportedLiveWrite` in
|
|
21
|
+
`plugins/kxm/src/engine.ts`).
|
|
22
|
+
|
|
23
|
+
`BUILTIN_TOOL_PRESETS` in `plugins/kxm/src/project-config.ts` is
|
|
24
|
+
`coordinator`, `read-only`, `workspace-writer`, and `tests-writer`.
|
|
25
|
+
|
|
26
|
+
```yaml
|
|
27
|
+
--8<-- "architecture/access-schema.yaml"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Related
|
|
31
|
+
|
|
32
|
+
- [Authentication](authentication.md)
|
|
33
|
+
- [Agent path](agent-path.md)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Agent path
|
|
2
|
+
|
|
3
|
+
Read from `plugins/kxm/src/cli/project.ts`, `plugins/kxm/src/engine.ts`,
|
|
4
|
+
`plugins/kxm/src/worktree-witness.ts`, and `plugins/kxm/src/oneshot-producer.ts`.
|
|
5
|
+
|
|
6
|
+
`kxm run` resolves the project from the current directory and posts
|
|
7
|
+
`POST /v1/runs` to the Runtime supervisor (`cmdKxmRun`). The response names
|
|
8
|
+
`kxm runs drive <runId> --wait` as the next step. Drive posts
|
|
9
|
+
`POST /v1/runs/<runId>/drive` and later reads the drive receipt. The
|
|
10
|
+
supervisor's producer is the one-shot producer registered from
|
|
11
|
+
`plugins/kxm/src/oneshot-producer.ts`. Around a live spawn, the engine takes
|
|
12
|
+
a checkout fingerprint, invokes the producer, then fingerprints again
|
|
13
|
+
(`captureWorktreeWitness` and `applyAuthoringWitness`). A write step that
|
|
14
|
+
does not change the tree cannot stay `passed`. A read-only step that changes
|
|
15
|
+
the tree cannot stay `passed`.
|
|
16
|
+
|
|
17
|
+
```mermaid
|
|
18
|
+
sequenceDiagram
|
|
19
|
+
participant CLI as kxm CLI
|
|
20
|
+
participant Sup as Runtime supervisor
|
|
21
|
+
participant Eng as engine
|
|
22
|
+
participant Har as harness process
|
|
23
|
+
CLI->>Sup: "POST /v1/runs"
|
|
24
|
+
CLI->>Sup: "kxm runs drive"
|
|
25
|
+
Sup->>Eng: "producer dispatch"
|
|
26
|
+
Eng->>Eng: "fingerprint before spawn"
|
|
27
|
+
Eng->>Har: "one-shot harness"
|
|
28
|
+
Har-->>Eng: "producer result"
|
|
29
|
+
Eng->>Eng: "fingerprint after spawn"
|
|
30
|
+
Eng-->>CLI: "drive receipt"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Related
|
|
34
|
+
|
|
35
|
+
- [Platform](platform.md)
|
|
36
|
+
- [First workflow](../start/first-workflow.md)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Authentication
|
|
2
|
+
|
|
3
|
+
Read from `plugins/kxm/src/harness.ts` and `plugins/kxm/src/cli.ts`.
|
|
4
|
+
|
|
5
|
+
`kxm harness list` runs `probeHarnesses` (`cmdHarnessList` in
|
|
6
|
+
`plugins/kxm/src/cli/project.ts`). For each detected harness that has
|
|
7
|
+
`authArgs`, `probeEntry` runs that command and `interpretAuth` reads the
|
|
8
|
+
output. KXM does not store provider credentials. The probe only classifies
|
|
9
|
+
the harness command's own stdout.
|
|
10
|
+
|
|
11
|
+
| Harness | Probe command | Logged-in signal in this file |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| Pi | no `authArgs` on the catalog entry | `authenticated` stays null with `auth_context_required`. A separate assignment probe can run `pi auth check`. |
|
|
14
|
+
| Claude | `auth status` | JSON `loggedIn: true`, method `claude.ai` or `api-key` |
|
|
15
|
+
| Codex | `login status` | `Logged in using ChatGPT` or `Logged in using an API key` |
|
|
16
|
+
| Grok | `models` | exact line `You are logged in with grok.com.` |
|
|
17
|
+
| Kimi | `provider list` | a line containing `managed:kimi`, `type=kimi`, or `Default model:` |
|
|
18
|
+
| agy | `models` | a model row matched by `AGY_MODEL_ROW`, method `antigravity-oauth` |
|
|
19
|
+
| omp | `models --json` | success, and a non-empty `models` array when JSON parses |
|
|
20
|
+
| deepseek | no `authArgs` | `authenticated` stays null with `auth_unknown` |
|
|
21
|
+
|
|
22
|
+
`kxm auth` in `plugins/kxm/src/cli.ts` is `kxm auth token`. It inspects,
|
|
23
|
+
issues, or clears the local session token file. That token is a KXM session
|
|
24
|
+
token, not a provider key. Provider logins stay in each harness.
|
|
25
|
+
|
|
26
|
+
## Related
|
|
27
|
+
|
|
28
|
+
- [Access](access.md)
|
|
29
|
+
- [Harness routing](../reference/harness-routing.md)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Hosted direction
|
|
2
|
+
|
|
3
|
+
Target. This page is a direction, not a live deployment.
|
|
4
|
+
|
|
5
|
+
Read from `plans/plan-per-tenant-hosting.md`. `plans/plan-greenfield-infra.md`
|
|
6
|
+
is not in this checkout.
|
|
7
|
+
|
|
8
|
+
```mermaid
|
|
9
|
+
flowchart LR
|
|
10
|
+
titleNode["Target: hosted direction, not a live deployment"]
|
|
11
|
+
tenant["one box per tenant"]
|
|
12
|
+
edge["edge identity in front"]
|
|
13
|
+
portal["portal backend"]
|
|
14
|
+
hub["loopback hub"]
|
|
15
|
+
store["SQLite hub store"]
|
|
16
|
+
titleNode --> tenant
|
|
17
|
+
edge --> portal
|
|
18
|
+
portal --> hub
|
|
19
|
+
hub --> store
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Per-tenant hosting plan
|
|
23
|
+
|
|
24
|
+
`plans/plan-per-tenant-hosting.md` frontmatter says `status: "draft"` and
|
|
25
|
+
`blocked_by: []`.
|
|
26
|
+
|
|
27
|
+
The file's own summary says it is the rationale and boundary for hosting KXM
|
|
28
|
+
beside the portal: one tenant per box, Authentik at the edge, existing
|
|
29
|
+
static-token auth unchanged, hub state stays SQLite, and the portal backend
|
|
30
|
+
is the hosted client of the loopback hub. It says delivery order lives only
|
|
31
|
+
in the implementation tracker and that this file keeps no schedule.
|
|
32
|
+
|
|
33
|
+
The four decisions in that file, in its words:
|
|
34
|
+
|
|
35
|
+
1. Tenancy is the machine.
|
|
36
|
+
2. Auth stays exactly as it is. Hosting is additive.
|
|
37
|
+
3. Authentik owns the browser. The portal backend is the hub's client.
|
|
38
|
+
4. No PostgreSQL for the hub. If one is ever needed, one database per hub.
|
|
39
|
+
|
|
40
|
+
The file says none of the delivery is scheduled there. The ordered queue is
|
|
41
|
+
the tracker's Still open section. The tracker records S0 through S4 as
|
|
42
|
+
delivered and S5 as still open on interactive login. That disagreement is a
|
|
43
|
+
roadmap question. The tracker wins.
|
|
44
|
+
|
|
45
|
+
## Greenfield infra plan
|
|
46
|
+
|
|
47
|
+
`plans/plan-greenfield-infra.md` is not observed from this checkout. Its
|
|
48
|
+
`status` and `blocked_by` are not observed from this checkout.
|
|
49
|
+
|
|
50
|
+
The tracker names that file. The sentences that can be repeated without a
|
|
51
|
+
hostname, an account name, or a secret are: a first move is recorded as
|
|
52
|
+
installed, Postgres and Temporal are described as loopback only, KXM does not
|
|
53
|
+
write those stores, Redis Streams, NATS, raw WebSockets, and the A2A Python
|
|
54
|
+
SDK stay backlog, there is no S3, and the SQLite write path is unchanged.
|
|
55
|
+
|
|
56
|
+
## Related
|
|
57
|
+
|
|
58
|
+
- [Roadmap](../roadmap/dashboard.md)
|
|
59
|
+
- [SQLite ADR](../adr/ADR-0003-sqlite-only-store.md)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
Read from `plans/kxm-roadmap/state.json` and the pages linked below.
|
|
4
|
+
|
|
5
|
+
Verified date: null. A review pass has not set `architecture.verified`.
|
|
6
|
+
|
|
7
|
+
| Page | What it covers |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| [Platform](platform.md) | Local-first processes and how they connect |
|
|
10
|
+
| [Surfaces](inventory.md) | Executables, listeners, and the stores they own |
|
|
11
|
+
| [Access](access.md) | Roles, claims, and tool presets observed in code |
|
|
12
|
+
| [Authentication](authentication.md) | How harness login is probed, and where credentials are not stored |
|
|
13
|
+
| [Agent path](agent-path.md) | `kxm run` through the drive receipt |
|
|
14
|
+
| [Hosted direction](hosted-direction.md) | Target only. Not a live deployment |
|
|
15
|
+
|
|
16
|
+
## Related
|
|
17
|
+
|
|
18
|
+
- [Roadmap](../roadmap/dashboard.md)
|
|
19
|
+
- [Trust model](../concepts/trust-model.md)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Surfaces
|
|
2
|
+
|
|
3
|
+
Read from `plugins/kxm/src/cli.ts`, `scripts/kxm-hub.mjs`, `plugins/kxm/src/hub.ts`,
|
|
4
|
+
`plugins/kxm/src/runtime-supervisor.ts`, `plugins/kxm/src/runtime-paths.ts`,
|
|
5
|
+
`plugins/kxm/src/mcp-server.ts`, `plugins/kxm/src/oneshot-producer.ts`,
|
|
6
|
+
`plugins/kxm/src/studio-layout.ts`, `plugins/kxm/src/cli/types.ts`
|
|
7
|
+
(`workspaceDirs`), `plugins/kxm/src/local-snapshot.ts`, and
|
|
8
|
+
`scripts/kxm-worker.mjs`.
|
|
9
|
+
|
|
10
|
+
| Surface | Started by | Listener or path | Store it owns | Defining file |
|
|
11
|
+
| --- | --- | --- | --- | --- |
|
|
12
|
+
| `kxm` CLI | `node scripts/kxm.mjs` or the installed bin | no listener | none | `plugins/kxm/src/cli.ts` |
|
|
13
|
+
| Hub | `kxm hub start` via `scripts/kxm-hub.mjs` | `127.0.0.1:7331` | `.kxm/state/kxm.db` under the workspace state dir | `plugins/kxm/src/hub.ts` |
|
|
14
|
+
| Hub credentials | written when the hub starts | `hub-env.json` under the user state root | that JSON file, not SQLite | `plugins/kxm/src/hub-env.ts` |
|
|
15
|
+
| Runtime supervisor | `kxm runtime` / `scripts/kxm-runtime-supervisor.mjs` | `127.0.0.1` and the requested port, or ephemeral | registry and event stores below | `plugins/kxm/src/runtime-supervisor.ts` |
|
|
16
|
+
| Runtime registry | opened by the supervisor | `runtime/registry.db` under the user state root | `registry.db` | `plugins/kxm/src/runtime-paths.ts` |
|
|
17
|
+
| Runtime event store | opened by the supervisor | `runtime/projects/<key>/run-events.db` | `run-events.db` | `plugins/kxm/src/runtime-paths.ts` |
|
|
18
|
+
| MCP server | Claude plugin or stdio launch | stdio | none | `plugins/kxm/src/mcp-server.ts` |
|
|
19
|
+
| One-shot harness | supervisor producer | child process, no listener | none | `plugins/kxm/src/oneshot-producer.ts` |
|
|
20
|
+
| Pi worker | `kxm agent worker` | no HTTP listener in `scripts/kxm-worker.mjs` | none of its own | `scripts/kxm-worker.mjs` |
|
|
21
|
+
| Studio | `kxm studio serve` | `127.0.0.1:4242` | none | `plugins/kxm/src/studio-layout.ts` |
|
|
22
|
+
| Workspace config | `workspaceDirs` | `.kxm/config`, or `KXM_CONFIG_DIR` | files in that directory | `plugins/kxm/src/cli/types.ts` |
|
|
23
|
+
| Workspace logs | `workspaceDirs` | `.kxm/logs`, or `KXM_LOGS_DIR` | log files | `plugins/kxm/src/cli/types.ts` |
|
|
24
|
+
| Workspace assets | `workspaceDirs` | `.kxm/assets`, or `KXM_ASSETS_DIR` | asset files | `plugins/kxm/src/cli/types.ts` |
|
|
25
|
+
| Workspace state | `workspaceDirs` | `.kxm/state`, or `KXM_STATE_DIR` | `kxm.db` when the hub uses this directory | `plugins/kxm/src/cli/types.ts` |
|
|
26
|
+
|
|
27
|
+
On macOS the user state root is `Library/Application Support/KXM` under the
|
|
28
|
+
home directory (`kxmUserStateRoot` in `plugins/kxm/src/bindings.ts`). Windows
|
|
29
|
+
uses `AppData/Local/KXM`. Other platforms use `$XDG_STATE_HOME/kxm` or
|
|
30
|
+
`.local/state/kxm`. `KXM_STATE_HOME` overrides that root when it is absolute.
|
|
31
|
+
The tracker mentions `docs/operations.md` for the six backup roots. That file
|
|
32
|
+
is not in this checkout. The six roots are described in
|
|
33
|
+
[Backup and restore](../operations/backup-and-restore.md).
|
|
34
|
+
|
|
35
|
+
## Related
|
|
36
|
+
|
|
37
|
+
- [Platform](platform.md)
|
|
38
|
+
- [Backup and restore](../operations/backup-and-restore.md)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Platform
|
|
2
|
+
|
|
3
|
+
Read from `plugins/kxm/src/cli.ts`, `plugins/kxm/src/runtime-supervisor.ts`,
|
|
4
|
+
`scripts/kxm-hub.mjs`, `plugins/kxm/src/hub.ts`, `plugins/kxm/src/mcp-server.ts`,
|
|
5
|
+
and `plugins/kxm/src/oneshot-producer.ts`.
|
|
6
|
+
|
|
7
|
+
KXM on this checkout is local-first. The `kxm` CLI is the operator entry
|
|
8
|
+
(`plugins/kxm/src/cli.ts`, launched through `scripts/kxm.mjs`). The hub is an
|
|
9
|
+
HTTP server started by `scripts/kxm-hub.mjs`, which loads
|
|
10
|
+
`plugins/kxm/dist/server.js`. `createHub` defaults the listener to
|
|
11
|
+
`127.0.0.1` and port `7331` (`plugins/kxm/src/hub.ts`, `DEFAULT_PORT` in
|
|
12
|
+
`plugins/kxm/src/protocol.ts`). The Runtime supervisor
|
|
13
|
+
(`plugins/kxm/src/runtime-supervisor.ts`) listens on `127.0.0.1`. Its port
|
|
14
|
+
defaults to `0`, so the kernel picks an ephemeral port unless a port is
|
|
15
|
+
requested. The MCP server (`plugins/kxm/src/mcp-server.ts`) uses
|
|
16
|
+
`StdioServerTransport`. It has no TCP listener. It calls the hub at
|
|
17
|
+
`KXM_SERVER_URL` or `http://127.0.0.1:7331`. One-shot harness calls are
|
|
18
|
+
spawned by the producer registered in `plugins/kxm/src/oneshot-producer.ts`.
|
|
19
|
+
That child process is not a listener.
|
|
20
|
+
|
|
21
|
+
```mermaid
|
|
22
|
+
flowchart LR
|
|
23
|
+
cli["kxm CLI"]
|
|
24
|
+
hub["hub"]
|
|
25
|
+
sup["Runtime supervisor"]
|
|
26
|
+
mcp["MCP server"]
|
|
27
|
+
shot["one-shot harness"]
|
|
28
|
+
cli -->|"kxm hub start"| hub
|
|
29
|
+
mcp -->|"HTTP to hub"| hub
|
|
30
|
+
cli -->|"kxm run"| sup
|
|
31
|
+
sup -->|"spawn producer"| shot
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Listeners
|
|
35
|
+
|
|
36
|
+
| Route | Listener |
|
|
37
|
+
| --- | --- |
|
|
38
|
+
| Hub HTTP | `127.0.0.1:7331` unless host or port is overridden |
|
|
39
|
+
| Supervisor HTTP | `127.0.0.1` and an ephemeral port when the requested port is `0` |
|
|
40
|
+
| MCP | stdio, no TCP port |
|
|
41
|
+
| CLI and one-shot harness | no listener |
|
|
42
|
+
| Studio, when served | `127.0.0.1:4242` from `createStudioServer` in `plugins/kxm/src/studio-layout.ts` |
|
|
43
|
+
| Antigravity OAuth callback | loopback port `51121` only during login (`plugins/kxm/src/providers/antigravity/auth/oauth.ts`) |
|
|
44
|
+
|
|
45
|
+
## Related
|
|
46
|
+
|
|
47
|
+
- [Surfaces](inventory.md)
|
|
48
|
+
- [Agent path](agent-path.md)
|
|
Binary file
|
|
@@ -19,9 +19,9 @@ a KXM product feature.
|
|
|
19
19
|
`origin/main`. The runner loads `.kxm/roster.yaml` only from there.
|
|
20
20
|
- A separate worktree for the writer. `kxm lane create <unit>` creates one from
|
|
21
21
|
`origin/main`.
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
- The harness CLIs the roster admits, installed and logged in.
|
|
23
|
+
`node scripts/kxm.mjs harness list` shows which are. The loop below is
|
|
24
|
+
`kxm assign`. `just` still runs the transport recipes.
|
|
25
25
|
- A task directory whose final path segment equals the task ID. Every path you
|
|
26
26
|
pass to the runner must be absolute.
|
|
27
27
|
|
|
@@ -80,10 +80,12 @@ Use this slim loop for daily work and for docs. The 13-step `fix` workflow in
|
|
|
80
80
|
`examples/project/` is a product fixture, not the developer loop.
|
|
81
81
|
|
|
82
82
|
> [!NOTE]
|
|
83
|
-
>
|
|
83
|
+
> `kxm assign` never loads a `.env` file from the working directory. An
|
|
84
84
|
> unreviewed file could otherwise set `NODE_OPTIONS` and run code before the
|
|
85
|
-
> runner validates anything.
|
|
86
|
-
>
|
|
85
|
+
> runner validates anything. The process environment is passed through as it
|
|
86
|
+
> is. Export any variable you need before the command.
|
|
87
|
+
|
|
88
|
+
The seven `just` assignment recipes remain available and will be removed after one real unit has been accepted through `kxm assign`; until then both forms are equivalent because both call `scripts/assignment-run.mjs` unchanged.
|
|
87
89
|
|
|
88
90
|
### 1. Pin the current plan
|
|
89
91
|
|
|
@@ -91,7 +93,7 @@ Every writer assignment binds to the current plan. Stamp the pointer, or advance
|
|
|
91
93
|
it with a generation check:
|
|
92
94
|
|
|
93
95
|
```bash
|
|
94
|
-
|
|
96
|
+
kxm assign plan-current --task-dir /abs/task-dir --plan /abs/plan.md --sha256 <sha256> --base-commit <base-commit> --expected-generation <expected-generation>
|
|
95
97
|
```
|
|
96
98
|
|
|
97
99
|
The runner writes `plan-current.json` (`kxm.plan-pointer.v1`) in the task
|
|
@@ -137,7 +139,7 @@ Optional keys are `rework_of`, `timeout_ms` and `max_turns`. Each `inputs`
|
|
|
137
139
|
entry is `{ "path", "sha256" }`, and the runner checks the hash. Dispatch it:
|
|
138
140
|
|
|
139
141
|
```bash
|
|
140
|
-
|
|
142
|
+
kxm assign run --manifest /abs/tasks/fix-improve-sources/asg-writer-1.json
|
|
141
143
|
```
|
|
142
144
|
|
|
143
145
|
The runner validates the manifest, the route and the base, writes
|
|
@@ -151,7 +153,7 @@ generated files, then run the witness:
|
|
|
151
153
|
|
|
152
154
|
```bash
|
|
153
155
|
git -C /abs/kxm-fix-improve-sources add -A
|
|
154
|
-
|
|
156
|
+
kxm assign witness --record-dir /abs/tasks/fix-improve-sources/asg-writer-1
|
|
155
157
|
```
|
|
156
158
|
|
|
157
159
|
The witness refuses with `dirty_baseline` while anything is unstaged or
|
|
@@ -185,17 +187,18 @@ witnessed tree: either the staged index (`base.kind: "staged"` with its
|
|
|
185
187
|
Commit the exact witnessed tree, then bind the commit and both `PASS` records:
|
|
186
188
|
|
|
187
189
|
```bash
|
|
188
|
-
|
|
189
|
-
/abs/tasks/fix-improve-sources
|
|
190
|
-
|
|
191
|
-
/abs/tasks/fix-improve-sources/asg-
|
|
190
|
+
kxm assign accept \
|
|
191
|
+
--task-dir /abs/tasks/fix-improve-sources \
|
|
192
|
+
--commit <commit-sha> \
|
|
193
|
+
--record-dir /abs/tasks/fix-improve-sources/asg-writer-1 \
|
|
194
|
+
--critic /abs/tasks/fix-improve-sources/asg-review-arch-1 \
|
|
195
|
+
--critic /abs/tasks/fix-improve-sources/asg-review-cli-1
|
|
192
196
|
```
|
|
193
197
|
|
|
194
|
-
To record an observed pull request or CI run,
|
|
195
|
-
the recipe does not pass those flags:
|
|
198
|
+
To record an observed pull request or CI run, pass the same flags:
|
|
196
199
|
|
|
197
200
|
```bash
|
|
198
|
-
|
|
201
|
+
kxm assign accept \
|
|
199
202
|
--task-dir /abs/tasks/fix-improve-sources \
|
|
200
203
|
--commit <commit-sha> \
|
|
201
204
|
--record-dir /abs/tasks/fix-improve-sources/asg-writer-1 \
|
|
@@ -205,7 +208,7 @@ node scripts/assignment-run.mjs accept \
|
|
|
205
208
|
--observed-ci <ci-id>
|
|
206
209
|
```
|
|
207
210
|
|
|
208
|
-
`accept` prints JSON and takes no `--json` flag.
|
|
211
|
+
`accept` prints JSON and takes no `--json` flag, and `kxm assign --json` is not passed through. The runner checks, in order, that:
|
|
209
212
|
|
|
210
213
|
1. the trusted roster policy loads and validates, before anything is written;
|
|
211
214
|
2. the commit exists and its tree equals the witnessed tree;
|
|
@@ -226,7 +229,7 @@ You decide, then dispatch:
|
|
|
226
229
|
1. Write a new manifest with `"kind": "repair"` and `"rework_of"` set to the
|
|
227
230
|
assignment ID it reworks. The runner checks that the earlier assignment has a
|
|
228
231
|
`completion.json` in the same task directory, with the same task ID.
|
|
229
|
-
2. Dispatch it with `
|
|
232
|
+
2. Dispatch it with `kxm assign run`, then run `kxm assign witness` on the new record.
|
|
230
233
|
3. Dispatch fresh critics against the new tree, and accept.
|
|
231
234
|
|
|
232
235
|
A `BLOCK` stops acceptance only for the tree it judged. A repair that changes
|
|
@@ -266,7 +269,7 @@ Record friction or a model regression as a private note, without touching any
|
|
|
266
269
|
completion:
|
|
267
270
|
|
|
268
271
|
```bash
|
|
269
|
-
|
|
272
|
+
kxm assign attribute --task-dir /abs/task-dir --record-dir /abs/record-dir --class <class> --explanation-file /abs/note.txt
|
|
270
273
|
```
|
|
271
274
|
|
|
272
275
|
The class is `orchestration`, `model`, `environment` or `unclassified`. Each
|
|
@@ -277,7 +280,7 @@ Import a cost observation for a run whose native telemetry was not captured,
|
|
|
277
280
|
such as a subscription session:
|
|
278
281
|
|
|
279
282
|
```bash
|
|
280
|
-
|
|
283
|
+
kxm assign observe-cost --task-dir /abs/task-dir --input /abs/observation.json
|
|
281
284
|
```
|
|
282
285
|
|
|
283
286
|
The record (`kxm.cost-observation.v1`) is cost-only. It cannot mint witness
|
|
@@ -286,7 +289,7 @@ proof or authorize acceptance.
|
|
|
286
289
|
Summarize a task's attempts, rework and spend:
|
|
287
290
|
|
|
288
291
|
```bash
|
|
289
|
-
|
|
292
|
+
kxm assign change-report --task-dir /abs/task-dir
|
|
290
293
|
```
|
|
291
294
|
|
|
292
295
|
The report (`kxm.change-report.v1`) keeps provider-reported spend, list-price
|
|
@@ -356,7 +359,7 @@ ones:
|
|
|
356
359
|
|---|---|---|
|
|
357
360
|
| `route_invalid` | Route not in the role's lineup, permission above its ceiling, or the roster policy cannot load | Run from a clean control checkout on `origin/main`; check the lineup |
|
|
358
361
|
| `base_invalid` | `base.commit` is not `HEAD`, the tree is dirty, or a writer targets a staged index | Commit or stash elsewhere; writers need a clean base |
|
|
359
|
-
| `plan_ref_invalid` | The plan hash or path does not match `plan-current.json` | Advance the pointer with `
|
|
362
|
+
| `plan_ref_invalid` | The plan hash or path does not match `plan-current.json` | Advance the pointer with `kxm assign plan-current` |
|
|
360
363
|
| `rework_invalid` | `rework_of` names no completed assignment in this task | Point it at an existing record directory's assignment ID |
|
|
361
364
|
| `witness_failed` | The fixed gate exited non-zero | Fix the failures and run a repair |
|
|
362
365
|
| `dirty_baseline` | Unstaged or untracked changes when the witness starts | Stage the candidate with `git add -A`, then re-witness |
|
|
@@ -58,7 +58,7 @@ Every top-level `kxm` command is owned by exactly one skill. A skill can own sev
|
|
|
58
58
|
| `kxm-peer` | `peer` | Delegate to, fan out to, await and answer other agents |
|
|
59
59
|
| `kxm-workflow` | `workflow`, `gate` | Record journal entries, pass checkpoints and wait on signed callbacks |
|
|
60
60
|
| `kxm-definitions` | `role` | Inspect or edit roles, role hosts and model rosters without granting writer admission |
|
|
61
|
-
| `kxm-runs` | `run`, `runs`, `lane` | Create, drive, inspect and cancel runs, manage worktree lanes,
|
|
61
|
+
| `kxm-runs` | `run`, `runs`, `lane`, `assign` | Create, drive, inspect and cancel runs, manage worktree lanes, smoke-test a workflow, or call the assignment runner |
|
|
62
62
|
| `kxm-context-memory` | `context`, `memory`, `explain` | Recall what the project knows, explain a context footprint, record memory candidates |
|
|
63
63
|
| `kxm-skill-lifecycle` | `skills` | Turn a repeated practice into a governed skill candidate |
|
|
64
64
|
| `kxm-routing-improve` | `routing`, `improve` | Find what KXM learned and what repeats, and read recorded route spend |
|
package/docs/index.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# KXM
|
|
2
|
+
|
|
3
|
+
Pages in this site are generated from this checkout. The roadmap is the
|
|
4
|
+
tracker. Architecture pages name the files they were read from.
|
|
5
|
+
|
|
6
|
+
<div class="grid cards" markdown>
|
|
7
|
+
|
|
8
|
+
- [Roadmap](roadmap/dashboard.md)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Next phase, open tasks, blockers, and questions.
|
|
13
|
+
|
|
14
|
+
- [Architecture](architecture/index.md)
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
Platform, surfaces, access, authentication, the agent path, and the hosted target.
|
|
19
|
+
|
|
20
|
+
- [Start](start/install.md)
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
Install the `kxm` CLI and run a first workflow.
|
|
25
|
+
|
|
26
|
+
- [Concepts](concepts/architecture.md)
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
How the local Runtime and the hub fit together.
|
|
31
|
+
|
|
32
|
+
- [Guides](guides/peer-messaging.md)
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
Peer messaging, workers, workflows, context, and browser sessions.
|
|
37
|
+
|
|
38
|
+
- [Reference](reference/cli-reference.md)
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
Commands, configuration, tools, contracts, and templates.
|
|
43
|
+
|
|
44
|
+
- [Operations](operations/backup-and-restore.md)
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
Backup, deploy, monitoring, sync, and upgrade.
|
|
49
|
+
|
|
50
|
+
- [Contributing](contributing/development.md)
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
Development, tests, and the glossary.
|
|
55
|
+
|
|
56
|
+
</div>
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
(function () {
|
|
2
|
+
function addButton(node) {
|
|
3
|
+
var parent = node.parentElement;
|
|
4
|
+
if (parent && parent.classList.contains("kxm-diagram")) return parent;
|
|
5
|
+
var wrap = document.createElement("div");
|
|
6
|
+
wrap.className = "kxm-diagram";
|
|
7
|
+
node.parentNode.insertBefore(wrap, node);
|
|
8
|
+
wrap.appendChild(node);
|
|
9
|
+
var button = document.createElement("button");
|
|
10
|
+
button.type = "button";
|
|
11
|
+
button.className = "kxm-fs";
|
|
12
|
+
button.textContent = "Full screen";
|
|
13
|
+
button.addEventListener("click", function () {
|
|
14
|
+
if (typeof wrap.requestFullscreen === "function") {
|
|
15
|
+
if (document.fullscreenElement === wrap) {
|
|
16
|
+
document.exitFullscreen();
|
|
17
|
+
} else {
|
|
18
|
+
wrap.requestFullscreen();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
wrap.classList.toggle("kxm-fs-open");
|
|
22
|
+
});
|
|
23
|
+
wrap.appendChild(button);
|
|
24
|
+
return wrap;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function boot() {
|
|
28
|
+
var nodes = Array.prototype.filter.call(document.querySelectorAll(".mermaid"), function (node) {
|
|
29
|
+
if (node.getAttribute("data-kxm-mermaid") === "1") return false;
|
|
30
|
+
node.setAttribute("data-kxm-mermaid", "1");
|
|
31
|
+
addButton(node);
|
|
32
|
+
return true;
|
|
33
|
+
});
|
|
34
|
+
if (window.mermaid && !window.__kxmMermaidReady) {
|
|
35
|
+
window.mermaid.initialize({
|
|
36
|
+
startOnLoad: false,
|
|
37
|
+
securityLevel: "strict",
|
|
38
|
+
theme: "base",
|
|
39
|
+
themeVariables: {
|
|
40
|
+
darkMode: true,
|
|
41
|
+
background: "#0e0d0b",
|
|
42
|
+
primaryColor: "#3068da",
|
|
43
|
+
primaryTextColor: "#f2eee7",
|
|
44
|
+
primaryBorderColor: "#3068da",
|
|
45
|
+
secondaryColor: "#0e0d0b",
|
|
46
|
+
secondaryTextColor: "#f2eee7",
|
|
47
|
+
secondaryBorderColor: "#3068da",
|
|
48
|
+
tertiaryColor: "#0e0d0b",
|
|
49
|
+
tertiaryTextColor: "#f2eee7",
|
|
50
|
+
tertiaryBorderColor: "#3068da",
|
|
51
|
+
lineColor: "#3068da",
|
|
52
|
+
textColor: "#f2eee7",
|
|
53
|
+
mainBkg: "#0e0d0b",
|
|
54
|
+
nodeBorder: "#3068da",
|
|
55
|
+
clusterBkg: "#0e0d0b",
|
|
56
|
+
titleColor: "#f2eee7",
|
|
57
|
+
edgeLabelBackground: "#0e0d0b",
|
|
58
|
+
actorBorder: "#3068da",
|
|
59
|
+
actorBkg: "#0e0d0b",
|
|
60
|
+
actorTextColor: "#f2eee7",
|
|
61
|
+
signalColor: "#3068da",
|
|
62
|
+
signalTextColor: "#f2eee7",
|
|
63
|
+
noteBkgColor: "#0e0d0b",
|
|
64
|
+
noteTextColor: "#f2eee7",
|
|
65
|
+
noteBorderColor: "#3068da",
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
window.__kxmMermaidReady = true;
|
|
69
|
+
}
|
|
70
|
+
var pending = window.mermaid && nodes.length
|
|
71
|
+
? window.mermaid.run({ nodes: nodes, suppressErrors: true })
|
|
72
|
+
: Promise.resolve();
|
|
73
|
+
Promise.resolve(pending).then(function () {
|
|
74
|
+
nodes.forEach(addButton);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (window.document$ && typeof window.document$.subscribe === "function") {
|
|
79
|
+
window.document$.subscribe(boot);
|
|
80
|
+
} else {
|
|
81
|
+
document.addEventListener("DOMContentLoaded", boot);
|
|
82
|
+
}
|
|
83
|
+
})();
|