@kontextmind/kxm 0.6.0 → 0.7.10
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/.kxm/agents/coordinator.yaml +9 -0
- package/.kxm/agents/critic-arch.yaml +13 -0
- package/.kxm/agents/critic-cli.yaml +13 -0
- package/.kxm/agents/implementer.yaml +13 -0
- package/.kxm/gates.yaml +8 -0
- package/.kxm/producers.yaml +22 -0
- package/.kxm/project.yaml +15 -0
- package/.kxm/roles/writer.yaml +7 -0
- package/.kxm/workflows/default.yaml +47 -0
- package/CHANGELOG.md +39 -7
- package/README.md +1 -0
- package/docs/README.md +5 -0
- package/docs/adr/ADR-0002-browser-automation-steel-doks.md +103 -0
- package/docs/agent-skills.md +135 -0
- package/docs/architecture.md +1 -1
- package/docs/assignment-runner.md +21 -8
- package/docs/browser-automation.md +116 -0
- package/docs/configuration.md +11 -2
- package/docs/getting-started.md +21 -0
- package/docs/kb/how-credentials-retrieved-safely.md +31 -0
- package/docs/kb/how-to-capture-and-annotate-section.md +60 -0
- package/docs/kb/how-to-connect-playwright-to-steel.md +54 -0
- package/docs/kb/how-to-recover-expired-session-or-orphan.md +54 -0
- package/docs/kb/how-to-resume-after-mfa.md +28 -0
- package/docs/kb/how-to-take-over-session.md +32 -0
- package/docs/kb/why-authentication-disappeared.md +32 -0
- package/docs/kb/why-automation-opened-different-browser.md +32 -0
- package/docs/kb/why-session-viewer-cannot-control.md +31 -0
- package/docs/kxm-handbook.md +3 -3
- package/docs/operations.md +24 -0
- package/docs/operator-pi-packages.md +63 -0
- package/docs/prompts/browser-annotate-feedback.md +41 -0
- package/docs/prompts/browser-diagnose-recover.md +38 -0
- package/docs/prompts/browser-explore.md +42 -0
- package/docs/prompts/browser-repro-fix.md +48 -0
- package/docs/prompts/browser-start.md +41 -0
- package/docs/prompts/browser-takeover.md +50 -0
- package/docs/skills/repo-work-delivery.md +107 -0
- package/docs/skills.md +2 -0
- package/docs/test-matrix.md +4 -3
- package/docs/troubleshooting.md +41 -1
- package/docs/vnext/validation.md +9 -0
- package/docs/webhook-workflows.md +2 -2
- package/examples/README.md +1 -1
- package/package.json +16 -17
- package/plugins/kxm/.claude-plugin/plugin.json +1 -1
- package/plugins/kxm/README.md +1 -1
- package/plugins/kxm/dist/cli.js +41620 -35578
- package/plugins/kxm/dist/core.js +271 -34
- package/plugins/kxm/dist/extension.js +7759 -86
- package/plugins/kxm/dist/mcp-server.js +75 -21
- package/plugins/kxm/dist/runtime.js +8218 -2328
- package/plugins/kxm/dist/server.js +3125 -2260
- package/plugins/kxm/dist/vnext-runtime-supervisor.js +5961 -661
- package/plugins/kxm/package.json +1 -1
- package/plugins/kxm/skills/SUITE.md +5 -0
- package/plugins/kxm/skills/hints.json +103 -0
- package/plugins/kxm/skills/kxm/SKILL.md +30 -83
- package/plugins/kxm/skills/kxm-browser-annotate/SKILL.md +90 -0
- package/plugins/kxm/skills/kxm-browser-auth/SKILL.md +47 -0
- package/plugins/kxm/skills/kxm-browser-diagnostics/SKILL.md +48 -0
- package/plugins/kxm/skills/kxm-browser-explore/SKILL.md +48 -0
- package/plugins/kxm/skills/kxm-browser-session/SKILL.md +94 -0
- package/plugins/kxm/skills/kxm-browser-takeover/SKILL.md +87 -0
- package/plugins/kxm/skills/kxm-browser-verify/SKILL.md +71 -0
- package/plugins/kxm/skills/kxm-context-memory/SKILL.md +69 -0
- package/plugins/kxm/skills/kxm-definitions/SKILL.md +65 -0
- package/plugins/kxm/skills/kxm-harness-auth/SKILL.md +34 -0
- package/plugins/kxm/skills/kxm-harvest/SKILL.md +48 -0
- package/plugins/kxm/skills/kxm-hub-ops/SKILL.md +43 -0
- package/plugins/kxm/skills/kxm-insights/SKILL.md +48 -0
- package/plugins/kxm/skills/kxm-mind/SKILL.md +59 -0
- package/plugins/kxm/skills/kxm-peer/SKILL.md +110 -0
- package/plugins/kxm/skills/kxm-project-setup/SKILL.md +42 -0
- package/plugins/kxm/skills/kxm-projects/SKILL.md +43 -0
- package/plugins/kxm/skills/kxm-protocol/SKILL.md +66 -0
- package/plugins/kxm/skills/kxm-query/SKILL.md +45 -0
- package/plugins/kxm/skills/kxm-routing-improve/SKILL.md +30 -0
- package/plugins/kxm/skills/kxm-runs/SKILL.md +29 -0
- package/plugins/kxm/skills/kxm-setup/SKILL.md +55 -0
- package/plugins/kxm/skills/kxm-skill-lifecycle/SKILL.md +31 -0
- package/plugins/kxm/skills/kxm-tasks/SKILL.md +33 -0
- package/plugins/kxm/skills/kxm-triage/SKILL.md +47 -0
- package/plugins/kxm/skills/kxm-work/SKILL.md +44 -0
- package/plugins/kxm/skills/kxm-workflow/SKILL.md +45 -0
- package/plugins/kxm/src/autocomplete.ts +9 -3
- package/plugins/kxm/src/browser.ts +603 -0
- package/plugins/kxm/src/cli/context-skills.ts +373 -0
- package/plugins/kxm/src/cli/hub.ts +614 -0
- package/plugins/kxm/src/cli/roles.ts +615 -0
- package/plugins/kxm/src/cli/system.ts +906 -0
- package/plugins/kxm/src/cli/tasks.ts +364 -0
- package/plugins/kxm/src/cli/types.ts +270 -0
- package/plugins/kxm/src/cli/vnext.ts +698 -0
- package/plugins/kxm/src/cli/workflows.ts +699 -0
- package/plugins/kxm/src/cli.ts +362 -2849
- package/plugins/kxm/src/commands.ts +150 -8
- package/plugins/kxm/src/completion-install.ts +223 -0
- package/plugins/kxm/src/config.ts +7 -4
- package/plugins/kxm/src/context-packet.ts +172 -0
- package/plugins/kxm/src/database.ts +1 -1
- package/plugins/kxm/src/extension.ts +36 -1
- package/plugins/kxm/src/external-effects.ts +357 -8
- package/plugins/kxm/src/hub-env.ts +193 -0
- package/plugins/kxm/src/hub.ts +2 -4
- package/plugins/kxm/src/improve.ts +72 -0
- package/plugins/kxm/src/init-guide-setup.ts +547 -0
- package/plugins/kxm/src/local-snapshot.ts +1 -1
- package/plugins/kxm/src/mcp-server.ts +1 -1
- package/plugins/kxm/src/model-inventory.ts +127 -0
- package/plugins/kxm/src/modes.ts +348 -0
- package/plugins/kxm/src/policy-draft.d.mts +55 -0
- package/plugins/kxm/src/policy-draft.mjs +565 -0
- package/plugins/kxm/src/price-calc.ts +17 -18
- package/plugins/kxm/src/prices.ts +32 -16
- package/plugins/kxm/src/producers.ts +71 -0
- package/plugins/kxm/src/protocol.ts +111 -0
- package/plugins/kxm/src/restricted-yaml.d.mts +31 -0
- package/plugins/kxm/src/restricted-yaml.mjs +145 -0
- package/plugins/kxm/src/role.ts +710 -0
- package/plugins/kxm/src/routing.ts +99 -1
- package/plugins/kxm/src/runtime.ts +4 -0
- package/plugins/kxm/src/safety-integrity.ts +76 -0
- package/plugins/kxm/src/session-work.ts +9 -2
- package/plugins/kxm/src/sqlite.ts +76 -0
- package/plugins/kxm/src/ssh-remote.ts +560 -0
- package/plugins/kxm/src/store.ts +1 -1
- package/plugins/kxm/src/studio-layout.ts +660 -17
- package/plugins/kxm/src/subagent-control.ts +312 -0
- package/plugins/kxm/src/suggest.ts +7 -13
- package/plugins/kxm/src/telemetry.ts +82 -0
- package/plugins/kxm/src/tui.ts +140 -0
- package/plugins/kxm/src/vnext-bindings.ts +1 -1
- package/plugins/kxm/src/vnext-config.ts +53 -111
- package/plugins/kxm/src/vnext-engine-command.ts +2 -0
- package/plugins/kxm/src/vnext-engine.ts +214 -62
- package/plugins/kxm/src/vnext-harness.ts +336 -84
- package/plugins/kxm/src/vnext-oneshot-evidence.ts +117 -0
- package/plugins/kxm/src/vnext-oneshot-process.ts +187 -0
- package/plugins/kxm/src/vnext-oneshot-producer.ts +182 -224
- package/plugins/kxm/src/vnext-pi-producer.ts +11 -7
- package/plugins/kxm/src/vnext-runtime-store.ts +36 -2
- package/plugins/kxm/src/vnext-runtime-supervisor.ts +122 -5
- package/plugins/kxm/src/vnext-runtime.ts +14 -0
- package/plugins/kxm/src/workflow-manager.ts +392 -0
- package/plugins/kxm/src/workflow-tui.ts +255 -0
- package/plugins/kxm/src/workflow.ts +144 -0
- package/schemas/policy-draft/README.md +17 -0
- package/schemas/policy-draft/model.v2.schema.json +140 -0
- package/schemas/policy-draft/role.v2.schema.json +91 -0
- package/schemas/vnext/modes.schema.json +56 -0
- package/schemas/vnext/role.schema.json +76 -0
- package/schemas/vnext/run-event.schema.json +1 -0
- package/scripts/assignment-run.d.mts +1 -1
- package/scripts/assignment-run.mjs +44 -35
- package/scripts/check-generated.mjs +33 -9
- package/scripts/emit-codex-artifacts.mjs +255 -11
- package/scripts/harness-run.d.mts +12 -4
- package/scripts/harness-run.mjs +65 -17
- package/scripts/kxm-bump-version.mjs +146 -0
- package/scripts/kxm-hub.mjs +150 -2
- package/scripts/kxm-publish-npm.mjs +3 -1
- package/scripts/kxm-release-github.mjs +3 -1
- package/scripts/kxm.mjs +0 -0
- package/scripts/native-critic.d.mts +5 -0
- package/scripts/native-critic.mjs +60 -0
- package/.kxm/config/README.md +0 -5
- package/.kxm/config/agents.json +0 -43
- package/.kxm/config/env.example +0 -56
- package/.kxm/config/update.example.yaml +0 -9
- package/.kxm/config/workflows/fix.json +0 -160
- package/.kxm/config/workflows/jira-development.json +0 -116
- package/.kxm/config/workflows/provenance-quorum.json +0 -150
- package/.kxm/config/workflows/v04-dogfood.json +0 -72
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema: "kxm.doc.v1"
|
|
3
|
+
id: "GUIDE-BROWSER-001"
|
|
4
|
+
type: "guide"
|
|
5
|
+
title: "KXM Browser Automation Guide"
|
|
6
|
+
project: "kxm"
|
|
7
|
+
status: "accepted"
|
|
8
|
+
owner: "@operator"
|
|
9
|
+
created: "2026-09-14"
|
|
10
|
+
updated: "2026-09-14"
|
|
11
|
+
authority: "instruction"
|
|
12
|
+
confidence: "verified"
|
|
13
|
+
summary: "Comprehensive guide to browser automation in KXM using self-hosted Steel on DOKS, agent-browser, Playwright, pass-cli, and human takeover."
|
|
14
|
+
tags: ["browser", "automation", "steel", "playwright", "agent-browser", "doks"]
|
|
15
|
+
related: ["docs/adr/ADR-0002-browser-automation-steel-doks.md", "docs/agent-skills.md"]
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# KXM Browser Automation Guide
|
|
19
|
+
|
|
20
|
+
This guide describes how to use KXM's browser automation capability powered by self-hosted Steel on DigitalOcean Kubernetes (DOKS), `agent-browser` for exploratory inspection, `Playwright` for automated regression testing, and `pass-cli` for credential security.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 1. Architecture & Trust Boundaries
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
Herdr / Pi / Agent Harness
|
|
28
|
+
│
|
|
29
|
+
├──► KXM Browser Skills & Prompts (kxm-browser-*)
|
|
30
|
+
│
|
|
31
|
+
├──► pass-cli (Authoritative Vault: "AI Provider Keys")
|
|
32
|
+
│
|
|
33
|
+
├──► agent-browser (Exploratory CLI) ──┐
|
|
34
|
+
│ │ (CDP WebSocket)
|
|
35
|
+
├──► Playwright (E2E Test Suites) ────┼──► DOKS Steel Browser Cluster
|
|
36
|
+
│ │ (https://steel.kontextmind.com)
|
|
37
|
+
└──► Human Operator (Takeover UI) ─────┘ (https://steel.kontextmind.com/ui)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Key Components
|
|
41
|
+
|
|
42
|
+
1. **Steel on DOKS (`https://steel.kontextmind.com`)**:
|
|
43
|
+
- Primary browser execution environment.
|
|
44
|
+
- Isolated Chromium containers with dedicated shared memory (`/dev/shm`).
|
|
45
|
+
- Exposed endpoints: REST API (port 443 / 3000), CDP WebSocket proxy (port 443 / 9223), Web UI (`/ui`), OpenAPI docs (`/documentation`).
|
|
46
|
+
2. **`pass-cli`**:
|
|
47
|
+
- The authoritative store for all long-lived passwords, session tokens, and the `STEEL_API_KEY`.
|
|
48
|
+
- Never write credentials to tracked git files.
|
|
49
|
+
3. **`agent-browser`**:
|
|
50
|
+
- Fast, token-efficient terminal CLI for accessibility snapshots, interactive navigation, and exploratory testing.
|
|
51
|
+
4. **`Playwright`**:
|
|
52
|
+
- High-fidelity assertion engine for bug reproduction, visual proofs, and permanent regression suites.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 2. Getting Started: The First Browser Workflow
|
|
57
|
+
|
|
58
|
+
### Step 1: Verify Prerequisites
|
|
59
|
+
|
|
60
|
+
Check that `pass-cli` can access the Steel configuration:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pass-cli item view --vault-name "AI Provider Keys" --item-title "Steel Browser (KontextMind DOKS)"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Step 2: Launch a Steel Browser Session
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
STEEL_KEY=$(pass-cli item view --vault-name "AI Provider Keys" --item-title "Steel Browser (KontextMind DOKS)" --field STEEL_API_KEY)
|
|
70
|
+
|
|
71
|
+
# Create a 5-minute session
|
|
72
|
+
SESSION_RESP=$(curl -s -X POST https://steel.kontextmind.com/v1/sessions \
|
|
73
|
+
-H "Content-Type: application/json" \
|
|
74
|
+
-H "x-steel-api-key: $STEEL_KEY" \
|
|
75
|
+
-d '{"timeout": 300000}')
|
|
76
|
+
|
|
77
|
+
SESSION_ID=$(echo "$SESSION_RESP" | jq -r .id)
|
|
78
|
+
echo "Session created: $SESSION_ID"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Step 3: Run Exploratory Automation or Scrapes
|
|
82
|
+
|
|
83
|
+
To run a fast scrape without managing sessions:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
curl -s -X POST https://steel.kontextmind.com/v1/scrape \
|
|
87
|
+
-H "Content-Type: application/json" \
|
|
88
|
+
-H "x-steel-api-key: $STEEL_KEY" \
|
|
89
|
+
-d '{"url": "https://example.com"}'
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Step 4: Release the Session
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
curl -s -X POST https://steel.kontextmind.com/v1/sessions/$SESSION_ID/release \
|
|
96
|
+
-H "x-steel-api-key: $STEEL_KEY"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 3. Human Takeover Protocol
|
|
102
|
+
|
|
103
|
+
When authentication challenges (MFA, CAPTCHA, SSO) are encountered:
|
|
104
|
+
|
|
105
|
+
1. **Agent Pauses**: The agent stops automated actions and sets state to `HUMAN_CONTROL`.
|
|
106
|
+
2. **Emits Link**: Emits the protected URL: `https://steel.kontextmind.com/ui?sessionId=<SESSION_ID>`.
|
|
107
|
+
3. **Human Interacts**: The operator opens the session viewer, completes the login/MFA action, and confirms in the terminal (`auth complete`).
|
|
108
|
+
4. **Agent Verifies**: The agent inspects the resulting page, confirms dashboard/user state, refreshes DOM observations, and returns to `AGENT_CONTROL`.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## 4. Resource Controls & Cost Safety
|
|
113
|
+
|
|
114
|
+
- **Session Timeouts**: Default 300s (5m), max 1800s (30m). Sessions terminate automatically on expiry.
|
|
115
|
+
- **Orphan Sweeping**: Periodically sweep untracked sessions via `GET /v1/sessions` and release idle processes.
|
|
116
|
+
- **Memory Protection**: Kubernetes mounts a 2Gi `emptyDir` memory volume at `/dev/shm` to prevent Chromium tab crashes without exhausting node memory.
|
package/docs/configuration.md
CHANGED
|
@@ -74,6 +74,15 @@ rewrites it.
|
|
|
74
74
|
|
|
75
75
|
The hub refuses a non-loopback bind without `KXM_AUTH_TOKEN`. Use a long random administrative token even when project tokens are configured, because administrative endpoints such as `/metrics` require it outside loopback.
|
|
76
76
|
|
|
77
|
+
When `KXM_AUTH_TOKEN` is unset, `kxm hub start` resolves credentials from the
|
|
78
|
+
persisted `kxm.hub-env.v1` file under the user state root
|
|
79
|
+
(`~/.local/state/kxm/hub-env.json`; honors `KXM_STATE_HOME` and platform
|
|
80
|
+
equivalents). A missing admin token is generated once, persisted with `0600`
|
|
81
|
+
permissions, and reused across hub restarts so workers and dashboards on the
|
|
82
|
+
same machine share one stable credential. Explicit `KXM_AUTH_TOKEN` or
|
|
83
|
+
`KXM_PROJECT_TOKENS` environment values take precedence and are persisted for
|
|
84
|
+
later restarts. Delete the file and restart to rotate the generated token.
|
|
85
|
+
|
|
77
86
|
Project tokens are an authorization boundary. A project-specific token can register only in its mapped project and see only that project's agents and messages. The administrative token remains a fallback for projects without an explicit entry. For provenance-gated workflows, configure an explicit project token and give workers only that token; reserve a distinct administrative token for operations such as quorum degradation approval.
|
|
78
87
|
|
|
79
88
|
PowerShell example:
|
|
@@ -269,7 +278,7 @@ Global flags: `--json`, `--dry-run`, `--workspace`. Project-root `kxm init` disc
|
|
|
269
278
|
|
|
270
279
|
Configure either `KXM_WEBHOOK_WORKFLOWS` or `KXM_WEBHOOK_WORKFLOWS_FILE`, never both. A definition selects a provider source, project, coordinator, event and payload filters, prompt template, and ordered stages. Use `secretEnv` to resolve the workflow-start HMAC secret from another environment variable. Use the optional `signalSecretEnv` for a separate callback secret; otherwise external signals use the workflow-start secret. Do not store either secret in JSON.
|
|
271
280
|
|
|
272
|
-
See [Webhook workflows](webhook-workflows.md) for the base schema and the complete Jira configuration under `.kxm/
|
|
281
|
+
See [Webhook workflows](webhook-workflows.md) for the base schema and the complete Jira configuration under `.kxm/workflows`. See [Peer provenance and quorum gates](provenance-gates.md) for `evidencePolicies`, `workflowContext`, `evidenceRefs`, and explicit degradation.
|
|
273
282
|
|
|
274
283
|
## Delivery modes
|
|
275
284
|
|
|
@@ -279,7 +288,7 @@ See [Webhook workflows](webhook-workflows.md) for the base schema and the comple
|
|
|
279
288
|
| `steer` | An active blocker requires a course change | Deliver at the next decision boundary |
|
|
280
289
|
| `nextTurn` | Information should wait for a later turn | Queue context without immediate work |
|
|
281
290
|
|
|
282
|
-
`followUp` is the safe default.
|
|
291
|
+
`followUp` is the safe default. Load values through your shell, supervisor, container platform, or secret manager using the variables documented on this page and in the [KXM Handbook](kxm-handbook.md). Never commit real tokens.
|
|
283
292
|
|
|
284
293
|
## Nous providers (opt-in)
|
|
285
294
|
|
package/docs/getting-started.md
CHANGED
|
@@ -61,6 +61,27 @@ kxm init
|
|
|
61
61
|
|
|
62
62
|
`kxm init` never copies the package repository's dogfood roster or workflows into a consumer workspace.
|
|
63
63
|
|
|
64
|
+
When `kxm init` succeeds in an interactive terminal, it offers to install shell
|
|
65
|
+
completion for the detected shell. Accepting writes the completion script
|
|
66
|
+
under the user config directory, appends one idempotent stanza to the shell
|
|
67
|
+
rc file, and, when the kxm bin directory is not already on `PATH`, adds a
|
|
68
|
+
`PATH` export. Declining is safe: run `kxm completion install` later, or set
|
|
69
|
+
`KXM_SKIP_COMPLETION_PROMPT=1` to suppress the offer. Non-interactive,
|
|
70
|
+
`--json`, and `--dry-run` runs never prompt or write shell files.
|
|
71
|
+
|
|
72
|
+
After the completion offer, an interactive `kxm init` also offers to set up
|
|
73
|
+
workflow-guide agents and workflows for the harnesses you have installed and
|
|
74
|
+
authenticated. Accepting lists the software-engineering workflows from
|
|
75
|
+
[`workflow-guide.md`](workflow-guide.md); pick by number or slug (`all` works
|
|
76
|
+
too). kxm resolves each role's first guide candidate whose harness is
|
|
77
|
+
authenticated and writes only current vNext project resources —
|
|
78
|
+
`.kxm/agents/<role>.yaml` (`kxm.agent.v1`) and `.kxm/workflows/<slug>.yaml`
|
|
79
|
+
(`kxm.workflow.v1`). It never writes retired legacy authority (`.kxm/config`,
|
|
80
|
+
`.kxm/roster.json`). Roles whose candidates have no authenticated harness are
|
|
81
|
+
reported as skipped, not silently downgraded. Guide candidates are dated
|
|
82
|
+
research — verify them before dispatch. Declining is safe: set
|
|
83
|
+
`KXM_SKIP_GUIDE_SETUP_PROMPT=1` to suppress the offer.
|
|
84
|
+
|
|
64
85
|
## 3. Start the hub in another terminal
|
|
65
86
|
|
|
66
87
|
`kxm hub start` is foreground. Keep that terminal running.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema: "kxm.doc.v1"
|
|
3
|
+
id: "KB-BROWSER-003"
|
|
4
|
+
type: "kb"
|
|
5
|
+
title: "How are credentials retrieved without exposing them to the model?"
|
|
6
|
+
project: "kxm"
|
|
7
|
+
status: "accepted"
|
|
8
|
+
owner: "@operator"
|
|
9
|
+
created: "2026-09-14"
|
|
10
|
+
updated: "2026-09-14"
|
|
11
|
+
authority: "instruction"
|
|
12
|
+
confidence: "verified"
|
|
13
|
+
summary: "Explains safe pass-cli credential delivery and environment piping patterns that avoid LLM context leakage."
|
|
14
|
+
tags: ["browser", "credentials", "pass-cli", "security"]
|
|
15
|
+
related: ["docs/browser-automation.md", "docs/agent-skills.md"]
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# How are credentials retrieved without exposing them to the model?
|
|
19
|
+
|
|
20
|
+
To protect passwords, MFA secrets, and API tokens from leaking into model reasoning traces, KXM enforces strict credential-reference boundaries:
|
|
21
|
+
|
|
22
|
+
## Mechanisms
|
|
23
|
+
|
|
24
|
+
1. **Authoritative Store**: All secrets reside in `pass-cli` (Proton Pass).
|
|
25
|
+
2. **In-Process Environment Piping**:
|
|
26
|
+
- Automated test scripts use `pass-cli run -- npm test` or retrieve credentials directly into child process memory via standard environment variables.
|
|
27
|
+
- The LLM prompt only receives credential references (e.g., `vault: "AI Provider Keys", item: "Steel Browser (KontextMind DOKS)"`), never raw secret values.
|
|
28
|
+
3. **Log Sanitization**:
|
|
29
|
+
- The KXM browser client strips API keys and token parameters (`apiKey=[REDACTED]`, `steel_[REDACTED]`) before logging or emitting outputs.
|
|
30
|
+
4. **Human Handoff for High-Privilege Auth**:
|
|
31
|
+
- For sensitive production accounts or MFA, the agent never touches the credential at all; it invokes `kxm-browser-takeover` and lets the human authenticate directly in the UI.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema: "kxm.doc.v1"
|
|
3
|
+
id: "KB-BROWSER-009"
|
|
4
|
+
type: "kb"
|
|
5
|
+
title: "How do I capture a UI section and annotate changes for an agent?"
|
|
6
|
+
project: "kxm"
|
|
7
|
+
status: "accepted"
|
|
8
|
+
owner: "@operator"
|
|
9
|
+
created: "2026-09-14"
|
|
10
|
+
updated: "2026-09-14"
|
|
11
|
+
authority: "instruction"
|
|
12
|
+
confidence: "verified"
|
|
13
|
+
summary: "Guide to capturing specific DOM elements, attaching visual annotations, and submitting structured change feedback to the agent."
|
|
14
|
+
tags: ["browser", "annotation", "screenshot", "feedback", "ui"]
|
|
15
|
+
related: ["docs/browser-automation.md", "docs/prompts/browser-annotate-feedback.md"]
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# How do I capture a UI section and annotate changes for an agent?
|
|
19
|
+
|
|
20
|
+
When reviewing a web interface in a Steel session, you can isolate a specific component, attach annotations, and deliver structured change requests directly back to an agent.
|
|
21
|
+
|
|
22
|
+
## Workflow
|
|
23
|
+
|
|
24
|
+
1. **Capture the Component**:
|
|
25
|
+
Use Playwright element screenshotting to crop only the affected container:
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
await page.locator('.billing-card').screenshot({ path: '.kxm/artifacts/browser/billing-card.png' });
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
2. **Draft the Annotation Feedback**:
|
|
32
|
+
Record the target selector, observed issues, and required fixes:
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { createAnnotationFeedback, formatAnnotationFeedbackPrompt } from "@kontextmind/kxm/runtime";
|
|
36
|
+
|
|
37
|
+
const feedback = createAnnotationFeedback({
|
|
38
|
+
url: "https://app.example.com/settings/billing",
|
|
39
|
+
sectionSelector: ".billing-card",
|
|
40
|
+
screenshotPath: ".kxm/artifacts/browser/billing-card.png",
|
|
41
|
+
overallSummary: "Billing tier layout breaks on mobile viewport",
|
|
42
|
+
annotations: [
|
|
43
|
+
{
|
|
44
|
+
label: "Tier Name Overflow",
|
|
45
|
+
selector: ".tier-title",
|
|
46
|
+
note: "Truncate or wrap long tier titles with ellipsis",
|
|
47
|
+
severity: "fix"
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
requestedChanges: [
|
|
51
|
+
"Update `.tier-title` CSS to include `truncate` or `break-words`",
|
|
52
|
+
"Adjust padding on small viewports to `px-4`"
|
|
53
|
+
]
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const prompt = formatAnnotationFeedbackPrompt(feedback);
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
3. **Send to the Agent**:
|
|
60
|
+
Feed the rendered prompt into the agent session or KXM workflow run. The agent reads the screenshot, navigates to the source code, applies the changes, and verifies the result with Playwright.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema: "kxm.doc.v1"
|
|
3
|
+
id: "KB-BROWSER-007"
|
|
4
|
+
type: "kb"
|
|
5
|
+
title: "How do I connect Playwright to the existing Steel session?"
|
|
6
|
+
project: "kxm"
|
|
7
|
+
status: "accepted"
|
|
8
|
+
owner: "@operator"
|
|
9
|
+
created: "2026-09-14"
|
|
10
|
+
updated: "2026-09-14"
|
|
11
|
+
authority: "instruction"
|
|
12
|
+
confidence: "verified"
|
|
13
|
+
summary: "Guide to attaching Playwright tests to an active remote Steel browser session using chromium.connectOverCDP()."
|
|
14
|
+
tags: ["browser", "playwright", "cdp", "steel", "testing"]
|
|
15
|
+
related: ["docs/browser-automation.md", "docs/kb/why-automation-opened-different-browser.md"]
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# How do I connect Playwright to the existing Steel session?
|
|
19
|
+
|
|
20
|
+
To run Playwright tests against self-hosted Steel on DOKS instead of a local browser:
|
|
21
|
+
|
|
22
|
+
## 1. Retrieve the CDP Endpoint
|
|
23
|
+
|
|
24
|
+
Format the WebSocket CDP URL using the active session ID and API key:
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { formatCDPEndpoint, resolveSteelConfig } from "@kontextmind/kxm/runtime";
|
|
28
|
+
|
|
29
|
+
const config = resolveSteelConfig();
|
|
30
|
+
const cdpUrl = formatCDPEndpoint({ id: sessionId, websocketUrl: "" }, config);
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The resulting URL will look like:
|
|
34
|
+
`wss://steel.kontextmind.com/v1/devtools?sessionId=<SESSION_ID>&apiKey=<STEEL_API_KEY>`
|
|
35
|
+
|
|
36
|
+
## 2. Connect in Playwright
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { test, expect, chromium } from "@playwright/test";
|
|
40
|
+
|
|
41
|
+
test("execute test on remote steel session", async () => {
|
|
42
|
+
const browser = await chromium.connectOverCDP(process.env.STEEL_CDP_URL!);
|
|
43
|
+
|
|
44
|
+
// Use existing context or create one
|
|
45
|
+
const context = browser.contexts()[0] || await browser.newContext();
|
|
46
|
+
const page = context.pages()[0] || await context.newPage();
|
|
47
|
+
|
|
48
|
+
await page.goto("https://app.example.com");
|
|
49
|
+
await expect(page.getByRole("heading", { level: 1 })).toBeVisible();
|
|
50
|
+
|
|
51
|
+
// Disconnecting closes the Playwright CDP socket without terminating the remote container
|
|
52
|
+
await browser.close();
|
|
53
|
+
});
|
|
54
|
+
```
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema: "kxm.doc.v1"
|
|
3
|
+
id: "KB-BROWSER-008"
|
|
4
|
+
type: "kb"
|
|
5
|
+
title: "How do I recover an expired session or remove an orphaned browser?"
|
|
6
|
+
project: "kxm"
|
|
7
|
+
status: "accepted"
|
|
8
|
+
owner: "@operator"
|
|
9
|
+
created: "2026-09-14"
|
|
10
|
+
updated: "2026-09-14"
|
|
11
|
+
authority: "instruction"
|
|
12
|
+
confidence: "verified"
|
|
13
|
+
summary: "Procedures for detecting and releasing stale or orphaned browser sessions on Steel."
|
|
14
|
+
tags: ["browser", "cleanup", "orphans", "troubleshooting"]
|
|
15
|
+
related: ["docs/browser-automation.md", "docs/kb/why-authentication-disappeared.md"]
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# How do I recover an expired session or remove an orphaned browser?
|
|
19
|
+
|
|
20
|
+
If an automation run crashed or disconnected without calling `/release`, a browser container may remain idling on DOKS.
|
|
21
|
+
|
|
22
|
+
## 1. List Active Remote Sessions
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
STEEL_KEY=$(pass-cli item view --vault-name "AI Provider Keys" --item-title "Steel Browser (KontextMind DOKS)" --field STEEL_API_KEY)
|
|
26
|
+
|
|
27
|
+
curl -s https://steel.kontextmind.com/v1/sessions \
|
|
28
|
+
-H "x-steel-api-key: $STEEL_KEY" | jq .
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 2. Release Orphaned Sessions
|
|
32
|
+
|
|
33
|
+
To terminate a specific stale session:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
curl -s -X POST https://steel.kontextmind.com/v1/sessions/<SESSION_ID>/release \
|
|
37
|
+
-H "x-steel-api-key: $STEEL_KEY"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 3. Automatic Orphan Sweeping via KXM Client
|
|
41
|
+
|
|
42
|
+
The KXM client provides `checkOrphanedSessions(maxIdleMs)` to automate this:
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { SteelClient } from "@kontextmind/kxm/runtime";
|
|
46
|
+
|
|
47
|
+
const client = new SteelClient();
|
|
48
|
+
const orphans = await client.checkOrphanedSessions(600000); // > 10 min idle
|
|
49
|
+
|
|
50
|
+
for (const sessionId of orphans) {
|
|
51
|
+
console.log(`Releasing orphaned session: ${sessionId}`);
|
|
52
|
+
await client.releaseSession(sessionId);
|
|
53
|
+
}
|
|
54
|
+
```
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema: "kxm.doc.v1"
|
|
3
|
+
id: "KB-BROWSER-002"
|
|
4
|
+
type: "kb"
|
|
5
|
+
title: "How does an agent resume after MFA?"
|
|
6
|
+
project: "kxm"
|
|
7
|
+
status: "accepted"
|
|
8
|
+
owner: "@operator"
|
|
9
|
+
created: "2026-09-14"
|
|
10
|
+
updated: "2026-09-14"
|
|
11
|
+
authority: "instruction"
|
|
12
|
+
confidence: "verified"
|
|
13
|
+
summary: "Details the verification and observation refresh sequence when resuming automation after MFA."
|
|
14
|
+
tags: ["browser", "mfa", "resume", "verification"]
|
|
15
|
+
related: ["docs/kb/how-to-take-over-session.md", "docs/browser-automation.md"]
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# How does an agent resume after MFA?
|
|
19
|
+
|
|
20
|
+
Once the human completes the MFA challenge in the browser viewer, the agent must not immediately execute blind clicks. It follows this sequence:
|
|
21
|
+
|
|
22
|
+
1. **State Transition**: Moves from `HUMAN_CONTROL` to `VERIFY_AUTHENTICATION`.
|
|
23
|
+
2. **CDP Re-attachment**: Re-queries the active tab target from the remote Steel CDP endpoint.
|
|
24
|
+
3. **App State Verification**:
|
|
25
|
+
- Inspects `page.url()` to confirm the browser navigated away from the MFA prompt to the intended destination (e.g. `/dashboard` or `/overview`).
|
|
26
|
+
- Checks for authenticated elements (e.g. account menu, logout button, user profile avatar).
|
|
27
|
+
4. **Observation Refresh**: Runs a fresh `agent-browser snapshot` or queries fresh DOM locators before executing the next action.
|
|
28
|
+
5. **Restore Control**: Returns to `AGENT_CONTROL` and proceeds with the task.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema: "kxm.doc.v1"
|
|
3
|
+
id: "KB-BROWSER-001"
|
|
4
|
+
type: "kb"
|
|
5
|
+
title: "How do I take over a browser session to log in?"
|
|
6
|
+
project: "kxm"
|
|
7
|
+
status: "accepted"
|
|
8
|
+
owner: "@operator"
|
|
9
|
+
created: "2026-09-14"
|
|
10
|
+
updated: "2026-09-14"
|
|
11
|
+
authority: "instruction"
|
|
12
|
+
confidence: "verified"
|
|
13
|
+
summary: "Instructions for taking over an active Steel browser session during an authentication gate."
|
|
14
|
+
tags: ["browser", "takeover", "auth", "mfa"]
|
|
15
|
+
related: ["docs/browser-automation.md", "docs/kb/how-to-resume-after-mfa.md"]
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# How do I take over a browser session to log in?
|
|
19
|
+
|
|
20
|
+
When an agent encounters a login screen, OAuth prompt, or security challenge, it triggers the `kxm-browser-takeover` protocol.
|
|
21
|
+
|
|
22
|
+
## Steps
|
|
23
|
+
|
|
24
|
+
1. **Copy the Takeover URL**:
|
|
25
|
+
The agent will emit a message in the terminal with a link like:
|
|
26
|
+
`https://steel.kontextmind.com/ui?sessionId=<SESSION_ID>`
|
|
27
|
+
2. **Open the Session Viewer**:
|
|
28
|
+
Open that URL in your desktop browser. You will see the live screencast of the exact remote Chrome container the agent was operating.
|
|
29
|
+
3. **Interact and Authenticate**:
|
|
30
|
+
Enter the username, password, or security key into the session, or use the devtools inspector (`https://steel.kontextmind.com/v1/devtools/inspector.html`) to trigger the submission.
|
|
31
|
+
4. **Signal Completion**:
|
|
32
|
+
Return to your Herdr or Pi terminal session and notify the agent: `auth complete` or `proceed`.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema: "kxm.doc.v1"
|
|
3
|
+
id: "KB-BROWSER-004"
|
|
4
|
+
type: "kb"
|
|
5
|
+
title: "Why did authentication disappear?"
|
|
6
|
+
project: "kxm"
|
|
7
|
+
status: "accepted"
|
|
8
|
+
owner: "@operator"
|
|
9
|
+
created: "2026-09-14"
|
|
10
|
+
updated: "2026-09-14"
|
|
11
|
+
authority: "instruction"
|
|
12
|
+
confidence: "verified"
|
|
13
|
+
summary: "Diagnosing lost authentication state, session expiration, and ephemeral container recreation."
|
|
14
|
+
tags: ["browser", "authentication", "cookies", "troubleshooting"]
|
|
15
|
+
related: ["docs/browser-automation.md", "docs/kb/why-automation-opened-different-browser.md"]
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# Why did authentication disappear?
|
|
19
|
+
|
|
20
|
+
If an agent was authenticated on a previous step or run and suddenly encounters a login screen again, the root causes are typically:
|
|
21
|
+
|
|
22
|
+
## Root Causes & Fixes
|
|
23
|
+
|
|
24
|
+
1. **Session Released or Expired**:
|
|
25
|
+
- Steel sessions are ephemeral by default. Once a session reaches its timeout (e.g. 5–30 minutes) or is released via `POST /v1/sessions/:id/release`, all memory cookies and local storage are cleared.
|
|
26
|
+
- **Fix**: To reuse state across tasks, save `storageState` via Playwright and reload it on the next session initialization.
|
|
27
|
+
2. **New Session Launched Instead of Attaching**:
|
|
28
|
+
- If the agent created a brand-new session instead of passing the existing `sessionId`, it opened a clean Chrome profile.
|
|
29
|
+
- **Fix**: Verify that the task passes `sessionId` to `getSession()` or uses the existing CDP endpoint.
|
|
30
|
+
3. **Domain / Subdomain Cookie Scoping**:
|
|
31
|
+
- OAuth flows often set cookies on subdomains (e.g., `auth.example.com`) that do not automatically share with `app.example.com`.
|
|
32
|
+
- **Fix**: Ensure cookies were issued for the primary domain or that SSO redirect completed fully before saving state.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema: "kxm.doc.v1"
|
|
3
|
+
id: "KB-BROWSER-005"
|
|
4
|
+
type: "kb"
|
|
5
|
+
title: "Why did automation open a different browser?"
|
|
6
|
+
project: "kxm"
|
|
7
|
+
status: "accepted"
|
|
8
|
+
owner: "@operator"
|
|
9
|
+
created: "2026-09-14"
|
|
10
|
+
updated: "2026-09-14"
|
|
11
|
+
authority: "instruction"
|
|
12
|
+
confidence: "verified"
|
|
13
|
+
summary: "Preventing accidental local browser launches and ensuring Playwright and agent-browser connect to remote Steel."
|
|
14
|
+
tags: ["browser", "cdp", "playwright", "agent-browser", "troubleshooting"]
|
|
15
|
+
related: ["docs/browser-automation.md", "docs/kb/how-to-connect-playwright-to-steel.md"]
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# Why did automation open a different browser?
|
|
19
|
+
|
|
20
|
+
If you expected automation to run on DOKS Steel but saw a local Chrome window pop up or failed to see the agent's actions in the Steel session viewer:
|
|
21
|
+
|
|
22
|
+
## Root Causes
|
|
23
|
+
|
|
24
|
+
1. **Called `chromium.launch()` Instead of `chromium.connectOverCDP()`**:
|
|
25
|
+
- `chromium.launch()` spawns a local browser process on the workstation.
|
|
26
|
+
- **Fix**: In Playwright, always use `chromium.connectOverCDP(cdpUrl)`.
|
|
27
|
+
2. **Missing `--cdp` Flag in `agent-browser`**:
|
|
28
|
+
- Running `agent-browser open <url>` without `--cdp` spawns a local headless browser.
|
|
29
|
+
- **Fix**: Always pass `--cdp "wss://steel.kontextmind.com/v1/devtools?sessionId=<id>&apiKey=<key>"`.
|
|
30
|
+
3. **Missing Environment Variables**:
|
|
31
|
+
- If `STEEL_CDP_URL` is undefined, scripts that fall back to local execution will launch a local browser.
|
|
32
|
+
- **Fix**: Ensure `STEEL_CDP_URL` or `STEEL_API_KEY` is loaded from `pass-cli`.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema: "kxm.doc.v1"
|
|
3
|
+
id: "KB-BROWSER-006"
|
|
4
|
+
type: "kb"
|
|
5
|
+
title: "Why can I view a session but not control it?"
|
|
6
|
+
project: "kxm"
|
|
7
|
+
status: "accepted"
|
|
8
|
+
owner: "@operator"
|
|
9
|
+
created: "2026-09-14"
|
|
10
|
+
updated: "2026-09-14"
|
|
11
|
+
authority: "instruction"
|
|
12
|
+
confidence: "verified"
|
|
13
|
+
summary: "Understanding self-hosted Steel OSS screencast viewer capabilities vs devtools inspector input modes."
|
|
14
|
+
tags: ["browser", "takeover", "steel", "ui"]
|
|
15
|
+
related: ["docs/browser-automation.md", "docs/kb/how-to-take-over-session.md"]
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# Why can I view a session but not control it?
|
|
19
|
+
|
|
20
|
+
In self-hosted open-source Steel (`steel-dev/steel-browser`), the web UI at `/ui` provides a real-time screencast stream, event logs, and network tracking. Depending on browser canvas capture modes, direct clicks on the video canvas may not send synthetic mouse events.
|
|
21
|
+
|
|
22
|
+
## Resolution
|
|
23
|
+
|
|
24
|
+
1. **Use the Chrome DevTools Inspector**:
|
|
25
|
+
Navigate to the devtools inspector page for the session:
|
|
26
|
+
`https://steel.kontextmind.com/v1/devtools/inspector.html`
|
|
27
|
+
or open the remote debugger on port 9223.
|
|
28
|
+
2. **Interact via the DOM Console**:
|
|
29
|
+
The devtools inspector gives full interactive control over the DOM, console, network, and storage.
|
|
30
|
+
3. **Agent Automation Coexistence**:
|
|
31
|
+
Ensure the agent is in `HUMAN_CONTROL` state so automation does not race or override your clicks.
|
package/docs/kxm-handbook.md
CHANGED
|
@@ -695,7 +695,7 @@ Claude MCP also exposes:
|
|
|
695
695
|
Set exactly one of:
|
|
696
696
|
|
|
697
697
|
```text
|
|
698
|
-
KXM_WEBHOOK_WORKFLOWS_FILE=.kxm/
|
|
698
|
+
KXM_WEBHOOK_WORKFLOWS_FILE=.kxm/workflows/default.yaml
|
|
699
699
|
```
|
|
700
700
|
|
|
701
701
|
or:
|
|
@@ -712,7 +712,7 @@ required evidence, attempt limits, and optional peer policies.
|
|
|
712
712
|
Validate before restart:
|
|
713
713
|
|
|
714
714
|
```powershell
|
|
715
|
-
kxm gate validate --file .kxm/
|
|
715
|
+
kxm gate validate --file .kxm/workflows/default.yaml
|
|
716
716
|
```
|
|
717
717
|
|
|
718
718
|
Secrets belong in environment variables named by `secretEnv` and
|
|
@@ -921,7 +921,7 @@ with content hashes. See `docs/skills.md` for the full lifecycle.
|
|
|
921
921
|
|
|
922
922
|
### Reference /fix workflow
|
|
923
923
|
|
|
924
|
-
`.kxm/
|
|
924
|
+
`.kxm/workflows/default.yaml` implements the reference bug-fix flow:
|
|
925
925
|
read-only exploration, a tests-only reproduction draft, independent two-critic
|
|
926
926
|
`repro-review` that captures the immutable oracle (a sibling API is invalid),
|
|
927
927
|
plan review by independent critics, a human approval gate, bounded rework
|
package/docs/operations.md
CHANGED
|
@@ -21,10 +21,34 @@ These operator commands assume the packed release CLI installation from
|
|
|
21
21
|
[Getting started](getting-started.md#install-the-operator-command). From a
|
|
22
22
|
source clone, use `npm run hub` instead.
|
|
23
23
|
|
|
24
|
+
When `KXM_AUTH_TOKEN` is not set, `kxm hub start` loads the persisted hub
|
|
25
|
+
credential file (schema `kxm.hub-env.v1`) under the user state root
|
|
26
|
+
(`~/.local/state/kxm/hub-env.json` on Linux, honoring `KXM_STATE_HOME` and
|
|
27
|
+
platform equivalents). If no persisted token exists, a long random
|
|
28
|
+
administrative token is generated, saved there with `0600` permissions, and
|
|
29
|
+
used. The hub therefore never silently starts with `auth=none` because a
|
|
30
|
+
token was forgotten; a missing token is created once and reused by every
|
|
31
|
+
later restart, worker, and dashboard on the same machine. Explicit
|
|
32
|
+
`KXM_AUTH_TOKEN` / `KXM_PROJECT_TOKENS` environment values always win and are
|
|
33
|
+
persisted so restarts keep them. The generated value is never printed in
|
|
34
|
+
full; kxm only reports which file it came from.
|
|
35
|
+
|
|
24
36
|
Stop with `Ctrl+C` or `SIGTERM`. The hub stops accepting connections, closes SSE streams, waits for active HTTP connections, and closes SQLite.
|
|
25
37
|
|
|
26
38
|
For unattended service, use a supervisor that sets a stable working directory, injects secrets, captures stdout, restarts after failure, and allows at least five seconds for graceful shutdown.
|
|
27
39
|
|
|
40
|
+
### PID claims and restart recovery
|
|
41
|
+
|
|
42
|
+
The hub wrapper records its own PID and the server child PID in
|
|
43
|
+
`.kxm/state/hub.pid`. A claim whose wrapper is dead is reclaimed automatically
|
|
44
|
+
on the next `kxm hub start`; when the dead wrapper left an orphaned server
|
|
45
|
+
child behind (for example after `SIGKILL` or a machine crash), the new
|
|
46
|
+
wrapper terminates that orphan before reclaiming. `kxm hub stop` also
|
|
47
|
+
recovers orphans directly: it signals a still-running recorded server child
|
|
48
|
+
of a dead wrapper, waits for exit, and removes the stale claim. Malformed or
|
|
49
|
+
foreign PID claims stay fail-closed; remove those only after verifying no
|
|
50
|
+
hub process is running.
|
|
51
|
+
|
|
28
52
|
Run each long-lived coordinator with `kxm agent worker --name <stable-name> --project <project> [--model <provider/model>] [--fallback-models <provider/model,...>] [--tools <name,...>]` under a separate service-manager unit. Use distinct worktrees for concurrent writers, explicit CPU and memory limits, and restart throttling outside the built-in bounded backoff. Enforce role ownership with the Pi tool allowlist: omit `bash`, `edit`, and `write` from read-only reviewers, even if their prompt also says not to edit. The worker launches Pi RPC mode and retains the most recent session unless configured otherwise. Use `--fresh-start` for a clean first session that may still resume after a later provider failure; reserve `--no-continue` for a worker that must never resume. For release verification, configure the [exact extension and skill sets](configuration.md#long-lived-worker-settings), including every required provider extension; configured categories disable discovery and fail closed on invalid paths. `kxm hub stop` writes a generation-matched control request; the worker asks Pi RPC to abort, waits for confirmation and state flush, and only force-stops the process tree after the bounded drain deadline. A final provider error leaves the inbound hub message delivered, gracefully restarts Pi, rotates to an unused fallback model, and preserves the session; Pi's own automatic retries always finish first. A tool that exceeds `KXM_WORKER_TOOL_TIMEOUT_MS` follows the same durable restart path without changing models. If `--continue` reports an invalid tool-result session, the worker retries once fresh, journals a redacted recovery envelope, and injects a bounded resume instruction for the durable run and stage. Do not copy `pi-agent-*.log` into journals or retrospectives.
|
|
29
53
|
|
|
30
54
|
### Workflow-specific Pi sessions
|