@webpresso/agent-kit 3.1.30 → 3.2.0

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.

Potentially problematic release.


This version of @webpresso/agent-kit might be problematic. Click here for more details.

Files changed (257) hide show
  1. package/README.md +53 -15
  2. package/bin/_run.js +179 -19
  3. package/catalog/AGENTS.md.tpl +3 -3
  4. package/catalog/agent/agents/implementer.md +45 -0
  5. package/catalog/agent/rules/parallel-orchestration-quota.md +100 -0
  6. package/catalog/agent/rules/pre-implementation.md +28 -1
  7. package/catalog/agent/rules/supported-agent-clis.md +9 -0
  8. package/catalog/agent/rules/typescript-version.md +50 -0
  9. package/catalog/agent/skills/codex/SKILL.md +25 -1
  10. package/catalog/agent/skills/verify/SKILL.md +4 -2
  11. package/catalog/docs/templates/blueprint.md +1 -1
  12. package/dist/esm/audit/agents.js +1 -0
  13. package/dist/esm/audit/blueprint-lifecycle-sql.d.ts +12 -0
  14. package/dist/esm/audit/blueprint-lifecycle-sql.js +23 -2
  15. package/dist/esm/audit/blueprint-pr-coverage.js +4 -0
  16. package/dist/esm/audit/ci-guardrails-wiring.d.ts +22 -0
  17. package/dist/esm/audit/ci-guardrails-wiring.js +90 -0
  18. package/dist/esm/audit/ci-test-perf.js +30 -0
  19. package/dist/esm/audit/command-surface.js +4 -2
  20. package/dist/esm/audit/host-substitution-risk.d.ts +2 -0
  21. package/dist/esm/audit/host-substitution-risk.js +256 -0
  22. package/dist/esm/audit/registry.d.ts +4 -4
  23. package/dist/esm/audit/registry.js +8 -1
  24. package/dist/esm/audit/toolchain-isolation.js +1 -2
  25. package/dist/esm/audit/typescript-version.d.ts +2 -0
  26. package/dist/esm/audit/typescript-version.js +123 -0
  27. package/dist/esm/blueprint/core/parser.js +43 -1
  28. package/dist/esm/blueprint/core/validation/criteria.d.ts +14 -0
  29. package/dist/esm/blueprint/core/validation/criteria.js +41 -2
  30. package/dist/esm/blueprint/core/validation/state.js +25 -14
  31. package/dist/esm/blueprint/db/migrations/run.js +4 -2
  32. package/dist/esm/blueprint/lifecycle/audit.d.ts +20 -0
  33. package/dist/esm/blueprint/lifecycle/audit.js +65 -10
  34. package/dist/esm/blueprint/lifecycle/canonicalize.d.ts +6 -0
  35. package/dist/esm/blueprint/lifecycle/canonicalize.js +135 -0
  36. package/dist/esm/blueprint/lifecycle/local.d.ts +2 -1
  37. package/dist/esm/blueprint/lifecycle/local.js +19 -3
  38. package/dist/esm/blueprint/lifecycle/review-provenance.js +36 -11
  39. package/dist/esm/blueprint/service/BlueprintCreationService.d.ts +1 -0
  40. package/dist/esm/blueprint/service/BlueprintCreationService.js +53 -4
  41. package/dist/esm/blueprint/service/blueprint-tech-debt-links.js +16 -2
  42. package/dist/esm/blueprint/trust/command-runner.d.ts +26 -0
  43. package/dist/esm/blueprint/trust/command-runner.js +148 -0
  44. package/dist/esm/blueprint/trust/gates.d.ts +7 -0
  45. package/dist/esm/blueprint/trust/gates.js +20 -0
  46. package/dist/esm/blueprint/trust/promotion.d.ts +8 -0
  47. package/dist/esm/blueprint/trust/promotion.js +62 -112
  48. package/dist/esm/blueprint/trust/scaffold.d.ts +19 -0
  49. package/dist/esm/blueprint/trust/scaffold.js +64 -0
  50. package/dist/esm/blueprint/trust/validator.d.ts +1 -0
  51. package/dist/esm/blueprint/trust/validator.js +7 -1
  52. package/dist/esm/blueprint/utils/archive.js +27 -5
  53. package/dist/esm/blueprint/utils/document-paths.d.ts +18 -0
  54. package/dist/esm/blueprint/utils/document-paths.js +45 -12
  55. package/dist/esm/build/cli-mcp-parity.js +10 -0
  56. package/dist/esm/cli/bundle/commands/blueprint.d.ts +1 -0
  57. package/dist/esm/cli/bundle/commands/blueprint.js +1 -0
  58. package/dist/esm/cli/cli.d.ts +1 -1
  59. package/dist/esm/cli/cli.js +34 -0
  60. package/dist/esm/cli/commands/agent-launch.d.ts +6 -1
  61. package/dist/esm/cli/commands/agent-launch.js +82 -4
  62. package/dist/esm/cli/commands/audit-core.d.ts +1 -1
  63. package/dist/esm/cli/commands/audit-core.js +8 -1
  64. package/dist/esm/cli/commands/audit.js +17 -5
  65. package/dist/esm/cli/commands/blueprint/execution.js +18 -6
  66. package/dist/esm/cli/commands/blueprint/mutations.js +59 -40
  67. package/dist/esm/cli/commands/blueprint/router-dispatch.d.ts +2 -1
  68. package/dist/esm/cli/commands/blueprint/router-dispatch.js +20 -1
  69. package/dist/esm/cli/commands/blueprint/router-output.d.ts +21 -0
  70. package/dist/esm/cli/commands/blueprint/router-output.js +48 -17
  71. package/dist/esm/cli/commands/blueprint/router.d.ts +7 -0
  72. package/dist/esm/cli/commands/blueprint/router.js +13 -1
  73. package/dist/esm/cli/commands/ci-preflight.d.ts +13 -2
  74. package/dist/esm/cli/commands/ci-preflight.js +6 -3
  75. package/dist/esm/cli/commands/compile.js +5 -31
  76. package/dist/esm/cli/commands/dash/delivery-status.d.ts +1 -0
  77. package/dist/esm/cli/commands/dash/delivery-status.js +11 -4
  78. package/dist/esm/cli/commands/doctor.js +5 -0
  79. package/dist/esm/cli/commands/hook.d.ts +5 -0
  80. package/dist/esm/cli/commands/hook.js +15 -9
  81. package/dist/esm/cli/commands/init/config.js +2 -2
  82. package/dist/esm/cli/commands/init/convergence-apply.d.ts +24 -0
  83. package/dist/esm/cli/commands/init/convergence-apply.js +221 -0
  84. package/dist/esm/cli/commands/init/convergence-state.d.ts +13 -0
  85. package/dist/esm/cli/commands/init/convergence-state.js +54 -0
  86. package/dist/esm/cli/commands/init/convergence.d.ts +23 -0
  87. package/dist/esm/cli/commands/init/convergence.js +57 -0
  88. package/dist/esm/cli/commands/init/git-convergence.d.ts +19 -0
  89. package/dist/esm/cli/commands/init/git-convergence.js +168 -0
  90. package/dist/esm/cli/commands/init/gitignore-patcher.js +2 -0
  91. package/dist/esm/cli/commands/init/grok-privacy-smoke.d.ts +52 -0
  92. package/dist/esm/cli/commands/init/grok-privacy-smoke.js +91 -0
  93. package/dist/esm/cli/commands/init/host-native-proof.d.ts +18 -0
  94. package/dist/esm/cli/commands/init/host-native-proof.js +88 -0
  95. package/dist/esm/cli/commands/init/host-visibility.d.ts +2 -2
  96. package/dist/esm/cli/commands/init/host-visibility.js +94 -5
  97. package/dist/esm/cli/commands/init/index.d.ts +1 -0
  98. package/dist/esm/cli/commands/init/index.js +326 -173
  99. package/dist/esm/cli/commands/init/mcp-spec.d.ts +57 -0
  100. package/dist/esm/cli/commands/init/mcp-spec.js +273 -0
  101. package/dist/esm/cli/commands/init/merge.d.ts +1 -0
  102. package/dist/esm/cli/commands/init/merge.js +30 -1
  103. package/dist/esm/cli/commands/init/plugin-cache-prune.d.ts +0 -3
  104. package/dist/esm/cli/commands/init/plugin-cache-prune.js +0 -1
  105. package/dist/esm/cli/commands/init/scaffold-agents-md.d.ts +1 -1
  106. package/dist/esm/cli/commands/init/scaffold-agents-md.js +9 -3
  107. package/dist/esm/cli/commands/init/scaffold-base-kit.d.ts +11 -0
  108. package/dist/esm/cli/commands/init/scaffold-base-kit.js +56 -1
  109. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/emitters/grok.d.ts +14 -8
  110. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/emitters/grok.js +41 -24
  111. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.d.ts +2 -0
  112. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.js +51 -23
  113. package/dist/esm/cli/commands/init/scaffolders/codex-mcp/index.d.ts +12 -31
  114. package/dist/esm/cli/commands/init/scaffolders/codex-mcp/index.js +288 -202
  115. package/dist/esm/cli/commands/init/scaffolders/file-transaction.d.ts +7 -0
  116. package/dist/esm/cli/commands/init/scaffolders/file-transaction.js +58 -0
  117. package/dist/esm/cli/commands/init/scaffolders/grok-mcp/index.d.ts +38 -0
  118. package/dist/esm/cli/commands/init/scaffolders/grok-mcp/index.js +73 -0
  119. package/dist/esm/cli/commands/init/scaffolders/opencode-plugin/index.d.ts +21 -0
  120. package/dist/esm/cli/commands/init/scaffolders/opencode-plugin/index.js +559 -63
  121. package/dist/esm/cli/commands/init/untracked-collision.d.ts +14 -0
  122. package/dist/esm/cli/commands/init/untracked-collision.js +42 -0
  123. package/dist/esm/cli/commands/opencode-rotate.d.ts +49 -0
  124. package/dist/esm/cli/commands/opencode-rotate.js +135 -0
  125. package/dist/esm/cli/commands/public-readiness.d.ts +11 -0
  126. package/dist/esm/cli/commands/public-readiness.js +42 -0
  127. package/dist/esm/cli/commands/review.d.ts +35 -3
  128. package/dist/esm/cli/commands/review.js +729 -209
  129. package/dist/esm/cli/commands/run-wait.d.ts +2 -0
  130. package/dist/esm/cli/commands/run-wait.js +122 -0
  131. package/dist/esm/cli/commands/setup-help.js +1 -1
  132. package/dist/esm/cli/commands/setup-repair-help.js +1 -1
  133. package/dist/esm/cli/commands/worktree/router-dispatch.js +13 -8
  134. package/dist/esm/cli/direct-provider-launch.js +9 -5
  135. package/dist/esm/cli/optional-tool-freshness.d.ts +27 -0
  136. package/dist/esm/cli/optional-tool-freshness.js +219 -9
  137. package/dist/esm/daemon/domains/git-actions.d.ts +29 -0
  138. package/dist/esm/daemon/domains/git-actions.js +136 -0
  139. package/dist/esm/daemon/domains/run-registry-interop.d.ts +16 -0
  140. package/dist/esm/daemon/domains/run-registry-interop.js +45 -0
  141. package/dist/esm/daemon/domains/sessions-search.d.ts +11 -0
  142. package/dist/esm/daemon/domains/sessions-search.js +29 -0
  143. package/dist/esm/daemon/handlers/blueprints-handlers.d.ts +5 -0
  144. package/dist/esm/daemon/handlers/blueprints-handlers.js +36 -0
  145. package/dist/esm/daemon/handlers/deploy-handlers.d.ts +6 -0
  146. package/dist/esm/daemon/handlers/deploy-handlers.js +5 -0
  147. package/dist/esm/daemon/handlers/fleet-handlers.d.ts +15 -0
  148. package/dist/esm/daemon/handlers/fleet-handlers.js +91 -0
  149. package/dist/esm/daemon/handlers/git-handlers.d.ts +6 -0
  150. package/dist/esm/daemon/handlers/git-handlers.js +27 -0
  151. package/dist/esm/daemon/handlers/product.d.ts +7 -0
  152. package/dist/esm/daemon/handlers/product.js +10 -119
  153. package/dist/esm/daemon/handlers/sessions-handlers.d.ts +12 -0
  154. package/dist/esm/daemon/handlers/sessions-handlers.js +31 -0
  155. package/dist/esm/daemon/handlers/shared.d.ts +5 -0
  156. package/dist/esm/daemon/handlers/shared.js +16 -0
  157. package/dist/esm/daemon/methods.d.ts +8 -1
  158. package/dist/esm/daemon/methods.js +7 -0
  159. package/dist/esm/daemon/protocol/contract.d.ts +43 -0
  160. package/dist/esm/daemon/protocol/contract.js +26 -0
  161. package/dist/esm/daemon/protocol/index.d.ts +1 -1
  162. package/dist/esm/daemon/protocol/index.js +1 -1
  163. package/dist/esm/hooks/__conformance__/matrix.d.ts +6 -0
  164. package/dist/esm/hooks/__conformance__/matrix.js +137 -0
  165. package/dist/esm/hooks/conformance/batch.js +5 -0
  166. package/dist/esm/hooks/doctor.d.ts +3 -3
  167. package/dist/esm/hooks/doctor.js +30 -15
  168. package/dist/esm/hooks/permission-request/index.js +9 -3
  169. package/dist/esm/hooks/permission-request/policy.d.ts +9 -0
  170. package/dist/esm/hooks/permission-request/policy.js +13 -0
  171. package/dist/esm/hooks/pretool-guard/dev-routing.d.ts +9 -0
  172. package/dist/esm/hooks/pretool-guard/dev-routing.js +41 -5
  173. package/dist/esm/hooks/pretool-guard/logger.d.ts +7 -0
  174. package/dist/esm/hooks/pretool-guard/logger.js +16 -0
  175. package/dist/esm/hooks/pretool-guard/runner.d.ts +6 -0
  176. package/dist/esm/hooks/pretool-guard/runner.js +68 -16
  177. package/dist/esm/hooks/pretool-guard/validators/blueprint.js +30 -10
  178. package/dist/esm/hooks/pretool-guard/validators/forbidden-commands.js +54 -0
  179. package/dist/esm/hooks/pretool-guard/validators/index.d.ts +7 -0
  180. package/dist/esm/hooks/pretool-guard/validators/index.js +21 -0
  181. package/dist/esm/hooks/pretool-guard/validators/path-contract.d.ts +19 -0
  182. package/dist/esm/hooks/pretool-guard/validators/path-contract.js +25 -8
  183. package/dist/esm/hooks/shared/guard-outcome.d.ts +149 -0
  184. package/dist/esm/hooks/shared/guard-outcome.js +215 -0
  185. package/dist/esm/hooks/shared/hook-bootstrap.d.ts +26 -0
  186. package/dist/esm/hooks/shared/hook-bootstrap.js +64 -1
  187. package/dist/esm/hooks/shared/types.d.ts +8 -5
  188. package/dist/esm/hooks/shared/types.js +23 -8
  189. package/dist/esm/hooks/stop/qa-changed-files.d.ts +11 -0
  190. package/dist/esm/hooks/stop/qa-changed-files.js +74 -0
  191. package/dist/esm/mcp/blueprint/_shared/lifecycle.js +14 -1
  192. package/dist/esm/mcp/blueprint/handlers/document-mutations.js +78 -4
  193. package/dist/esm/mcp/blueprint/handlers/review-log.js +8 -1
  194. package/dist/esm/mcp/blueprint/handlers/task-advance.js +113 -54
  195. package/dist/esm/mcp/blueprint/handlers/task-verify.js +39 -19
  196. package/dist/esm/mcp/blueprint/registration.js +3 -2
  197. package/dist/esm/mcp/server.d.ts +1 -0
  198. package/dist/esm/mcp/server.js +27 -0
  199. package/dist/esm/mcp/tools/_names.d.ts +1 -1
  200. package/dist/esm/mcp/tools/_names.js +5 -0
  201. package/dist/esm/mcp/tools/_registry.js +10 -0
  202. package/dist/esm/mcp/tools/_shared/audit-kinds.d.ts +1 -1
  203. package/dist/esm/mcp/tools/_shared/result.js +44 -1
  204. package/dist/esm/mcp/tools/audit.d.ts +4 -1
  205. package/dist/esm/mcp/tools/audit.js +30 -0
  206. package/dist/esm/mcp/tools/audits.d.ts +3 -0
  207. package/dist/esm/mcp/tools/ci-preflight.d.ts +50 -0
  208. package/dist/esm/mcp/tools/ci-preflight.js +183 -0
  209. package/dist/esm/mcp/tools/pr-upsert.js +39 -1
  210. package/dist/esm/mcp/tools/review-run.d.ts +28 -0
  211. package/dist/esm/mcp/tools/review-run.js +216 -0
  212. package/dist/esm/mcp/tools/run-wait.d.ts +86 -0
  213. package/dist/esm/mcp/tools/run-wait.js +593 -0
  214. package/dist/esm/mcp/tools/session-id.d.ts +3 -0
  215. package/dist/esm/mcp/tools/session-id.js +45 -0
  216. package/dist/esm/mcp/tools/session-info.d.ts +3 -0
  217. package/dist/esm/mcp/tools/session-info.js +49 -0
  218. package/dist/esm/output-transforms/audit.d.ts +23 -0
  219. package/dist/esm/output-transforms/audit.js +47 -0
  220. package/dist/esm/output-transforms/index.js +2 -0
  221. package/dist/esm/review/authority.js +13 -5
  222. package/dist/esm/review/availability.d.ts +22 -0
  223. package/dist/esm/review/availability.js +107 -20
  224. package/dist/esm/review/delivery-verifier.d.ts +27 -0
  225. package/dist/esm/review/delivery-verifier.js +115 -0
  226. package/dist/esm/review/events.d.ts +3 -2
  227. package/dist/esm/review/events.js +23 -3
  228. package/dist/esm/review/execution/adapters.js +26 -9
  229. package/dist/esm/review/execution/output-policy.d.ts +2 -0
  230. package/dist/esm/review/execution/output-policy.js +12 -0
  231. package/dist/esm/review/execution/review-checkout.js +87 -6
  232. package/dist/esm/review/execution/supervisor.js +5 -0
  233. package/dist/esm/review/execution/types.d.ts +8 -0
  234. package/dist/esm/review/opencode-account.d.ts +24 -0
  235. package/dist/esm/review/opencode-account.js +68 -0
  236. package/dist/esm/review/opencode-auth.d.ts +33 -0
  237. package/dist/esm/review/opencode-auth.js +79 -0
  238. package/dist/esm/review/subject.d.ts +12 -0
  239. package/dist/esm/review/subject.js +74 -22
  240. package/dist/esm/runtime/opencode-account-materializer.d.ts +34 -0
  241. package/dist/esm/runtime/opencode-account-materializer.js +33 -0
  242. package/dist/esm/status/snapshot.js +30 -19
  243. package/dist/esm/test/duration-sequencer.d.ts +20 -0
  244. package/dist/esm/test/duration-sequencer.js +54 -0
  245. package/dist/esm/test/shard-durations.json +922 -0
  246. package/dist/esm/test/worker-budget.d.ts +6 -0
  247. package/dist/esm/test/worker-budget.js +59 -1
  248. package/dist/esm/test-helpers/global-setup.d.ts +1 -1
  249. package/dist/esm/test-helpers/global-setup.js +68 -24
  250. package/dist/esm/ultragoal/service.d.ts +7 -0
  251. package/dist/esm/ultragoal/service.js +42 -2
  252. package/dist/esm/utils/write-json-file.js +3 -1
  253. package/dist/esm/worktrees/codex-project-trust.d.ts +15 -0
  254. package/dist/esm/worktrees/codex-project-trust.js +56 -0
  255. package/dist/esm/worktrees/registry.d.ts +8 -0
  256. package/dist/esm/worktrees/registry.js +18 -3
  257. package/package.json +16 -13
