@langgexyz/anycode 0.4.6 → 0.4.10

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/README.md CHANGED
@@ -75,7 +75,7 @@ anycode doctor
75
75
  `https://anycode.me/releases/latest.json`;不指定版本默认安装 stable。发布包支持 macOS 和 Linux 的 `arm64`、`x64` 以及 Windows `x64`;安装器支持
76
76
  macOS 和 Linux,Windows 用户从 `https://anycode.me/releases/v<版本>/` 手动下载。安装目录为
77
77
  `~/.local/share/anycode`,启动器为 `~/.local/bin/anycode`。本地工程操作不要求登录;需要访问
78
- AnyCode 账户的操作使用 `anycode login`,升级使用 `anycode update`;Windows 暂不支持自动更新,需手动下载指定版本。
78
+ AnyCode 账户的操作使用 `anycode login`。升级使用 `anycode update`(`anycode upgrade` 是同义别名);默认更新 stable,`--rc` 更新预览版。`anycode version` 和 `anycode --version` 显示当前版本号;Windows 暂不支持自动更新,需手动下载指定版本。
79
79
 
80
80
  仓库内没有 workflow 推送 tag;维护者从具备仓库写权限的 Git 环境推送 tag,测试机只用于构建与测试。
81
81
 
package/npm/README.md CHANGED
@@ -29,8 +29,14 @@ npx @langgexyz/anycode <command>
29
29
  curl -fsSL https://anycode.me/install.sh | sh
30
30
  curl -fsSL https://anycode.me/install.sh | ANYCODE_VERSION=<version> sh
31
31
  anycode update
32
+ anycode upgrade
33
+ anycode version
34
+ anycode --version
32
35
  ```
33
36
 
37
+ `upgrade` is an alias for `update`; plain version commands print the installed
38
+ version number.
39
+
34
40
  The release packages support macOS and Linux on `arm64` and `x64`, plus Windows
35
41
  `x64`. The installer supports macOS and Linux; Windows users can manually
36
42
  download the `windows-x64` package from
package/npm/dist/cli.mjs CHANGED
@@ -1,17 +1,36 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire } from "node:module";
3
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
2
4
 
3
- // npm/src/cli.ts
4
- import { createHash as createHash3 } from "node:crypto";
5
+ // src/cli.ts
6
+ import { createHash as createHash5 } from "node:crypto";
5
7
  import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
6
8
  import { homedir } from "node:os";
7
- import { dirname as dirname3, join as join4 } from "node:path";
8
- import { fileURLToPath } from "node:url";
9
+ import { dirname as dirname4, join as join4 } from "node:path";
9
10
  import { spawnSync } from "node:child_process";
10
11
 
11
- // runtime/archive/src/index.ts
12
+ // ../runtime/harness-context/src/entry-module.ts
13
+ import { realpathSync } from "node:fs";
14
+ import { resolve } from "node:path";
15
+ import { fileURLToPath } from "node:url";
16
+ function isEntryModule(moduleUrl, invokedFile, isRuntimeMain = false, runtimeExecutable) {
17
+ if (isRuntimeMain)
18
+ return true;
19
+ if (invokedFile === undefined)
20
+ return false;
21
+ if (runtimeExecutable !== undefined && resolve(invokedFile) === resolve(runtimeExecutable))
22
+ return true;
23
+ try {
24
+ return realpathSync(resolve(invokedFile)) === realpathSync(resolve(fileURLToPath(moduleUrl)));
25
+ } catch {
26
+ return false;
27
+ }
28
+ }
29
+
30
+ // ../runtime/archive/src/index.ts
12
31
  import { gunzipSync, gzipSync } from "node:zlib";
13
32
  import { chmodSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
14
- import { dirname, join, posix, relative, resolve } from "node:path";
33
+ import { dirname, join, posix, relative, resolve as resolve2 } from "node:path";
15
34
  function readTarGzip(archive) {
16
35
  const bytes = gunzipSync(readFileSync(archive));
17
36
  const entries = [];
@@ -92,8 +111,8 @@ function parsePax(body) {
92
111
  }
93
112
  function safeArchivePath(root, value) {
94
113
  const normalized = normalizeArchivePath(value);
95
- const path = resolve(root, normalized);
96
- const relativePath = relative(resolve(root), path);
114
+ const path = resolve2(root, normalized);
115
+ const relativePath = relative(resolve2(root), path);
97
116
  if (!relativePath || relativePath === ".." || relativePath.startsWith(`..${"/"}`) || relativePath.startsWith("/"))
98
117
  throw new Error(`package contains unsafe path: ${value}`);
99
118
  return path;
@@ -126,7 +145,7 @@ function pendingNumber(buffer, offset, length, field) {
126
145
  return value;
127
146
  }
128
147
 
129
- // runtime/core/src/connector.ts
148
+ // ../runtime/core/src/connector.ts
130
149
  class ConnectorRegistry {
131
150
  connectors = new Map;
132
151
  capabilityOwners = new Map;
@@ -270,10 +289,10 @@ function failed(request, reason, errorCode) {
270
289
  }
271
290
  };
272
291
  }
273
- // runtime/core/src/protection.ts
292
+ // ../runtime/core/src/protection.ts
274
293
  var LOCAL_CAPABILITY_DOMAINS = new Set(["change", "project", "verification", "git"]);
275
294
  var TARGETS = new Set(["workstation", "test", "beta", "prod", "external"]);
276
- // runtime/core/src/index.ts
295
+ // ../runtime/core/src/index.ts
277
296
  class CapabilityRegistry {
278
297
  specs = new Map;
279
298
  constructor(specs = []) {
@@ -318,7 +337,7 @@ function validateCapabilityRequest(request) {
318
337
  }
319
338
  }
320
339
 
321
- // runtime/providers/src/installation/package-build.ts
340
+ // ../runtime/providers/src/installation/package-build.ts
322
341
  var LAUNCHER = `#!/bin/sh
