@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.
Files changed (175) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.kxm/agents/coordinator.yaml +9 -0
  3. package/.kxm/agents/critic-arch.yaml +13 -0
  4. package/.kxm/agents/critic-cli.yaml +13 -0
  5. package/.kxm/agents/implementer.yaml +13 -0
  6. package/.kxm/gates.yaml +8 -0
  7. package/.kxm/producers.yaml +22 -0
  8. package/.kxm/project.yaml +15 -0
  9. package/.kxm/roles/writer.yaml +7 -0
  10. package/.kxm/workflows/default.yaml +47 -0
  11. package/CHANGELOG.md +39 -7
  12. package/README.md +1 -0
  13. package/docs/README.md +5 -0
  14. package/docs/adr/ADR-0002-browser-automation-steel-doks.md +103 -0
  15. package/docs/agent-skills.md +135 -0
  16. package/docs/architecture.md +1 -1
  17. package/docs/assignment-runner.md +21 -8
  18. package/docs/browser-automation.md +116 -0
  19. package/docs/configuration.md +11 -2
  20. package/docs/getting-started.md +21 -0
  21. package/docs/kb/how-credentials-retrieved-safely.md +31 -0
  22. package/docs/kb/how-to-capture-and-annotate-section.md +60 -0
  23. package/docs/kb/how-to-connect-playwright-to-steel.md +54 -0
  24. package/docs/kb/how-to-recover-expired-session-or-orphan.md +54 -0
  25. package/docs/kb/how-to-resume-after-mfa.md +28 -0
  26. package/docs/kb/how-to-take-over-session.md +32 -0
  27. package/docs/kb/why-authentication-disappeared.md +32 -0
  28. package/docs/kb/why-automation-opened-different-browser.md +32 -0
  29. package/docs/kb/why-session-viewer-cannot-control.md +31 -0
  30. package/docs/kxm-handbook.md +3 -3
  31. package/docs/operations.md +24 -0
  32. package/docs/operator-pi-packages.md +63 -0
  33. package/docs/prompts/browser-annotate-feedback.md +41 -0
  34. package/docs/prompts/browser-diagnose-recover.md +38 -0
  35. package/docs/prompts/browser-explore.md +42 -0
  36. package/docs/prompts/browser-repro-fix.md +48 -0
  37. package/docs/prompts/browser-start.md +41 -0
  38. package/docs/prompts/browser-takeover.md +50 -0
  39. package/docs/skills/repo-work-delivery.md +107 -0
  40. package/docs/skills.md +2 -0
  41. package/docs/test-matrix.md +4 -3
  42. package/docs/troubleshooting.md +41 -1
  43. package/docs/vnext/validation.md +9 -0
  44. package/docs/webhook-workflows.md +2 -2
  45. package/examples/README.md +1 -1
  46. package/package.json +16 -17
  47. package/plugins/kxm/.claude-plugin/plugin.json +1 -1
  48. package/plugins/kxm/README.md +1 -1
  49. package/plugins/kxm/dist/cli.js +41620 -35578
  50. package/plugins/kxm/dist/core.js +271 -34
  51. package/plugins/kxm/dist/extension.js +7759 -86
  52. package/plugins/kxm/dist/mcp-server.js +75 -21
  53. package/plugins/kxm/dist/runtime.js +8218 -2328
  54. package/plugins/kxm/dist/server.js +3125 -2260
  55. package/plugins/kxm/dist/vnext-runtime-supervisor.js +5961 -661
  56. package/plugins/kxm/package.json +1 -1
  57. package/plugins/kxm/skills/SUITE.md +5 -0
  58. package/plugins/kxm/skills/hints.json +103 -0
  59. package/plugins/kxm/skills/kxm/SKILL.md +30 -83
  60. package/plugins/kxm/skills/kxm-browser-annotate/SKILL.md +90 -0
  61. package/plugins/kxm/skills/kxm-browser-auth/SKILL.md +47 -0
  62. package/plugins/kxm/skills/kxm-browser-diagnostics/SKILL.md +48 -0
  63. package/plugins/kxm/skills/kxm-browser-explore/SKILL.md +48 -0
  64. package/plugins/kxm/skills/kxm-browser-session/SKILL.md +94 -0
  65. package/plugins/kxm/skills/kxm-browser-takeover/SKILL.md +87 -0
  66. package/plugins/kxm/skills/kxm-browser-verify/SKILL.md +71 -0
  67. package/plugins/kxm/skills/kxm-context-memory/SKILL.md +69 -0
  68. package/plugins/kxm/skills/kxm-definitions/SKILL.md +65 -0
  69. package/plugins/kxm/skills/kxm-harness-auth/SKILL.md +34 -0
  70. package/plugins/kxm/skills/kxm-harvest/SKILL.md +48 -0
  71. package/plugins/kxm/skills/kxm-hub-ops/SKILL.md +43 -0
  72. package/plugins/kxm/skills/kxm-insights/SKILL.md +48 -0
  73. package/plugins/kxm/skills/kxm-mind/SKILL.md +59 -0
  74. package/plugins/kxm/skills/kxm-peer/SKILL.md +110 -0
  75. package/plugins/kxm/skills/kxm-project-setup/SKILL.md +42 -0
  76. package/plugins/kxm/skills/kxm-projects/SKILL.md +43 -0
  77. package/plugins/kxm/skills/kxm-protocol/SKILL.md +66 -0
  78. package/plugins/kxm/skills/kxm-query/SKILL.md +45 -0
  79. package/plugins/kxm/skills/kxm-routing-improve/SKILL.md +30 -0
  80. package/plugins/kxm/skills/kxm-runs/SKILL.md +29 -0
  81. package/plugins/kxm/skills/kxm-setup/SKILL.md +55 -0
  82. package/plugins/kxm/skills/kxm-skill-lifecycle/SKILL.md +31 -0
  83. package/plugins/kxm/skills/kxm-tasks/SKILL.md +33 -0
  84. package/plugins/kxm/skills/kxm-triage/SKILL.md +47 -0
  85. package/plugins/kxm/skills/kxm-work/SKILL.md +44 -0
  86. package/plugins/kxm/skills/kxm-workflow/SKILL.md +45 -0
  87. package/plugins/kxm/src/autocomplete.ts +9 -3
  88. package/plugins/kxm/src/browser.ts +603 -0
  89. package/plugins/kxm/src/cli/context-skills.ts +373 -0
  90. package/plugins/kxm/src/cli/hub.ts +614 -0
  91. package/plugins/kxm/src/cli/roles.ts +615 -0
  92. package/plugins/kxm/src/cli/system.ts +906 -0
  93. package/plugins/kxm/src/cli/tasks.ts +364 -0
  94. package/plugins/kxm/src/cli/types.ts +270 -0
  95. package/plugins/kxm/src/cli/vnext.ts +698 -0
  96. package/plugins/kxm/src/cli/workflows.ts +699 -0
  97. package/plugins/kxm/src/cli.ts +362 -2849
  98. package/plugins/kxm/src/commands.ts +150 -8
  99. package/plugins/kxm/src/completion-install.ts +223 -0
  100. package/plugins/kxm/src/config.ts +7 -4
  101. package/plugins/kxm/src/context-packet.ts +172 -0
  102. package/plugins/kxm/src/database.ts +1 -1
  103. package/plugins/kxm/src/extension.ts +36 -1
  104. package/plugins/kxm/src/external-effects.ts +357 -8
  105. package/plugins/kxm/src/hub-env.ts +193 -0
  106. package/plugins/kxm/src/hub.ts +2 -4
  107. package/plugins/kxm/src/improve.ts +72 -0
  108. package/plugins/kxm/src/init-guide-setup.ts +547 -0
  109. package/plugins/kxm/src/local-snapshot.ts +1 -1
  110. package/plugins/kxm/src/mcp-server.ts +1 -1
  111. package/plugins/kxm/src/model-inventory.ts +127 -0
  112. package/plugins/kxm/src/modes.ts +348 -0
  113. package/plugins/kxm/src/policy-draft.d.mts +55 -0
  114. package/plugins/kxm/src/policy-draft.mjs +565 -0
  115. package/plugins/kxm/src/price-calc.ts +17 -18
  116. package/plugins/kxm/src/prices.ts +32 -16
  117. package/plugins/kxm/src/producers.ts +71 -0
  118. package/plugins/kxm/src/protocol.ts +111 -0
  119. package/plugins/kxm/src/restricted-yaml.d.mts +31 -0
  120. package/plugins/kxm/src/restricted-yaml.mjs +145 -0
  121. package/plugins/kxm/src/role.ts +710 -0
  122. package/plugins/kxm/src/routing.ts +99 -1
  123. package/plugins/kxm/src/runtime.ts +4 -0
  124. package/plugins/kxm/src/safety-integrity.ts +76 -0
  125. package/plugins/kxm/src/session-work.ts +9 -2
  126. package/plugins/kxm/src/sqlite.ts +76 -0
  127. package/plugins/kxm/src/ssh-remote.ts +560 -0
  128. package/plugins/kxm/src/store.ts +1 -1
  129. package/plugins/kxm/src/studio-layout.ts +660 -17
  130. package/plugins/kxm/src/subagent-control.ts +312 -0
  131. package/plugins/kxm/src/suggest.ts +7 -13
  132. package/plugins/kxm/src/telemetry.ts +82 -0
  133. package/plugins/kxm/src/tui.ts +140 -0
  134. package/plugins/kxm/src/vnext-bindings.ts +1 -1
  135. package/plugins/kxm/src/vnext-config.ts +53 -111
  136. package/plugins/kxm/src/vnext-engine-command.ts +2 -0
  137. package/plugins/kxm/src/vnext-engine.ts +214 -62
  138. package/plugins/kxm/src/vnext-harness.ts +336 -84
  139. package/plugins/kxm/src/vnext-oneshot-evidence.ts +117 -0
  140. package/plugins/kxm/src/vnext-oneshot-process.ts +187 -0
  141. package/plugins/kxm/src/vnext-oneshot-producer.ts +182 -224
  142. package/plugins/kxm/src/vnext-pi-producer.ts +11 -7
  143. package/plugins/kxm/src/vnext-runtime-store.ts +36 -2
  144. package/plugins/kxm/src/vnext-runtime-supervisor.ts +122 -5
  145. package/plugins/kxm/src/vnext-runtime.ts +14 -0
  146. package/plugins/kxm/src/workflow-manager.ts +392 -0
  147. package/plugins/kxm/src/workflow-tui.ts +255 -0
  148. package/plugins/kxm/src/workflow.ts +144 -0
  149. package/schemas/policy-draft/README.md +17 -0
  150. package/schemas/policy-draft/model.v2.schema.json +140 -0
  151. package/schemas/policy-draft/role.v2.schema.json +91 -0
  152. package/schemas/vnext/modes.schema.json +56 -0
  153. package/schemas/vnext/role.schema.json +76 -0
  154. package/schemas/vnext/run-event.schema.json +1 -0
  155. package/scripts/assignment-run.d.mts +1 -1
  156. package/scripts/assignment-run.mjs +44 -35
  157. package/scripts/check-generated.mjs +33 -9
  158. package/scripts/emit-codex-artifacts.mjs +255 -11
  159. package/scripts/harness-run.d.mts +12 -4
  160. package/scripts/harness-run.mjs +65 -17
  161. package/scripts/kxm-bump-version.mjs +146 -0
  162. package/scripts/kxm-hub.mjs +150 -2
  163. package/scripts/kxm-publish-npm.mjs +3 -1
  164. package/scripts/kxm-release-github.mjs +3 -1
  165. package/scripts/kxm.mjs +0 -0
  166. package/scripts/native-critic.d.mts +5 -0
  167. package/scripts/native-critic.mjs +60 -0
  168. package/.kxm/config/README.md +0 -5
  169. package/.kxm/config/agents.json +0 -43
  170. package/.kxm/config/env.example +0 -56
  171. package/.kxm/config/update.example.yaml +0 -9
  172. package/.kxm/config/workflows/fix.json +0 -160
  173. package/.kxm/config/workflows/jira-development.json +0 -116
  174. package/.kxm/config/workflows/provenance-quorum.json +0 -150
  175. 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.
@@ -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/config/workflows`. See [Peer provenance and quorum gates](provenance-gates.md) for `evidencePolicies`, `workflowContext`, `evidenceRefs`, and explicit degradation.
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. Use [`.kxm/config/env.example`](../.kxm/config/env.example) as a reference, but load values through your shell, supervisor, container platform, or secret manager. Never commit real tokens.
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
 
@@ -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.
@@ -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/config/workflows/product.json
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/config/workflows/product.json
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/config/workflows/fix.json` implements the reference bug-fix flow:
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
@@ -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