@@ -1,8 +1,18 @@
1
1
  /**
2
2
  * Daemon-side git helpers for review panel RPCs (Task 1.5).
3
3
  * Runs real git via child_process — never re-implements porcelain.
4
+ *
5
+ * `gitCreatePr` additionally spawns `gh` (same class of utility-binary spawn
6
+ * as the `git` calls above — see Trust Dossier Material Decision MD1 on the
7
+ * desktop-daemon-rpc-completion blueprint overview for why this does not
8
+ * cross the daemon's "no agent-child spawn" invariant). It adapts
9
+ * the gh-wrapping logic from `src/mcp/tools/pr-upsert.ts` (preflight,
10
+ * collision detection, canonical re-fetch, output redaction) to this
11
+ * module's synchronous-git / injectable-deps pattern.
4
12
  */
5
13
  import { execFileSync } from "node:child_process";
14
+ import { runCommand, isRunFailure } from "#mcp/tools/_shared/run-command.js";
15
+ import { redactText } from "#mcp/tools/_shared/redact.js";
6
16
  export function gitDiff(cwd) {
7
17
  const out = execFileSync("git", ["status", "--porcelain=v1", "-uall", "--no-renames"], {
8
18
  cwd,
@@ -45,3 +55,129 @@ export function gitCommit(cwd, message, paths, options) {
45
55
  }).trim();
46
56
  return { commitSha };
47
57
  }
58
+ /** Same default timeoutMs `src/mcp/tools/pr-upsert.ts` already uses for `gh` calls. */
59
+ const GH_TIMEOUT_MS = 120_000;
60
+ function defaultCurrentBranch(cwd) {
61
+ const branch = execFileSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
62
+ cwd,
63
+ encoding: "utf8",
64
+ stdio: ["ignore", "pipe", "pipe"],
65
+ }).trim();
66
+ if (!branch || branch === "HEAD") {
67
+ throw new Error("git.createPr requires a named branch (HEAD is detached)");
68
+ }
69
+ return branch;
70
+ }
71
+ function defaultGh(args, cwd) {
72
+ return runCommand("gh", args, { cwd, timeoutMs: GH_TIMEOUT_MS });
73
+ }
74
+ function outcomeText(outcome) {
75
+ if (isRunFailure(outcome))
76
+ return outcome.error.message;
77
+ return [outcome.stdout, outcome.stderr].filter(Boolean).join("\n");
78
+ }
79
+ function outcomeOk(outcome) {
80
+ return !isRunFailure(outcome) && outcome.exitCode === 0;
81
+ }
82
+ function parseTarget(outcome) {
83
+ if (!outcomeOk(outcome))
84
+ return undefined;
85
+ try {
86
+ const parsed = JSON.parse(outcome.stdout);
87
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
88
+ return undefined;
89
+ const value = parsed;
90
+ return {
91
+ number: typeof value.number === "number" ? value.number : undefined,
92
+ url: typeof value.url === "string" ? value.url : undefined,
93
+ title: typeof value.title === "string" ? value.title : undefined,
94
+ state: typeof value.state === "string" ? value.state : undefined,
95
+ };
96
+ }
97
+ catch {
98
+ return undefined;
99
+ }
100
+ }
101
+ /** Mirrors `src/mcp/tools/pr-upsert.ts`'s `isNoPr` string-matching (do not reinvent). */
102
+ function isNoPr(outcome) {
103
+ if (outcomeOk(outcome))
104
+ return false;
105
+ const text = outcomeText(outcome).toLowerCase();
106
+ return (text.includes("no pull requests found") ||
107
+ text.includes("no pull request found") ||
108
+ text.includes("could not find pull request"));
109
+ }
110
+ /** Mirrors `src/mcp/tools/pr-upsert.ts`'s `isCreateCollision` string-matching (do not reinvent). */
111
+ function isCreateCollision(outcome) {
112
+ if (outcomeOk(outcome))
113
+ return false;
114
+ const text = outcomeText(outcome).toLowerCase();
115
+ return text.includes("already exists") || text.includes("a pull request already");
116
+ }
117
+ function throwGhFailure(action, outcome) {
118
+ const detail = redactText(outcomeText(outcome)) || "unknown error";
119
+ throw new Error(`git.createPr: gh ${action} failed: ${detail}`);
120
+ }
121
+ function requireUrl(target, context) {
122
+ if (!target.url) {
123
+ throw new Error(`git.createPr: ${context} did not return a PR url`);
124
+ }
125
+ return target.url;
126
+ }
127
+ function buildEditArgs(branch, title, body) {
128
+ const args = ["pr", "edit", branch, "--title", title];
129
+ if (body !== undefined)
130
+ args.push("--body", body);
131
+ return args;
132
+ }
133
+ function buildCreateArgs(branch, base, title, body) {
134
+ const args = ["pr", "create", "--head", branch, "--base", base, "--title", title];
135
+ if (body !== undefined)
136
+ args.push("--body", body);
137
+ return args;
138
+ }
139
+ /**
140
+ * Upsert semantics (the frozen daemon contract has no create/update `mode`
141
+ * field, see Trust Dossier MD2): edit the PR for the current branch if one
142
+ * already exists, else create it against the repo's default branch. Every
143
+ * success path re-fetches the canonical PR view rather than trusting
144
+ * `gh pr create`'s stdout alone (matches `src/mcp/tools/pr-upsert.ts`'s
145
+ * canonical-refetch pattern) so a create-collision (two callers racing)
146
+ * still returns the real PR instead of throwing.
147
+ */
148
+ export async function gitCreatePr(cwd, title, body, deps) {
149
+ const currentBranch = deps?.currentBranch ?? defaultCurrentBranch;
150
+ const gh = deps?.gh ?? defaultGh;
151
+ const branch = currentBranch(cwd);
152
+ const preflight = await gh(["pr", "view", branch, "--json", "number,url,title,state"], cwd);
153
+ if (outcomeOk(preflight)) {
154
+ const target = parseTarget(preflight);
155
+ if (!target)
156
+ throwGhFailure("pr view (preflight)", preflight);
157
+ const edit = await gh(buildEditArgs(branch, title, body), cwd);
158
+ if (!outcomeOk(edit))
159
+ throwGhFailure("pr edit", edit);
160
+ return { url: requireUrl(target, "pr view (preflight)"), number: target.number };
161
+ }
162
+ if (!isNoPr(preflight))
163
+ throwGhFailure("pr view (preflight)", preflight);
164
+ const repoView = await gh(["repo", "view", "--json", "defaultBranchRef", "-q", ".defaultBranchRef.name"], cwd);
165
+ if (!outcomeOk(repoView))
166
+ throwGhFailure("repo view (default branch)", repoView);
167
+ const base = repoView.stdout.trim();
168
+ if (!base) {
169
+ throw new Error("git.createPr: could not resolve the repository default branch");
170
+ }
171
+ const create = await gh(buildCreateArgs(branch, base, title, body), cwd);
172
+ if (!outcomeOk(create) && !isCreateCollision(create)) {
173
+ throwGhFailure("pr create", create);
174
+ }
175
+ const canonical = await gh(["pr", "view", branch, "--json", "number,url,title,state"], cwd);
176
+ const canonicalTarget = parseTarget(canonical);
177
+ if (!canonicalTarget)
178
+ throwGhFailure("pr view (canonical)", canonical);
179
+ return {
180
+ url: requireUrl(canonicalTarget, "pr view (canonical)"),
181
+ number: canonicalTarget.number,
182
+ };
183
+ }
@@ -2,6 +2,8 @@
2
2
  * Cross-process run-registry interop between wp dash and the desktop app (1.6).