323
342
  ` + `script="$0"
324
343
  ` + `while [ -L "$script" ]; do
@@ -342,7 +361,7 @@ var WINDOWS_LAUNCHER = `@echo off\r
342
361
  ` + `)\r
343
362
  ` + `"%ANYCODE_NODE%" "%root%\\runtime\\providers\\dist\\cli.mjs" %*\r
344
363
  `;
345
- // runtime/providers/src/installation/package-installed.ts
364
+ // ../runtime/providers/src/installation/package-installed.ts
346
365
  import { createHash } from "node:crypto";
347
366
  import { existsSync as existsSync2, lstatSync as lstatSync2, readFileSync as readFileSync2, readdirSync as readdirSync2, readlinkSync } from "node:fs";
348
367
  import { join as join2, posix as posix2, relative as relative2, sep } from "node:path";
@@ -370,7 +389,7 @@ function validateExistingInstall(root) {
370
389
  try {
371
390
  JSON.parse(readFileSync2(manifestPath, "utf8"));
372
391
  } catch {
373
- throw new Error(`旧版扁平安装清单解析失败:${manifestPath}`);
392
+ throw new Error(`\u65e7\u7248\u6241\u5e73\u5b89\u88c5\u6e05\u5355\u89e3\u6790\u5931\u8d25\uff1a${manifestPath}`);
374
393
  }
375
394
  verifyInstalledPackage(root);
376
395
  }
@@ -476,66 +495,459 @@ function isRecord(value) {
476
495
  return typeof value === "object" && value !== null && !Array.isArray(value);
477
496
  }
478
497
 
