@spotpatch/shared 1.13.0 → 1.14.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 (55) hide show
  1. package/dist/{annotation-C0Me9mN2.d.cts → annotation-Cz-NNgR4.d.cts} +2 -2
  2. package/dist/{annotation-C0Me9mN2.d.ts → annotation-Cz-NNgR4.d.ts} +2 -2
  3. package/dist/{chunk-IUTOVI5G.js → chunk-CLQ6MIJB.js} +5 -3
  4. package/dist/chunk-CLQ6MIJB.js.map +1 -0
  5. package/dist/{chunk-DYTWEIES.js → chunk-EWJTKNL4.js} +2 -1
  6. package/dist/chunk-EWJTKNL4.js.map +1 -0
  7. package/dist/{chunk-2LVIH7OA.js → chunk-IX6MSCK6.js} +6 -2
  8. package/dist/chunk-IX6MSCK6.js.map +1 -0
  9. package/dist/{chunk-YQ5GL523.js → chunk-JTZFOTPT.js} +3 -3
  10. package/dist/{chunk-C2PJ4UUU.js → chunk-R6QJFNT2.js} +3 -3
  11. package/dist/chunk-R6QJFNT2.js.map +1 -0
  12. package/dist/{contextual-ask-B0mCFn92.d.cts → contextual-ask-BpbkpFFf.d.cts} +25 -0
  13. package/dist/{contextual-ask-B0mCFn92.d.ts → contextual-ask-BpbkpFFf.d.ts} +25 -0
  14. package/dist/contextual-ask-browser.cjs +1 -0
  15. package/dist/contextual-ask-browser.cjs.map +1 -1
  16. package/dist/contextual-ask-browser.d.cts +1 -1
  17. package/dist/contextual-ask-browser.d.ts +1 -1
  18. package/dist/contextual-ask-browser.js +1 -1
  19. package/dist/contextual-ask-node.cjs +5 -2
  20. package/dist/contextual-ask-node.cjs.map +1 -1
  21. package/dist/contextual-ask-node.d.cts +3 -3
  22. package/dist/contextual-ask-node.d.ts +3 -3
  23. package/dist/contextual-ask-node.js +3 -3
  24. package/dist/{data-flow-runtime-vKeEaJgT.d.ts → data-flow-runtime-DhWpQoik.d.ts} +13 -0
  25. package/dist/{data-flow-runtime-D8HPSb2i.d.cts → data-flow-runtime-w43iwvGA.d.cts} +13 -0
  26. package/dist/data-flow-runtime.d.cts +1 -1
  27. package/dist/data-flow-runtime.d.ts +1 -1
  28. package/dist/{external-agent-control-CRBbjDDk.d.cts → external-agent-control-DKxQACUv.d.cts} +8 -3
  29. package/dist/{external-agent-control-CRBbjDDk.d.ts → external-agent-control-DKxQACUv.d.ts} +8 -3
  30. package/dist/external-agent-node.cjs +178 -20
  31. package/dist/external-agent-node.cjs.map +1 -1
  32. package/dist/external-agent-node.d.cts +18 -3
  33. package/dist/external-agent-node.d.ts +18 -3
  34. package/dist/external-agent-node.js +172 -20
  35. package/dist/external-agent-node.js.map +1 -1
  36. package/dist/{external-handoff-DighrWn8.d.ts → external-handoff-5zHu-fz2.d.ts} +12 -2
  37. package/dist/{external-handoff-DwtFFR6F.d.cts → external-handoff-DeiIvR-2.d.cts} +12 -2
  38. package/dist/external-handoff-browser.cjs +7 -1
  39. package/dist/external-handoff-browser.cjs.map +1 -1
  40. package/dist/external-handoff-browser.d.cts +5 -3
  41. package/dist/external-handoff-browser.d.ts +5 -3
  42. package/dist/external-handoff-browser.js +3 -1
  43. package/dist/external-handoff-browser.js.map +1 -1
  44. package/dist/index.cjs +36 -9
  45. package/dist/index.cjs.map +1 -1
  46. package/dist/index.d.cts +19 -7
  47. package/dist/index.d.ts +19 -7
  48. package/dist/index.js +31 -11
  49. package/dist/index.js.map +1 -1
  50. package/package.json +1 -1
  51. package/dist/chunk-2LVIH7OA.js.map +0 -1
  52. package/dist/chunk-C2PJ4UUU.js.map +0 -1
  53. package/dist/chunk-DYTWEIES.js.map +0 -1
  54. package/dist/chunk-IUTOVI5G.js.map +0 -1
  55. /package/dist/{chunk-YQ5GL523.js.map → chunk-JTZFOTPT.js.map} +0 -0
@@ -5,22 +5,24 @@ import {
5
5
  externalHandoffReportableDispatchPhaseSchema,
6
6
  externalHandoffSnapshotSchema,
7
7
  externalHandoffSummarySchema
8
- } from "./chunk-YQ5GL523.js";
8
+ } from "./chunk-JTZFOTPT.js";
9
9
  import {
10
10
  ERROR_CODES
11
- } from "./chunk-C2PJ4UUU.js";
11
+ } from "./chunk-R6QJFNT2.js";
12
12
  import {
13
13
  EXTERNAL_HANDOFF_ACTIVE_ADAPTER_KINDS,
14
14
  EXTERNAL_HANDOFF_BROKER_PROTOCOL_VERSION,
15
15
  EXTERNAL_HANDOFF_FRAMEWORKS,
16
16
  EXTERNAL_HANDOFF_LIMITS
17
- } from "./chunk-2LVIH7OA.js";
17
+ } from "./chunk-IX6MSCK6.js";
18
18
 
19
19
  // src/external-agent-node.ts
20
20
  import { createHash } from "crypto";
21
+ import { execFile } from "child_process";
21
22
  import { lstat, mkdir, realpath } from "fs/promises";
22
23
  import os from "os";
23
24
  import path from "path";
25
+ import { promisify } from "util";
24
26
  import { z } from "zod";
25
27
  var SPOTPATCH_BRIDGE_TOKEN_HEADER = "X-SpotPatch-Bridge-Token";