3
3
  * Reuses the existing dash run-registry store paths — no second registry.
4
4
  */
5
+ import type { DashRun } from "#cli/commands/dash/run-types.js";
6
+ import type { SessionsListResult, SessionSummary } from "#daemon/protocol/contract.js";
5
7
  export type RunRegistrySnapshot = {
6
8
  readonly root: string;
7
9
  readonly runIds: readonly string[];
@@ -12,3 +14,17 @@ export type RunRegistrySnapshot = {
12
14
  * `root` should be the directory that contains per-run JSON sidecars.
13
15
  */
14
16
  export declare function listRunRegistry(root: string): RunRegistrySnapshot;
17
+ /** Pure mapping from a dash run to the daemon's UI-facing session shape. */
18
+ export declare function toSessionSummary(run: DashRun): SessionSummary;
19
+ export interface ListDaemonSessionsOptions {
20
+ readonly cwd?: string;
21
+ readonly limit?: number;
22
+ }
23
+ /**
24
+ * Daemon `sessions.list` backing implementation: reads the real dash
25
+ * run-registry (no second registry) and maps it to the daemon wire shape.
26
+ * Complexity: O(n log n) for the updatedAt-descending sort (n = dash runs at
27
+ * one repo root — small/bounded); no additional filesystem scans beyond the
28
+ * single locked registry read `readDashRuns` already performs.
29
+ */
30
+ export declare function listDaemonSessions(options?: ListDaemonSessionsOptions): Promise<SessionsListResult>;
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import { existsSync, readdirSync, readFileSync } from "node:fs";
6
6
  import { join } from "node:path";
7
+ import { readDashRuns } from "#cli/commands/dash/run-registry.js";
7
8
  /**
8
9
  * List run ids under a dash-compatible registry root.
9
10
  * `root` should be the directory that contains per-run JSON sidecars.
@@ -27,3 +28,47 @@ export function listRunRegistry(root) {
27
28
  }
28
29
  return { root, runIds: runIds.sort(), readable: true };
29
30
  }
31
+ /**
32
+ * Daemon `providerIdSchema` (src/daemon/protocol/contract.ts) only accepts
33
+ * 'claude' | 'codex' | 'opencode' | 'fleet'. `DashRun.provider` can also be
34
+ * 'grok' (src/cli/commands/dash/provider-capabilities.ts DASH_PROVIDERS).
35
+ * `parseUiMethodResult` is `.strict()` and would throw on the whole response
36
+ * for one out-of-enum row, so an unrecognized provider is omitted (the field
37
+ * is optional on `SessionSummary`) rather than passed through or fabricated.
38
+ */
39
+ const KNOWN_DAEMON_PROVIDERS = new Set([
40
+ "claude",
41
+ "codex",
42
+ "opencode",
43
+ "fleet",
44
+ ]);
45
+ function isKnownDaemonProvider(provider) {
46
+ return KNOWN_DAEMON_PROVIDERS.has(provider);
47
+ }
48
+ /** Pure mapping from a dash run to the daemon's UI-facing session shape. */
49
+ export function toSessionSummary(run) {
50
+ return {
51
+ id: run.id,
52
+ ...(isKnownDaemonProvider(run.provider) ? { provider: run.provider } : {}),
53
+ label: run.label,
54
+ state: run.state,
55
+ cwd: run.cwd,
56
+ permissionMode: run.permissionMode,
57
+ updatedAt: run.updatedAt,
58
+ };
59
+ }
60
+ /**
61
+ * Daemon `sessions.list` backing implementation: reads the real dash
62
+ * run-registry (no second registry) and maps it to the daemon wire shape.
63
+ * Complexity: O(n log n) for the updatedAt-descending sort (n = dash runs at
64
+ * one repo root — small/bounded); no additional filesystem scans beyond the
65
+ * single locked registry read `readDashRuns` already performs.
66
+ */
67
+ export async function listDaemonSessions(options = {}) {
68
+ const { runs } = await readDashRuns({ cwd: options.cwd });
69
+ const sorted = [...runs].sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
70
+ const limited = typeof options.limit === "number" && options.limit >= 0
71
+ ? sorted.slice(0, options.limit)
72
+ : sorted;
73
+ return { sessions: limited.map(toSessionSummary) };
74
+ }
@@ -18,3 +18,14 @@ export declare function searchSessions(backend: SessionSearchBackend, options: {
18
18
  readonly query: string;
19
19
  readonly limit?: number;
20
20
  }): readonly SessionSearchHit[];
21
+ /**
22
+ * Production backend: opens the real `SessionMemoryStore` FTS index (porter
23
+ * → trigram → Levenshtein fallback, same engine behind `wp_session_search`)
24
+ * and reuses its indexed search — never a table scan. A fresh store is
25
+ * opened and closed per call, mirroring the exact pattern
26
+ * `src/mcp/tools/session-restore.ts`'s `buildRecallPayload` already uses for
27
+ * the identical class (avoids a stale open SQLite/WAL handle). Caching a
28
+ * store across daemon-lifetime calls is intentionally deferred (YAGNI) until
29
+ * there is evidence of per-RPC latency pressure.
30
+ */
31
+ export declare function createSessionMemorySearchBackend(indexDbPath: string): SessionSearchBackend;
@@ -2,6 +2,7 @@
2
2
  * Session search domain (Task 3.7).
3
3
  * Pure ranking/filter helpers + injectable FTS backend (session-memory store).
4
4
  */
5
+ import { SessionMemoryStore } from "#session-memory/store.js";
5
6
  /** Normalize and bound a search query; empty → no search. */
6
7
  export function normalizeSearchQuery(query) {
7
8
  return query.trim().replace(/\s+/gu, " ").slice(0, 200);
@@ -14,3 +15,31 @@ export function searchSessions(backend, options) {
14
15
  const limit = Math.min(Math.max(options.limit ?? 20, 1), 100);
15
16
  return backend.search(q, limit);
16
17
  }
18
+ /**
19
+ * Production backend: opens the real `SessionMemoryStore` FTS index (porter
20
+ * → trigram → Levenshtein fallback, same engine behind `wp_session_search`)
21
+ * and reuses its indexed search — never a table scan. A fresh store is
22
+ * opened and closed per call, mirroring the exact pattern
23
+ * `src/mcp/tools/session-restore.ts`'s `buildRecallPayload` already uses for
24
+ * the identical class (avoids a stale open SQLite/WAL handle). Caching a
25
+ * store across daemon-lifetime calls is intentionally deferred (YAGNI) until
26
+ * there is evidence of per-RPC latency pressure.
27
+ */
28
+ export function createSessionMemorySearchBackend(indexDbPath) {
29
+ return {
30
+ search(query, limit) {
31
+ const store = new SessionMemoryStore(indexDbPath);
32
+ try {
33
+ return store.search({ query, limit }).map((hit) => ({
34
+ id: hit.id,
35
+ source: hit.source,
36
+ text: hit.text,
37
+ score: hit.score,
38
+ }));
39
+ }
40
+ finally {
41
+ store.close();
42
+ }
43
+ },
44
+ };
45
+ }
@@ -0,0 +1,5 @@
1
+ import type { MethodHandler } from "#daemon/rpc.js";
2
+ /**
3
+ * Build blueprint-domain handlers scoped to `repoRoot`.
4
+ */
5
+ export declare function createBlueprintsHandlers(repoRoot: string): Readonly<Partial<Record<string, MethodHandler>>>;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Blueprint-domain product handlers: `blueprints.list` is a real
3
+ * implementation over the `blueprints/<status>/` directories; `blueprints.exec`
4
+ * is not implemented (exec remains CLI-owned).
5
+ */
6
+ import { readdirSync, existsSync, statSync } from "node:fs";
7
+ import { join } from "node:path";
8
+ function listBlueprintRows(repoRoot) {
9
+ const statuses = ["completed", "in-progress", "planned", "parked", "draft", "archived"];
10
+ const rows = [];
11
+ for (const status of statuses) {
12
+ const dir = join(repoRoot, "blueprints", status);
13
+ if (!existsSync(dir) || !statSync(dir).isDirectory())
14
+ continue;
15
+ for (const name of readdirSync(dir)) {
16
+ if (name.startsWith("."))
17
+ continue;
18
+ rows.push({ slug: name, status });
19
+ }
20
+ }
21
+ rows.sort((a, b) => a.slug.localeCompare(b.slug));
22
+ return rows;
23
+ }
24
+ /**
25
+ * Build blueprint-domain handlers scoped to `repoRoot`.
26
+ */
27
+ export function createBlueprintsHandlers(repoRoot) {
28
+ return {
29
+ "blueprints.list": () => ({
30
+ blueprints: listBlueprintRows(repoRoot),
31
+ }),
32
+ "blueprints.exec": () => {
33
+ throw new Error("blueprints.exec is not implemented (exec remains CLI-owned)");
34
+ },
35
+ };
36
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Deploy-domain product handlers: `deploy.run` is not implemented (no deploy
3
+ * job ledger; refuse fabricated handles).
4
+ */
5
+ import type { MethodHandler } from "#daemon/rpc.js";
6
+ export declare const deployHandlers: Readonly<Partial<Record<string, MethodHandler>>>;
@@ -0,0 +1,5 @@
1
+ export const deployHandlers = {
2
+ "deploy.run": () => {
3
+ throw new Error("deploy.run is not implemented (no deploy job ledger; refuse fabricated handles)");
4
+ },
5
+ };
@@ -0,0 +1,15 @@
1
+ import type { MethodHandler } from "#daemon/rpc.js";
2
+ import { type FleetStatus } from "#fleet/status.js";
3
+ import type { FleetStatusResult } from "#daemon/protocol/contract.js";
4
+ /**
5
+ * Adapt the rich `collectFleetStatus` output down to the FROZEN daemon wire
6
+ * contract `{ agents: [{ id, state, label? }] }` that
7
+ * apps/desktop/src-tauri/src/commands/fleet.rs already destructures. Pure /
8
+ * unit-testable without spawning real git or gh. Complexity: O(worktrees).
9
+ */
10
+ export declare function toFleetStatusResult(status: FleetStatus): FleetStatusResult;
11
+ /**
12
+ * Build fleet-domain handlers. `repoRoot` is the default worktree root used
13
+ * when a request does not supply its own `repoRoot` param.
14
+ */
15
+ export declare function createFleetHandlers(repoRoot: string): Readonly<Partial<Record<string, MethodHandler>>>;
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Fleet-domain product handlers: `worktrees.list` is a real implementation
3
+ * over `git worktree list`; `fleet.status` calls the production
4
+ * `collectFleetStatus` engine and adapts its shape to the frozen daemon
5
+ * wire contract.
6
+ */
7
+ import { execFileSync } from "node:child_process";
8
+ import { collectFleetStatus } from "#fleet/status.js";
9
+ import { asRecord } from "./shared.js";
10
+ function worktreeRows(repoRoot) {
11
+ try {
12
+ const out = execFileSync("git", ["worktree", "list", "--porcelain"], {
13
+ cwd: repoRoot,
14
+ encoding: "utf8",
15
+ stdio: ["ignore", "pipe", "pipe"],
16
+ });
17
+ const rows = [];
18
+ let path;
19
+ let branch;
20
+ for (const line of out.split("\n")) {
21
+ if (line.startsWith("worktree ")) {
22
+ if (path)
23
+ rows.push({ path, branch });
24
+ path = line.slice("worktree ".length).trim();
25
+ branch = undefined;
26
+ }
27
+ else if (line.startsWith("branch ")) {
28
+ branch = line
29
+ .slice("branch ".length)
30
+ .trim()
31
+ .replace(/^refs\/heads\//u, "");
32
+ }
33
+ else if (line === "") {
34
+ if (path)
35
+ rows.push({ path, branch });
36
+ path = undefined;
37
+ branch = undefined;
38
+ }
39
+ }
40
+ if (path)
41
+ rows.push({ path, branch });
42
+ return rows;
43
+ }
44
+ catch {
45
+ return [{ path: repoRoot }];
46
+ }
47
+ }
48
+ /** Single-string worktree classification the frozen daemon wire contract carries as `state`. */
49
+ function classifyWorktreeState(git) {
50
+ if (git.dirtyFiles === null)
51
+ return "unknown";
52
+ if (git.dirtyFiles > 0)
53
+ return "dirty";
54
+ if ((git.ahead ?? 0) > 0 || (git.behind ?? 0) > 0)
55
+ return "drifted";
56
+ return "clean";
57
+ }
58
+ /**
59
+ * Adapt the rich `collectFleetStatus` output down to the FROZEN daemon wire
60
+ * contract `{ agents: [{ id, state, label? }] }` that
61
+ * apps/desktop/src-tauri/src/commands/fleet.rs already destructures. Pure /
62
+ * unit-testable without spawning real git or gh. Complexity: O(worktrees).
63
+ */
64
+ export function toFleetStatusResult(status) {
65
+ return {
66
+ agents: status.worktrees.map((worktree) => ({
67
+ id: worktree.path,
68
+ state: classifyWorktreeState(worktree.git),
69
+ ...(worktree.label ? { label: worktree.label } : {}),
70
+ })),
71
+ };
72
+ }
73
+ /**
74
+ * Build fleet-domain handlers. `repoRoot` is the default worktree root used
75
+ * when a request does not supply its own `repoRoot` param.
76
+ */
77
+ export function createFleetHandlers(repoRoot) {
78
+ return {
79
+ "fleet.status": async () => {
80
+ const status = await collectFleetStatus({ cwd: repoRoot });
81
+ return toFleetStatusResult(status);
82
+ },
83
+ "worktrees.list": (_session, params) => {
84
+ const record = asRecord(params);
85
+ const root = typeof record.repoRoot === "string" && record.repoRoot.length > 0
86
+ ? record.repoRoot
87
+ : repoRoot;
88
+ return { worktrees: worktreeRows(root) };
89
+ },
90
+ };
91
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Git-domain product handlers: `git.diff`, `git.commit`, and `git.createPr`
3
+ * are real implementations over `src/daemon/domains/git-actions.ts`.
4
+ */
5
+ import type { MethodHandler } from "#daemon/rpc.js";
6
+ export declare const gitHandlers: Readonly<Partial<Record<string, MethodHandler>>>;
@@ -0,0 +1,27 @@
1
+ import { gitDiff, gitCommit, gitCreatePr } from "#daemon/domains/git-actions.js";
2
+ import { asRecord, requireString } from "./shared.js";
3
+ export const gitHandlers = {
4
+ "git.diff": (_session, params) => {
5
+ const record = asRecord(params);
6
+ const cwd = requireString(record, "cwd");
7
+ return gitDiff(cwd);
8
+ },
9
+ "git.commit": (_session, params) => {
10
+ const record = asRecord(params);
11
+ const cwd = requireString(record, "cwd");
12
+ const message = requireString(record, "message");
13
+ const paths = Array.isArray(record.paths)
14
+ ? record.paths.filter((p) => typeof p === "string")
15
+ : undefined;
16
+ return gitCommit(cwd, message, paths);
17
+ },
18
+ "git.createPr": (_session, params) => {
19
+ const record = asRecord(params);
20
+ const cwd = requireString(record, "cwd");
21
+ const title = requireString(record, "title");
22
+ // confirmationToken is already consumed by DaemonAuthz before this
23
+ // handler runs (methods.ts requiresConfirmation) — no re-check needed here.
24
+ const body = typeof record.body === "string" ? record.body : undefined;
25
+ return gitCreatePr(cwd, title, body);
26
+ },
27
+ };
@@ -1,3 +1,10 @@
1
+ /**
2
+ * Default production handlers for registered product-domain RPC methods.
3
+ * Wired at daemon start so callers do not need ad-hoc injection.
4
+ *
5
+ * Domain implementations live in the sibling `*-handlers.ts` files; this
6
+ * module only aggregates them into the map `startDaemonServer` consumes.
7
+ */
1
8
  import type { MethodHandler } from "#daemon/rpc.js";
2
9
  /**
3
10
  * Build the default handler map. Callers may override individual methods via
@@ -1,78 +1,8 @@
1
- /**
2
- * Default production handlers for registered product-domain RPC methods.
3
- * Wired at daemon start so callers do not need ad-hoc injection.
4
- */
5
- import { readdirSync, existsSync, statSync } from "node:fs";
6
- import { join } from "node:path";
7
- import { execFileSync } from "node:child_process";
8
- import { gitDiff, gitCommit } from "#daemon/domains/git-actions.js";
9
- function asRecord(params) {
10
- if (params === null || typeof params !== "object" || Array.isArray(params)) {
11
- return {};
12
- }
13
- return params;
14
- }
15
- function requireString(record, key) {
16
- const v = record[key];
17
- if (typeof v !== "string" || v.length === 0) {
18
- throw new Error(`missing string param: ${key}`);
19
- }
20
- return v;
21
- }
22
- function listBlueprintRows(repoRoot) {
23
- const statuses = ["completed", "in-progress", "planned", "parked", "draft", "archived"];
24
- const rows = [];
25
- for (const status of statuses) {
26
- const dir = join(repoRoot, "blueprints", status);
27
- if (!existsSync(dir) || !statSync(dir).isDirectory())
28
- continue;
29
- for (const name of readdirSync(dir)) {
30
- if (name.startsWith("."))
31
- continue;
32
- rows.push({ slug: name, status });
33
- }
34
- }
35
- rows.sort((a, b) => a.slug.localeCompare(b.slug));
36
- return rows;
37
- }
38
- function worktreeRows(repoRoot) {
39
- try {
40
- const out = execFileSync("git", ["worktree", "list", "--porcelain"], {
41
- cwd: repoRoot,
42
- encoding: "utf8",
43
- stdio: ["ignore", "pipe", "pipe"],
44
- });
45
- const rows = [];
46
- let path;
47
- let branch;
48
- for (const line of out.split("\n")) {
49
- if (line.startsWith("worktree ")) {
50
- if (path)
51
- rows.push({ path, branch });
52
- path = line.slice("worktree ".length).trim();
53
- branch = undefined;
54
- }
55
- else if (line.startsWith("branch ")) {
56
- branch = line
57
- .slice("branch ".length)
58
- .trim()
59
- .replace(/^refs\/heads\//u, "");
60
- }
61
- else if (line === "") {
62
- if (path)
63
- rows.push({ path, branch });
64
- path = undefined;
65
- branch = undefined;
66
- }
67
- }
68
- if (path)
69
- rows.push({ path, branch });
70
- return rows;
71
- }
72
- catch {
73
- return [{ path: repoRoot }];
74
- }
75
- }
1
+ import { gitHandlers } from "./git-handlers.js";
2
+ import { createFleetHandlers } from "./fleet-handlers.js";
3
+ import { createBlueprintsHandlers } from "./blueprints-handlers.js";
4
+ import { createSessionsHandlers } from "./sessions-handlers.js";
5
+ import { deployHandlers } from "./deploy-handlers.js";
76
6
  /**
77
7
  * Build the default handler map. Callers may override individual methods via
78
8
  * `startDaemonServer({ handlers })` — overrides win.
@@ -80,49 +10,10 @@ function worktreeRows(repoRoot) {
80
10
  export function createDefaultProductHandlers(options) {
81
11
  const repoRoot = options?.repoRoot ?? process.cwd();
82
12
  return {
83
- "git.diff": (_session, params) => {
84
- const record = asRecord(params);
85
- const cwd = requireString(record, "cwd");
86
- return gitDiff(cwd);
87
- },
88
- "git.commit": (_session, params) => {
89
- const record = asRecord(params);
90
- const cwd = requireString(record, "cwd");
91
- const message = requireString(record, "message");
92
- const paths = Array.isArray(record.paths)
93
- ? record.paths.filter((p) => typeof p === "string")
94
- : undefined;
95
- return gitCommit(cwd, message, paths);
96
- },
97
- "git.createPr": () => {
98
- throw new Error("git.createPr is not implemented in agent-kit daemon (host policy / gh required)");
99
- },
100
- "fleet.status": () => {
101
- throw new Error("fleet.status is not implemented (no worktree fleet integration; refuse empty success)");
102
- },
103
- "worktrees.list": (_session, params) => {
104
- const record = asRecord(params);
105
- const root = typeof record.repoRoot === "string" && record.repoRoot.length > 0
106
- ? record.repoRoot
107
- : repoRoot;
108
- return { worktrees: worktreeRows(root) };
109
- },
110
- "blueprints.list": () => ({
111
- blueprints: listBlueprintRows(repoRoot),
112
- }),
113
- "blueprints.exec": () => {
114
- throw new Error("blueprints.exec is not implemented (exec remains CLI-owned)");
115
- },
116
- "sessions.list": () => {
117
- throw new Error("sessions.list is not implemented (PTY sessions are Tauri-owned; refuse empty success)");
118
- },
119
- "deploy.run": () => {
120
- throw new Error("deploy.run is not implemented (no deploy job ledger; refuse fabricated handles)");
121
- },
122
- "launch.permissionState": () => ({
123
- mode: "safe",
124
- yoloPreference: false,
125
- isolationWarning: "permission state is advisory until full permission UX lands",
126
- }),
13
+ ...gitHandlers,
14
+ ...createFleetHandlers(repoRoot),
15
+ ...createBlueprintsHandlers(repoRoot),
16
+ ...createSessionsHandlers(repoRoot),
17
+ ...deployHandlers,
127
18
  };
128
19
  }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Session/launch-domain product handlers: `sessions.list` reads the real
3
+ * dash run-registry; `sessions.search` reuses the session-memory FTS index;
4
+ * `launch.permissionState` returns the advisory permission-state stub.
5
+ */
6
+ import type { MethodHandler } from "#daemon/rpc.js";
7
+ /**
8
+ * Build session-domain handlers scoped to `repoRoot`. `repoRoot` doubles as
9
+ * the dash run-registry cwd (sessions.list) and the session-memory index
10
+ * root (sessions.search) — both already resolve per-repo paths on their own.
11
+ */
12
+ export declare function createSessionsHandlers(repoRoot: string): Readonly<Partial<Record<string, MethodHandler>>>;