@gajae-code/coding-agent 0.15.6 → 0.16.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.
Files changed (167) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/dist/types/cli/args.d.ts +2 -0
  3. package/dist/types/cli/root-flags.d.ts +14 -0
  4. package/dist/types/cli/update-cli.d.ts +13 -0
  5. package/dist/types/cli.d.ts +7 -0
  6. package/dist/types/commands/launch.d.ts +10 -0
  7. package/dist/types/config/autorouting-tier-map.d.ts +24 -0
  8. package/dist/types/config/file-lock.d.ts +5 -0
  9. package/dist/types/config/model-registry.d.ts +6 -0
  10. package/dist/types/config/settings-schema.d.ts +10 -1
  11. package/dist/types/config/settings.d.ts +2 -0
  12. package/dist/types/coordinator-mcp/projection-scan.d.ts +8 -0
  13. package/dist/types/crash/record-loader.d.ts +15 -0
  14. package/dist/types/gjc-runtime/launch-worktree-reservation.d.ts +21 -0
  15. package/dist/types/gjc-runtime/managed-owner-supervisor.d.ts +2 -0
  16. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +66 -1
  17. package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +1 -0
  18. package/dist/types/gjc-runtime/tmux-sessions.d.ts +27 -0
  19. package/dist/types/master-mode/context.d.ts +21 -0
  20. package/dist/types/master-mode/first-request.d.ts +34 -0
  21. package/dist/types/master-mode/snapshot.d.ts +32 -0
  22. package/dist/types/modes/components/frictionless-onboarding-selector.d.ts +10 -0
  23. package/dist/types/modes/components/oauth-selector.d.ts +1 -0
  24. package/dist/types/modes/components/status-line/model-name.d.ts +18 -0
  25. package/dist/types/modes/components/status-line/priority-row.d.ts +34 -0
  26. package/dist/types/modes/components/status-line/segments.d.ts +10 -0
  27. package/dist/types/modes/print-mode.d.ts +17 -0
  28. package/dist/types/modes/ui-language.d.ts +7 -1
  29. package/dist/types/sdk/broker/broker.d.ts +77 -1
  30. package/dist/types/sdk/broker/endpoint-authority.d.ts +24 -0
  31. package/dist/types/sdk/broker/index.d.ts +3 -0
  32. package/dist/types/sdk/broker/lifecycle.d.ts +26 -0
  33. package/dist/types/sdk/broker/master-capability.d.ts +10 -0
  34. package/dist/types/sdk/broker/session-index.d.ts +40 -11
  35. package/dist/types/sdk/broker/session-scope.d.ts +72 -0
  36. package/dist/types/sdk/broker/spawn-authority.d.ts +201 -0
  37. package/dist/types/sdk/broker/spawn-substrate.d.ts +30 -0
  38. package/dist/types/sdk/broker/state-version.d.ts +4 -1
  39. package/dist/types/sdk/broker/worktree-occupancy.d.ts +28 -0
  40. package/dist/types/sdk/bus/chat-daemon-control.d.ts +3 -0
  41. package/dist/types/sdk/bus/index.d.ts +6 -0
  42. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +1 -1
  43. package/dist/types/sdk/cli/index.d.ts +1 -0
  44. package/dist/types/sdk/cli/master-cli.d.ts +63 -0
  45. package/dist/types/sdk/cli/rows.d.ts +4 -3
  46. package/dist/types/sdk/cli/session-cli.d.ts +18 -2
  47. package/dist/types/sdk/client/client.d.ts +3 -2
  48. package/dist/types/sdk/host/control/dispatch.d.ts +10 -0
  49. package/dist/types/sdk/host/control/index.d.ts +1 -1
  50. package/dist/types/sdk/host/control/operations.d.ts +2 -0
  51. package/dist/types/sdk/host/control/runtime-gate.d.ts +21 -7
  52. package/dist/types/sdk/host/host.d.ts +10 -0
  53. package/dist/types/sdk/host/session-runtime.d.ts +52 -0
  54. package/dist/types/sdk/lifecycle/broker-client.d.ts +6 -0
  55. package/dist/types/sdk/lifecycle/service.d.ts +15 -3
  56. package/dist/types/sdk/lifecycle-session.d.ts +2 -0
  57. package/dist/types/sdk/router/session-router.d.ts +2 -0
  58. package/dist/types/sdk/session.d.ts +16 -0
  59. package/dist/types/sdk/startup-capability.d.ts +2 -1
  60. package/dist/types/session/agent-session.d.ts +5 -0
  61. package/dist/types/session/credential-store-errors.d.ts +1 -0
  62. package/dist/types/session/session-manager.d.ts +65 -0
  63. package/dist/types/session/yield-queue.d.ts +5 -4
  64. package/dist/types/setup/frictionless-onboarding.d.ts +1 -0
  65. package/dist/types/tools/bash.d.ts +4 -0
  66. package/dist/types/tools/gh.d.ts +8 -0
  67. package/dist/types/tools/index.d.ts +4 -0
  68. package/package.json +7 -7
  69. package/scripts/generate-sdk-operation-inventory.ts +6 -0
  70. package/scripts/verify-gjc-sdk-canonicalization.ts +35 -1
  71. package/src/cli/accounts-cli.ts +9 -5
  72. package/src/cli/args.ts +17 -0
  73. package/src/cli/fast-help.ts +1 -0
  74. package/src/cli/root-flags.ts +5 -0
  75. package/src/cli/update-cli.ts +77 -11
  76. package/src/commands/launch.ts +86 -18
  77. package/src/commands/sdk.ts +113 -21
  78. package/src/config/autorouting-tier-map.ts +12 -0
  79. package/src/config/file-lock.ts +158 -83
  80. package/src/config/model-preset-registry.ts +1 -5
  81. package/src/config/model-profiles.ts +5 -5
  82. package/src/config/model-registry.ts +23 -0
  83. package/src/config/model-resolver.ts +5 -0
  84. package/src/config/settings-schema.ts +8 -1
  85. package/src/config/settings.ts +5 -0
  86. package/src/coordinator-mcp/projection-scan.ts +21 -0
  87. package/src/coordinator-mcp/question-state.ts +9 -11
  88. package/src/coordinator-mcp/server.ts +94 -20
  89. package/src/crash/index-store.ts +2 -0
  90. package/src/crash/record-loader.ts +10 -0
  91. package/src/gjc-runtime/launch-worktree-reservation.ts +242 -0
  92. package/src/gjc-runtime/managed-owner-supervisor.ts +63 -51
  93. package/src/gjc-runtime/session-state-lock.ts +79 -6
  94. package/src/gjc-runtime/session-state-sidecar.ts +929 -23
  95. package/src/gjc-runtime/tmux-owner-isolation-cli.ts +4 -7
  96. package/src/gjc-runtime/tmux-owner-isolation.ts +2 -2
  97. package/src/gjc-runtime/tmux-sessions.ts +252 -13
  98. package/src/hooks/skill-state.ts +6 -0
  99. package/src/internal-urls/docs-index.generated.ts +7 -7
  100. package/src/internal-urls/issue-pr-protocol.ts +4 -2
  101. package/src/main.ts +57 -2
  102. package/src/master-mode/context.ts +50 -0
  103. package/src/master-mode/first-request.ts +65 -0
  104. package/src/master-mode/snapshot.ts +205 -0
  105. package/src/modes/acp/acp-agent.ts +605 -156
  106. package/src/modes/components/footer.ts +4 -2
  107. package/src/modes/components/frictionless-onboarding-selector.ts +48 -2
  108. package/src/modes/components/oauth-selector.ts +6 -1
  109. package/src/modes/components/settings-selector.ts +1 -0
  110. package/src/modes/components/status-line/model-name.ts +53 -0
  111. package/src/modes/components/status-line/priority-row.ts +107 -0
  112. package/src/modes/components/status-line/segments.ts +23 -9
  113. package/src/modes/components/tool-status-header.ts +151 -15
  114. package/src/modes/controllers/input-controller.ts +28 -0
  115. package/src/modes/controllers/selector-controller.ts +191 -96
  116. package/src/modes/print-mode.ts +64 -0
  117. package/src/modes/ui-language.ts +49 -2
  118. package/src/prompts/system/master-mode.md +28 -0
  119. package/src/sdk/broker/broker.ts +1636 -26
  120. package/src/sdk/broker/endpoint-authority.ts +86 -0
  121. package/src/sdk/broker/ensure.ts +5 -0
  122. package/src/sdk/broker/index.ts +3 -0
  123. package/src/sdk/broker/lifecycle.ts +186 -41
  124. package/src/sdk/broker/master-capability.ts +232 -0
  125. package/src/sdk/broker/session-index.ts +121 -17
  126. package/src/sdk/broker/session-scope.ts +272 -0
  127. package/src/sdk/broker/spawn-authority.ts +1031 -0
  128. package/src/sdk/broker/spawn-substrate.ts +548 -0
  129. package/src/sdk/broker/state-version.ts +26 -14
  130. package/src/sdk/broker/transport.ts +1 -0
  131. package/src/sdk/broker/worktree-occupancy.ts +90 -0
  132. package/src/sdk/bus/chat-daemon-control.ts +5 -2
  133. package/src/sdk/bus/chat-daemon-runtime.ts +35 -4
  134. package/src/sdk/bus/index.ts +51 -4
  135. package/src/sdk/bus/telegram-daemon-contract.ts +1 -1
  136. package/src/sdk/cli/index.ts +1 -0
  137. package/src/sdk/cli/master-cli.ts +259 -0
  138. package/src/sdk/cli/rows.ts +11 -8
  139. package/src/sdk/cli/session-cli.ts +264 -5
  140. package/src/sdk/client/client.ts +14 -8
  141. package/src/sdk/host/control/dispatch.ts +99 -38
  142. package/src/sdk/host/control/index.ts +2 -0
  143. package/src/sdk/host/control/operations.ts +2 -0
  144. package/src/sdk/host/control/runtime-gate.ts +203 -11
  145. package/src/sdk/host/host.ts +27 -2
  146. package/src/sdk/host/session-runtime.test.ts +210 -6
  147. package/src/sdk/host/session-runtime.ts +291 -49
  148. package/src/sdk/lifecycle/broker-client.ts +28 -0
  149. package/src/sdk/lifecycle/service.ts +279 -20
  150. package/src/sdk/lifecycle-session.ts +10 -2
  151. package/src/sdk/protocol/operation-inventory.generated.json +51 -0
  152. package/src/sdk/protocol/operation-registry.ts +13 -3
  153. package/src/sdk/router/session-router.ts +67 -59
  154. package/src/sdk/session.ts +357 -155
  155. package/src/sdk/startup-capability.ts +1 -0
  156. package/src/session/agent-session.ts +640 -103
  157. package/src/session/blob-store.ts +15 -5
  158. package/src/session/credential-store-errors.ts +2 -0
  159. package/src/session/internal/managed-session-storage.ts +153 -78
  160. package/src/session/session-manager.ts +337 -24
  161. package/src/session/yield-queue.ts +24 -10
  162. package/src/setup/frictionless-onboarding.ts +2 -0
  163. package/src/telemetry/events.ts +1138 -12
  164. package/src/tools/bash.ts +256 -42
  165. package/src/tools/gh.ts +104 -48
  166. package/src/tools/github-cache.ts +2 -2
  167. package/src/tools/index.ts +4 -0
@@ -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
+ }