@gajae-code/coding-agent 0.15.6 → 0.16.1

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 (270) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/dist/types/async/job-manager.d.ts +32 -1
  3. package/dist/types/browser-backend.d.ts +12 -0
  4. package/dist/types/cli/args.d.ts +2 -0
  5. package/dist/types/cli/root-flags.d.ts +14 -0
  6. package/dist/types/cli/update-cli.d.ts +14 -0
  7. package/dist/types/cli.d.ts +7 -0
  8. package/dist/types/commands/launch.d.ts +10 -0
  9. package/dist/types/commands/sdk.d.ts +2 -0
  10. package/dist/types/config/autorouting-tier-map.d.ts +24 -0
  11. package/dist/types/config/billing-path.d.ts +25 -0
  12. package/dist/types/config/config-schema-version.d.ts +13 -1
  13. package/dist/types/config/file-lock.d.ts +5 -0
  14. package/dist/types/config/model-registry.d.ts +22 -0
  15. package/dist/types/config/settings-schema.d.ts +27 -8
  16. package/dist/types/config/settings.d.ts +2 -0
  17. package/dist/types/coordinator-mcp/projection-scan.d.ts +8 -0
  18. package/dist/types/crash/record-loader.d.ts +15 -0
  19. package/dist/types/extensibility/extensions/types.d.ts +8 -3
  20. package/dist/types/gjc-runtime/launch-worktree-reservation.d.ts +21 -0
  21. package/dist/types/gjc-runtime/launch-worktree.d.ts +25 -1
  22. package/dist/types/gjc-runtime/managed-owner-supervisor.d.ts +2 -0
  23. package/dist/types/gjc-runtime/session-state-lock.d.ts +22 -0
  24. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +66 -1
  25. package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +1 -0
  26. package/dist/types/gjc-runtime/tmux-sessions.d.ts +27 -0
  27. package/dist/types/main.d.ts +1 -0
  28. package/dist/types/master-mode/context.d.ts +21 -0
  29. package/dist/types/master-mode/first-request.d.ts +34 -0
  30. package/dist/types/master-mode/snapshot.d.ts +32 -0
  31. package/dist/types/modes/acp/acp-agent.d.ts +21 -21
  32. package/dist/types/modes/components/frictionless-onboarding-selector.d.ts +10 -0
  33. package/dist/types/modes/components/model-selector.d.ts +4 -0
  34. package/dist/types/modes/components/oauth-selector.d.ts +1 -0
  35. package/dist/types/modes/components/session-selector.d.ts +1 -1
  36. package/dist/types/modes/components/sessions-dashboard.d.ts +2 -1
  37. package/dist/types/modes/components/status-line/model-name.d.ts +18 -0
  38. package/dist/types/modes/components/status-line/priority-row.d.ts +34 -0
  39. package/dist/types/modes/components/status-line/segments.d.ts +10 -0
  40. package/dist/types/modes/interactive-mode.d.ts +16 -2
  41. package/dist/types/modes/print-mode.d.ts +17 -0
  42. package/dist/types/modes/theme/theme.d.ts +2 -1
  43. package/dist/types/modes/types.d.ts +2 -0
  44. package/dist/types/modes/ui-language.d.ts +7 -1
  45. package/dist/types/sdk/broker/broker.d.ts +79 -2
  46. package/dist/types/sdk/broker/endpoint-authority.d.ts +24 -0
  47. package/dist/types/sdk/broker/ensure.d.ts +3 -0
  48. package/dist/types/sdk/broker/index.d.ts +3 -0
  49. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +6 -0
  50. package/dist/types/sdk/broker/lifecycle.d.ts +40 -0
  51. package/dist/types/sdk/broker/master-capability.d.ts +10 -0
  52. package/dist/types/sdk/broker/session-index.d.ts +40 -11
  53. package/dist/types/sdk/broker/session-scope.d.ts +72 -0
  54. package/dist/types/sdk/broker/spawn-authority.d.ts +201 -0
  55. package/dist/types/sdk/broker/spawn-substrate.d.ts +30 -0
  56. package/dist/types/sdk/broker/startup-budget.d.ts +52 -0
  57. package/dist/types/sdk/broker/state-version.d.ts +21 -1
  58. package/dist/types/sdk/broker/worktree-occupancy.d.ts +28 -0
  59. package/dist/types/sdk/bus/chat-daemon-control.d.ts +3 -0
  60. package/dist/types/sdk/bus/discord-daemon.d.ts +1 -1
  61. package/dist/types/sdk/bus/index.d.ts +9 -1
  62. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +1 -1
  63. package/dist/types/sdk/bus/prompt-reconciliation.d.ts +1 -1
  64. package/dist/types/sdk/bus/slack-conversation.d.ts +1 -1
  65. package/dist/types/sdk/bus/slack-daemon.d.ts +1 -1
  66. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +1 -1
  67. package/dist/types/sdk/cli/index.d.ts +1 -0
  68. package/dist/types/sdk/cli/master-cli.d.ts +63 -0
  69. package/dist/types/sdk/cli/rows.d.ts +12 -5
  70. package/dist/types/sdk/cli/session-cli.d.ts +20 -3
  71. package/dist/types/sdk/client/client.d.ts +3 -2
  72. package/dist/types/sdk/host/control/dispatch.d.ts +10 -0
  73. package/dist/types/sdk/host/control/index.d.ts +1 -1
  74. package/dist/types/sdk/host/control/operations.d.ts +2 -0
  75. package/dist/types/sdk/host/control/runtime-gate.d.ts +21 -7
  76. package/dist/types/sdk/host/events.d.ts +1 -0
  77. package/dist/types/sdk/host/host.d.ts +10 -0
  78. package/dist/types/sdk/host/query/cursor.d.ts +4 -2
  79. package/dist/types/sdk/host/query/handlers.d.ts +1 -0
  80. package/dist/types/sdk/host/query/revision-store.d.ts +1 -0
  81. package/dist/types/sdk/host/session-runtime.d.ts +70 -17
  82. package/dist/types/sdk/lifecycle/broker-client.d.ts +6 -0
  83. package/dist/types/sdk/lifecycle/service.d.ts +15 -3
  84. package/dist/types/sdk/lifecycle-session.d.ts +3 -1
  85. package/dist/types/sdk/prompt-deadline-manager.d.ts +2 -5
  86. package/dist/types/sdk/receipt-state.d.ts +2 -0
  87. package/dist/types/sdk/router/session-router.d.ts +6 -0
  88. package/dist/types/sdk/session.d.ts +16 -0
  89. package/dist/types/sdk/startup-capability.d.ts +2 -1
  90. package/dist/types/sdk/turn-result.d.ts +6 -0
  91. package/dist/types/session/agent-session.d.ts +52 -7
  92. package/dist/types/session/credential-store-errors.d.ts +1 -0
  93. package/dist/types/session/fold-coordinator.d.ts +29 -2
  94. package/dist/types/session/session-manager.d.ts +79 -2
  95. package/dist/types/session/yield-queue.d.ts +5 -4
  96. package/dist/types/setup/frictionless-onboarding.d.ts +1 -0
  97. package/dist/types/tools/ask.d.ts +1 -0
  98. package/dist/types/tools/bash.d.ts +16 -0
  99. package/dist/types/tools/browser/launch.d.ts +10 -0
  100. package/dist/types/tools/browser/registry.d.ts +8 -0
  101. package/dist/types/tools/gh.d.ts +8 -0
  102. package/dist/types/tools/index.d.ts +10 -10
  103. package/dist/types/tools/job.d.ts +3 -1
  104. package/dist/types/utils/external-editor.d.ts +7 -0
  105. package/examples/extensions/README.md +1 -1
  106. package/examples/extensions/pirate.ts +7 -4
  107. package/package.json +7 -7
  108. package/scripts/generate-sdk-operation-inventory.ts +13 -1
  109. package/scripts/verify-gjc-sdk-canonicalization.ts +35 -1
  110. package/src/async/job-manager.ts +107 -9
  111. package/src/browser-backend.ts +29 -0
  112. package/src/cli/accounts-cli.ts +9 -5
  113. package/src/cli/args.ts +17 -0
  114. package/src/cli/fast-help.ts +1 -0
  115. package/src/cli/plugin-cli.ts +29 -0
  116. package/src/cli/root-flags.ts +5 -0
  117. package/src/cli/update-cli.ts +140 -23
  118. package/src/commands/launch.ts +86 -18
  119. package/src/commands/sdk.ts +135 -28
  120. package/src/config/autorouting-tier-map.ts +12 -0
  121. package/src/config/billing-path.ts +42 -0
  122. package/src/config/config-schema-version.ts +18 -1
  123. package/src/config/file-lock.ts +158 -83
  124. package/src/config/model-preset-registry.ts +178 -23
  125. package/src/config/model-profiles.ts +5 -5
  126. package/src/config/model-registry.ts +291 -42
  127. package/src/config/model-resolver.ts +5 -0
  128. package/src/config/settings-schema.ts +27 -8
  129. package/src/config/settings.ts +51 -15
  130. package/src/coordinator-mcp/projection-scan.ts +27 -6
  131. package/src/coordinator-mcp/question-state.ts +9 -11
  132. package/src/coordinator-mcp/server.ts +115 -21
  133. package/src/crash/index-store.ts +2 -0
  134. package/src/crash/record-loader.ts +10 -0
  135. package/src/defaults/gjc/skills/deep-interview/SKILL.md +1 -1
  136. package/src/extensibility/extensions/runner.ts +27 -0
  137. package/src/extensibility/extensions/types.ts +8 -3
  138. package/src/extensibility/gjc-plugins/installer.ts +51 -11
  139. package/src/extensibility/runtime-skill-discovery.ts +110 -3
  140. package/src/extensibility/skills.ts +22 -12
  141. package/src/gjc-runtime/launch-worktree-reservation.ts +242 -0
  142. package/src/gjc-runtime/launch-worktree.ts +285 -4
  143. package/src/gjc-runtime/managed-owner-supervisor.ts +63 -51
  144. package/src/gjc-runtime/session-state-lock.ts +213 -14
  145. package/src/gjc-runtime/session-state-sidecar.ts +938 -39
  146. package/src/gjc-runtime/tmux-owner-isolation-cli.ts +4 -7
  147. package/src/gjc-runtime/tmux-owner-isolation.ts +18 -3
  148. package/src/gjc-runtime/tmux-sessions.ts +252 -13
  149. package/src/hooks/skill-state.ts +6 -0
  150. package/src/internal-urls/docs-index.generated.ts +15 -15
  151. package/src/internal-urls/issue-pr-protocol.ts +4 -2
  152. package/src/main.ts +61 -3
  153. package/src/master-mode/context.ts +50 -0
  154. package/src/master-mode/first-request.ts +65 -0
  155. package/src/master-mode/snapshot.ts +205 -0
  156. package/src/modes/acp/acp-agent.ts +610 -161
  157. package/src/modes/components/footer.ts +4 -2
  158. package/src/modes/components/frictionless-onboarding-selector.ts +48 -2
  159. package/src/modes/components/model-selector.ts +76 -8
  160. package/src/modes/components/oauth-selector.ts +6 -1
  161. package/src/modes/components/session-selector.ts +23 -15
  162. package/src/modes/components/sessions-dashboard.ts +8 -5
  163. package/src/modes/components/settings-selector.ts +1 -0
  164. package/src/modes/components/status-line/model-name.ts +53 -0
  165. package/src/modes/components/status-line/priority-row.ts +107 -0
  166. package/src/modes/components/status-line/segments.ts +23 -9
  167. package/src/modes/components/tool-status-header.ts +151 -15
  168. package/src/modes/controllers/command-controller.ts +1 -1
  169. package/src/modes/controllers/event-controller.ts +30 -4
  170. package/src/modes/controllers/extension-ui-controller.ts +13 -13
  171. package/src/modes/controllers/input-controller.ts +30 -2
  172. package/src/modes/controllers/selector-controller.ts +200 -98
  173. package/src/modes/interactive-mode.ts +36 -12
  174. package/src/modes/print-mode.ts +64 -0
  175. package/src/modes/prompt-action-autocomplete.ts +30 -4
  176. package/src/modes/runtime-init.ts +12 -9
  177. package/src/modes/theme/theme.ts +5 -0
  178. package/src/modes/types.ts +2 -0
  179. package/src/modes/ui-language.ts +49 -2
  180. package/src/modes/utils/ui-helpers.ts +22 -3
  181. package/src/prompts/agent-fragments/browser-aside.md +22 -0
  182. package/src/prompts/system/master-mode.md +28 -0
  183. package/src/prompts/tools/ask.md +1 -1
  184. package/src/prompts/tools/bash.md +1 -0
  185. package/src/prompts/tools/job.md +1 -1
  186. package/src/sdk/acp/adapter.ts +5 -0
  187. package/src/sdk/broker/broker.ts +1646 -27
  188. package/src/sdk/broker/endpoint-authority.ts +86 -0
  189. package/src/sdk/broker/ensure.ts +81 -3
  190. package/src/sdk/broker/index.ts +3 -0
  191. package/src/sdk/broker/lifecycle-ledger.ts +6 -0
  192. package/src/sdk/broker/lifecycle.ts +440 -75
  193. package/src/sdk/broker/master-capability.ts +232 -0
  194. package/src/sdk/broker/session-index.ts +121 -17
  195. package/src/sdk/broker/session-scope.ts +272 -0
  196. package/src/sdk/broker/spawn-authority.ts +1031 -0
  197. package/src/sdk/broker/spawn-substrate.ts +591 -0
  198. package/src/sdk/broker/startup-budget.ts +144 -2
  199. package/src/sdk/broker/state-version.ts +43 -14
  200. package/src/sdk/broker/transport.ts +1 -0
  201. package/src/sdk/broker/worktree-occupancy.ts +90 -0
  202. package/src/sdk/bus/chat-daemon-control.ts +5 -2
  203. package/src/sdk/bus/chat-daemon-runtime.ts +136 -18
  204. package/src/sdk/bus/discord-daemon.ts +50 -10
  205. package/src/sdk/bus/index.ts +84 -7
  206. package/src/sdk/bus/kind-aware-reconciliation.ts +296 -48
  207. package/src/sdk/bus/lifecycle-commands.ts +4 -0
  208. package/src/sdk/bus/notification-service.ts +22 -5
  209. package/src/sdk/bus/prompt-reconciliation.ts +7 -2
  210. package/src/sdk/bus/reconciliation-store.ts +55 -31
  211. package/src/sdk/bus/slack-conversation.ts +1 -1
  212. package/src/sdk/bus/slack-daemon.ts +72 -38
  213. package/src/sdk/bus/telegram-daemon-contract.ts +1 -1
  214. package/src/sdk/cli/index.ts +1 -0
  215. package/src/sdk/cli/master-cli.ts +259 -0
  216. package/src/sdk/cli/rows.ts +41 -15
  217. package/src/sdk/cli/session-cli.ts +297 -26
  218. package/src/sdk/client/client.ts +14 -8
  219. package/src/sdk/host/control/dispatch.ts +101 -40
  220. package/src/sdk/host/control/index.ts +2 -0
  221. package/src/sdk/host/control/operations.ts +2 -0
  222. package/src/sdk/host/control/runtime-gate.ts +203 -11
  223. package/src/sdk/host/events.ts +1 -0
  224. package/src/sdk/host/host.ts +29 -2
  225. package/src/sdk/host/query/cursor.ts +52 -7
  226. package/src/sdk/host/query/handlers.ts +33 -12
  227. package/src/sdk/host/query/revision-store.ts +12 -0
  228. package/src/sdk/host/session-runtime.test.ts +673 -14
  229. package/src/sdk/host/session-runtime.ts +674 -103
  230. package/src/sdk/host/surface-policy.ts +3 -3
  231. package/src/sdk/lifecycle/broker-client.ts +28 -0
  232. package/src/sdk/lifecycle/service.ts +279 -20
  233. package/src/sdk/lifecycle-session.ts +17 -4
  234. package/src/sdk/prompt-deadline-manager.ts +2 -1
  235. package/src/sdk/protocol/operation-inventory.generated.json +105 -3
  236. package/src/sdk/protocol/operation-registry.ts +14 -4
  237. package/src/sdk/receipt-state.ts +10 -0
  238. package/src/sdk/router/session-router.ts +219 -118
  239. package/src/sdk/session.ts +416 -195
  240. package/src/sdk/startup-capability.ts +1 -0
  241. package/src/sdk/turn-result.ts +22 -0
  242. package/src/session/agent-session.ts +1628 -318
  243. package/src/session/blob-store.ts +15 -5
  244. package/src/session/credential-store-errors.ts +2 -0
  245. package/src/session/fold-coordinator.ts +40 -3
  246. package/src/session/internal/managed-session-storage.ts +153 -78
  247. package/src/session/session-manager.ts +850 -97
  248. package/src/session/yield-queue.ts +24 -10
  249. package/src/setup/frictionless-onboarding.ts +2 -0
  250. package/src/slash-commands/builtin-registry.ts +41 -0
  251. package/src/task/executor.ts +9 -4
  252. package/src/telemetry/events.ts +1138 -12
  253. package/src/tools/ask-contract.test.ts +64 -0
  254. package/src/tools/ask-contract.ts +36 -1
  255. package/src/tools/ask.ts +10 -8
  256. package/src/tools/bash-interactive.ts +11 -2
  257. package/src/tools/bash.ts +412 -75
  258. package/src/tools/browser/launch.ts +37 -0
  259. package/src/tools/browser/registry.ts +99 -9
  260. package/src/tools/cron.ts +6 -4
  261. package/src/tools/descriptors.test.ts +15 -0
  262. package/src/tools/descriptors.ts +5 -1
  263. package/src/tools/gh.ts +104 -48
  264. package/src/tools/github-cache.ts +2 -2
  265. package/src/tools/index.ts +10 -6
  266. package/src/tools/job.ts +4 -1
  267. package/src/tools/monitor.ts +12 -9
  268. package/src/tools/resolve.ts +30 -10
  269. package/src/tools/tool-catalog.generated.ts +2 -2
  270. package/src/utils/external-editor.ts +72 -1