26
28
  var SPOTPATCH_BRIDGE_PATHS = Object.freeze({
@@ -34,6 +36,75 @@ var SPOTPATCH_BRIDGE_PATHS = Object.freeze({
34
36
  activeRelease: "/bridge/v1/active/release"
35
37
  });
36
38
  var EXTERNAL_HANDOFF_PROJECT_KEY_SALT = "spotpatch-external-agent-project-v1";
39
+ var execFileAsync = promisify(execFile);
40
+ var WINDOWS_ACL_SCRIPT = String.raw`
41
+ $ErrorActionPreference = 'Stop'
42
+ $target = $env:SPOTPATCH_ACL_TARGET
43
+ $kind = $env:SPOTPATCH_ACL_KIND
44
+ $operation = $env:SPOTPATCH_ACL_OPERATION
45
+ $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent().User
46
+ $allowed = @($identity.Value, 'S-1-5-18', 'S-1-5-32-544')
47
+ if ($kind -eq 'directory') {
48
+ $item = [System.IO.DirectoryInfo]::new($target)
49
+ if ($operation -eq 'initialize') {
50
+ $security = [System.Security.AccessControl.DirectorySecurity]::new()
51
+ $security.SetOwner($identity)
52
+ foreach ($sidValue in $allowed) {
53
+ $sid = [System.Security.Principal.SecurityIdentifier]::new($sidValue)
54
+ $rule = [System.Security.AccessControl.FileSystemAccessRule]::new(
55
+ $sid,
56
+ [System.Security.AccessControl.FileSystemRights]::FullControl,
57
+ [System.Security.AccessControl.InheritanceFlags]'ContainerInherit, ObjectInherit',
58
+ [System.Security.AccessControl.PropagationFlags]::None,
59
+ [System.Security.AccessControl.AccessControlType]::Allow
60
+ )
61
+ [void]$security.AddAccessRule($rule)
62
+ }
63
+ $security.SetAccessRuleProtection($true, $false)
64
+ $item.SetAccessControl($security)
65
+ }
66
+ $acl = $item.GetAccessControl(
67
+ [System.Security.AccessControl.AccessControlSections]'Access, Owner'
68
+ )
69
+ } elseif ($kind -eq 'file') {
70
+ $item = [System.IO.FileInfo]::new($target)
71
+ if ($operation -eq 'initialize') {
72
+ $security = [System.Security.AccessControl.FileSecurity]::new()
73
+ $security.SetOwner($identity)
74
+ foreach ($sidValue in $allowed) {
75
+ $sid = [System.Security.Principal.SecurityIdentifier]::new($sidValue)
76
+ $rule = [System.Security.AccessControl.FileSystemAccessRule]::new(
77
+ $sid,
78
+ [System.Security.AccessControl.FileSystemRights]::FullControl,
79
+ [System.Security.AccessControl.AccessControlType]::Allow
80
+ )
81
+ [void]$security.AddAccessRule($rule)
82
+ }
83
+ $security.SetAccessRuleProtection($true, $false)
84
+ $item.SetAccessControl($security)
85
+ }
86
+ $acl = $item.GetAccessControl(
87
+ [System.Security.AccessControl.AccessControlSections]'Access, Owner'
88
+ )
89
+ } else {
90
+ exit 10
91
+ }
92
+ if ($acl.GetOwner([System.Security.Principal.SecurityIdentifier]).Value -ne $identity.Value) {
93
+ exit 11
94
+ }
95
+ foreach ($rule in $acl.GetAccessRules(
96
+ $true,
97
+ $true,
98
+ [System.Security.Principal.SecurityIdentifier]
99
+ )) {
100
+ if (
101
+ $rule.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Allow -and
102
+ $allowed -notcontains $rule.IdentityReference.Value
103
+ ) {
104
+ exit 12
105
+ }
106
+ }
107
+ `;
37
108
  var opaqueIdSchema = z.string().min(22).max(128).regex(/^[A-Za-z0-9_-]+$/u);
38
109
  var projectKeySchema = z.string().length(64).regex(/^[a-f0-9]+$/u);
39
110
  var loopbackEndpointSchema = z.url().refine((value) => {
@@ -113,46 +184,111 @@ var bridgeActiveStateResultSchema = z.strictObject({
113
184
  var bridgeActiveHeartbeatResultSchema = bridgeActiveStateResultSchema;
114
185
  var bridgeActiveReportResultSchema = bridgeActiveStateResultSchema;
115
186
  var bridgeActiveReleaseResultSchema = bridgeActiveStateResultSchema;
116
- function currentUid() {
117
- const uid = process.getuid?.();
118
- if (uid === void 0) {
187
+ function windowsPowerShellExecutable() {
188
+ const systemRoot = process.env.SystemRoot ?? process.env.SYSTEMROOT;
189
+ if (systemRoot === void 0 || !path.win32.isAbsolute(systemRoot)) {
119
190
  throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);
120
191
  }
121
- return uid;
192
+ return path.win32.join(
193
+ systemRoot,
194
+ "System32",
195
+ "WindowsPowerShell",
196
+ "v1.0",
197
+ "powershell.exe"
198
+ );
122
199
  }
123
- async function assertPrivateDirectory(directory, uid) {
124
- const status = await lstat(directory);
125
- if (!status.isDirectory() || status.isSymbolicLink() || status.uid !== uid || (status.mode & 63) !== 0) {
200
+ async function verifyWindowsAcl(candidate, kind, initialize) {
201
+ try {
202
+ await execFileAsync(
203
+ windowsPowerShellExecutable(),
204
+ ["-NoLogo", "-NoProfile", "-NonInteractive", "-Command", WINDOWS_ACL_SCRIPT],
205
+ {
206
+ encoding: "utf8",
207
+ env: {
208
+ ...process.env,
209
+ SPOTPATCH_ACL_KIND: kind,
210
+ SPOTPATCH_ACL_OPERATION: initialize ? "initialize" : "verify",
211
+ SPOTPATCH_ACL_TARGET: candidate
212
+ },
213
+ timeout: 1e4,
214
+ windowsHide: true
215
+ }
216
+ );
217
+ } catch (error) {
218
+ throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED, void 0, {
219
+ cause: error
220
+ });
221
+ }
222
+ }
223
+ async function assertPrivateExternalHandoffPath(candidate, kind) {
224
+ const status = await lstat(candidate);
225
+ const correctKind = kind === "directory" ? status.isDirectory() : status.isFile();
226
+ if (!correctKind || status.isSymbolicLink()) {
126
227
  throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);
127
228
  }
229
+ if (process.platform === "win32") {
230
+ await verifyWindowsAcl(candidate, kind, false);
231
+ return status;
232
+ }
233
+ const uid = process.getuid?.();
234
+ if (uid === void 0 || status.uid !== uid || (status.mode & 63) !== 0) {
235
+ throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);
236
+ }
237
+ return status;
238
+ }
239
+ async function initializePrivateExternalHandoffFile(candidate) {
240
+ if (process.platform === "win32") {
241
+ await verifyWindowsAcl(candidate, "file", true);
242
+ }
128
243
  }
129
- async function ensurePrivateSubdirectory(base, uid, create) {
244
+ async function initializeWindowsDirectory(directory) {
245
+ if (process.platform === "win32") {
246
+ await verifyWindowsAcl(directory, "directory", true);
247
+ }
248
+ }
249
+ async function ensurePrivateSubdirectory(base, create) {
130
250
  const directory = path.join(base, "spotpatch");
251
+ let created = false;
131
252
  if (create) {
132
253
  try {
133
254
  await mkdir(directory, { mode: 448 });
255
+ created = true;
134
256
  } catch (error) {
135
257
  if (error.code !== "EEXIST") {
136
258
  throw error;
137
259
  }
138
260
  }
139
261
  }
140
- await assertPrivateDirectory(directory, uid);
141
- return directory;
262
+ if (created) await initializeWindowsDirectory(directory);
263
+ await assertPrivateExternalHandoffPath(directory, "directory");
264
+ return realpath(directory);
142
265
  }
143
- async function resolveExternalHandoffRuntimeDirectory(create) {
144
- if (process.platform === "win32") {
266
+ async function resolveWindowsRuntimeDirectory(create) {
267
+ const configuredBase = process.env.LOCALAPPDATA;
268
+ if (configuredBase !== void 0 && !path.isAbsolute(configuredBase)) {
145
269
  throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);
146
270
  }
147
- const uid = currentUid();
271
+ const base = configuredBase ?? path.join(os.homedir(), "AppData", "Local");
272
+ const directory = path.join(base, "SpotPatch", "external-agent-runtime-v1");
273
+ let created = false;
274
+ if (create) {
275
+ created = await mkdir(directory, { mode: 448, recursive: true }) !== void 0;
276
+ }
277
+ if (created) await initializeWindowsDirectory(directory);
278
+ await assertPrivateExternalHandoffPath(directory, "directory");
279
+ return realpath(directory);
280
+ }
281
+ async function resolveExternalHandoffRuntimeDirectory(create) {
148
282
  const xdgRuntimeDirectory = process.env.XDG_RUNTIME_DIR;
149
283
  if (xdgRuntimeDirectory !== void 0 && !path.isAbsolute(xdgRuntimeDirectory)) {
150
284
  throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);
151
285
  }
152
286
  if (xdgRuntimeDirectory !== void 0) {
153
287
  try {
154
- await assertPrivateDirectory(xdgRuntimeDirectory, uid);
155
- return await ensurePrivateSubdirectory(xdgRuntimeDirectory, uid, create);
288
+ if (process.platform !== "win32") {
289
+ await assertPrivateExternalHandoffPath(xdgRuntimeDirectory, "directory");
290
+ }
291
+ return await ensurePrivateSubdirectory(xdgRuntimeDirectory, create);
156
292
  } catch (error) {
157
293
  if (!create && error.code === "ENOENT") {
158
294
  throw new SpotPatchError(ERROR_CODES.SESSION_NOT_FOUND);
@@ -160,6 +296,20 @@ async function resolveExternalHandoffRuntimeDirectory(create) {
160
296
  throw error;
161
297
  }
162
298
  }
299
+ if (process.platform === "win32") {
300
+ try {
301
+ return await resolveWindowsRuntimeDirectory(create);
302
+ } catch (error) {
303
+ if (!create && error.code === "ENOENT") {
304
+ throw new SpotPatchError(ERROR_CODES.SESSION_NOT_FOUND);
305
+ }
306
+ throw error;
307
+ }
308
+ }
309
+ const uid = process.getuid?.();
310
+ if (uid === void 0) {
311
+ throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);
312
+ }
163
313
  const fallback = path.join(os.tmpdir(), `spotpatch-${String(uid)}`);
164
314
  if (create) {
165
315
  try {
@@ -171,14 +321,14 @@ async function resolveExternalHandoffRuntimeDirectory(create) {
171
321
  }
172
322
  }
173
323
  try {
174
- await assertPrivateDirectory(fallback, uid);
324
+ await assertPrivateExternalHandoffPath(fallback, "directory");
175
325
  } catch (error) {
176
326
  if (!create && error.code === "ENOENT") {
177
327
  throw new SpotPatchError(ERROR_CODES.SESSION_NOT_FOUND);
178
328
  }
179
329
  throw error;
180
330
  }
181
- return fallback;
331
+ return realpath(fallback);
182
332
  }
183
333
  async function computeExternalHandoffProjectKey(root) {
184
334
  const canonicalRoot = await realpath(root);
@@ -188,6 +338,7 @@ export {
188
338
  EXTERNAL_HANDOFF_PROJECT_KEY_SALT,
189
339
  SPOTPATCH_BRIDGE_PATHS,
190
340
  SPOTPATCH_BRIDGE_TOKEN_HEADER,
341
+ assertPrivateExternalHandoffPath,
191
342
  bridgeAckRequestSchema,
192
343
  bridgeAckResultSchema,
193
344
  bridgeActiveClaimRequestSchema,
@@ -207,6 +358,7 @@ export {
207
358
  bridgeWaitResultSchema,
208
359
  computeExternalHandoffProjectKey,
209
360
  externalHandoffDescriptorSchema,
361
+ initializePrivateExternalHandoffFile,
210
362
  resolveExternalHandoffRuntimeDirectory
211
363
  };
212
364
  //# sourceMappingURL=external-agent-node.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/external-agent-node.ts"],"sourcesContent":["/// <reference types=\"node\" />\n\nimport { createHash } from \"node:crypto\";\nimport { lstat, mkdir, realpath } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nimport { z } from \"zod\";\n\nimport {\n EXTERNAL_HANDOFF_ACTIVE_ADAPTER_KINDS,\n EXTERNAL_HANDOFF_BROKER_PROTOCOL_VERSION,\n EXTERNAL_HANDOFF_FRAMEWORKS,\n EXTERNAL_HANDOFF_LIMITS,\n activeAdapterSummarySchema,\n dispatchSummarySchema,\n externalHandoffReportableDispatchPhaseSchema,\n externalHandoffSnapshotSchema,\n externalHandoffSummarySchema,\n type ActiveAdapterSummary,\n type DispatchSummary,\n type ExternalHandoffSnapshot,\n} from \"./protocol/external-handoff.js\";\nimport { ERROR_CODES } from \"./errors/error-code.js\";\nimport { SpotPatchError } from \"./errors/spotpatch-error.js\";\n\nexport const SPOTPATCH_BRIDGE_TOKEN_HEADER = \"X-SpotPatch-Bridge-Token\" as const;\nexport const SPOTPATCH_BRIDGE_PATHS = Object.freeze({\n status: \"/bridge/v1/status\",\n current: \"/bridge/v1/handoff/current\",\n wait: \"/bridge/v1/handoff/wait\",\n ack: \"/bridge/v1/handoff/ack\",\n activeClaim: \"/bridge/v1/active/claim\",\n activeHeartbeat: \"/bridge/v1/active/heartbeat\",\n activeReport: \"/bridge/v1/active/report\",\n activeRelease: \"/bridge/v1/active/release\",\n});\nexport const EXTERNAL_HANDOFF_PROJECT_KEY_SALT =\n \"spotpatch-external-agent-project-v1\" as const;\n\nconst opaqueIdSchema = z\n .string()\n .min(22)\n .max(128)\n .regex(/^[A-Za-z0-9_-]+$/u);\nconst projectKeySchema = z\n .string()\n .length(64)\n .regex(/^[a-f0-9]+$/u);\nconst loopbackEndpointSchema = z.url().refine((value) => {\n const match = /^http:\\/\\/127\\.0\\.0\\.1:([1-9][0-9]{0,4})$/u.exec(value);\n\n if (match?.[1] === undefined) {\n return false;\n }\n\n const port = Number(match[1]);\n return Number.isSafeInteger(port) && port <= 65_535;\n});\n\nexport const externalHandoffDescriptorSchema = z.strictObject({\n schemaVersion: z.literal(1),\n brokerProtocolVersion: z.literal(EXTERNAL_HANDOFF_BROKER_PROTOCOL_VERSION),\n projectKey: projectKeySchema,\n sessionId: opaqueIdSchema,\n framework: z.enum(EXTERNAL_HANDOFF_FRAMEWORKS),\n endpoint: loopbackEndpointSchema,\n bridgeToken: z\n .string()\n .min(43)\n .max(128)\n .regex(/^[A-Za-z0-9_-]+$/u),\n pid: z.number().int().positive(),\n createdAt: z.iso.datetime(),\n});\n\nexport const bridgeStatusRequestSchema = z.strictObject({});\nexport const bridgeCurrentRequestSchema = z.strictObject({\n cursor: opaqueIdSchema.optional(),\n});\nexport const bridgeWaitRequestSchema = z.strictObject({\n afterCursor: opaqueIdSchema.optional(),\n timeoutMs: z\n .number()\n .int()\n .positive()\n .max(EXTERNAL_HANDOFF_LIMITS.maximumWaitMs)\n .default(EXTERNAL_HANDOFF_LIMITS.defaultWaitMs),\n});\nexport const bridgeAckRequestSchema = z.strictObject({\n cursor: opaqueIdSchema,\n connectorInstanceId: opaqueIdSchema,\n});\nexport const bridgeActiveClaimRequestSchema = z.strictObject({\n adapterKind: z.enum(EXTERNAL_HANDOFF_ACTIVE_ADAPTER_KINDS),\n connectorInstanceId: opaqueIdSchema,\n});\nexport const bridgeActiveHeartbeatRequestSchema = z.strictObject({\n leaseToken: opaqueIdSchema,\n});\nexport const bridgeActiveReportRequestSchema = z.strictObject({\n leaseToken: opaqueIdSchema,\n cursor: opaqueIdSchema,\n phase: externalHandoffReportableDispatchPhaseSchema,\n});\nexport const bridgeActiveReleaseRequestSchema = z.strictObject({\n leaseToken: opaqueIdSchema,\n});\nexport const bridgeStatusSchema = z.strictObject({\n brokerProtocolVersion: z.literal(EXTERNAL_HANDOFF_BROKER_PROTOCOL_VERSION),\n projectKey: projectKeySchema,\n sessionId: opaqueIdSchema,\n framework: z.enum(EXTERNAL_HANDOFF_FRAMEWORKS),\n current: externalHandoffSummarySchema.nullable(),\n});\nexport const bridgeCurrentResultSchema = z.strictObject({\n outcome: z.literal(\"handoff\"),\n snapshot: externalHandoffSnapshotSchema,\n});\nexport const bridgeWaitResultSchema = z.discriminatedUnion(\"outcome\", [\n bridgeCurrentResultSchema,\n z.strictObject({ outcome: z.literal(\"timeout\") }),\n]);\nexport const bridgeAckResultSchema = z.strictObject({\n summary: externalHandoffSummarySchema,\n});\nexport const bridgeActiveClaimResultSchema = z.strictObject({\n leaseToken: opaqueIdSchema,\n heartbeatIntervalMs: z.literal(EXTERNAL_HANDOFF_LIMITS.activeHeartbeatIntervalMs),\n baselineCursor: opaqueIdSchema.nullable(),\n activeAdapter: activeAdapterSummarySchema,\n});\nexport const bridgeActiveStateResultSchema = z.strictObject({\n activeAdapter: activeAdapterSummarySchema.nullable(),\n dispatch: dispatchSummarySchema.nullable(),\n});\nexport const bridgeActiveHeartbeatResultSchema = bridgeActiveStateResultSchema;\nexport const bridgeActiveReportResultSchema = bridgeActiveStateResultSchema;\nexport const bridgeActiveReleaseResultSchema = bridgeActiveStateResultSchema;\n\nexport type ExternalHandoffDescriptor = z.infer<typeof externalHandoffDescriptorSchema>;\nexport type BridgeStatus = z.infer<typeof bridgeStatusSchema>;\nexport type BridgeWaitResult =\n | Readonly<{ outcome: \"handoff\"; snapshot: ExternalHandoffSnapshot }>\n | Readonly<{ outcome: \"timeout\" }>;\nexport interface BridgeActiveClaimResult {\n readonly leaseToken: string;\n readonly heartbeatIntervalMs: typeof EXTERNAL_HANDOFF_LIMITS.activeHeartbeatIntervalMs;\n readonly baselineCursor: string | null;\n readonly activeAdapter: ActiveAdapterSummary;\n}\nexport interface BridgeActiveStateResult {\n readonly activeAdapter: ActiveAdapterSummary | null;\n readonly dispatch: DispatchSummary | null;\n}\n\nfunction currentUid(): number {\n const uid = process.getuid?.();\n\n if (uid === undefined) {\n throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);\n }\n\n return uid;\n}\n\nasync function assertPrivateDirectory(directory: string, uid: number): Promise<void> {\n const status = await lstat(directory);\n\n if (\n !status.isDirectory() ||\n status.isSymbolicLink() ||\n status.uid !== uid ||\n (status.mode & 0o077) !== 0\n ) {\n throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);\n }\n}\n\nasync function ensurePrivateSubdirectory(\n base: string,\n uid: number,\n create: boolean,\n): Promise<string> {\n const directory = path.join(base, \"spotpatch\");\n\n if (create) {\n try {\n await mkdir(directory, { mode: 0o700 });\n } catch (error: unknown) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") {\n throw error;\n }\n }\n }\n\n await assertPrivateDirectory(directory, uid);\n return directory;\n}\n\nexport async function resolveExternalHandoffRuntimeDirectory(\n create: boolean,\n): Promise<string> {\n if (process.platform === \"win32\") {\n throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);\n }\n\n const uid = currentUid();\n const xdgRuntimeDirectory = process.env.XDG_RUNTIME_DIR;\n\n if (xdgRuntimeDirectory !== undefined && !path.isAbsolute(xdgRuntimeDirectory)) {\n throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);\n }\n\n if (xdgRuntimeDirectory !== undefined) {\n try {\n await assertPrivateDirectory(xdgRuntimeDirectory, uid);\n return await ensurePrivateSubdirectory(xdgRuntimeDirectory, uid, create);\n } catch (error: unknown) {\n if (!create && (error as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new SpotPatchError(ERROR_CODES.SESSION_NOT_FOUND);\n }\n\n throw error;\n }\n }\n\n const fallback = path.join(os.tmpdir(), `spotpatch-${String(uid)}`);\n\n if (create) {\n try {\n await mkdir(fallback, { mode: 0o700 });\n } catch (error: unknown) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") {\n throw error;\n }\n }\n }\n\n try {\n await assertPrivateDirectory(fallback, uid);\n } catch (error: unknown) {\n if (!create && (error as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new SpotPatchError(ERROR_CODES.SESSION_NOT_FOUND);\n }\n\n throw error;\n }\n\n return fallback;\n}\n\nexport async function computeExternalHandoffProjectKey(root: string): Promise<string> {\n const canonicalRoot = await realpath(root);\n return createHash(\"sha256\")\n .update(`${EXTERNAL_HANDOFF_PROJECT_KEY_SALT}\\0${canonicalRoot}`)\n .digest(\"hex\");\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/external-agent-node.ts"],"sourcesContent":["/// <reference types=\"node\" />\n\nimport { createHash } from \"node:crypto\";\nimport { execFile } from \"node:child_process\";\nimport type { Stats } from \"node:fs\";\nimport { lstat, mkdir, realpath } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\n\nimport { z } from \"zod\";\n\nimport {\n EXTERNAL_HANDOFF_ACTIVE_ADAPTER_KINDS,\n EXTERNAL_HANDOFF_BROKER_PROTOCOL_VERSION,\n EXTERNAL_HANDOFF_FRAMEWORKS,\n EXTERNAL_HANDOFF_LIMITS,\n activeAdapterSummarySchema,\n dispatchSummarySchema,\n externalHandoffReportableDispatchPhaseSchema,\n externalHandoffSnapshotSchema,\n externalHandoffSummarySchema,\n type ActiveAdapterSummary,\n type DispatchSummary,\n type ExternalHandoffSnapshot,\n} from \"./protocol/external-handoff.js\";\nimport { ERROR_CODES } from \"./errors/error-code.js\";\nimport { SpotPatchError } from \"./errors/spotpatch-error.js\";\n\nexport const SPOTPATCH_BRIDGE_TOKEN_HEADER = \"X-SpotPatch-Bridge-Token\" as const;\nexport const SPOTPATCH_BRIDGE_PATHS = Object.freeze({\n status: \"/bridge/v1/status\",\n current: \"/bridge/v1/handoff/current\",\n wait: \"/bridge/v1/handoff/wait\",\n ack: \"/bridge/v1/handoff/ack\",\n activeClaim: \"/bridge/v1/active/claim\",\n activeHeartbeat: \"/bridge/v1/active/heartbeat\",\n activeReport: \"/bridge/v1/active/report\",\n activeRelease: \"/bridge/v1/active/release\",\n});\nexport const EXTERNAL_HANDOFF_PROJECT_KEY_SALT =\n \"spotpatch-external-agent-project-v1\" as const;\n\nconst execFileAsync = promisify(execFile);\nconst WINDOWS_ACL_SCRIPT = String.raw`\n$ErrorActionPreference = 'Stop'\n$target = $env:SPOTPATCH_ACL_TARGET\n$kind = $env:SPOTPATCH_ACL_KIND\n$operation = $env:SPOTPATCH_ACL_OPERATION\n$identity = [System.Security.Principal.WindowsIdentity]::GetCurrent().User\n$allowed = @($identity.Value, 'S-1-5-18', 'S-1-5-32-544')\nif ($kind -eq 'directory') {\n $item = [System.IO.DirectoryInfo]::new($target)\n if ($operation -eq 'initialize') {\n $security = [System.Security.AccessControl.DirectorySecurity]::new()\n $security.SetOwner($identity)\n foreach ($sidValue in $allowed) {\n $sid = [System.Security.Principal.SecurityIdentifier]::new($sidValue)\n $rule = [System.Security.AccessControl.FileSystemAccessRule]::new(\n $sid,\n [System.Security.AccessControl.FileSystemRights]::FullControl,\n [System.Security.AccessControl.InheritanceFlags]'ContainerInherit, ObjectInherit',\n [System.Security.AccessControl.PropagationFlags]::None,\n [System.Security.AccessControl.AccessControlType]::Allow\n )\n [void]$security.AddAccessRule($rule)\n }\n $security.SetAccessRuleProtection($true, $false)\n $item.SetAccessControl($security)\n }\n $acl = $item.GetAccessControl(\n [System.Security.AccessControl.AccessControlSections]'Access, Owner'\n )\n} elseif ($kind -eq 'file') {\n $item = [System.IO.FileInfo]::new($target)\n if ($operation -eq 'initialize') {\n $security = [System.Security.AccessControl.FileSecurity]::new()\n $security.SetOwner($identity)\n foreach ($sidValue in $allowed) {\n $sid = [System.Security.Principal.SecurityIdentifier]::new($sidValue)\n $rule = [System.Security.AccessControl.FileSystemAccessRule]::new(\n $sid,\n [System.Security.AccessControl.FileSystemRights]::FullControl,\n [System.Security.AccessControl.AccessControlType]::Allow\n )\n [void]$security.AddAccessRule($rule)\n }\n $security.SetAccessRuleProtection($true, $false)\n $item.SetAccessControl($security)\n }\n $acl = $item.GetAccessControl(\n [System.Security.AccessControl.AccessControlSections]'Access, Owner'\n )\n} else {\n exit 10\n}\nif ($acl.GetOwner([System.Security.Principal.SecurityIdentifier]).Value -ne $identity.Value) {\n exit 11\n}\nforeach ($rule in $acl.GetAccessRules(\n $true,\n $true,\n [System.Security.Principal.SecurityIdentifier]\n)) {\n if (\n $rule.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Allow -and\n $allowed -notcontains $rule.IdentityReference.Value\n ) {\n exit 12\n }\n}\n`;\n\nconst opaqueIdSchema = z\n .string()\n .min(22)\n .max(128)\n .regex(/^[A-Za-z0-9_-]+$/u);\nconst projectKeySchema = z\n .string()\n .length(64)\n .regex(/^[a-f0-9]+$/u);\nconst loopbackEndpointSchema = z.url().refine((value) => {\n const match = /^http:\\/\\/127\\.0\\.0\\.1:([1-9][0-9]{0,4})$/u.exec(value);\n\n if (match?.[1] === undefined) {\n return false;\n }\n\n const port = Number(match[1]);\n return Number.isSafeInteger(port) && port <= 65_535;\n});\n\nexport const externalHandoffDescriptorSchema = z.strictObject({\n schemaVersion: z.literal(1),\n brokerProtocolVersion: z.literal(EXTERNAL_HANDOFF_BROKER_PROTOCOL_VERSION),\n projectKey: projectKeySchema,\n sessionId: opaqueIdSchema,\n framework: z.enum(EXTERNAL_HANDOFF_FRAMEWORKS),\n endpoint: loopbackEndpointSchema,\n bridgeToken: z\n .string()\n .min(43)\n .max(128)\n .regex(/^[A-Za-z0-9_-]+$/u),\n pid: z.number().int().positive(),\n createdAt: z.iso.datetime(),\n});\n\nexport const bridgeStatusRequestSchema = z.strictObject({});\nexport const bridgeCurrentRequestSchema = z.strictObject({\n cursor: opaqueIdSchema.optional(),\n});\nexport const bridgeWaitRequestSchema = z.strictObject({\n afterCursor: opaqueIdSchema.optional(),\n timeoutMs: z\n .number()\n .int()\n .positive()\n .max(EXTERNAL_HANDOFF_LIMITS.maximumWaitMs)\n .default(EXTERNAL_HANDOFF_LIMITS.defaultWaitMs),\n});\nexport const bridgeAckRequestSchema = z.strictObject({\n cursor: opaqueIdSchema,\n connectorInstanceId: opaqueIdSchema,\n});\nexport const bridgeActiveClaimRequestSchema = z.strictObject({\n adapterKind: z.enum(EXTERNAL_HANDOFF_ACTIVE_ADAPTER_KINDS),\n connectorInstanceId: opaqueIdSchema,\n});\nexport const bridgeActiveHeartbeatRequestSchema = z.strictObject({\n leaseToken: opaqueIdSchema,\n});\nexport const bridgeActiveReportRequestSchema = z.strictObject({\n leaseToken: opaqueIdSchema,\n cursor: opaqueIdSchema,\n phase: externalHandoffReportableDispatchPhaseSchema,\n});\nexport const bridgeActiveReleaseRequestSchema = z.strictObject({\n leaseToken: opaqueIdSchema,\n});\nexport const bridgeStatusSchema = z.strictObject({\n brokerProtocolVersion: z.literal(EXTERNAL_HANDOFF_BROKER_PROTOCOL_VERSION),\n projectKey: projectKeySchema,\n sessionId: opaqueIdSchema,\n framework: z.enum(EXTERNAL_HANDOFF_FRAMEWORKS),\n current: externalHandoffSummarySchema.nullable(),\n});\nexport const bridgeCurrentResultSchema = z.strictObject({\n outcome: z.literal(\"handoff\"),\n snapshot: externalHandoffSnapshotSchema,\n});\nexport const bridgeWaitResultSchema = z.discriminatedUnion(\"outcome\", [\n bridgeCurrentResultSchema,\n z.strictObject({ outcome: z.literal(\"timeout\") }),\n]);\nexport const bridgeAckResultSchema = z.strictObject({\n summary: externalHandoffSummarySchema,\n});\nexport const bridgeActiveClaimResultSchema = z.strictObject({\n leaseToken: opaqueIdSchema,\n heartbeatIntervalMs: z.literal(EXTERNAL_HANDOFF_LIMITS.activeHeartbeatIntervalMs),\n baselineCursor: opaqueIdSchema.nullable(),\n activeAdapter: activeAdapterSummarySchema,\n});\nexport const bridgeActiveStateResultSchema = z.strictObject({\n activeAdapter: activeAdapterSummarySchema.nullable(),\n dispatch: dispatchSummarySchema.nullable(),\n});\nexport const bridgeActiveHeartbeatResultSchema = bridgeActiveStateResultSchema;\nexport const bridgeActiveReportResultSchema = bridgeActiveStateResultSchema;\nexport const bridgeActiveReleaseResultSchema = bridgeActiveStateResultSchema;\n\nexport type ExternalHandoffDescriptor = z.infer<typeof externalHandoffDescriptorSchema>;\nexport type BridgeStatus = z.infer<typeof bridgeStatusSchema>;\nexport type BridgeWaitResult =\n | Readonly<{ outcome: \"handoff\"; snapshot: ExternalHandoffSnapshot }>\n | Readonly<{ outcome: \"timeout\" }>;\nexport interface BridgeActiveClaimResult {\n readonly leaseToken: string;\n readonly heartbeatIntervalMs: typeof EXTERNAL_HANDOFF_LIMITS.activeHeartbeatIntervalMs;\n readonly baselineCursor: string | null;\n readonly activeAdapter: ActiveAdapterSummary;\n}\nexport interface BridgeActiveStateResult {\n readonly activeAdapter: ActiveAdapterSummary | null;\n readonly dispatch: DispatchSummary | null;\n}\n\nfunction windowsPowerShellExecutable(): string {\n const systemRoot = process.env.SystemRoot ?? process.env.SYSTEMROOT;\n if (systemRoot === undefined || !path.win32.isAbsolute(systemRoot)) {\n throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);\n }\n return path.win32.join(\n systemRoot,\n \"System32\",\n \"WindowsPowerShell\",\n \"v1.0\",\n \"powershell.exe\",\n );\n}\n\nasync function verifyWindowsAcl(\n candidate: string,\n kind: \"directory\" | \"file\",\n initialize: boolean,\n): Promise<void> {\n try {\n await execFileAsync(\n windowsPowerShellExecutable(),\n [\"-NoLogo\", \"-NoProfile\", \"-NonInteractive\", \"-Command\", WINDOWS_ACL_SCRIPT],\n {\n encoding: \"utf8\",\n env: {\n ...process.env,\n SPOTPATCH_ACL_KIND: kind,\n SPOTPATCH_ACL_OPERATION: initialize ? \"initialize\" : \"verify\",\n SPOTPATCH_ACL_TARGET: candidate,\n },\n timeout: 10_000,\n windowsHide: true,\n },\n );\n } catch (error: unknown) {\n throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED, undefined, {\n cause: error,\n });\n }\n}\n\nexport async function assertPrivateExternalHandoffPath(\n candidate: string,\n kind: \"directory\" | \"file\",\n): Promise<Stats> {\n const status = await lstat(candidate);\n const correctKind = kind === \"directory\" ? status.isDirectory() : status.isFile();\n\n if (!correctKind || status.isSymbolicLink()) {\n throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);\n }\n\n if (process.platform === \"win32\") {\n await verifyWindowsAcl(candidate, kind, false);\n return status;\n }\n\n const uid = process.getuid?.();\n if (uid === undefined || status.uid !== uid || (status.mode & 0o077) !== 0) {\n throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);\n }\n\n return status;\n}\n\nexport async function initializePrivateExternalHandoffFile(\n candidate: string,\n): Promise<void> {\n if (process.platform === \"win32\") {\n await verifyWindowsAcl(candidate, \"file\", true);\n }\n}\n\nasync function initializeWindowsDirectory(directory: string): Promise<void> {\n if (process.platform === \"win32\") {\n await verifyWindowsAcl(directory, \"directory\", true);\n }\n}\n\nasync function ensurePrivateSubdirectory(\n base: string,\n create: boolean,\n): Promise<string> {\n const directory = path.join(base, \"spotpatch\");\n let created = false;\n\n if (create) {\n try {\n await mkdir(directory, { mode: 0o700 });\n created = true;\n } catch (error: unknown) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") {\n throw error;\n }\n }\n }\n\n if (created) await initializeWindowsDirectory(directory);\n await assertPrivateExternalHandoffPath(directory, \"directory\");\n return realpath(directory);\n}\n\nasync function resolveWindowsRuntimeDirectory(create: boolean): Promise<string> {\n const configuredBase = process.env.LOCALAPPDATA;\n\n if (configuredBase !== undefined && !path.isAbsolute(configuredBase)) {\n throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);\n }\n\n const base = configuredBase ?? path.join(os.homedir(), \"AppData\", \"Local\");\n const directory = path.join(base, \"SpotPatch\", \"external-agent-runtime-v1\");\n let created = false;\n\n if (create) {\n created = (await mkdir(directory, { mode: 0o700, recursive: true })) !== undefined;\n }\n\n if (created) await initializeWindowsDirectory(directory);\n await assertPrivateExternalHandoffPath(directory, \"directory\");\n return realpath(directory);\n}\n\nexport async function resolveExternalHandoffRuntimeDirectory(\n create: boolean,\n): Promise<string> {\n const xdgRuntimeDirectory = process.env.XDG_RUNTIME_DIR;\n\n if (xdgRuntimeDirectory !== undefined && !path.isAbsolute(xdgRuntimeDirectory)) {\n throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);\n }\n\n if (xdgRuntimeDirectory !== undefined) {\n try {\n if (process.platform !== \"win32\") {\n await assertPrivateExternalHandoffPath(xdgRuntimeDirectory, \"directory\");\n }\n return await ensurePrivateSubdirectory(xdgRuntimeDirectory, create);\n } catch (error: unknown) {\n if (!create && (error as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new SpotPatchError(ERROR_CODES.SESSION_NOT_FOUND);\n }\n\n throw error;\n }\n }\n\n if (process.platform === \"win32\") {\n try {\n return await resolveWindowsRuntimeDirectory(create);\n } catch (error: unknown) {\n if (!create && (error as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new SpotPatchError(ERROR_CODES.SESSION_NOT_FOUND);\n }\n\n throw error;\n }\n }\n\n const uid = process.getuid?.();\n if (uid === undefined) {\n throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);\n }\n\n const fallback = path.join(os.tmpdir(), `spotpatch-${String(uid)}`);\n\n if (create) {\n try {\n await mkdir(fallback, { mode: 0o700 });\n } catch (error: unknown) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") {\n throw error;\n }\n }\n }\n\n try {\n await assertPrivateExternalHandoffPath(fallback, \"directory\");\n } catch (error: unknown) {\n if (!create && (error as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new SpotPatchError(ERROR_CODES.SESSION_NOT_FOUND);\n }\n\n throw error;\n }\n\n return realpath(fallback);\n}\n\nexport async function computeExternalHandoffProjectKey(root: string): Promise<string> {\n const canonicalRoot = await realpath(root);\n return createHash(\"sha256\")\n .update(`${EXTERNAL_HANDOFF_PROJECT_KEY_SALT}\\0${canonicalRoot}`)\n .digest(\"hex\");\n}\n"],"mappings":"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","names":[]}
@@ -1,10 +1,10 @@
1
1
  import { z } from 'zod';
2
- import { S as SpotAnnotation } from './annotation-C0Me9mN2.js';
2
+ import { S as SpotAnnotation } from './annotation-Cz-NNgR4.js';
3
3
 
4
4
  declare const EXTERNAL_HANDOFF_SNAPSHOT_SCHEMA_VERSION: 1;
5
5
  declare const EXTERNAL_HANDOFF_BROKER_PROTOCOL_VERSION: 2;
6
6
  declare const EXTERNAL_HANDOFF_STATES: readonly ["available", "expired", "superseded"];
7
- declare const EXTERNAL_HANDOFF_FRAMEWORKS: readonly ["vite", "next"];
7
+ declare const EXTERNAL_HANDOFF_FRAMEWORKS: readonly ["vite", "next", "astro"];
8
8
  declare const EXTERNAL_HANDOFF_ACTIVE_ADAPTER_KINDS: readonly ["claude-channel", "codex-app-server"];
9
9
  declare const EXTERNAL_HANDOFF_ACTIVE_ADAPTER_STATES: readonly ["ready", "busy", "blocked"];
10
10
  declare const EXTERNAL_HANDOFF_DISPATCH_PHASES: readonly ["queued", "dispatching", "dispatched", "working", "completed", "failed", "delivery-unknown"];
@@ -54,6 +54,7 @@ declare const externalHandoffReportableDispatchPhaseSchema: z.ZodEnum<{
54
54
  declare const externalHandoffSummarySchema: z.ZodObject<{
55
55
  sessionId: z.ZodString;
56
56
  framework: z.ZodEnum<{
57
+ astro: "astro";
57
58
  vite: "vite";
58
59
  next: "next";
59
60
  }>;
@@ -80,6 +81,7 @@ declare const externalHandoffSnapshotSchema: z.ZodObject<{
80
81
  session: z.ZodObject<{
81
82
  id: z.ZodString;
82
83
  framework: z.ZodEnum<{
84
+ astro: "astro";
83
85
  vite: "vite";
84
86
  next: "next";
85
87
  }>;
@@ -119,6 +121,7 @@ declare const externalHandoffSnapshotSchema: z.ZodObject<{
119
121
  column: z.ZodOptional<z.ZodNumber>;
120
122
  origin: z.ZodEnum<{
121
123
  "jsx-host": "jsx-host";
124
+ "astro-host": "astro-host";
122
125
  "react-fiber": "react-fiber";
123
126
  "dom-ancestor": "dom-ancestor";
124
127
  none: "none";
@@ -144,6 +147,7 @@ declare const externalHandoffSnapshotSchema: z.ZodObject<{
144
147
  column: z.ZodOptional<z.ZodNumber>;
145
148
  origin: z.ZodEnum<{
146
149
  "jsx-host": "jsx-host";
150
+ "astro-host": "astro-host";
147
151
  "react-fiber": "react-fiber";
148
152
  "dom-ancestor": "dom-ancestor";
149
153
  none: "none";
@@ -186,6 +190,7 @@ declare const externalHandoffSnapshotSchema: z.ZodObject<{
186
190
  language: z.ZodEnum<{
187
191
  tsx: "tsx";
188
192
  jsx: "jsx";
193
+ astro: "astro";
189
194
  }>;
190
195
  startLine: z.ZodNumber;
191
196
  endLine: z.ZodNumber;
@@ -266,6 +271,7 @@ declare const externalHandoffPublishRequestSchema: z.ZodObject<{
266
271
  column: z.ZodOptional<z.ZodNumber>;
267
272
  origin: z.ZodEnum<{
268
273
  "jsx-host": "jsx-host";
274
+ "astro-host": "astro-host";
269
275
  "react-fiber": "react-fiber";
270
276
  "dom-ancestor": "dom-ancestor";
271
277
  none: "none";
@@ -291,6 +297,7 @@ declare const externalHandoffPublishRequestSchema: z.ZodObject<{
291
297
  column: z.ZodOptional<z.ZodNumber>;
292
298
  origin: z.ZodEnum<{
293
299
  "jsx-host": "jsx-host";
300
+ "astro-host": "astro-host";
294
301
  "react-fiber": "react-fiber";
295
302
  "dom-ancestor": "dom-ancestor";
296
303
  none: "none";
@@ -333,6 +340,7 @@ declare const externalHandoffPublishRequestSchema: z.ZodObject<{
333
340
  language: z.ZodEnum<{
334
341
  tsx: "tsx";
335
342
  jsx: "jsx";
343
+ astro: "astro";
336
344
  }>;
337
345
  startLine: z.ZodNumber;
338
346
  endLine: z.ZodNumber;
@@ -432,6 +440,7 @@ declare const externalHandoffPublishResultSchema: z.ZodObject<{
432
440
  handoff: z.ZodObject<{
433
441
  sessionId: z.ZodString;
434
442
  framework: z.ZodEnum<{
443
+ astro: "astro";
435
444
  vite: "vite";
436
445
  next: "next";
437
446
  }>;
@@ -494,6 +503,7 @@ declare const externalHandoffStatusResultSchema: z.ZodObject<{
494
503
  handoff: z.ZodObject<{
495
504
  sessionId: z.ZodString;
496
505
  framework: z.ZodEnum<{
506
+ astro: "astro";
497
507
  vite: "vite";
498
508
  next: "next";
499
509
  }>;
@@ -1,10 +1,10 @@
1
1
  import { z } from 'zod';
2
- import { S as SpotAnnotation } from './annotation-C0Me9mN2.cjs';
2
+ import { S as SpotAnnotation } from './annotation-Cz-NNgR4.cjs';
3
3
 
4
4
  declare const EXTERNAL_HANDOFF_SNAPSHOT_SCHEMA_VERSION: 1;
5
5
  declare const EXTERNAL_HANDOFF_BROKER_PROTOCOL_VERSION: 2;
6
6
  declare const EXTERNAL_HANDOFF_STATES: readonly ["available", "expired", "superseded"];
7
- declare const EXTERNAL_HANDOFF_FRAMEWORKS: readonly ["vite", "next"];
7
+ declare const EXTERNAL_HANDOFF_FRAMEWORKS: readonly ["vite", "next", "astro"];
8
8
  declare const EXTERNAL_HANDOFF_ACTIVE_ADAPTER_KINDS: readonly ["claude-channel", "codex-app-server"];
9
9
  declare const EXTERNAL_HANDOFF_ACTIVE_ADAPTER_STATES: readonly ["ready", "busy", "blocked"];
10
10
  declare const EXTERNAL_HANDOFF_DISPATCH_PHASES: readonly ["queued", "dispatching", "dispatched", "working", "completed", "failed", "delivery-unknown"];
@@ -54,6 +54,7 @@ declare const externalHandoffReportableDispatchPhaseSchema: z.ZodEnum<{
54
54
  declare const externalHandoffSummarySchema: z.ZodObject<{
55
55
  sessionId: z.ZodString;
56
56
  framework: z.ZodEnum<{
57
+ astro: "astro";
57
58
  vite: "vite";
58
59
  next: "next";
59
60
  }>;
@@ -80,6 +81,7 @@ declare const externalHandoffSnapshotSchema: z.ZodObject<{
80
81
  session: z.ZodObject<{
81
82
  id: z.ZodString;
82
83
  framework: z.ZodEnum<{
84
+ astro: "astro";
83
85
  vite: "vite";
84
86
  next: "next";
85
87
  }>;
@@ -119,6 +121,7 @@ declare const externalHandoffSnapshotSchema: z.ZodObject<{
119
121
  column: z.ZodOptional<z.ZodNumber>;
120
122
  origin: z.ZodEnum<{
121
123
  "jsx-host": "jsx-host";
124
+ "astro-host": "astro-host";
122
125
  "react-fiber": "react-fiber";
123
126
  "dom-ancestor": "dom-ancestor";
124
127
  none: "none";
@@ -144,6 +147,7 @@ declare const externalHandoffSnapshotSchema: z.ZodObject<{
144
147
  column: z.ZodOptional<z.ZodNumber>;
145
148
  origin: z.ZodEnum<{
146
149
  "jsx-host": "jsx-host";
150
+ "astro-host": "astro-host";
147
151
  "react-fiber": "react-fiber";
148
152
  "dom-ancestor": "dom-ancestor";
149
153
  none: "none";
@@ -186,6 +190,7 @@ declare const externalHandoffSnapshotSchema: z.ZodObject<{
186
190
  language: z.ZodEnum<{
187
191
  tsx: "tsx";
188
192
  jsx: "jsx";
193
+ astro: "astro";
189
194
  }>;
190
195
  startLine: z.ZodNumber;
191
196
  endLine: z.ZodNumber;
@@ -266,6 +271,7 @@ declare const externalHandoffPublishRequestSchema: z.ZodObject<{
266
271
  column: z.ZodOptional<z.ZodNumber>;
267
272
  origin: z.ZodEnum<{
268
273
  "jsx-host": "jsx-host";
274
+ "astro-host": "astro-host";
269
275
  "react-fiber": "react-fiber";
270
276
  "dom-ancestor": "dom-ancestor";
271
277
  none: "none";
@@ -291,6 +297,7 @@ declare const externalHandoffPublishRequestSchema: z.ZodObject<{
291
297
  column: z.ZodOptional<z.ZodNumber>;
292
298
  origin: z.ZodEnum<{
293
299
  "jsx-host": "jsx-host";
300
+ "astro-host": "astro-host";
294
301
  "react-fiber": "react-fiber";
295
302
  "dom-ancestor": "dom-ancestor";
296
303
  none: "none";
@@ -333,6 +340,7 @@ declare const externalHandoffPublishRequestSchema: z.ZodObject<{
333
340
  language: z.ZodEnum<{
334
341
  tsx: "tsx";
335
342
  jsx: "jsx";
343
+ astro: "astro";
336
344
  }>;
337
345
  startLine: z.ZodNumber;
338
346
  endLine: z.ZodNumber;
@@ -432,6 +440,7 @@ declare const externalHandoffPublishResultSchema: z.ZodObject<{
432
440
  handoff: z.ZodObject<{
433
441
  sessionId: z.ZodString;
434
442
  framework: z.ZodEnum<{
443
+ astro: "astro";
435
444
  vite: "vite";
436
445
  next: "next";
437
446
  }>;
@@ -494,6 +503,7 @@ declare const externalHandoffStatusResultSchema: z.ZodObject<{
494
503
  handoff: z.ZodObject<{
495
504
  sessionId: z.ZodString;
496
505
  framework: z.ZodEnum<{
506
+ astro: "astro";
497
507
  vite: "vite";
498
508
  next: "next";
499
509
  }>;
@@ -59,7 +59,11 @@ var EXTERNAL_HANDOFF_STATES = Object.freeze([
59
59
  "expired",
60
60
  "superseded"
61
61
  ]);
62
- var EXTERNAL_HANDOFF_FRAMEWORKS = Object.freeze(["vite", "next"]);
62
+ var EXTERNAL_HANDOFF_FRAMEWORKS = Object.freeze([
63
+ "vite",
64
+ "next",
65
+ "astro"
66
+ ]);
63
67
  var EXTERNAL_HANDOFF_ACTIVE_ADAPTER_KINDS = Object.freeze([
64
68
  "claude-channel",
65
69
  "codex-app-server"
@@ -168,6 +172,8 @@ var EXTERNAL_HANDOFF_LIMITS2 = Object.freeze({
168
172
  activeStatusPollMs: 1e3
169
173
  });
170
174
  var EXTERNAL_AGENT_CONTROL_LIMITS = Object.freeze({
175
+ maximumModels: 128,
176
+ maximumModelCharacters: 128,
171
177
  maximumEventSubscribers: 4,
172
178
  eventHeartbeatMs: 15e3,
173
179
  eventReconnectMinimumMs: 500,