@langgexyz/anycode 0.0.0-stage → 0.4.9

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.
@@ -0,0 +1,1353 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from "node:module";
3
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
4
+
5
+ // src/cli.ts
6
+ import { createHash as createHash5 } from "node:crypto";
7
+ import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
8
+ import { homedir } from "node:os";
9
+ import { dirname as dirname4, join as join4 } from "node:path";
10
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
11
+ import { spawnSync } from "node:child_process";
12
+
13
+ // ../runtime/harness-context/src/entry-module.ts
14
+ import { realpathSync } from "node:fs";
15
+ import { resolve } from "node:path";
16
+ import { fileURLToPath } from "node:url";
17
+ function isEntryModule(moduleUrl, invokedFile, isRuntimeMain = false, runtimeExecutable) {
18
+ if (isRuntimeMain)
19
+ return true;
20
+ if (invokedFile === undefined)
21
+ return false;
22
+ if (runtimeExecutable !== undefined && resolve(invokedFile) === resolve(runtimeExecutable))
23
+ return true;
24
+ try {
25
+ return realpathSync(resolve(invokedFile)) === realpathSync(resolve(fileURLToPath(moduleUrl)));
26
+ } catch {
27
+ return false;
28
+ }
29
+ }
30
+
31
+ // ../runtime/archive/src/index.ts
32
+ import { gunzipSync, gzipSync } from "node:zlib";
33
+ import { chmodSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
34
+ import { dirname, join, posix, relative, resolve as resolve2 } from "node:path";
35
+ function readTarGzip(archive) {
36
+ const bytes = gunzipSync(readFileSync(archive));
37
+ const entries = [];
38
+ let offset = 0;
39
+ let pendingPath = "";
40
+ let pendingPax = {};
41
+ while (offset + 512 <= bytes.length) {
42
+ const header = bytes.subarray(offset, offset + 512);
43
+ offset += 512;
44
+ if (header.every((value) => value === 0))
45
+ break;
46
+ verifyChecksum(header);
47
+ const typeFlag = text(header, 156, 1) || "0";
48
+ const size = octal(header, 124, 12);
49
+ const bodySize = Math.ceil(size / 512) * 512;
50
+ if (offset + bodySize > bytes.length)
51
+ throw new Error("archive entry exceeds archive size");
52
+ const body = bytes.subarray(offset, offset + size);
53
+ offset += bodySize;
54
+ if (typeFlag === "x" || typeFlag === "g") {
55
+ pendingPax = typeFlag === "x" ? parsePax(body) : pendingPax;
56
+ continue;
57
+ }
58
+ if (typeFlag === "L") {
59
+ pendingPath = body.toString("utf8").replace(/\0+$/u, "").replace(/\n+$/u, "");
60
+ continue;
61
+ }
62
+ const path = pendingPax["path"] || pendingPath || join(text(header, 345, 155), text(header, 0, 100));
63
+ pendingPath = "";
64
+ pendingPax = {};
65
+ if (!path)
66
+ throw new Error("archive entry path is empty");
67
+ const mode = pendingNumber(header, 100, 8, "mode");
68
+ const type = typeFlag === "0" || typeFlag === "" ? "file" : typeFlag === "5" ? "directory" : "unsupported";
69
+ entries.push({ path, type, mode, data: Buffer.from(body) });
70
+ }
71
+ return entries;
72
+ }
73
+ function extractTarGzip(archive, destination) {
74
+ const entries = readTarGzip(archive);
75
+ const seen = new Set;
76
+ for (const entry of entries) {
77
+ const path = safeArchivePath(destination, entry.path);
78
+ const normalized = normalizeArchivePath(entry.path);
79
+ if (seen.has(normalized))
80
+ throw new Error(`archive contains duplicate member: ${entry.path}`);
81
+ seen.add(normalized);
82
+ if (entry.type === "unsupported")
83
+ throw new Error("package contains unsupported archive member type");
84
+ if (entry.type === "directory") {
85
+ mkdirSync(path, { recursive: true });
86
+ continue;
87
+ }
88
+ mkdirSync(dirname(path), { recursive: true });
89
+ writeFileSync(path, entry.data, { mode: entry.mode || 420 });
90
+ chmodSync(path, entry.mode & 4095 || 420);
91
+ }
92
+ return entries;
93
+ }
94
+ function parsePax(body) {
95
+ const result = {};
96
+ let offset = 0;
97
+ while (offset < body.length) {
98
+ const space = body.indexOf(32, offset);
99
+ if (space < 0)
100
+ throw new Error("invalid archive PAX header");
101
+ const length = Number(body.subarray(offset, space).toString("ascii"));
102
+ if (!Number.isInteger(length) || length <= 0 || offset + length > body.length)
103
+ throw new Error("invalid archive PAX length");
104
+ const record = body.subarray(space + 1, offset + length - 1).toString("utf8");
105
+ const equal = record.indexOf("=");
106
+ if (equal <= 0)
107
+ throw new Error("invalid archive PAX record");
108
+ result[record.slice(0, equal)] = record.slice(equal + 1);
109
+ offset += length;
110
+ }
111
+ return result;
112
+ }
113
+ function safeArchivePath(root, value) {
114
+ const normalized = normalizeArchivePath(value);
115
+ const path = resolve2(root, normalized);
116
+ const relativePath = relative(resolve2(root), path);
117
+ if (!relativePath || relativePath === ".." || relativePath.startsWith(`..${"/"}`) || relativePath.startsWith("/"))
118
+ throw new Error(`package contains unsafe path: ${value}`);
119
+ return path;
120
+ }
121
+ function normalizeArchivePath(value) {
122
+ const normalized = posix.normalize(value.replaceAll("\\", "/")).replace(/^\.\//u, "");
123
+ if (!normalized || normalized === "." || normalized.startsWith("..") || normalized.includes("/../") || normalized.startsWith("/"))
124
+ throw new Error(`package contains unsafe path: ${value}`);
125
+ return normalized;
126
+ }
127
+ function verifyChecksum(header) {
128
+ const expected = octal(header, 148, 8);
129
+ const copy = Buffer.from(header);
130
+ copy.fill(32, 148, 156);
131
+ const actual = [...copy].reduce((sum, value) => sum + value, 0);
132
+ if (expected !== actual)
133
+ throw new Error("archive header checksum mismatch");
134
+ }
135
+ function text(buffer, offset, length) {
136
+ return buffer.subarray(offset, offset + length).toString("utf8").replace(/\0+$/u, "").trim();
137
+ }
138
+ function octal(buffer, offset, length) {
139
+ const value = text(buffer, offset, length).replace(/\0/g, "").trim();
140
+ return value ? Number.parseInt(value, 8) : 0;
141
+ }
142
+ function pendingNumber(buffer, offset, length, field) {
143
+ const value = octal(buffer, offset, length);
144
+ if (!Number.isSafeInteger(value) || value < 0)
145
+ throw new Error(`archive ${field} is invalid`);
146
+ return value;
147
+ }
148
+
149
+ // ../runtime/core/src/connector.ts
150
+ class ConnectorRegistry {
151
+ connectors = new Map;
152
+ capabilityOwners = new Map;
153
+ capabilitySetups = new Map;
154
+ constructor(connectors = [], setups = []) {
155
+ for (const setup of setups)
156
+ this.registerSetup(setup);
157
+ for (const connector of connectors)
158
+ this.register(connector);
159
+ }
160
+ register(connector) {
161
+ validateConnector(connector);
162
+ if (this.connectors.has(connector.id))
163
+ throw new Error(`duplicate connector: ${connector.id}`);
164
+ for (const capability of connector.capabilities) {
165
+ const setup = connector.setup?.[capability];
166
+ if (setup !== undefined) {
167
+ validateSetup(setup);
168
+ if (setup.connectorId !== connector.id || setup.capability !== capability) {
169
+ throw new Error(`Connector setup identity does not match its owner: ${connector.id}/${capability}`);
170
+ }
171
+ if (this.capabilitySetups.has(setupKey(connector.id, capability)))
172
+ throw new Error(`capability setup already registered: ${capability}`);
173
+ }
174
+ }
175
+ this.connectors.set(connector.id, connector);
176
+ for (const capability of connector.capabilities) {
177
+ const owners = this.capabilityOwners.get(capability) ?? [];
178
+ owners.push(connector);
179
+ this.capabilityOwners.set(capability, owners);
180
+ const setup = connector.setup?.[capability];
181
+ if (setup !== undefined)
182
+ this.capabilitySetups.set(setupKey(connector.id, capability), setup);
183
+ }
184
+ }
185
+ registerSetup(setup) {
186
+ validateSetup(setup);
187
+ const key = setupKey(setup.connectorId, setup.capability);
188
+ if (this.capabilitySetups.has(key))
189
+ throw new Error(`capability setup already registered: ${setup.capability}`);
190
+ this.capabilitySetups.set(key, setup);
191
+ }
192
+ resolve(capabilityId, connectorId) {
193
+ const owners = this.capabilityOwners.get(capabilityId) ?? [];
194
+ if (connectorId !== undefined)
195
+ return owners.find((connector) => connector.id === connectorId);
196
+ return owners.length === 1 ? owners[0] : undefined;
197
+ }
198
+ all() {
199
+ return [...this.connectors.values()];
200
+ }
201
+ declaredCapabilities() {
202
+ return [...new Set([...this.capabilityOwners.keys(), ...[...this.capabilitySetups.values()].map((setup) => setup.capability)])];
203
+ }
204
+ async execute(request, connectorId) {
205
+ validateCapabilityRequest(request);
206
+ const owners = this.capabilityOwners.get(request.capabilityId) ?? [];
207
+ if (connectorId !== undefined && !owners.some((connector2) => connector2.id === connectorId)) {
208
+ return unavailable(request, this.capabilitySetups.get(setupKey(connectorId, request.capabilityId)));
209
+ }
210
+ if (connectorId === undefined && owners.length > 1) {
211
+ return failed(request, `multiple Connectors implement ${request.capabilityId}; select one in the project binding`, "connector_binding_required");
212
+ }
213
+ const connector = connectorId === undefined ? owners[0] : this.resolve(request.capabilityId, connectorId);
214
+ if (!connector) {
215
+ const setups = [...this.capabilitySetups.values()].filter((setup) => setup.capability === request.capabilityId);
216
+ return unavailable(request, connectorId === undefined && setups.length === 1 ? setups[0] : undefined);
217
+ }
218
+ try {
219
+ const result = await connector.execute(request);
220
+ validateCapabilityResult(result);
221
+ if (result.capability !== request.capabilityId || result.runId !== request.runId)
222
+ return failed(request, "connector result identity does not match capability request", "connector_identity_mismatch");
223
+ return result;
224
+ } catch (error) {
225
+ return failed(request, error instanceof Error ? error.message : String(error), "connector_execution_failed");
226
+ }
227
+ }
228
+ }
229
+ function setupKey(connectorId, capability) {
230
+ return `${connectorId}\x00${capability}`;
231
+ }
232
+ function validateSetup(setup) {
233
+ if (!setup.connectorId.trim() || !setup.capability.trim())
234
+ throw new Error("Connector setup requires connectorId and capability");
235
+ }
236
+ function validateConnector(connector) {
237
+ if (!connector.id.trim())
238
+ throw new Error("connector id must not be empty");
239
+ if (connector.capabilities.length === 0)
240
+ throw new Error(`connector requires capabilities: ${connector.id}`);
241
+ const unique = new Set;
242
+ for (const capability of connector.capabilities) {
243
+ if (!/^[a-z0-9][a-z0-9-]*\.[a-z0-9][a-z0-9-]*$/u.test(capability))
244
+ throw new Error(`connector capability must use domain.name form: ${capability}`);
245
+ if (unique.has(capability))
246
+ throw new Error(`connector declares duplicate capability: ${capability}`);
247
+ unique.add(capability);
248
+ }
249
+ }
250
+ function unavailable(request, setup) {
251
+ return {
252
+ capability: request.capabilityId,
253
+ runId: request.runId,
254
+ status: "blocked",
255
+ inputs: request.inputs,
256
+ outputs: {},
257
+ evidence: [],
258
+ reason: `connector unavailable for capability: ${request.capabilityId}`,
259
+ certainty: "confirmed",
260
+ sideEffect: "none",
261
+ errorCode: "connector_unavailable",
262
+ declaration: "real",
263
+ recovery: {
264
+ action: "configure_connector",
265
+ capability: request.capabilityId,
266
+ target: request.trace.target,
267
+ idempotencyKey: request.idempotencyKey,
268
+ ...setup === undefined ? {} : { setup }
269
+ }
270
+ };
271
+ }
272
+ function failed(request, reason, errorCode) {
273
+ return {
274
+ capability: request.capabilityId,
275
+ runId: request.runId,
276
+ status: "failed",
277
+ inputs: request.inputs,
278
+ outputs: {},
279
+ evidence: [],
280
+ reason,
281
+ certainty: "unknown",
282
+ sideEffect: "possible",
283
+ errorCode,
284
+ declaration: "real",
285
+ recovery: {
286
+ action: "probe_connector",
287
+ capability: request.capabilityId,
288
+ target: request.trace.target,
289
+ idempotencyKey: request.idempotencyKey
290
+ }
291
+ };
292
+ }
293
+ // ../runtime/core/src/protection.ts
294
+ var LOCAL_CAPABILITY_DOMAINS = new Set(["change", "project", "verification", "git"]);
295
+ var TARGETS = new Set(["workstation", "test", "beta", "prod", "external"]);
296
+ // ../runtime/core/src/index.ts
297
+ class CapabilityRegistry {
298
+ specs = new Map;
299
+ constructor(specs = []) {
300
+ for (const spec of specs)
301
+ this.register(spec);
302
+ }
303
+ register(spec) {
304
+ if (this.specs.has(spec.capabilityId))
305
+ throw new Error(`duplicate capability: ${spec.capabilityId}`);
306
+ this.specs.set(spec.capabilityId, spec);
307
+ }
308
+ resolve(capabilityId) {
309
+ const spec = this.specs.get(capabilityId);
310
+ if (!spec)
311
+ throw new Error(`capability is not registered: ${capabilityId}`);
312
+ return spec;
313
+ }
314
+ all() {
315
+ return [...this.specs.values()];
316
+ }
317
+ }
318
+ function validateCapabilityResult(result) {
319
+ if (!result.capability.trim() || !result.runId.trim())
320
+ throw new Error("capability and runId must not be empty");
321
+ if (result.declaration !== "real" && result.declaration !== "probe")
322
+ throw new Error("declaration must be real or probe");
323
+ if (result.status === "pass" && result.evidence.length === 0)
324
+ throw new Error("pass result must include evidence");
325
+ if (result.status !== "pass" && !result.reason.trim())
326
+ throw new Error(`${result.status} result must include reason`);
327
+ if (result.recovery?.retryAfterMs !== undefined && (!Number.isFinite(result.recovery.retryAfterMs) || result.recovery.retryAfterMs < 0))
328
+ throw new Error("recovery retryAfterMs must be a non-negative finite number");
329
+ }
330
+ function validateCapabilityRequest(request) {
331
+ if (!request.capabilityId.trim() || !request.runId.trim())
332
+ throw new Error("capabilityId and runId must not be empty");
333
+ if (!request.trace.traceId.trim() || !request.trace.requestId.trim() || !request.trace.sessionId.trim()) {
334
+ throw new Error("trace requires traceId, requestId and sessionId");
335
+ }
336
+ if (request.timeoutMs !== undefined && (!Number.isInteger(request.timeoutMs) || request.timeoutMs <= 0)) {
337
+ throw new Error("timeoutMs must be a positive integer");
338
+ }
339
+ }
340
+
341
+ // ../runtime/providers/src/installation/package-build.ts
342
+ var LAUNCHER = `#!/bin/sh
343
+ ` + `script="$0"
344
+ ` + `while [ -L "$script" ]; do
345
+ ` + ` target="$(readlink "$script")"
346
+ ` + ` case "$target" in
347
+ ` + ` /*) script="$target" ;;
348
+ ` + ` *) script="$(dirname "$script")/$target" ;;
349
+ ` + ` esac
350
+ ` + `done
351
+ ` + `root="$(CDPATH= cd -- "$(dirname -- "$script")/.." && pwd)"
352
+ ` + `if [ "$1" = "claude-hook" ]; then
353
+ ` + ' exec "${ANYCODE_NODE:-node}" "$root/runtime/claude/dist/cli.mjs" "$@"\n' + `fi
354
+ ` + 'exec "${ANYCODE_NODE:-node}" "$root/runtime/providers/dist/cli.mjs" "$@"\n';
355
+ var WINDOWS_LAUNCHER = `@echo off\r
356
+ ` + `set "script=%~dp0"\r
357
+ ` + `set "root=%script%.."\r
358
+ ` + `if "%ANYCODE_NODE%"=="" set "ANYCODE_NODE=node"\r
359
+ ` + `if "%~1"=="claude-hook" (\r
360
+ ` + ` "%ANYCODE_NODE%" "%root%\\runtime\\claude\\dist\\cli.mjs" %*\r
361
+ ` + ` exit /b %ERRORLEVEL%\r
362
+ ` + `)\r
363
+ ` + `"%ANYCODE_NODE%" "%root%\\runtime\\providers\\dist\\cli.mjs" %*\r
364
+ `;
365
+ // ../runtime/providers/src/installation/package-installed.ts
366
+ import { createHash } from "node:crypto";
367
+ import { existsSync as existsSync2, lstatSync as lstatSync2, readFileSync as readFileSync2, readdirSync as readdirSync2, readlinkSync } from "node:fs";
368
+ import { join as join2, posix as posix2, relative as relative2, sep } from "node:path";
369
+ var PACKAGE_SCHEMA = "anycode.package.v1";
370
+ var FULL_REVISION = /^[0-9a-f]{40}$/u;
371
+ function validateExistingInstall(root) {
372
+ let stat;
373
+ try {
374
+ stat = lstatSync2(root);
375
+ } catch (error) {
376
+ if (error.code === "ENOENT")
377
+ return;
378
+ throw error;
379
+ }
380
+ if (!stat.isDirectory() || stat.isSymbolicLink())
381
+ throw new Error(`AnyCode install path must be a directory: ${root}`);
382
+ const names = readdirSync2(root);
383
+ if (!names.length)
384
+ return;
385
+ if (isLegacyVersionedInstall(root, names))
386
+ return;
387
+ const manifestPath = join2(root, "package-manifest.json");
388
+ if (!names.includes("package-manifest.json"))
389
+ throw new Error(`AnyCode install directory contains unrecognized files: ${root}`);
390
+ try {
391
+ JSON.parse(readFileSync2(manifestPath, "utf8"));
392
+ } catch {
393
+ throw new Error(`\u65e7\u7248\u6241\u5e73\u5b89\u88c5\u6e05\u5355\u89e3\u6790\u5931\u8d25\uff1a${manifestPath}`);
394
+ }
395
+ verifyInstalledPackage(root);
396
+ }
397
+ function isLegacyVersionedInstall(root, names) {
398
+ if (!names.includes("current") || names.some((name) => name !== "current" && !/^v\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u.test(name)))
399
+ return false;
400
+ try {
401
+ const currentPath = join2(root, "current");
402
+ if (!lstatSync2(currentPath).isSymbolicLink())
403
+ return false;
404
+ const target = readlinkSync(currentPath);
405
+ if (target.includes("\\") || target.startsWith("/") || target.includes("..") || !names.includes(target))
406
+ return false;
407
+ for (const name of names) {
408
+ if (name === "current")
409
+ continue;
410
+ const versionRoot = join2(root, name);
411
+ if (!lstatSync2(versionRoot).isDirectory())
412
+ return false;
413
+ const manifest = verifyInstalledPackage(versionRoot);
414
+ if (name !== `v${manifest.version}`)
415
+ return false;
416
+ }
417
+ return true;
418
+ } catch {
419
+ return false;
420
+ }
421
+ }
422
+ function verifyInstalledPackage(root) {
423
+ if (!existsSync2(root) || !lstatSync2(root).isDirectory())
424
+ throw new Error(`installed package does not exist: ${root}`);
425
+ const manifestPath = join2(root, "package-manifest.json");
426
+ if (!existsSync2(manifestPath) || !lstatSync2(manifestPath).isFile())
427
+ throw new Error(`installed package is missing manifest: ${manifestPath}`);
428
+ const value = JSON.parse(readFileSync2(manifestPath, "utf8"));
429
+ if (!isRecord(value))
430
+ throw new Error("installed package manifest is invalid");
431
+ if (value["schema"] !== PACKAGE_SCHEMA || value["name"] !== "anycode")
432
+ throw new Error("installed package manifest identity is invalid");
433
+ if (typeof value["version"] !== "string" || !value["version"])
434
+ throw new Error("installed package version is invalid");
435
+ if (typeof value["source_revision"] !== "string" || !FULL_REVISION.test(value["source_revision"]))
436
+ throw new Error("installed package source_revision is invalid");
437
+ if (!isRecord(value["files"]) || Object.keys(value["files"]).length === 0)
438
+ throw new Error("installed package files are invalid");
439
+ if (!Object.hasOwn(value["files"], "bin/anycode") && !Object.hasOwn(value["files"], "bin/anycode.exe"))
440
+ throw new Error("installed package is missing launcher: bin/anycode");
441
+ const files = {};
442
+ for (const [name, digest] of Object.entries(value["files"])) {
443
+ const relative3 = normalizeMember(name);
444
+ if (typeof digest !== "string" || !/^sha256:[0-9a-f]{64}$/u.test(digest))
445
+ throw new Error(`installed package file digest is invalid: ${name}`);
446
+ files[relative3] = digest;
447
+ const path = join2(root, ...relative3.split("/"));
448
+ if (!existsSync2(path) || !lstatSync2(path).isFile() || lstatSync2(path).isSymbolicLink())
449
+ throw new Error(`installed package verification failed: ${relative3}`);
450
+ if (fileDigest(path) !== digest)
451
+ throw new Error(`installed package verification failed: ${relative3}`);
452
+ }
453
+ if (typeof value["payload_digest"] !== "string" || value["payload_digest"] !== payloadDigest(files))
454
+ throw new Error("installed package payload digest is invalid");
455
+ const extras = installedFiles(root).filter((name) => !(name in files) && name !== "package-manifest.json");
456
+ if (extras.length > 0)
457
+ throw new Error(`installed package contains untracked files: ${extras.slice(0, 10).join(", ")}`);
458
+ return { schema: value["schema"], name: value["name"], version: value["version"], source_revision: value["source_revision"], files, payload_digest: value["payload_digest"] };
459
+ }
460
+ function installedFiles(root) {
461
+ const result = [];
462
+ const walk = (path) => {
463
+ for (const name of readdirSync2(path).sort()) {
464
+ const child = join2(path, name);
465
+ if (lstatSync2(child).isSymbolicLink())
466
+ throw new Error(`installed package contains unsupported symlink: ${child}`);
467
+ if (lstatSync2(child).isFile())
468
+ result.push(relative2(root, child).split(sep).join("/"));
469
+ else if (lstatSync2(child).isDirectory())
470
+ walk(child);
471
+ }
472
+ };
473
+ walk(root);
474
+ return result;
475
+ }
476
+ function normalizeMember(value) {
477
+ const normalized = posix2.normalize(value.replace(/^\.\//u, ""));
478
+ if (!value || value.includes("\\") || normalized === "." || normalized === ".." || normalized.startsWith("../") || value.startsWith("/"))
479
+ throw new Error(`installed package contains unsafe path: ${value}`);
480
+ return normalized;
481
+ }
482
+ function payloadDigest(files) {
483
+ const ordered = Object.fromEntries(Object.entries(files).sort(([left], [right]) => left.localeCompare(right)));
484
+ return digestText(JSON.stringify(ordered));
485
+ }
486
+ function fileDigest(path) {
487
+ return digestBytes(readFileSync2(path));
488
+ }
489
+ function digestText(value) {
490
+ return digestBytes(new TextEncoder().encode(value));
491
+ }
492
+ function digestBytes(value) {
493
+ return `sha256:${createHash("sha256").update(value).digest("hex")}`;
494
+ }
495
+ function isRecord(value) {
496
+ return typeof value === "object" && value !== null && !Array.isArray(value);
497
+ }
498
+
499
+ // ../runtime/providers/src/installation/activation.ts
500
+ import { copyFileSync, existsSync as existsSync3, lstatSync as lstatSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync4, readlinkSync as readlinkSync2, renameSync as renameSync2, rmSync, statSync as statSync2, symlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
501
+ import { dirname as dirname3, join as join3, relative as relative3, resolve as resolve3 } from "node:path";
502
+ // ../runtime/providers/src/infrastructure/command-runner.ts
503
+ var SAFE_ENVIRONMENT_KEYS = new Set([
504
+ "PATH",
505
+ "HOME",
506
+ "LANG",
507
+ "LC_ALL",
508
+ "LC_CTYPE",
509
+ "TZ",
510
+ "TMPDIR",
511
+ "HTTP_PROXY",
512
+ "HTTPS_PROXY",
513
+ "ALL_PROXY",
514
+ "NO_PROXY",
515
+ "http_proxy",
516
+ "https_proxy",
517
+ "all_proxy",
518
+ "no_proxy"
519
+ ]);
520
+ var PROXY_KEYS = new Set(["HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY", "http_proxy", "https_proxy", "all_proxy"]);
521
+ // ../runtime/credentials/src/memory.ts
522
+ import { createHash as createHash2 } from "node:crypto";
523
+
524
+ // ../runtime/credentials/src/validation.ts
525
+ function validateCredentialRef(ref) {
526
+ for (const [name, value] of Object.entries(ref)) {
527
+ if (!value.trim())
528
+ throw new Error(`credential ${name} must not be empty`);
529
+ if (!/^[A-Za-z0-9._:/-]+$/u.test(value))
530
+ throw new Error(`credential ${name} contains unsupported characters`);
531
+ }
532
+ }
533
+ function credentialKey(ref) {
534
+ validateCredentialRef(ref);
535
+ return JSON.stringify([ref.scope, ref.field]);
536
+ }
537
+
538
+ // ../runtime/credentials/src/secret-lease.ts
539
+ var leaseStates = new WeakMap;
540
+ function createSecretLease(ref, secret) {
541
+ const secretForms = [
542
+ secret,
543
+ encodeURIComponent(secret),
544
+ Buffer.from(secret, "utf8").toString("base64"),
545
+ Buffer.from(secret, "utf8").toString("base64url"),
546
+ Buffer.from(secret, "utf8").toString("hex")
547
+ ].filter((form) => form.length > 0);
548
+ const state = { active: true, secret };
549
+ const lease = Object.freeze({
550
+ ref: Object.freeze({ ...ref }),
551
+ use(consumer) {
552
+ if (!state.active)
553
+ throw new Error("credential lease is no longer active");
554
+ let result;
555
+ try {
556
+ result = consumer(state.secret);
557
+ } catch (error) {
558
+ throw sanitizedError(error, secretForms);
559
+ }
560
+ return guardResult(result, secretForms);
561
+ }
562
+ });
563
+ leaseStates.set(lease, state);
564
+ return lease;
565
+ }
566
+ function guardResult(result, secretForms) {
567
+ let promiseLike;
568
+ try {
569
+ promiseLike = isPromiseLike(result);
570
+ } catch (error) {
571
+ throw sanitizedError(error, secretForms);
572
+ }
573
+ if (promiseLike) {
574
+ return Promise.resolve(result).then((value) => guardValue(value, secretForms), (error) => {
575
+ throw sanitizedError(error, secretForms);
576
+ });
577
+ }
578
+ return guardValue(result, secretForms);
579
+ }
580
+ function guardValue(value, secretForms) {
581
+ if (containsSecret(value, secretForms, new WeakSet)) {
582
+ throw new Error("Connector result must not contain a credential value");
583
+ }
584
+ return value;
585
+ }
586
+ function containsSecret(value, secretForms, visited) {
587
+ if (typeof value === "string")
588
+ return secretForms.some((form) => value.includes(form));
589
+ if (typeof value === "function")
590
+ return true;
591
+ if (value === null || typeof value !== "object")
592
+ return false;
593
+ if (visited.has(value))
594
+ return false;
595
+ visited.add(value);
596
+ if (value instanceof Uint8Array)
597
+ return secretForms.some((form) => includesBytes(value, new TextEncoder().encode(form)));
598
+ if (value instanceof Map)
599
+ return [...value].some(([key, entry]) => containsSecret(key, secretForms, visited) || containsSecret(entry, secretForms, visited));
600
+ if (value instanceof Set)
601
+ return [...value].some((entry) => containsSecret(entry, secretForms, visited));
602
+ try {
603
+ const prototype = Object.getPrototypeOf(value);
604
+ if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null)
605
+ return true;
606
+ if (Reflect.ownKeys(value).some((key) => typeof key === "string" ? secretForms.some((form) => key.includes(form)) : secretForms.some((form) => String(key).includes(form))))
607
+ return true;
608
+ for (const descriptor of Object.values(Object.getOwnPropertyDescriptors(value))) {
609
+ if (!("value" in descriptor))
610
+ return true;
611
+ if (containsSecret(descriptor.value, secretForms, visited))
612
+ return true;
613
+ }
614
+ } catch {
615
+ return true;
616
+ }
617
+ return false;
618
+ }
619
+ function includesBytes(bytes, needle) {
620
+ if (needle.length === 0)
621
+ return false;
622
+ outer:
623
+ for (let start = 0;start <= bytes.length - needle.length; start += 1) {
624
+ for (let offset = 0;offset < needle.length; offset += 1) {
625
+ if (bytes[start + offset] !== needle[offset])
626
+ continue outer;
627
+ }
628
+ return true;
629
+ }
630
+ return false;
631
+ }
632
+ function sanitizedError(error, secretForms) {
633
+ let message;
634
+ try {
635
+ message = error instanceof Error ? error.message : String(error);
636
+ } catch {
637
+ message = "Connector operation failed";
638
+ }
639
+ const sanitized = secretForms.some((form) => message.includes(form)) ? "Connector operation failed; error details contained a credential value" : message;
640
+ const result = new Error(sanitized);
641
+ if (error instanceof Error)
642
+ result.name = error.name;
643
+ return result;
644
+ }
645
+ function isPromiseLike(value) {
646
+ return (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
647
+ }
648
+
649
+ // ../runtime/credentials/src/memory.ts
650
+ class MemoryCredentialStorage {
651
+ id = "memory";
652
+ strategyId = this.id;
653
+ entries = new Map;
654
+ inspect(ref) {
655
+ validateCredentialRef(ref);
656
+ const entry = this.entries.get(credentialKey(ref));
657
+ return entry ? metadata(entry) : { ref, present: false };
658
+ }
659
+ list() {
660
+ return [...this.entries.values()].map(metadata);
661
+ }
662
+ write(ref, input) {
663
+ validateCredentialRef(ref);
664
+ if (!input.value)
665
+ throw new Error("credential value must not be empty");
666
+ const entry = { ref, value: input.value, updatedAt: new Date().toISOString() };
667
+ this.entries.set(credentialKey(ref), entry);
668
+ return metadata(entry);
669
+ }
670
+ fingerprint(ref) {
671
+ const entry = this.require(ref);
672
+ return { ...metadata(entry), fingerprint: fingerprint(entry.value) };
673
+ }
674
+ remove(ref) {
675
+ validateCredentialRef(ref);
676
+ return this.entries.delete(credentialKey(ref));
677
+ }
678
+ useSecret(ref, consumer) {
679
+ const entry = this.require(ref);
680
+ return createSecretLease(entry.ref, entry.value).use(consumer);
681
+ }
682
+ require(ref) {
683
+ validateCredentialRef(ref);
684
+ const entry = this.entries.get(credentialKey(ref));
685
+ if (!entry)
686
+ throw new Error(`credential is unavailable: ${credentialKey(ref)}`);
687
+ return entry;
688
+ }
689
+ }
690
+ function metadata(entry) {
691
+ return { ref: entry.ref, present: true, updatedAt: entry.updatedAt };
692
+ }
693
+ function fingerprint(value) {
694
+ return `sha256:${createHash2("sha256").update(value).digest("hex")}`;
695
+ }
696
+ // ../runtime/credentials/src/encrypted-file.ts
697
+ import { createCipheriv, createDecipheriv, createHash as createHash3, randomBytes } from "node:crypto";
698
+ import { chmodSync as chmodSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, renameSync, writeFileSync as writeFileSync2 } from "node:fs";
699
+ import { dirname as dirname2 } from "node:path";
700
+ class EncryptedFileCredentialStorage {
701
+ filePath;
702
+ keyProvider;
703
+ id = "encrypted-file";
704
+ strategyId = this.id;
705
+ constructor(filePath, keyProvider) {
706
+ this.filePath = filePath;
707
+ this.keyProvider = keyProvider;
708
+ }
709
+ inspect(ref) {
710
+ const entry = this.entries().get(credentialKey(ref));
711
+ return entry ? metadata2(entry) : { ref, present: false };
712
+ }
713
+ list() {
714
+ return [...this.entries().values()].map(metadata2);
715
+ }
716
+ write(ref, input) {
717
+ validateCredentialRef(ref);
718
+ if (!input.value)
719
+ throw new Error("credential value must not be empty");
720
+ const entries = this.entries();
721
+ const entry = { ref, value: input.value, updatedAt: new Date().toISOString() };
722
+ entries.set(credentialKey(ref), entry);
723
+ this.save(entries);
724
+ return metadata2(entry);
725
+ }
726
+ fingerprint(ref) {
727
+ const entry = this.require(ref);
728
+ return { ...metadata2(entry), fingerprint: fingerprint2(entry.value) };
729
+ }
730
+ remove(ref) {
731
+ const entries = this.entries();
732
+ const removed = entries.delete(credentialKey(ref));
733
+ if (removed)
734
+ this.save(entries);
735
+ return removed;
736
+ }
737
+ useSecret(ref, consumer) {
738
+ const entry = this.require(ref);
739
+ return createSecretLease(entry.ref, entry.value).use(consumer);
740
+ }
741
+ require(ref) {
742
+ const entry = this.entries().get(credentialKey(ref));
743
+ if (!entry)
744
+ throw new Error(`credential is unavailable: ${credentialKey(ref)}`);
745
+ return entry;
746
+ }
747
+ entries() {
748
+ try {
749
+ const envelope = JSON.parse(readFileSync3(this.filePath, "utf8"));
750
+ return decode(envelope, this.keyProvider.key());
751
+ } catch (error) {
752
+ if (isMissingFile(error))
753
+ return new Map;
754
+ throw new Error(`credential store cannot be opened: ${error instanceof Error ? error.message : String(error)}`);
755
+ }
756
+ }
757
+ save(entries) {
758
+ const directory = dirname2(this.filePath);
759
+ mkdirSync2(directory, { recursive: true, mode: 448 });
760
+ const temporary = `${this.filePath}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`;
761
+ writeFileSync2(temporary, JSON.stringify(encode(entries, this.keyProvider.key())) + `
762
+ `, { mode: 384 });
763
+ chmodSync2(temporary, 384);
764
+ renameSync(temporary, this.filePath);
765
+ chmodSync2(this.filePath, 384);
766
+ }
767
+ }
768
+ function encode(entries, key) {
769
+ const iv = randomBytes(12);
770
+ const cipher = createCipheriv("aes-256-gcm", key, iv);
771
+ const plaintext = JSON.stringify([...entries.values()]);
772
+ const ciphertext = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
773
+ return { version: 1, iv: iv.toString("base64url"), tag: cipher.getAuthTag().toString("base64url"), ciphertext: ciphertext.toString("base64url") };
774
+ }
775
+ function decode(envelope, key) {
776
+ if (envelope.version !== 1)
777
+ throw new Error("unsupported credential store version");
778
+ const decipher = createDecipheriv("aes-256-gcm", key, Buffer.from(envelope.iv, "base64url"));
779
+ decipher.setAuthTag(Buffer.from(envelope.tag, "base64url"));
780
+ const plaintext = Buffer.concat([decipher.update(Buffer.from(envelope.ciphertext, "base64url")), decipher.final()]).toString("utf8");
781
+ const values = JSON.parse(plaintext);
782
+ const entries = new Map;
783
+ for (const entry of values) {
784
+ validateCredentialRef(entry.ref);
785
+ entries.set(credentialKey(entry.ref), entry);
786
+ }
787
+ return entries;
788
+ }
789
+ function metadata2(entry) {
790
+ return { ref: entry.ref, present: true, updatedAt: entry.updatedAt };
791
+ }
792
+ function fingerprint2(value) {
793
+ return `sha256:${createHash3("sha256").update(value).digest("hex")}`;
794
+ }
795
+ function isMissingFile(error) {
796
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
797
+ }
798
+ // ../runtime/credentials/src/registry.ts
799
+ class CredentialStorageRegistry {
800
+ strategies = new Map;
801
+ constructor(strategies = []) {
802
+ for (const strategy of strategies)
803
+ this.register(strategy);
804
+ }
805
+ register(strategy) {
806
+ if (this.strategies.has(strategy.id))
807
+ throw new Error(`duplicate credential storage strategy: ${strategy.id}`);
808
+ this.strategies.set(strategy.id, strategy);
809
+ }
810
+ resolve(policy) {
811
+ const id = policy.kind === "external" ? policy.provider : policy.kind;
812
+ if (!id)
813
+ throw new Error("external credential storage requires a provider");
814
+ const strategy = this.strategies.get(id);
815
+ if (!strategy)
816
+ throw new Error(`credential storage strategy is unavailable: ${id}`);
817
+ return strategy;
818
+ }
819
+ }
820
+ // ../runtime/providers/src/infrastructure/authenticated-transport.ts
821
+ var MAX_REQUEST_BYTES = 1024 * 1024;
822
+ var MAX_RESPONSE_BYTES = 4 * 1024 * 1024;
823
+ var REQUEST_HEADERS = new Set(["accept", "content-type", "user-agent"]);
824
+ // ../runtime/providers/src/infrastructure/sensitive-key.ts
825
+ var SECRET_NOUNS = ["authorization", "credentials", "credential", "password", "passwd", "secret", "token"];
826
+ var KEY_QUALIFIERS = ["access", "api", "private", "secret"];
827
+ var nounPattern = SECRET_NOUNS.join("|");
828
+ var qualifierPattern = `(?:${KEY_QUALIFIERS.join("|")})[_-]?key`;
829
+ var SENSITIVE_KEY_PATTERN = `[\\p{L}\\p{N}_-]*(?:${nounPattern}|${qualifierPattern})(?![\\p{L}\\p{N}_])`;
830
+
831
+ // ../runtime/providers/src/infrastructure/redaction-rules.ts
832
+ var REDACTION_RULES = [
833
+ {
834
+ id: "private-key",
835
+ pattern: /-----BEGIN [^-]*PRIVATE KEY-----[\s\S]*?-----END [^-]*PRIVATE KEY-----/gu,
836
+ replacement: "[REDACTED:private-key]"
837
+ },
838
+ {
839
+ id: "bearer",
840
+ pattern: /\bBearer\s+(?!\[REDACTED:)[^\s,;}\]]+/giu,
841
+ replacement: "Bearer [REDACTED:bearer]"
842
+ },
843
+ {
844
+ id: "authorization",
845
+ pattern: /(?<authorizationQuote>["']?)(?<authorizationKey>authorization)\k<authorizationQuote>(?<authorizationSeparator>\s*[:=]\s*)(?!\s*\[REDACTED:)(?:(?<authorizationValueQuote>["'])(?:[\s\S]*?)\k<authorizationValueQuote>|[^\r\n"']+)/giu,
846
+ replacement: "$<authorizationQuote>$<authorizationKey>$<authorizationQuote>$<authorizationSeparator>$<authorizationValueQuote>[REDACTED:authorization]$<authorizationValueQuote>"
847
+ },
848
+ {
849
+ id: "assignment",
850
+ pattern: new RegExp(`(?<assignmentQuote>["']?)(?<assignmentKey>${SENSITIVE_KEY_PATTERN})\\k<assignmentQuote>(?<assignmentSeparator>\\s*[:=]\\s*)(?!\\s*\\[REDACTED:)(?:(?<assignmentValueQuote>["'])(?:[\\s\\S]*?)\\k<assignmentValueQuote>|[^\\s,;}\\]"']+)`, "giu"),
851
+ replacement: "$<assignmentQuote>$<assignmentKey>$<assignmentQuote>$<assignmentSeparator>$<assignmentValueQuote>[REDACTED:assignment]$<assignmentValueQuote>"
852
+ },
853
+ {
854
+ id: "url-userinfo",
855
+ pattern: /(?<urlScheme>\b[a-z][a-z0-9+.-]*:\/\/[^\s:@\/?#]*:)(?!\[REDACTED:)[^\s@\/?#]+(?=@)/giu,
856
+ replacement: "$<urlScheme>[REDACTED:url-password]"
857
+ }
858
+ ];
859
+
860
+ // ../runtime/providers/src/infrastructure/redaction.ts
861
+ var COMBINED_RULES = new RegExp(REDACTION_RULES.map((rule, index) => `(?<r${index}>${rule.pattern.source})`).join("|"), "giu");
862
+ // ../runtime/providers/src/infrastructure/transaction.ts
863
+ function rethrowAfterUndo(original, steps) {
864
+ const failures = [];
865
+ for (const undo of steps)
866
+ try {
867
+ undo();
868
+ } catch (error) {
869
+ failures.push(error);
870
+ }
871
+ if (failures.length === 0)
872
+ throw original;
873
+ throw new AggregateError([original, ...failures], `${original instanceof Error ? original.message : String(original)}; rollback had ${failures.length} failure(s)`, { cause: original });
874
+ }
875
+ // ../runtime/providers/src/installation/activation.ts
876
+ function activatePackage(stagedPackage, installRoot, launcherPath, options = {}) {
877
+ const platform = options.platform ?? process.platform;
878
+ const executable = options.executable ?? (platform === "win32" ? "anycode.exe" : "anycode");
879
+ mkdirSync3(dirname3(installRoot), { recursive: true });
880
+ const releaseLock = acquireActivationLock(installRoot, platform);
881
+ const previous = `${installRoot}.previous`;
882
+ let movedCurrent = false;
883
+ let installedNew = false;
884
+ try {
885
+ reconcileActivation(installRoot, previous, launcherPath, executable, platform);
886
+ const manifest = verifyInstalledPackage(stagedPackage);
887
+ validateExistingInstall(installRoot);
888
+ validateLauncherOwnership(launcherPath, installRoot, stagedPackage, executable, platform);
889
+ if (existsSync3(installRoot)) {
890
+ rmSync(previous, { recursive: true, force: true });
891
+ renameSync2(installRoot, previous);
892
+ movedCurrent = true;
893
+ }
894
+ renameSync2(stagedPackage, installRoot);
895
+ installedNew = true;
896
+ const installed = verifyInstalledPackage(installRoot);
897
+ if (installed.version !== manifest.version || installed.payload_digest !== manifest.payload_digest)
898
+ throw new Error("\u5b89\u88c5\u540e\u7684 AnyCode \u5305\u6821\u9a8c\u5931\u8d25");
899
+ linkLauncher(join3(installRoot, "bin", executable), launcherPath, platform);
900
+ try {
901
+ removeActivationPath(previous);
902
+ } catch {}
903
+ return installRoot;
904
+ } catch (error) {
905
+ rethrowAfterUndo(error, [
906
+ () => {
907
+ if (installedNew && existsSync3(installRoot))
908
+ rmSync(installRoot, { recursive: true, force: true });
909
+ },
910
+ () => {
911
+ if (movedCurrent && existsSync3(previous) && !existsSync3(installRoot))
912
+ renameSync2(previous, installRoot);
913
+ }
914
+ ]);
915
+ } finally {
916
+ releaseLock();
917
+ }
918
+ }
919
+ function acquireActivationLock(installRoot, platform) {
920
+ const lock = `${installRoot}.activation-lock`;
921
+ const deadline = Date.now() + 30000;
922
+ const token = `${process.pid}:${Date.now()}:${Math.random().toString(16).slice(2)}`;
923
+ while (true) {
924
+ try {
925
+ if (platform === "win32") {
926
+ mkdirSync3(lock);
927
+ try {
928
+ writeFileSync3(join3(lock, "owner"), token, { flag: "wx", mode: 384 });
929
+ } catch (error) {
930
+ rethrowAfterUndo(error, [() => rmSync(lock, { recursive: true, force: true })]);
931
+ }
932
+ } else {
933
+ symlinkSync(token, lock);
934
+ }
935
+ return () => {
936
+ for (let attempt = 0;attempt < 2; attempt += 1) {
937
+ try {
938
+ const owner = platform === "win32" ? readFileSync4(join3(lock, "owner"), "utf8") : readlinkSync2(lock);
939
+ if (owner === token)
940
+ rmSync(lock, { recursive: true, force: true });
941
+ return;
942
+ } catch {}
943
+ }
944
+ };
945
+ } catch (error) {
946
+ if (error.code !== "EEXIST")
947
+ throw error;
948
+ let stale = false;
949
+ try {
950
+ const metadata3 = lstatSync3(lock);
951
+ const owner = metadata3.isSymbolicLink() ? readlinkSync2(lock) : readFileSync4(join3(lock, "owner"), "utf8");
952
+ const pid = Number(owner.split(":", 1)[0]);
953
+ if (Number.isSafeInteger(pid) && pid > 0) {
954
+ try {
955
+ process.kill(pid, 0);
956
+ } catch (probeError) {
957
+ stale = probeError.code === "ESRCH";
958
+ }
959
+ }
960
+ } catch {
961
+ try {
962
+ stale = Date.now() - statSync2(lock).mtimeMs > 30000;
963
+ } catch {
964
+ stale = true;
965
+ }
966
+ }
967
+ if (stale) {
968
+ rmSync(lock, { recursive: true, force: true });
969
+ continue;
970
+ }
971
+ if (Date.now() >= deadline)
972
+ throw new Error(`timed out waiting for AnyCode activation lock: ${lock}`);
973
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 50);
974
+ }
975
+ }
976
+ }
977
+ function removeActivationPath(path) {
978
+ try {
979
+ rmSync(path, { recursive: true, force: true });
980
+ } catch (first) {
981
+ try {
982
+ rmSync(path, { recursive: true, force: true });
983
+ } catch (second) {
984
+ throw new AggregateError([first, second], `could not remove activation recovery path: ${path}`, { cause: first });
985
+ }
986
+ }
987
+ }
988
+ function reconcileActivation(installRoot, previous, launcherPath, executable, platform) {
989
+ if (!existsSync3(installRoot)) {
990
+ if (!existsSync3(previous))
991
+ return;
992
+ validateExistingInstall(previous);
993
+ renameSync2(previous, installRoot);
994
+ return;
995
+ }
996
+ if (!existsSync3(previous))
997
+ return;
998
+ try {
999
+ verifyInstalledPackage(installRoot);
1000
+ } catch {
1001
+ return;
1002
+ }
1003
+ validateLauncherOwnership(launcherPath, installRoot, installRoot, executable, platform);
1004
+ linkLauncher(join3(installRoot, "bin", executable), launcherPath, platform);
1005
+ try {
1006
+ rmSync(previous, { recursive: true, force: true });
1007
+ } catch {}
1008
+ }
1009
+ function validateLauncherOwnership(launcher, root, staged, executable, platform) {
1010
+ let existing;
1011
+ try {
1012
+ existing = lstatSync3(launcher);
1013
+ } catch (error) {
1014
+ if (error.code === "ENOENT")
1015
+ return;
1016
+ throw error;
1017
+ }
1018
+ if (existing.isSymbolicLink()) {
1019
+ const target = resolve3(dirname3(launcher), readlinkSync2(launcher));
1020
+ const path = relative3(resolve3(root), target).replaceAll("\\", "/");
1021
+ if (path === `bin/${executable}` || !path.startsWith("../") && path !== ".." && path.endsWith(`/bin/${executable}`))
1022
+ return;
1023
+ } else if (platform === "win32" && existing.isFile()) {
1024
+ const bytes = readFileSync4(launcher);
1025
+ for (const candidate of [join3(staged, "bin", executable), join3(root, "bin", executable)]) {
1026
+ if (existsSync3(candidate) && bytes.equals(readFileSync4(candidate)))
1027
+ return;
1028
+ }
1029
+ }
1030
+ throw new Error(`refusing to replace an unmanaged anycode launcher: ${launcher}`);
1031
+ }
1032
+ function linkLauncher(source, launcherPath, platform) {
1033
+ mkdirSync3(dirname3(launcherPath), { recursive: true });
1034
+ const next = `${launcherPath}.next`;
1035
+ rmSync(next, { force: true });
1036
+ if (platform === "win32")
1037
+ copyFileSync(source, next);
1038
+ else
1039
+ symlinkSync(source, next);
1040
+ try {
1041
+ renameSync2(next, launcherPath);
1042
+ } catch (error) {
1043
+ try {
1044
+ rmSync(next, { force: true });
1045
+ } catch {}
1046
+ throw error;
1047
+ }
1048
+ }
1049
+ // ../runtime/providers/src/installation/release-trust.ts
1050
+ import { verify } from "node:crypto";
1051
+ import { basename } from "node:path";
1052
+
1053
+ // ../runtime/providers/src/installation/release-key.generated.ts
1054
+ var RELEASE_PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
1055
+ MCowBQYDK2VwAyEA/hfqP5bUwAMqzY3QS+j9GIGjbYpyrtcheixQGJt93zo=
1056
+ -----END PUBLIC KEY-----
1057
+ `;
1058
+
1059
+ // ../runtime/providers/src/installation/release-trust.ts
1060
+ function verifyReleaseChecksums(sums, encodedSignature, publicKey = RELEASE_PUBLIC_KEY_PEM) {
1061
+ const encoded = encodedSignature.trim();
1062
+ const signature = Buffer.from(encoded, "base64");
1063
+ if (signature.toString("base64") !== encoded || signature.byteLength !== 64)
1064
+ throw new Error("AnyCode SHA256SUMS \u7b7e\u540d\u683c\u5f0f\u65e0\u6548");
1065
+ if (!verify(null, sums, publicKey, signature))
1066
+ throw new Error("AnyCode SHA256SUMS Ed25519 \u7b7e\u540d\u9a8c\u8bc1\u5931\u8d25");
1067
+ return parseReleaseChecksums(Buffer.from(sums).toString("utf8"));
1068
+ }
1069
+ function parseReleaseChecksums(value) {
1070
+ const result = new Map;
1071
+ for (const line of value.split(/\r?\n/u)) {
1072
+ if (!line.trim())
1073
+ continue;
1074
+ const match = /^([a-f0-9]{64})\s+[* ]?([^\s]+)$/u.exec(line.trim());
1075
+ if (!match || basename(match[2]) !== match[2] || result.has(match[2]))
1076
+ throw new Error("\u5df2\u7b7e\u540d SHA256SUMS \u683c\u5f0f\u65e0\u6548");
1077
+ result.set(match[2], match[1]);
1078
+ }
1079
+ if (!result.size)
1080
+ throw new Error("\u5df2\u7b7e\u540d SHA256SUMS \u4e0d\u80fd\u4e3a\u7a7a");
1081
+ return result;
1082
+ }
1083
+
1084
+ // ../runtime/providers/src/installation/update.ts
1085
+ import { createHash as createHash4, createPublicKey } from "node:crypto";
1086
+ var PLATFORM = new Map([
1087
+ ["darwin-arm64", "darwin-arm64"],
1088
+ ["darwin-x64", "darwin-x64"],
1089
+ ["linux-arm64", "linux-arm64"],
1090
+ ["linux-x64", "linux-x64"],
1091
+ ["win32-arm64", "windows-arm64"],
1092
+ ["win32-x64", "windows-x64"]
1093
+ ]);
1094
+ var RELEASE_PUBLIC_KEY_DER_SHA256 = createHash4("sha256").update(createPublicKey(RELEASE_PUBLIC_KEY_PEM).export({ type: "spki", format: "der" })).digest("hex");
1095
+ // src/cli.ts
1096
+ var HARNESS_IDS = ["opencode-v1", "opencode-v2", "claude", "pi"];
1097
+ var HARNESS_ENTRYPOINTS = {
1098
+ "opencode-v1": "bin/harness/opencode-1.x.js",
1099
+ "opencode-v2": "bin/harness/opencode-2.x.js",
1100
+ claude: "bin/harness/claude.js",
1101
+ pi: "bin/harness/pi.js"
1102
+ };
1103
+ function isRecord2(value) {
1104
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1105
+ }
1106
+ function parsePackageMetadata(value) {
1107
+ if (!isRecord2(value) || typeof value["version"] !== "string" || !value["version"].trim()) {
1108
+ throw new Error("package.json must contain a non-empty version");
1109
+ }
1110
+ return { version: value["version"] };
1111
+ }
1112
+ var metadata3 = parsePackageMetadata(JSON.parse(await readFile(new URL("../../package.json", import.meta.url), "utf8")));
1113
+ var PACKAGE_VERSION = metadata3.version;
1114
+ var RELEASE_BASE_URL = (process.env["ANYCODE_RELEASE_BASE_URL"] ?? "https://anycode.me").replace(/\/$/u, "");
1115
+ var homeDirectory = homedir();
1116
+ var INSTALL_ROOT = join4(process.env["ANYCODE_INSTALL_ROOT"] ?? join4(homeDirectory, ".local", "share", "anycode"));
1117
+ var BIN_DIR = process.env["ANYCODE_BIN_DIR"] ?? join4(homeDirectory, ".local", "bin");
1118
+ var NODE_MINIMUM_MAJOR = 20;
1119
+ var DOWNLOAD_TIMEOUT_MS = 60000;
1120
+ function usage() {
1121
+ console.log(`AnyCode ${PACKAGE_VERSION}
1122
+
1123
+ Usage:
1124
+ curl -fsSL https://anycode.me/install.sh | sh
1125
+ curl -fsSL https://anycode.me/install.sh | ANYCODE_VERSION=<version> sh
1126
+
1127
+ After installation:
1128
+ anycode doctor
1129
+ anycode help [topic] [--json]
1130
+ anycode <native-anycode-command> [...args]
1131
+
1132
+ Install downloads and verifies the immutable GitHub release. Other commands are
1133
+ forwarded to the activated native AnyCode runtime.
1134
+
1135
+ Node.js ${NODE_MINIMUM_MAJOR} or newer is required. Git and a Harness (OpenCode,
1136
+ Claude Code, or Pi) are separate optional integrations.
1137
+ Supported Harness adapters: opencode-v1, opencode-v2, claude, pi.`);
1138
+ }
1139
+ function normalizedVersion(value) {
1140
+ const version = value.startsWith("v") ? value.slice(1) : value;
1141
+ if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/.test(version)) {
1142
+ throw new Error(`invalid AnyCode version: ${value}`);
1143
+ }
1144
+ return version;
1145
+ }
1146
+ function option(args, name, fallback) {
1147
+ const index = args.indexOf(name);
1148
+ if (index < 0)
1149
+ return fallback;
1150
+ const value = args[index + 1];
1151
+ if (!value || value.startsWith("--"))
1152
+ throw new Error(`${name} requires a value`);
1153
+ return value;
1154
+ }
1155
+ function ensureNodeVersion() {
1156
+ const major = Number.parseInt(process.versions.node.split(".")[0] ?? "0", 10);
1157
+ if (!Number.isInteger(major) || major < NODE_MINIMUM_MAJOR) {
1158
+ throw new Error(`AnyCode requires Node.js >= ${NODE_MINIMUM_MAJOR}; detected ${process.versions.node}. Install or upgrade Node.js before continuing.`);
1159
+ }
1160
+ }
1161
+ async function verifyArtifact(artifact, checksumFile) {
1162
+ const expected = (await readFile(checksumFile, "utf8")).trim().split(/\s+/).at(-1);
1163
+ const actual = createHash5("sha256").update(await readFile(artifact)).digest("hex");
1164
+ const normalized = expected?.replace(/^sha256:/, "");
1165
+ if (!normalized || normalized !== actual) {
1166
+ throw new Error("release artifact sha256 does not match its checksum");
1167
+ }
1168
+ }
1169
+ async function verifySignedRelease(version, target, artifact, options = {}) {
1170
+ const root = `${(options.baseUrl ?? RELEASE_BASE_URL).replace(/\/$/u, "")}/releases/v${version}`;
1171
+ if (!root.startsWith("https://"))
1172
+ throw new Error("AnyCode release base URL must use HTTPS");
1173
+ const fetcher = options.fetcher ?? fetch;
1174
+ const [manifestResponse, sumsResponse, signatureResponse] = await Promise.all([
1175
+ fetcher(`${root}/latest.json`, { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS) }),
1176
+ fetcher(`${root}/SHA256SUMS`, { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS) }),
1177
+ fetcher(`${root}/SHA256SUMS.sig`, { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS) })
1178
+ ]);
1179
+ if (!manifestResponse.ok || !sumsResponse.ok || !signatureResponse.ok)
1180
+ throw new Error("AnyCode release trust metadata is unavailable");
1181
+ const manifest = await manifestResponse.json();
1182
+ if (manifest.version !== version)
1183
+ throw new Error("AnyCode release manifest version does not match the requested version");
1184
+ const platform = `${target.os}-${target.arch}`;
1185
+ const name = `anycode-${version}-${platform}.tar.gz`;
1186
+ const file = manifest.files?.find((candidate) => candidate.platform === platform && candidate.name === name);
1187
+ if (!file || typeof file.sha256 !== "string")
1188
+ throw new Error("AnyCode release manifest has no unique platform asset");
1189
+ const sums = await sumsResponse.text();
1190
+ const signedHash = verifyReleaseChecksums(Buffer.from(sums), await signatureResponse.text(), options.publicKeyPem ?? RELEASE_PUBLIC_KEY_PEM).get(name);
1191
+ if (signedHash !== file.sha256)
1192
+ throw new Error("AnyCode manifest does not match signed SHA256SUMS");
1193
+ const actual = createHash5("sha256").update(await readFile(artifact)).digest("hex");
1194
+ if (actual !== signedHash)
1195
+ throw new Error("AnyCode release artifact does not match signed SHA256SUMS");
1196
+ }
1197
+ var RELEASE_TARGETS = {
1198
+ "linux-x64": { os: "linux", arch: "x64", executable: "anycode" },
1199
+ "linux-arm64": { os: "linux", arch: "arm64", executable: "anycode" },
1200
+ "darwin-x64": { os: "darwin", arch: "x64", executable: "anycode" },
1201
+ "darwin-arm64": { os: "darwin", arch: "arm64", executable: "anycode" },
1202
+ "win32-x64": { os: "windows", arch: "x64", executable: "anycode.exe" }
1203
+ };
1204
+ function releaseTarget() {
1205
+ const target = RELEASE_TARGETS[`${process.platform}-${process.arch}`];
1206
+ if (target === undefined)
1207
+ throw new Error(`AnyCode has no native release for ${process.platform}-${process.arch}`);
1208
+ return target;
1209
+ }
1210
+ function harnessOption(args) {
1211
+ const value = option(args, "--harness", "");
1212
+ if (!value)
1213
+ return;
1214
+ if (!HARNESS_IDS.includes(value))
1215
+ throw new Error(`unsupported Harness: ${value}; choose ${HARNESS_IDS.join(", ")}`);
1216
+ return value;
1217
+ }
1218
+ async function install(version, harness, options = {}) {
1219
+ ensureNodeVersion();
1220
+ const target = options.target ?? releaseTarget();
1221
+ const installRoot = options.installRoot ?? INSTALL_ROOT;
1222
+ const binDirectory = options.binDirectory ?? BIN_DIR;
1223
+ const baseUrl = (options.baseUrl ?? RELEASE_BASE_URL).replace(/\/$/u, "");
1224
+ if (!baseUrl.startsWith("https://"))
1225
+ throw new Error("AnyCode release base URL must use HTTPS");
1226
+ const fetcher = options.fetcher ?? fetch;
1227
+ const requestOptions = { redirect: "follow", signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS) };
1228
+ await mkdir(dirname4(installRoot), { recursive: true });
1229
+ const temporary = await mkdtemp(join4(dirname4(installRoot), ".anycode-npm-"));
1230
+ const artifact = join4(temporary, `anycode-${version}-${target.os}-${target.arch}.tar.gz`);
1231
+ const checksum = `${artifact}.sha256`;
1232
+ const source = join4(temporary, "source");
1233
+ try {
1234
+ await downloadWith(fetcher, `${baseUrl}/releases/v${version}/anycode-${version}-${target.os}-${target.arch}.tar.gz`, artifact, requestOptions);
1235
+ await downloadWith(fetcher, `${baseUrl}/releases/v${version}/anycode-${version}-${target.os}-${target.arch}.tar.gz.sha256`, checksum, requestOptions);
1236
+ await verifyArtifact(artifact, checksum);
1237
+ await verifySignedRelease(version, target, artifact, options);
1238
+ await mkdir(source, { recursive: true });
1239
+ extractTarGzip(artifact, source);
1240
+ const manifest = verifyInstalledPackage(source);
1241
+ if (manifest.files[`bin/${target.executable}`] === undefined)
1242
+ throw new Error(`release package is missing native executable bin/${target.executable}`);
1243
+ if (harness !== undefined && manifest.files[HARNESS_ENTRYPOINTS[harness]] === undefined) {
1244
+ throw new Error(`release package does not contain the requested Harness adapter: ${harness}`);
1245
+ }
1246
+ activatePackage(source, installRoot, join4(binDirectory, target.executable), {
1247
+ executable: target.executable,
1248
+ ...options.platform === undefined ? {} : { platform: options.platform }
1249
+ });
1250
+ console.log(`AnyCode ${version} installed at ${installRoot}`);
1251
+ if (harness !== undefined)
1252
+ console.log(`Register only ${HARNESS_ENTRYPOINTS[harness]} in the native ${harness} configuration.`);
1253
+ if (!pathContains(binDirectory))
1254
+ console.log(`Add ${binDirectory} to PATH before using the anycode command in a new shell.`);
1255
+ } finally {
1256
+ await rm(temporary, { recursive: true, force: true });
1257
+ }
1258
+ }
1259
+ async function downloadWith(fetcher, url, destination, requestOptions) {
1260
+ const response = await fetcher(url, requestOptions);
1261
+ if (!response.ok)
1262
+ throw new Error(`download failed: ${response.status} ${response.statusText}`);
1263
+ await writeFile(destination, Buffer.from(await response.arrayBuffer()));
1264
+ }
1265
+ function pathContains(directory) {
1266
+ const separator = process.platform === "win32" ? ";" : ":";
1267
+ return (process.env["PATH"] ?? "").split(separator).includes(directory);
1268
+ }
1269
+ function compareVersions(left, right) {
1270
+ const parse = (value) => {
1271
+ const [base, suffix] = value.split("-", 2);
1272
+ return { core: base.split(".").map(Number), suffix: suffix?.split(".") };
1273
+ };
1274
+ const a = parse(left);
1275
+ const b = parse(right);
1276
+ for (let index = 0;index < 3; index += 1) {
1277
+ const difference = (a.core[index] ?? 0) - (b.core[index] ?? 0);
1278
+ if (difference)
1279
+ return Math.sign(difference);
1280
+ }
1281
+ if (!a.suffix && !b.suffix)
1282
+ return 0;
1283
+ if (!a.suffix)
1284
+ return 1;
1285
+ if (!b.suffix)
1286
+ return -1;
1287
+ for (let index = 0;index < Math.max(a.suffix.length, b.suffix.length); index += 1) {
1288
+ const x = a.suffix[index];
1289
+ const y = b.suffix[index];
1290
+ if (x === undefined)
1291
+ return -1;
1292
+ if (y === undefined)
1293
+ return 1;
1294
+ if (x === y)
1295
+ continue;
1296
+ const nx = /^\d+$/u.test(x);
1297
+ const ny = /^\d+$/u.test(y);
1298
+ if (nx && ny)
1299
+ return Number(x) < Number(y) ? -1 : 1;
1300
+ if (nx !== ny)
1301
+ return nx ? -1 : 1;
1302
+ return x.localeCompare(y);
1303
+ }
1304
+ return 0;
1305
+ }
1306
+ function newerNativeExecutable() {
1307
+ const path = join4(INSTALL_ROOT, "bin", releaseTarget().executable);
1308
+ const probe = spawnSync(path, ["version", "--json"], { encoding: "utf8", timeout: 5000 });
1309
+ if (probe.status !== 0)
1310
+ return;
1311
+ try {
1312
+ const value = JSON.parse(probe.stdout);
1313
+ if (!isRecord2(value) || typeof value["version"] !== "string" || compareVersions(value["version"], PACKAGE_VERSION) <= 0)
1314
+ return;
1315
+ return { path, version: value["version"] };
1316
+ } catch {
1317
+ return;
1318
+ }
1319
+ }
1320
+ async function main(args) {
1321
+ if (args.length === 0 || args[0] === "--help" || args[0] === "-h" || args[0] === "install" && (args.includes("--help") || args.includes("-h"))) {
1322
+ usage();
1323
+ return 0;
1324
+ }
1325
+ if (args.includes("--version") && args.length === 1) {
1326
+ const native = newerNativeExecutable();
1327
+ console.log(native ? `${native.version} (${native.path})` : `${PACKAGE_VERSION} (${fileURLToPath2(import.meta.url)})`);
1328
+ return 0;
1329
+ }
1330
+ if (args[0] === "install") {
1331
+ const version = normalizedVersion(option(args, "--version", PACKAGE_VERSION));
1332
+ await install(version, harnessOption(args));
1333
+ return 0;
1334
+ }
1335
+ const executable = newerNativeExecutable()?.path ?? join4(INSTALL_ROOT, "bin", releaseTarget().executable);
1336
+ const result = spawnSync(executable, args, { stdio: "inherit" });
1337
+ if (result.error) {
1338
+ throw new Error(`AnyCode is not installed at ${INSTALL_ROOT}; run: curl -fsSL https://anycode.me/install.sh | sh`);
1339
+ }
1340
+ return result.status ?? 1;
1341
+ }
1342
+ if (isEntryModule(import.meta.url, process.argv[1], process.versions["bun"] !== undefined && __require.main == __require.module === true)) {
1343
+ main(process.argv.slice(2)).then((code) => {
1344
+ process.exitCode = code;
1345
+ }).catch((error) => {
1346
+ const message = error instanceof Error ? error.message : String(error);
1347
+ console.error(`anycode: ${message}`);
1348
+ process.exitCode = 1;
1349
+ });
1350
+ }
1351
+ export {
1352
+ install
1353
+ };