@@ -0,0 +1,272 @@
1
+ import { canonicalSessionCwd, type SessionLocatorV2, sessionWorktreeRoot } from "./session-index";
2
+
3
+ export type ScopeNameV1 = "repo" | "pwd" | "global";
4
+
5
+ export type ScopeRequestV1 = {
6
+ version: 1;
7
+ requested: ScopeNameV1;
8
+ requestAnchor: { cwd: string; worktreeRoot: string | null };
9
+ };
10
+
11
+ export type ResolvedScopeV1 = {
12
+ version: 1;
13
+ requested: ScopeNameV1;
14
+ requestAnchor: { cwd: string; worktreeRoot: string | null };
15
+ resolved:
16
+ | { kind: "repo"; worktreeRoot: string }
17
+ | { kind: "pwd"; cwd: string }
18
+ | { kind: "global"; visibility: "current-broker" }
19
+ | null;
20
+ resolution: "resolved" | "not-in-git-worktree";
21
+ };
22
+
23
+ export type SdkSearchRowV1 = {
24
+ id: string;
25
+ locator: { cwd: string; worktreeRoot: string | null; stateRoot: string };
26
+ live: boolean;
27
+ probe?: "reachable" | "unreachable" | "stale";
28
+ };
29
+
30
+ export type SdkSearchResultV1 = {
31
+ version: 1;
32
+ scope: ResolvedScopeV1;
33
+ status: "populated" | "empty" | "not-in-git-worktree" | "unavailable";
34
+ observedAt: string;
35
+ indexSeq?: number;
36
+ rows: readonly SdkSearchRowV1[];
37
+ cursor?: string;
38
+ warnings: readonly string[];
39
+ error?: { code: string; message: string };
40
+ };
41
+
42
+ export class ScopeRequestValidationError extends Error {
43
+ constructor(message: string) {
44
+ super(message);
45
+ this.name = "ScopeRequestValidationError";
46
+ }
47
+ }
48
+
49
+ function record(value: unknown): Record<string, unknown> | undefined {
50
+ return value !== null && typeof value === "object" && !Array.isArray(value)
51
+ ? (value as Record<string, unknown>)
52
+ : undefined;
53
+ }
54
+
55
+ /** Strictly validates the versioned request shape before canonical resolution. */
56
+ export function scopeRequestV1(value: unknown): ScopeRequestV1 | undefined {
57
+ const request = record(value);
58
+ const anchor = request === undefined ? undefined : record(request.requestAnchor);
59
+ if (
60
+ request?.version !== 1 ||
61
+ (request.requested !== "repo" && request.requested !== "pwd" && request.requested !== "global") ||
62
+ anchor === undefined ||
63
+ typeof anchor.cwd !== "string" ||
64
+ anchor.cwd.length === 0 ||
65
+ (anchor.worktreeRoot !== null && (typeof anchor.worktreeRoot !== "string" || anchor.worktreeRoot.length === 0)) ||
66
+ Object.keys(request).some(key => key !== "version" && key !== "requested" && key !== "requestAnchor") ||
67
+ Object.keys(anchor).some(key => key !== "cwd" && key !== "worktreeRoot")
68
+ )
69
+ return undefined;
70
+ return {
71
+ version: 1,
72
+ requested: request.requested,
73
+ requestAnchor: { cwd: anchor.cwd, worktreeRoot: anchor.worktreeRoot },
74
+ };
75
+ }
76
+
77
+ /** Strictly validates a resolved descriptor returned by Broker pages. */
78
+ export function resolvedScopeV1(value: unknown): ResolvedScopeV1 | undefined {
79
+ const scope = record(value);
80
+ if (!scope) return undefined;
81
+ const request = scopeRequestV1({
82
+ version: scope.version,
83
+ requested: scope.requested,
84
+ requestAnchor: scope.requestAnchor,
85
+ });
86
+ if (
87
+ !request ||
88
+ (scope.resolution !== "resolved" && scope.resolution !== "not-in-git-worktree") ||
89
+ Object.keys(scope).some(
90
+ key =>
91
+ key !== "version" &&
92
+ key !== "requested" &&
93
+ key !== "requestAnchor" &&
94
+ key !== "resolved" &&
95
+ key !== "resolution",
96
+ )
97
+ )
98
+ return undefined;
99
+ const resolved = scope.resolved;
100
+ if (resolved === null)
101
+ return scope.resolution === "not-in-git-worktree" && request.requested === "repo"
102
+ ? { ...request, resolved: null, resolution: "not-in-git-worktree" }
103
+ : undefined;
104
+ const descriptor = record(resolved);
105
+ if (!descriptor || scope.resolution !== "resolved") return undefined;
106
+ if (
107
+ request.requested === "repo" &&
108
+ descriptor.kind === "repo" &&
109
+ typeof descriptor.worktreeRoot === "string" &&
110
+ Object.keys(descriptor).every(key => key === "kind" || key === "worktreeRoot")
111
+ )
112
+ return { ...request, resolved: { kind: "repo", worktreeRoot: descriptor.worktreeRoot }, resolution: "resolved" };
113
+ if (
114
+ request.requested === "pwd" &&
115
+ descriptor.kind === "pwd" &&
116
+ typeof descriptor.cwd === "string" &&
117
+ Object.keys(descriptor).every(key => key === "kind" || key === "cwd")
118
+ )
119
+ return { ...request, resolved: { kind: "pwd", cwd: descriptor.cwd }, resolution: "resolved" };
120
+ if (
121
+ request.requested === "global" &&
122
+ descriptor.kind === "global" &&
123
+ descriptor.visibility === "current-broker" &&
124
+ Object.keys(descriptor).every(key => key === "kind" || key === "visibility")
125
+ )
126
+ return { ...request, resolved: { kind: "global", visibility: "current-broker" }, resolution: "resolved" };
127
+ return undefined;
128
+ }
129
+
130
+ /** Strictly validates a safe broker-search row. */
131
+ export function sdkSearchRowV1(value: unknown): SdkSearchRowV1 | undefined {
132
+ const row = record(value);
133
+ const locator = row === undefined ? undefined : record(row.locator);
134
+ if (
135
+ typeof row?.id !== "string" ||
136
+ row.id.length === 0 ||
137
+ (row.live !== true && row.live !== false) ||
138
+ (row.probe !== undefined && row.probe !== "reachable" && row.probe !== "unreachable" && row.probe !== "stale") ||
139
+ !locator ||
140
+ typeof locator.cwd !== "string" ||
141
+ (locator.worktreeRoot !== null && typeof locator.worktreeRoot !== "string") ||
142
+ typeof locator.stateRoot !== "string" ||
143
+ Object.keys(locator).some(key => key !== "cwd" && key !== "worktreeRoot" && key !== "stateRoot") ||
144
+ Object.keys(row).some(key => key !== "id" && key !== "locator" && key !== "live" && key !== "probe")
145
+ )
146
+ return undefined;
147
+ return {
148
+ id: row.id,
149
+ locator: { cwd: locator.cwd, worktreeRoot: locator.worktreeRoot, stateRoot: locator.stateRoot },
150
+ live: row.live,
151
+ ...(row.probe === undefined ? {} : { probe: row.probe }),
152
+ };
153
+ }
154
+
155
+ /** Strictly validates the aggregate credential-free search envelope. */
156
+ export function sdkSearchResultV1(value: unknown): SdkSearchResultV1 | undefined {
157
+ const result = record(value);
158
+ const scope = result === undefined ? undefined : resolvedScopeV1(result.scope);
159
+ const cursor = typeof result?.cursor === "string" && result.cursor.length > 0 ? result.cursor : undefined;
160
+ if (
161
+ result?.version !== 1 ||
162
+ !scope ||
163
+ (result.status !== "populated" &&
164
+ result.status !== "empty" &&
165
+ result.status !== "not-in-git-worktree" &&
166
+ result.status !== "unavailable") ||
167
+ typeof result.observedAt !== "string" ||
168
+ !Array.isArray(result.rows) ||
169
+ !Array.isArray(result.warnings) ||
170
+ result.rows.some(row => !sdkSearchRowV1(row)) ||
171
+ (result.cursor !== undefined && cursor === undefined) ||
172
+ result.warnings.some(warning => typeof warning !== "string") ||
173
+ Object.keys(result).some(
174
+ key =>
175
+ key !== "version" &&
176
+ key !== "scope" &&
177
+ key !== "status" &&
178
+ key !== "observedAt" &&
179
+ key !== "indexSeq" &&
180
+ key !== "rows" &&
181
+ key !== "cursor" &&
182
+ key !== "warnings" &&
183
+ key !== "error",
184
+ )
185
+ )
186
+ return undefined;
187
+ if (result.status === "not-in-git-worktree" && (scope.resolved !== null || result.rows.length !== 0))
188
+ return undefined;
189
+ const error = record(result.error);
190
+ if (
191
+ result.status === "unavailable" &&
192
+ (!error ||
193
+ typeof error.code !== "string" ||
194
+ typeof error.message !== "string" ||
195
+ Object.keys(error).some(key => key !== "code" && key !== "message"))
196
+ )
197
+ return undefined;
198
+ const indexSeq = typeof result.indexSeq === "number" ? result.indexSeq : undefined;
199
+ if (result.indexSeq !== undefined && indexSeq === undefined) return undefined;
200
+ if (indexSeq !== undefined && (!Number.isSafeInteger(indexSeq) || indexSeq < 0)) return undefined;
201
+ return {
202
+ version: 1,
203
+ scope,
204
+ status: result.status,
205
+ observedAt: result.observedAt,
206
+ ...(indexSeq === undefined ? {} : { indexSeq }),
207
+ rows: result.rows.map(row => sdkSearchRowV1(row)!),
208
+ ...(cursor === undefined ? {} : { cursor }),
209
+ warnings: [...result.warnings],
210
+ ...(error === undefined ? {} : { error: { code: error.code as string, message: error.message as string } }),
211
+ };
212
+ }
213
+
214
+ /** Resolves and validates an anchor against its canonical cwd worktree identity. */
215
+ export async function resolveScopeRequest(request: ScopeRequestV1): Promise<ResolvedScopeV1> {
216
+ const cwd = await canonicalSessionCwd(request.requestAnchor.cwd);
217
+ const worktreeRoot = await sessionWorktreeRoot(cwd);
218
+ const suppliedWorktree =
219
+ request.requestAnchor.worktreeRoot === null
220
+ ? null
221
+ : await canonicalSessionCwd(request.requestAnchor.worktreeRoot);
222
+ if (suppliedWorktree !== worktreeRoot)
223
+ throw new ScopeRequestValidationError("scope request anchor does not match its canonical worktree identity");
224
+ const requestAnchor = { cwd, worktreeRoot };
225
+ if (request.requested === "global")
226
+ return {
227
+ version: 1,
228
+ requested: request.requested,
229
+ requestAnchor,
230
+ resolved: { kind: "global", visibility: "current-broker" },
231
+ resolution: "resolved",
232
+ };
233
+ if (request.requested === "pwd")
234
+ return {
235
+ version: 1,
236
+ requested: request.requested,
237
+ requestAnchor,
238
+ resolved: { kind: "pwd", cwd },
239
+ resolution: "resolved",
240
+ };
241
+ return worktreeRoot === null
242
+ ? { version: 1, requested: request.requested, requestAnchor, resolved: null, resolution: "not-in-git-worktree" }
243
+ : {
244
+ version: 1,
245
+ requested: request.requested,
246
+ requestAnchor,
247
+ resolved: { kind: "repo", worktreeRoot },
248
+ resolution: "resolved",
249
+ };
250
+ }
251
+
252
+ export function scopeMatchesLocator(
253
+ scope: ResolvedScopeV1,
254
+ locator: Pick<SessionLocatorV2, "cwd" | "worktreeRoot">,
255
+ ): boolean {
256
+ if (scope.resolved === null) return false;
257
+ if (scope.resolved.kind === "global") return true;
258
+ if (scope.resolved.kind === "pwd") return locator.cwd === scope.resolved.cwd;
259
+ return locator.worktreeRoot === scope.resolved.worktreeRoot;
260
+ }
261
+
262
+ export function searchRowV1(session: { sessionId: string; locator: SessionLocatorV2; live: boolean }): SdkSearchRowV1 {
263
+ return {
264
+ id: session.sessionId,
265
+ locator: {
266
+ cwd: session.locator.cwd,
267
+ worktreeRoot: session.locator.worktreeRoot,
268
+ stateRoot: session.locator.stateRoot,
269
+ },
270
+ live: session.live,
271
+ };
272
+ }