479
- // runtime/providers/src/installation/activation.ts
480
- import { copyFileSync, existsSync as existsSync3, lstatSync as lstatSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, readlinkSync as readlinkSync2, realpathSync, renameSync, rmSync, statSync as statSync2, symlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
481
- import { dirname as dirname2, join as join3, relative as relative3, resolve as resolve2 } from "node:path";
498
+ // ../runtime/providers/src/installation/activation.ts
499
+ 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";
500
+ import { dirname as dirname3, join as join3, relative as relative3, resolve as resolve3 } from "node:path";
501
+ // ../runtime/providers/src/infrastructure/command-runner.ts
502
+ var SAFE_ENVIRONMENT_KEYS = new Set([
503
+ "PATH",
504
+ "HOME",
505
+ "LANG",
506
+ "LC_ALL",
507
+ "LC_CTYPE",
508
+ "TZ",
509
+ "TMPDIR",
510
+ "HTTP_PROXY",
511
+ "HTTPS_PROXY",
512
+ "ALL_PROXY",
513
+ "NO_PROXY",
514
+ "http_proxy",
515
+ "https_proxy",
516
+ "all_proxy",
517
+ "no_proxy"
518
+ ]);
519
+ var PROXY_KEYS = new Set(["HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY", "http_proxy", "https_proxy", "all_proxy"]);
520
+ // ../runtime/credentials/src/memory.ts
521
+ import { createHash as createHash2 } from "node:crypto";
522
+
523
+ // ../runtime/credentials/src/validation.ts
524
+ function validateCredentialRef(ref) {
525
+ for (const [name, value] of Object.entries(ref)) {
526
+ if (!value.trim())
527
+ throw new Error(`credential ${name} must not be empty`);
528
+ if (!/^[A-Za-z0-9._:/-]+$/u.test(value))
529
+ throw new Error(`credential ${name} contains unsupported characters`);
530
+ }
531
+ }
532
+ function credentialKey(ref) {
533
+ validateCredentialRef(ref);
534
+ return JSON.stringify([ref.scope, ref.field]);
535
+ }
536
+
537
+ // ../runtime/credentials/src/secret-lease.ts
538
+ var leaseStates = new WeakMap;
539
+ function createSecretLease(ref, secret) {
540
+ const secretForms = [
541
+ secret,
542
+ encodeURIComponent(secret),
543
+ Buffer.from(secret, "utf8").toString("base64"),
544
+ Buffer.from(secret, "utf8").toString("base64url"),
545
+ Buffer.from(secret, "utf8").toString("hex")
546
+ ].filter((form) => form.length > 0);
547
+ const state = { active: true, secret };
548
+ const lease = Object.freeze({
549
+ ref: Object.freeze({ ...ref }),
550
+ use(consumer) {
551
+ if (!state.active)
552
+ throw new Error("credential lease is no longer active");
553
+ let result;
554
+ try {
555
+ result = consumer(state.secret);
556
+ } catch (error) {
557
+ throw sanitizedError(error, secretForms);
558
+ }
559
+ return guardResult(result, secretForms);
560
+ }
561
+ });
562
+ leaseStates.set(lease, state);
563
+ return lease;
564
+ }
565
+ function guardResult(result, secretForms) {
566
+ let promiseLike;
567
+ try {
568
+ promiseLike = isPromiseLike(result);
569
+ } catch (error) {
570
+ throw sanitizedError(error, secretForms);
571
+ }
572
+ if (promiseLike) {
573
+ return Promise.resolve(result).then((value) => guardValue(value, secretForms), (error) => {
574
+ throw sanitizedError(error, secretForms);
575
+ });
576
+ }
577
+ return guardValue(result, secretForms);
578
+ }
579
+ function guardValue(value, secretForms) {
580
+ if (containsSecret(value, secretForms, new WeakSet)) {
581
+ throw new Error("Connector result must not contain a credential value");
582
+ }
583
+ return value;
584
+ }
585
+ function containsSecret(value, secretForms, visited) {
586
+ if (typeof value === "string")
587
+ return secretForms.some((form) => value.includes(form));
588
+ if (typeof value === "function")
589
+ return true;
590
+ if (value === null || typeof value !== "object")
591
+ return false;
592
+ if (visited.has(value))
593
+ return false;
594
+ visited.add(value);
595
+ if (value instanceof Uint8Array)
596
+ return secretForms.some((form) => includesBytes(value, new TextEncoder().encode(form)));
597
+ if (value instanceof Map)
598
+ return [...value].some(([key, entry]) => containsSecret(key, secretForms, visited) || containsSecret(entry, secretForms, visited));
599
+ if (value instanceof Set)
600
+ return [...value].some((entry) => containsSecret(entry, secretForms, visited));
601
+ try {
602
+ const prototype = Object.getPrototypeOf(value);
603
+ if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null)
604
+ return true;
605
+ if (Reflect.ownKeys(value).some((key) => typeof key === "string" ? secretForms.some((form) => key.includes(form)) : secretForms.some((form) => String(key).includes(form))))
606
+ return true;
607
+ for (const descriptor of Object.values(Object.getOwnPropertyDescriptors(value))) {
608
+ if (!("value" in descriptor))
609
+ return true;
610
+ if (containsSecret(descriptor.value, secretForms, visited))
611
+ return true;
612
+ }
613
+ } catch {
614
+ return true;
615
+ }
616
+ return false;
617
+ }
618
+ function includesBytes(bytes, needle) {
619
+ if (needle.length === 0)
620
+ return false;
621
+ outer:
622
+ for (let start = 0;start <= bytes.length - needle.length; start += 1) {
623
+ for (let offset = 0;offset < needle.length; offset += 1) {
624
+ if (bytes[start + offset] !== needle[offset])
625
+ continue outer;
626
+ }
627
+ return true;
628
+ }
629
+ return false;
630
+ }
631
+ function sanitizedError(error, secretForms) {
632
+ let message;
633
+ try {
634
+ message = error instanceof Error ? error.message : String(error);
635
+ } catch {
636
+ message = "Connector operation failed";
637
+ }
638
+ const sanitized = secretForms.some((form) => message.includes(form)) ? "Connector operation failed; error details contained a credential value" : message;
639
+ const result = new Error(sanitized);
640
+ if (error instanceof Error)
641
+ result.name = error.name;
642
+ return result;
643
+ }
644
+ function isPromiseLike(value) {
645
+ return (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
646
+ }
647
+
648
+ // ../runtime/credentials/src/memory.ts
649
+ class MemoryCredentialStorage {
650
+ id = "memory";
651
+ strategyId = this.id;
652
+ entries = new Map;
653
+ inspect(ref) {
654
+ validateCredentialRef(ref);
655
+ const entry = this.entries.get(credentialKey(ref));
656
+ return entry ? metadata(entry) : { ref, present: false };
657
+ }
658
+ list() {
659
+ return [...this.entries.values()].map(metadata);
660
+ }
661
+ write(ref, input) {
662
+ validateCredentialRef(ref);
663
+ if (!input.value)
664
+ throw new Error("credential value must not be empty");
665
+ const entry = { ref, value: input.value, updatedAt: new Date().toISOString() };
666
+ this.entries.set(credentialKey(ref), entry);
667
+ return metadata(entry);
668
+ }
669
+ fingerprint(ref) {
670
+ const entry = this.require(ref);
671
+ return { ...metadata(entry), fingerprint: fingerprint(entry.value) };
672
+ }
673
+ remove(ref) {
674
+ validateCredentialRef(ref);
675
+ return this.entries.delete(credentialKey(ref));
676
+ }
677
+ useSecret(ref, consumer) {
678
+ const entry = this.require(ref);
679
+ return createSecretLease(entry.ref, entry.value).use(consumer);
680
+ }
681
+ require(ref) {
682
+ validateCredentialRef(ref);
683
+ const entry = this.entries.get(credentialKey(ref));
684
+ if (!entry)
685
+ throw new Error(`credential is unavailable: ${credentialKey(ref)}`);
686
+ return entry;
687
+ }
688
+ }
689
+ function metadata(entry) {
690
+ return { ref: entry.ref, present: true, updatedAt: entry.updatedAt };
691
+ }
692
+ function fingerprint(value) {
693
+ return `sha256:${createHash2("sha256").update(value).digest("hex")}`;
694
+ }
695
+ // ../runtime/credentials/src/encrypted-file.ts
696
+ import { createCipheriv, createDecipheriv, createHash as createHash3, randomBytes } from "node:crypto";
697
+ import { chmodSync as chmodSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, renameSync, writeFileSync as writeFileSync2 } from "node:fs";
698
+ import { dirname as dirname2 } from "node:path";
699
+ class EncryptedFileCredentialStorage {
700
+ filePath;
701
+ keyProvider;
702
+ id = "encrypted-file";
703
+ strategyId = this.id;
704
+ constructor(filePath, keyProvider) {
705
+ this.filePath = filePath;
706
+ this.keyProvider = keyProvider;
707
+ }
708
+ inspect(ref) {
709
+ const entry = this.entries().get(credentialKey(ref));
710
+ return entry ? metadata2(entry) : { ref, present: false };
711
+ }
712
+ list() {
713
+ return [...this.entries().values()].map(metadata2);
714
+ }
715
+ write(ref, input) {
716
+ validateCredentialRef(ref);
717
+ if (!input.value)
718
+ throw new Error("credential value must not be empty");
719
+ const entries = this.entries();
720
+ const entry = { ref, value: input.value, updatedAt: new Date().toISOString() };
721
+ entries.set(credentialKey(ref), entry);
722
+ this.save(entries);
723
+ return metadata2(entry);
724
+ }
725
+ fingerprint(ref) {
726
+ const entry = this.require(ref);
727
+ return { ...metadata2(entry), fingerprint: fingerprint2(entry.value) };
728
+ }
729
+ remove(ref) {
730
+ const entries = this.entries();
731
+ const removed = entries.delete(credentialKey(ref));
732
+ if (removed)
733
+ this.save(entries);
734
+ return removed;
735
+ }
736
+ useSecret(ref, consumer) {
737
+ const entry = this.require(ref);
738
+ return createSecretLease(entry.ref, entry.value).use(consumer);
739
+ }
740
+ require(ref) {
741
+ const entry = this.entries().get(credentialKey(ref));
742
+ if (!entry)
743
+ throw new Error(`credential is unavailable: ${credentialKey(ref)}`);
744
+ return entry;
745
+ }
746
+ entries() {
747
+ try {
748
+ const envelope = JSON.parse(readFileSync3(this.filePath, "utf8"));
749
+ return decode(envelope, this.keyProvider.key());
750
+ } catch (error) {
751
+ if (isMissingFile(error))
752
+ return new Map;
753
+ throw new Error(`credential store cannot be opened: ${error instanceof Error ? error.message : String(error)}`);
754
+ }
755
+ }
756
+ save(entries) {
757
+ const directory = dirname2(this.filePath);
758
+ mkdirSync2(directory, { recursive: true, mode: 448 });
759
+ const temporary = `${this.filePath}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`;
760
+ writeFileSync2(temporary, JSON.stringify(encode(entries, this.keyProvider.key())) + `
761
+ `, { mode: 384 });
762
+ chmodSync2(temporary, 384);
763
+ renameSync(temporary, this.filePath);
764
+ chmodSync2(this.filePath, 384);
765
+ }
766
+ }
767
+ function encode(entries, key) {
768
+ const iv = randomBytes(12);
769
+ const cipher = createCipheriv("aes-256-gcm", key, iv);
770
+ const plaintext = JSON.stringify([...entries.values()]);
771
+ const ciphertext = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
772
+ return { version: 1, iv: iv.toString("base64url"), tag: cipher.getAuthTag().toString("base64url"), ciphertext: ciphertext.toString("base64url") };
773
+ }
774
+ function decode(envelope, key) {
775
+ if (envelope.version !== 1)
776
+ throw new Error("unsupported credential store version");
777
+ const decipher = createDecipheriv("aes-256-gcm", key, Buffer.from(envelope.iv, "base64url"));
778
+ decipher.setAuthTag(Buffer.from(envelope.tag, "base64url"));
779
+ const plaintext = Buffer.concat([decipher.update(Buffer.from(envelope.ciphertext, "base64url")), decipher.final()]).toString("utf8");
780
+ const values = JSON.parse(plaintext);
781
+ const entries = new Map;
782
+ for (const entry of values) {
783
+ validateCredentialRef(entry.ref);
784
+ entries.set(credentialKey(entry.ref), entry);
785
+ }
786
+ return entries;
787
+ }
788
+ function metadata2(entry) {
789
+ return { ref: entry.ref, present: true, updatedAt: entry.updatedAt };
790
+ }
791
+ function fingerprint2(value) {
792
+ return `sha256:${createHash3("sha256").update(value).digest("hex")}`;
793
+ }
794
+ function isMissingFile(error) {
795
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
796
+ }
797
+ // ../runtime/credentials/src/registry.ts
798
+ class CredentialStorageRegistry {
799
+ strategies = new Map;
800
+ constructor(strategies = []) {
801
+ for (const strategy of strategies)
802
+ this.register(strategy);
803
+ }
804
+ register(strategy) {
805
+ if (this.strategies.has(strategy.id))
806
+ throw new Error(`duplicate credential storage strategy: ${strategy.id}`);
807
+ this.strategies.set(strategy.id, strategy);
808
+ }
809
+ resolve(policy) {
810
+ const id = policy.kind === "external" ? policy.provider : policy.kind;
811
+ if (!id)
812
+ throw new Error("external credential storage requires a provider");
813
+ const strategy = this.strategies.get(id);
814
+ if (!strategy)
815
+ throw new Error(`credential storage strategy is unavailable: ${id}`);
816
+ return strategy;
817
+ }
818
+ }
819
+ // ../runtime/providers/src/infrastructure/authenticated-transport.ts
820
+ var MAX_REQUEST_BYTES = 1024 * 1024;
821
+ var MAX_RESPONSE_BYTES = 4 * 1024 * 1024;
822
+ var REQUEST_HEADERS = new Set(["accept", "content-type", "user-agent"]);
823
+ // ../runtime/providers/src/infrastructure/sensitive-key.ts
824
+ var SECRET_NOUNS = ["authorization", "credentials", "credential", "password", "passwd", "secret", "token"];
825
+ var KEY_QUALIFIERS = ["access", "api", "private", "secret"];
826
+ var nounPattern = SECRET_NOUNS.join("|");
827
+ var qualifierPattern = `(?:${KEY_QUALIFIERS.join("|")})[_-]?key`;
828
+ var SENSITIVE_KEY_PATTERN = `[\\p{L}\\p{N}_-]*(?:${nounPattern}|${qualifierPattern})(?![\\p{L}\\p{N}_])`;
829
+
830
+ // ../runtime/providers/src/infrastructure/redaction-rules.ts
831
+ var REDACTION_RULES = [
832
+ {
833
+ id: "private-key",
834
+ pattern: /-----BEGIN [^-]*PRIVATE KEY-----[\s\S]*?-----END [^-]*PRIVATE KEY-----/gu,
835
+ replacement: "[REDACTED:private-key]"
836
+ },
837
+ {
838
+ id: "bearer",
839
+ pattern: /\bBearer\s+(?!\[REDACTED:)[^\s,;}\]]+/giu,
840
+ replacement: "Bearer [REDACTED:bearer]"
841
+ },
842
+ {
843
+ id: "authorization",
844
+ pattern: /(?<authorizationQuote>["']?)(?<authorizationKey>authorization)\k<authorizationQuote>(?<authorizationSeparator>\s*[:=]\s*)(?!\s*\[REDACTED:)(?:(?<authorizationValueQuote>["'])(?:[\s\S]*?)\k<authorizationValueQuote>|[^\r\n"']+)/giu,
845
+ replacement: "$<authorizationQuote>$<authorizationKey>$<authorizationQuote>$<authorizationSeparator>$<authorizationValueQuote>[REDACTED:authorization]$<authorizationValueQuote>"
846
+ },
847
+ {
848
+ id: "assignment",
849
+ pattern: new RegExp(`(?<assignmentQuote>["']?)(?<assignmentKey>${SENSITIVE_KEY_PATTERN})\\k<assignmentQuote>(?<assignmentSeparator>\\s*[:=]\\s*)(?!\\s*\\[REDACTED:)(?:(?<assignmentValueQuote>["'])(?:[\\s\\S]*?)\\k<assignmentValueQuote>|[^\\s,;}\\]"']+)`, "giu"),
850
+ replacement: "$<assignmentQuote>$<assignmentKey>$<assignmentQuote>$<assignmentSeparator>$<assignmentValueQuote>[REDACTED:assignment]$<assignmentValueQuote>"
851
+ },
852
+ {
853
+ id: "url-userinfo",
854
+ pattern: /(?<urlScheme>\b[a-z][a-z0-9+.-]*:\/\/[^\s:@\/?#]*:)(?!\[REDACTED:)[^\s@\/?#]+(?=@)/giu,
855
+ replacement: "$<urlScheme>[REDACTED:url-password]"
856
+ }
857
+ ];
858
+
859
+ // ../runtime/providers/src/infrastructure/redaction.ts
860
+ var COMBINED_RULES = new RegExp(REDACTION_RULES.map((rule, index) => `(?<r${index}>${rule.pattern.source})`).join("|"), "giu");
861
+ // ../runtime/providers/src/infrastructure/transaction.ts
862
+ function rethrowAfterUndo(original, steps) {
863
+ const failures = [];
864
+ for (const undo of steps)
865
+ try {
866
+ undo();
867
+ } catch (error) {
868
+ failures.push(error);
869
+ }
870
+ if (failures.length === 0)
871
+ throw original;
872
+ throw new AggregateError([original, ...failures], `${original instanceof Error ? original.message : String(original)}; rollback had ${failures.length} failure(s)`, { cause: original });
873
+ }
874
+ // ../runtime/providers/src/installation/activation.ts
482
875
  function activatePackage(stagedPackage, installRoot, launcherPath, options = {}) {
483
876
  const platform = options.platform ?? process.platform;
484
877
  const executable = options.executable ?? (platform === "win32" ? "anycode.exe" : "anycode");
485
- mkdirSync2(dirname2(installRoot), { recursive: true });
486
- const releaseLock = acquireActivationLock(installRoot);
878
+ mkdirSync3(dirname3(installRoot), { recursive: true });
879
+ const releaseLock = acquireActivationLock(installRoot, platform);
487
880
  const previous = `${installRoot}.previous`;
488
881
  let movedCurrent = false;
489
882
  let installedNew = false;
490
883
  try {
491
- recoverInterruptedActivation(installRoot, previous);
884
+ reconcileActivation(installRoot, previous, launcherPath, executable, platform);
492
885
  const manifest = verifyInstalledPackage(stagedPackage);
493
886
  validateExistingInstall(installRoot);
494
887
  validateLauncherOwnership(launcherPath, installRoot, stagedPackage, executable, platform);
495
888
  if (existsSync3(installRoot)) {
496
889
  rmSync(previous, { recursive: true, force: true });
497
- renameSync(installRoot, previous);
890
+ renameSync2(installRoot, previous);
498
891
  movedCurrent = true;
499
892
  }
500
- renameSync(stagedPackage, installRoot);
893
+ renameSync2(stagedPackage, installRoot);
501
894
  installedNew = true;
502
895
  const installed = verifyInstalledPackage(installRoot);
503
896
  if (installed.version !== manifest.version || installed.payload_digest !== manifest.payload_digest)
504
- throw new Error("安装后的 AnyCode 包校验失败");
897
+ throw new Error("\u5b89\u88c5\u540e\u7684 AnyCode \u5305\u6821\u9a8c\u5931\u8d25");
505
898
  linkLauncher(join3(installRoot, "bin", executable), launcherPath, platform);
899
+ try {
900
+ removeActivationPath(previous);
901
+ } catch {}
506
902
  return installRoot;
507
903
  } catch (error) {
508
- if (installedNew && existsSync3(installRoot)) {
509
- rmSync(installRoot, { recursive: true, force: true });
510
- }
511
- if (movedCurrent && existsSync3(previous) && !existsSync3(installRoot))
512
- renameSync(previous, installRoot);
513
- throw error;
904
+ rethrowAfterUndo(error, [
905
+ () => {
906
+ if (installedNew && existsSync3(installRoot))
907
+ rmSync(installRoot, { recursive: true, force: true });
908
+ },
909
+ () => {
910
+ if (movedCurrent && existsSync3(previous) && !existsSync3(installRoot))
911
+ renameSync2(previous, installRoot);
912
+ }
913
+ ]);
514
914
  } finally {
515
915
  releaseLock();
516
916
  }
517
917
  }
518
- function acquireActivationLock(installRoot) {
918
+ function acquireActivationLock(installRoot, platform) {
519
919
  const lock = `${installRoot}.activation-lock`;
520
920
  const deadline = Date.now() + 30000;
521
921
  const token = `${process.pid}:${Date.now()}:${Math.random().toString(16).slice(2)}`;
522
922
  while (true) {
523
923
  try {
524
- mkdirSync2(lock);
525
- writeFileSync2(join3(lock, "owner"), token, { flag: "wx", mode: 384 });
526
- return () => {
924
+ if (platform === "win32") {
925
+ mkdirSync3(lock);
527
926
  try {
528
- if (readFileSync3(join3(lock, "owner"), "utf8") === token)
529
- rmSync(lock, { recursive: true, force: true });
530
- } catch {}
927
+ writeFileSync3(join3(lock, "owner"), token, { flag: "wx", mode: 384 });
928
+ } catch (error) {
929
+ rethrowAfterUndo(error, [() => rmSync(lock, { recursive: true, force: true })]);
930
+ }
931
+ } else {
932
+ symlinkSync(token, lock);
933
+ }
934
+ return () => {
935
+ for (let attempt = 0;attempt < 2; attempt += 1) {
936
+ try {
937
+ const owner = platform === "win32" ? readFileSync4(join3(lock, "owner"), "utf8") : readlinkSync2(lock);
938
+ if (owner === token)
939
+ rmSync(lock, { recursive: true, force: true });
940
+ return;
941
+ } catch {}
942
+ }
531
943
  };
532
944
  } catch (error) {
533
945
  if (error.code !== "EEXIST")
534
946
  throw error;
535
- const ownerPath = join3(lock, "owner");
536
947
  let stale = false;
537
948
  try {
538
- const owner = readFileSync3(ownerPath, "utf8");
949
+ const metadata3 = lstatSync3(lock);
950
+ const owner = metadata3.isSymbolicLink() ? readlinkSync2(lock) : readFileSync4(join3(lock, "owner"), "utf8");
539
951
  const pid = Number(owner.split(":", 1)[0]);
540
952
  if (Number.isSafeInteger(pid) && pid > 0) {
541
953
  try {
@@ -561,13 +973,37 @@ function acquireActivationLock(installRoot) {
561
973
  }
562
974
  }
563
975
  }
564
- function recoverInterruptedActivation(installRoot, previous) {
565
- if (existsSync3(installRoot))
976
+ function removeActivationPath(path) {
977
+ try {
978
+ rmSync(path, { recursive: true, force: true });
979
+ } catch (first) {
980
+ try {
981
+ rmSync(path, { recursive: true, force: true });
982
+ } catch (second) {
983
+ throw new AggregateError([first, second], `could not remove activation recovery path: ${path}`, { cause: first });
984
+ }
985
+ }
986
+ }
987
+ function reconcileActivation(installRoot, previous, launcherPath, executable, platform) {
988
+ if (!existsSync3(installRoot)) {
989
+ if (!existsSync3(previous))
990
+ return;
991
+ validateExistingInstall(previous);
992
+ renameSync2(previous, installRoot);
566
993
  return;
994
+ }
567
995
  if (!existsSync3(previous))
568
996
  return;
569
- validateExistingInstall(previous);
570
- renameSync(previous, installRoot);
997
+ try {
998
+ verifyInstalledPackage(installRoot);
999
+ } catch {
1000
+ return;
1001
+ }
1002
+ validateLauncherOwnership(launcherPath, installRoot, installRoot, executable, platform);
1003
+ linkLauncher(join3(installRoot, "bin", executable), launcherPath, platform);
1004
+ try {
1005
+ rmSync(previous, { recursive: true, force: true });
1006
+ } catch {}
571
1007
  }
572
1008
  function validateLauncherOwnership(launcher, root, staged, executable, platform) {
573
1009
  let existing;
@@ -579,52 +1015,54 @@ function validateLauncherOwnership(launcher, root, staged, executable, platform)
579
1015
  throw error;
580
1016
  }
581
1017
  if (existing.isSymbolicLink()) {
582
- const target = resolve2(dirname2(launcher), readlinkSync2(launcher));
583
- const path = relative3(resolve2(root), target).replaceAll("\\", "/");
584
- if (path === `bin/${executable}`)
1018
+ const target = resolve3(dirname3(launcher), readlinkSync2(launcher));
1019
+ const path = relative3(resolve3(root), target).replaceAll("\\", "/");
1020
+ if (path === `bin/${executable}` || !path.startsWith("../") && path !== ".." && path.endsWith(`/bin/${executable}`))
585
1021
  return;
586
- try {
587
- validateExistingInstall(root);
588
- if (path === `current/bin/${executable}` && realpathSync(target) === realpathSync(join3(root, "current", "bin", executable)))
589
- return;
590
- } catch {}
591
1022
  } else if (platform === "win32" && existing.isFile()) {
592
- const bytes = readFileSync3(launcher);
1023
+ const bytes = readFileSync4(launcher);
593
1024
  for (const candidate of [join3(staged, "bin", executable), join3(root, "bin", executable)]) {
594
- if (existsSync3(candidate) && bytes.equals(readFileSync3(candidate)))
1025
+ if (existsSync3(candidate) && bytes.equals(readFileSync4(candidate)))
595
1026
  return;
596
1027
  }
597
1028
  }
598
1029
  throw new Error(`refusing to replace an unmanaged anycode launcher: ${launcher}`);
599
1030
  }
600
1031
  function linkLauncher(source, launcherPath, platform) {
601
- mkdirSync2(dirname2(launcherPath), { recursive: true });
602
- const next = `${launcherPath}.${process.pid}.next`;
1032
+ mkdirSync3(dirname3(launcherPath), { recursive: true });
1033
+ const next = `${launcherPath}.next`;
603
1034
  rmSync(next, { force: true });
604
1035
  if (platform === "win32")
605
1036
  copyFileSync(source, next);
606
1037
  else
607
1038
  symlinkSync(source, next);
608
- renameSync(next, launcherPath);
1039
+ try {
1040
+ renameSync2(next, launcherPath);
1041
+ } catch (error) {
1042
+ try {
1043
+ rmSync(next, { force: true });
1044
+ } catch {}
1045
+ throw error;
1046
+ }
609
1047
  }
610
- // runtime/providers/src/installation/release-trust.ts
1048
+ // ../runtime/providers/src/installation/release-trust.ts
611
1049
  import { verify } from "node:crypto";
612
1050
  import { basename } from "node:path";
613
1051
 
614
- // runtime/providers/src/installation/release-key.generated.ts
1052
+ // ../runtime/providers/src/installation/release-key.generated.ts
615
1053
  var RELEASE_PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
616
1054
  MCowBQYDK2VwAyEA/hfqP5bUwAMqzY3QS+j9GIGjbYpyrtcheixQGJt93zo=
617
1055
  -----END PUBLIC KEY-----
618
1056
  `;
619
1057
 
620
- // runtime/providers/src/installation/release-trust.ts
1058
+ // ../runtime/providers/src/installation/release-trust.ts
621
1059
  function verifyReleaseChecksums(sums, encodedSignature, publicKey = RELEASE_PUBLIC_KEY_PEM) {
622
1060
  const encoded = encodedSignature.trim();
623
1061
  const signature = Buffer.from(encoded, "base64");
624
1062
  if (signature.toString("base64") !== encoded || signature.byteLength !== 64)
625
- throw new Error("AnyCode SHA256SUMS 签名格式无效");
1063
+ throw new Error("AnyCode SHA256SUMS \u7b7e\u540d\u683c\u5f0f\u65e0\u6548");
626
1064
  if (!verify(null, sums, publicKey, signature))
627
- throw new Error("AnyCode SHA256SUMS Ed25519 签名验证失败");
1065
+ throw new Error("AnyCode SHA256SUMS Ed25519 \u7b7e\u540d\u9a8c\u8bc1\u5931\u8d25");
628
1066
  return parseReleaseChecksums(Buffer.from(sums).toString("utf8"));
629
1067
  }
630
1068
  function parseReleaseChecksums(value) {
@@ -634,16 +1072,16 @@ function parseReleaseChecksums(value) {
634
1072
  continue;
635
1073
  const match = /^([a-f0-9]{64})\s+[* ]?([^\s]+)$/u.exec(line.trim());
636
1074
  if (!match || basename(match[2]) !== match[2] || result.has(match[2]))
637
- throw new Error("已签名 SHA256SUMS 格式无效");
1075
+ throw new Error("\u5df2\u7b7e\u540d SHA256SUMS \u683c\u5f0f\u65e0\u6548");
638
1076
  result.set(match[2], match[1]);
639
1077
  }
640
1078
  if (!result.size)
641
- throw new Error("已签名 SHA256SUMS 不能为空");
1079
+ throw new Error("\u5df2\u7b7e\u540d SHA256SUMS \u4e0d\u80fd\u4e3a\u7a7a");
642
1080
  return result;
643
1081
  }
644
1082
 
645
- // runtime/providers/src/installation/update.ts
646
- import { createHash as createHash2, createPublicKey } from "node:crypto";
1083
+ // ../runtime/providers/src/installation/update.ts
1084
+ import { createHash as createHash4, createPublicKey } from "node:crypto";
647
1085
  var PLATFORM = new Map([
648
1086
  ["darwin-arm64", "darwin-arm64"],
649
1087
  ["darwin-x64", "darwin-x64"],
@@ -652,8 +1090,8 @@ var PLATFORM = new Map([
652
1090
  ["win32-arm64", "windows-arm64"],
653
1091
  ["win32-x64", "windows-x64"]
654
1092
  ]);
655
- var RELEASE_PUBLIC_KEY_DER_SHA256 = createHash2("sha256").update(createPublicKey(RELEASE_PUBLIC_KEY_PEM).export({ type: "spki", format: "der" })).digest("hex");
656
- // npm/src/cli.ts
1093
+ var RELEASE_PUBLIC_KEY_DER_SHA256 = createHash4("sha256").update(createPublicKey(RELEASE_PUBLIC_KEY_PEM).export({ type: "spki", format: "der" })).digest("hex");
1094
+ // src/cli.ts
657
1095
  var HARNESS_IDS = ["opencode-v1", "opencode-v2", "claude", "pi"];
658
1096
  var HARNESS_ENTRYPOINTS = {
659
1097
  "opencode-v1": "bin/harness/opencode-1.x.js",
@@ -670,8 +1108,8 @@ function parsePackageMetadata(value) {
670
1108
  }
671
1109
  return { version: value["version"] };
672
1110
  }
673
- var metadata = parsePackageMetadata(JSON.parse(await readFile(new URL("../../package.json", import.meta.url), "utf8")));
674
- var PACKAGE_VERSION = metadata.version;
1111
+ var metadata3 = parsePackageMetadata(JSON.parse(await readFile(new URL("../../package.json", import.meta.url), "utf8")));
1112
+ var PACKAGE_VERSION = metadata3.version;
675
1113
  var RELEASE_BASE_URL = (process.env["ANYCODE_RELEASE_BASE_URL"] ?? "https://anycode.me").replace(/\/$/u, "");
676
1114
  var homeDirectory = homedir();
677
1115
  var INSTALL_ROOT = join4(process.env["ANYCODE_INSTALL_ROOT"] ?? join4(homeDirectory, ".local", "share", "anycode"));
@@ -721,7 +1159,7 @@ function ensureNodeVersion() {
721
1159
  }
722
1160
  async function verifyArtifact(artifact, checksumFile) {
723
1161
  const expected = (await readFile(checksumFile, "utf8")).trim().split(/\s+/).at(-1);
724
- const actual = createHash3("sha256").update(await readFile(artifact)).digest("hex");
1162
+ const actual = createHash5("sha256").update(await readFile(artifact)).digest("hex");
725
1163
  const normalized = expected?.replace(/^sha256:/, "");
726
1164
  if (!normalized || normalized !== actual) {
727
1165
  throw new Error("release artifact sha256 does not match its checksum");
@@ -751,7 +1189,7 @@ async function verifySignedRelease(version, target, artifact, options = {}) {
751
1189
  const signedHash = verifyReleaseChecksums(Buffer.from(sums), await signatureResponse.text(), options.publicKeyPem ?? RELEASE_PUBLIC_KEY_PEM).get(name);
752
1190
  if (signedHash !== file.sha256)
753
1191
  throw new Error("AnyCode manifest does not match signed SHA256SUMS");
754
- const actual = createHash3("sha256").update(await readFile(artifact)).digest("hex");
1192
+ const actual = createHash5("sha256").update(await readFile(artifact)).digest("hex");
755
1193
  if (actual !== signedHash)
756
1194
  throw new Error("AnyCode release artifact does not match signed SHA256SUMS");
757
1195
  }
@@ -786,8 +1224,8 @@ async function install(version, harness, options = {}) {
786
1224
  throw new Error("AnyCode release base URL must use HTTPS");
787
1225
  const fetcher = options.fetcher ?? fetch;
788
1226
  const requestOptions = { redirect: "follow", signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS) };
789
- await mkdir(dirname3(installRoot), { recursive: true });
790
- const temporary = await mkdtemp(join4(dirname3(installRoot), ".anycode-npm-"));
1227
+ await mkdir(dirname4(installRoot), { recursive: true });
1228
+ const temporary = await mkdtemp(join4(dirname4(installRoot), ".anycode-npm-"));
791
1229
  const artifact = join4(temporary, `anycode-${version}-${target.os}-${target.arch}.tar.gz`);
792
1230
  const checksum = `${artifact}.sha256`;
793
1231
  const source = join4(temporary, "source");
@@ -885,7 +1323,7 @@ async function main(args) {
885
1323
  }
886
1324
  if (args.includes("--version") && args.length === 1) {
887
1325
  const native = newerNativeExecutable();
888
- console.log(native ? `${native.version} (${native.path})` : `${PACKAGE_VERSION} (${fileURLToPath(import.meta.url)})`);
1326
+ console.log(native ? native.version : PACKAGE_VERSION);
889
1327
  return 0;
890
1328
  }
891
1329
  if (args[0] === "install") {
@@ -900,7 +1338,7 @@ async function main(args) {
900
1338
  }
901
1339
  return result.status ?? 1;
902
1340
  }
903
- if (process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1]) {
1341
+ if (isEntryModule(import.meta.url, process.argv[1], process.versions["bun"] !== undefined && __require.main == __require.module === true)) {
904
1342
  main(process.argv.slice(2)).then((code) => {
905
1343
  process.exitCode = code;
906
1344
  }).catch((error) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langgexyz/anycode",
3
- "version": "0.4.6",
3
+ "version": "0.4.10",
4
4
  "description": "AnyCode distribution bootstrap for the native runtime",
5
5
  "type": "module",
6
6
  "bin": {
@@ -23,7 +23,7 @@
23
23
  "typescript": "7.0.2"
24
24
  },
25
25
  "scripts": {
26
- "build": "bun scripts/generate-release-key.ts --check && bun build npm/src/cli.ts --outfile npm/dist/cli.mjs --target node",
26
+ "build": "bun scripts/generate-release-key.ts --check && bun scripts/provider-bundle.ts --bundle npm --outfile npm/dist/cli.mjs",
27
27
  "build:binary": "bun scripts/build-binary.ts",
28
28
  "build:binary-package": "bun scripts/build-binary-package.ts",
29
29
  "build:git-gate": "bun build scripts/git-gate.ts --outfile scripts/git-gate.mjs --target node",