@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.
- package/dist/{annotation-C0Me9mN2.d.cts → annotation-Cz-NNgR4.d.cts} +2 -2
- package/dist/{annotation-C0Me9mN2.d.ts → annotation-Cz-NNgR4.d.ts} +2 -2
- package/dist/{chunk-IUTOVI5G.js → chunk-CLQ6MIJB.js} +5 -3
- package/dist/chunk-CLQ6MIJB.js.map +1 -0
- package/dist/{chunk-DYTWEIES.js → chunk-EWJTKNL4.js} +2 -1
- package/dist/chunk-EWJTKNL4.js.map +1 -0
- package/dist/{chunk-2LVIH7OA.js → chunk-IX6MSCK6.js} +6 -2
- package/dist/chunk-IX6MSCK6.js.map +1 -0
- package/dist/{chunk-YQ5GL523.js → chunk-JTZFOTPT.js} +3 -3
- package/dist/{chunk-C2PJ4UUU.js → chunk-R6QJFNT2.js} +3 -3
- package/dist/chunk-R6QJFNT2.js.map +1 -0
- package/dist/{contextual-ask-B0mCFn92.d.cts → contextual-ask-BpbkpFFf.d.cts} +25 -0
- package/dist/{contextual-ask-B0mCFn92.d.ts → contextual-ask-BpbkpFFf.d.ts} +25 -0
- package/dist/contextual-ask-browser.cjs +1 -0
- package/dist/contextual-ask-browser.cjs.map +1 -1
- package/dist/contextual-ask-browser.d.cts +1 -1
- package/dist/contextual-ask-browser.d.ts +1 -1
- package/dist/contextual-ask-browser.js +1 -1
- package/dist/contextual-ask-node.cjs +5 -2
- package/dist/contextual-ask-node.cjs.map +1 -1
- package/dist/contextual-ask-node.d.cts +3 -3
- package/dist/contextual-ask-node.d.ts +3 -3
- package/dist/contextual-ask-node.js +3 -3
- package/dist/{data-flow-runtime-vKeEaJgT.d.ts → data-flow-runtime-DhWpQoik.d.ts} +13 -0
- package/dist/{data-flow-runtime-D8HPSb2i.d.cts → data-flow-runtime-w43iwvGA.d.cts} +13 -0
- package/dist/data-flow-runtime.d.cts +1 -1
- package/dist/data-flow-runtime.d.ts +1 -1
- package/dist/{external-agent-control-CRBbjDDk.d.cts → external-agent-control-DKxQACUv.d.cts} +8 -3
- package/dist/{external-agent-control-CRBbjDDk.d.ts → external-agent-control-DKxQACUv.d.ts} +8 -3
- package/dist/external-agent-node.cjs +178 -20
- package/dist/external-agent-node.cjs.map +1 -1
- package/dist/external-agent-node.d.cts +18 -3
- package/dist/external-agent-node.d.ts +18 -3
- package/dist/external-agent-node.js +172 -20
- package/dist/external-agent-node.js.map +1 -1
- package/dist/{external-handoff-DighrWn8.d.ts → external-handoff-5zHu-fz2.d.ts} +12 -2
- package/dist/{external-handoff-DwtFFR6F.d.cts → external-handoff-DeiIvR-2.d.cts} +12 -2
- package/dist/external-handoff-browser.cjs +7 -1
- package/dist/external-handoff-browser.cjs.map +1 -1
- package/dist/external-handoff-browser.d.cts +5 -3
- package/dist/external-handoff-browser.d.ts +5 -3
- package/dist/external-handoff-browser.js +3 -1
- package/dist/external-handoff-browser.js.map +1 -1
- package/dist/index.cjs +36 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -7
- package/dist/index.d.ts +19 -7
- package/dist/index.js +31 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-2LVIH7OA.js.map +0 -1
- package/dist/chunk-C2PJ4UUU.js.map +0 -1
- package/dist/chunk-DYTWEIES.js.map +0 -1
- package/dist/chunk-IUTOVI5G.js.map +0 -1
- /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-
|
|
8
|
+
} from "./chunk-JTZFOTPT.js";
|
|
9
9
|
import {
|
|
10
10
|
ERROR_CODES
|
|
11
|
-
} from "./chunk-
|
|
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-
|
|
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
|
|
117
|
-
const
|
|
118
|
-
if (
|
|
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
|
|
192
|
+
return path.win32.join(
|
|
193
|
+
systemRoot,
|
|
194
|
+
"System32",
|
|
195
|
+
"WindowsPowerShell",
|
|
196
|
+
"v1.0",
|
|
197
|
+
"powershell.exe"
|
|
198
|
+
);
|
|
122
199
|
}
|
|
123
|
-
async function
|
|
124
|
-
|
|
125
|
-
|
|
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
|
|
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
|
|
141
|
-
|
|
262
|
+
if (created) await initializeWindowsDirectory(directory);
|
|
263
|
+
await assertPrivateExternalHandoffPath(directory, "directory");
|
|
264
|
+
return realpath(directory);
|
|
142
265
|
}
|
|
143
|
-
async function
|
|
144
|
-
|
|
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
|
|
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
|
-
|
|
155
|
-
|
|
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
|
|
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-
|
|
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-
|
|
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([
|
|
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,
|