@tangle-network/cli-agent-registry 0.14.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +30 -0
  2. package/dist/{backend-types-CREj4iOY.mjs → backend-types-CNo_Zj_K.mjs} +3 -12
  3. package/dist/{backend-types-CJH-wHS3.d.mts → backend-types-DRmLR1e0.d.mts} +4 -13
  4. package/dist/backend-types.d.mts +1 -1
  5. package/dist/backend-types.mjs +1 -1
  6. package/dist/cli-auth-bundle-C6DtK7GX.mjs +95 -0
  7. package/dist/cli-auth-bundle-CwAaH0Ap.d.mts +51 -0
  8. package/dist/cli-auth-bundle.d.mts +2 -49
  9. package/dist/cli-auth-bundle.mjs +1 -91
  10. package/dist/cli-auth-placeholder.d.mts +1 -1
  11. package/dist/cli-auth-placeholder.mjs +2 -2
  12. package/dist/cli-backend-auth-env.mjs +3 -3
  13. package/dist/default-backend.d.mts +1 -1
  14. package/dist/default-backend.mjs +2 -2
  15. package/dist/{harness-DIdVNSwl.mjs → harness-D1fTxnDD.mjs} +66 -34
  16. package/dist/{native-session-contracts-DWFzgoye.mjs → harness-contracts-BZoECCMc.mjs} +87 -173
  17. package/dist/host-contracts.d.mts +30 -0
  18. package/dist/host-contracts.json +422 -0
  19. package/dist/host-contracts.mjs +63 -0
  20. package/dist/index.d.mts +117 -120
  21. package/dist/index.mjs +17 -12
  22. package/dist/local-cli-auth.d.mts +1 -1
  23. package/dist/local-cli-auth.mjs +1 -1
  24. package/dist/native-session-contracts.d.mts +57 -62
  25. package/dist/native-session-contracts.mjs +40 -2
  26. package/dist/servable-models.d.mts +5 -6
  27. package/dist/servable-models.mjs +6 -22
  28. package/dist/{session-contract-BC75JdnA.d.mts → session-contract-BhzcbPRW.d.mts} +10 -44
  29. package/dist/session-contract.d.mts +1 -1
  30. package/dist/session-contract.mjs +14 -62
  31. package/dist/{specs-BSELpX1h.d.mts → spec-CcvTM7-j.d.mts} +22 -91
  32. package/dist/{specs-Bbiay_8K.mjs → specs-BBF55TnM.mjs} +125 -94
  33. package/dist/specs.d.mts +72 -3
  34. package/dist/specs.mjs +2 -2
  35. package/package.json +15 -9
package/README.md CHANGED
@@ -23,6 +23,36 @@ overrides unless `env` is also supplied. Returned contents are sensitive raw fil
23
23
  not proof of a valid OAuth subscription. Callers own consent and native login
24
24
  validation before enrollment. This filesystem reader does not read macOS Keychain.
25
25
 
26
+ ## Native HOME layouts (0.15)
27
+
28
+ `CliDirLayout.configAllow` accepts strings or `{ path, kind: "symlink" }` rules.
29
+ Consumers must narrow an entry before calling string methods and apply its kind
30
+ constraint. The maintained Orchestrator classifier does both; arbitrary external
31
+ string-only consumers require migration. `mergeCliDirLayout` keeps its four keys,
32
+ key order and fresh default-plus-addition arrays.
33
+
34
+ Codex's known cache and plugin trees and coordination files are preserved as
35
+ auxiliary source bytes. Only its four generated arg0 symlink aliases are named
36
+ configuration; regular files at those names and unknown siblings remain held.
37
+ Credential exclusions, native-store identity and conservation still apply.
38
+
39
+ ## Host registry export
40
+
41
+ `host-contracts.json` is the generated data-only projection of the canonical
42
+ `harness-contracts/` session stores, store environment, CLI versions and model
43
+ environment names. Non-JavaScript Git consumers can pin this committed file by
44
+ commit and hash. Build emits its byte-identical package copy in `dist`; the public
45
+ `/host-contracts.json` export resolves there, and prepack rejects drift in either copy.
46
+ The real CLI/Python
47
+ boundary check is `node tests/host-contracts.integration.mjs`.
48
+
49
+ The `/host-contracts` entry also exports `HOST_CONTRACTS`. Host-only `cursor-cli`
50
+ and the Cursor CLI declaration describes its native on-disk stores; it does not
51
+ register sandbox backends, change Cursor SDK's unsupported status, or establish
52
+ sandbox recovery conformance. Per-store `env` selects its base-directory override;
53
+ `xdg` supplies a lower-priority XDG base. `session.storeEnv` declares each override's
54
+ default home-relative base; append the remaining suffix of `store.root`.
55
+
26
56
  ## Identity, availability and implementation
27
57
 
28
58
  Interface describes recognized identities, including historical ones. This
@@ -1,15 +1,6 @@
1
1
  import { z } from "zod";
2
2
  //#region ../runtime-contracts/dist/backend-types.js
3
- /**
4
- * This distribution's backend vocabulary, declared positively. The shared
5
- * Interface vocabulary also contains historical and differently hosted harnesses;
6
- * knowing one upstream must not require installing it here or make this module
7
- * throw at import time. Keep old wire identities readable when retiring execution.
8
- *
9
- * Gemini is not a direct Sandbox backend; it is available only through a backing
10
- * transport. Adding it upstream never implicitly makes it dispatchable here.
11
- * The spec/adapter composition must still prove every backend it actually enables.
12
- */
3
+ /** This distribution's backend vocabulary. Gemini is only a backing transport, not a direct backend. */
13
4
  const BACKEND_TYPE = {
14
5
  OPENCODE: "opencode",
15
6
  CLAUDE_CODE: "claude-code",
@@ -20,11 +11,11 @@ const BACKEND_TYPE = {
20
11
  PI: "pi",
21
12
  PRIME: "prime",
22
13
  HERMES: "hermes",
23
- FORGE: "forge",
24
14
  OPENCLAW: "openclaw",
25
15
  NANOCLAW: "nanoclaw",
26
16
  ACP: "acp",
27
17
  CURSOR: "cursor",
18
+ GROK: "grok",
28
19
  CLI_BASE: "cli-base"
29
20
  };
30
21
  /** Stable declaration order; registry tests check the shipped spec composition. */
@@ -42,4 +33,4 @@ function parseBackendType(value) {
42
33
  //#endregion
43
34
  export { parseBackendType as a, isBackendType as i, BACKEND_TYPE as n, backendTypeSchema as r, ALL_BACKEND_TYPES as t };
44
35
 
45
- //# sourceMappingURL=backend-types-CREj4iOY.mjs.map
36
+ //# sourceMappingURL=backend-types-CNo_Zj_K.mjs.map
@@ -1,16 +1,7 @@
1
1
  import { z } from "zod";
2
2
 
3
3
  //#region ../runtime-contracts/dist/backend-types.d.ts
4
- /**
5
- * This distribution's backend vocabulary, declared positively. The shared
6
- * Interface vocabulary also contains historical and differently hosted harnesses;
7
- * knowing one upstream must not require installing it here or make this module
8
- * throw at import time. Keep old wire identities readable when retiring execution.
9
- *
10
- * Gemini is not a direct Sandbox backend; it is available only through a backing
11
- * transport. Adding it upstream never implicitly makes it dispatchable here.
12
- * The spec/adapter composition must still prove every backend it actually enables.
13
- */
4
+ /** This distribution's backend vocabulary. Gemini is only a backing transport, not a direct backend. */
14
5
  declare const BACKEND_TYPE: {
15
6
  readonly OPENCODE: "opencode";
16
7
  readonly CLAUDE_CODE: "claude-code";
@@ -21,11 +12,11 @@ declare const BACKEND_TYPE: {
21
12
  readonly PI: "pi";
22
13
  readonly PRIME: "prime";
23
14
  readonly HERMES: "hermes";
24
- readonly FORGE: "forge";
25
15
  readonly OPENCLAW: "openclaw";
26
16
  readonly NANOCLAW: "nanoclaw";
27
17
  readonly ACP: "acp";
28
18
  readonly CURSOR: "cursor";
19
+ readonly GROK: "grok";
29
20
  readonly CLI_BASE: "cli-base";
30
21
  };
31
22
  /** Derived from the local declaration, not the complement of the upstream enum. */
@@ -44,8 +35,8 @@ declare const backendTypeSchema: z.ZodEnum<{
44
35
  openclaw: "openclaw";
45
36
  amp: "amp";
46
37
  "factory-droids": "factory-droids";
47
- forge: "forge";
48
38
  cursor: "cursor";
39
+ grok: "grok";
49
40
  acp: "acp";
50
41
  "cli-base": "cli-base";
51
42
  }>;
@@ -53,4 +44,4 @@ declare function isBackendType(value: string): value is BackendType;
53
44
  declare function parseBackendType(value: string): BackendType;
54
45
  //#endregion
55
46
  export { isBackendType as a, backendTypeSchema as i, BACKEND_TYPE as n, parseBackendType as o, BackendType as r, ALL_BACKEND_TYPES as t };
56
- //# sourceMappingURL=backend-types-CJH-wHS3.d.mts.map
47
+ //# sourceMappingURL=backend-types-DRmLR1e0.d.mts.map
@@ -1,2 +1,2 @@
1
- import { a as isBackendType, i as backendTypeSchema, n as BACKEND_TYPE, o as parseBackendType, r as BackendType, t as ALL_BACKEND_TYPES } from "./backend-types-CJH-wHS3.mjs";
1
+ import { a as isBackendType, i as backendTypeSchema, n as BACKEND_TYPE, o as parseBackendType, r as BackendType, t as ALL_BACKEND_TYPES } from "./backend-types-DRmLR1e0.mjs";
2
2
  export { ALL_BACKEND_TYPES, BACKEND_TYPE, BackendType, backendTypeSchema, isBackendType, parseBackendType };
@@ -1,2 +1,2 @@
1
- import { a as parseBackendType, i as isBackendType, n as BACKEND_TYPE, r as backendTypeSchema, t as ALL_BACKEND_TYPES } from "./backend-types-CREj4iOY.mjs";
1
+ import { a as parseBackendType, i as isBackendType, n as BACKEND_TYPE, r as backendTypeSchema, t as ALL_BACKEND_TYPES } from "./backend-types-CNo_Zj_K.mjs";
2
2
  export { ALL_BACKEND_TYPES, BACKEND_TYPE, backendTypeSchema, isBackendType, parseBackendType };
@@ -0,0 +1,95 @@
1
+ import { l as getSpec } from "./specs-BBF55TnM.mjs";
2
+ import "@tangle-network/agent-interface";
3
+ import { z } from "zod";
4
+ //#region ../runtime-contracts/dist/public-profile-request.js
5
+ const cliAuthReferenceSchema = z.strictObject({
6
+ account: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9@._+-]{0,127}$/),
7
+ secretEnv: z.string().regex(/^[A-Za-z_][A-Za-z0-9_]{0,63}$/),
8
+ format: z.enum([
9
+ "token",
10
+ "bundle",
11
+ "files"
12
+ ])
13
+ });
14
+ //#endregion
15
+ //#region src/cli-auth-bundle.ts
16
+ const DEFAULT_MODE = 384;
17
+ const AUTH_BUNDLE_PATHS = Object.freeze({
18
+ codex: ".codex/auth.json",
19
+ "claude-code": ".claude/.credentials.json"
20
+ });
21
+ /** Convert a native credential JSON bundle without reading host credentials. */
22
+ function materializeCliAuthBundle(backendType, rawBundle) {
23
+ if (backendType !== "codex" && backendType !== "claude-code") throw new Error("CLI auth bundle is not supported for the selected backend");
24
+ if (typeof rawBundle !== "string") throw new Error("CLI auth bundle must be a JSON object");
25
+ let value;
26
+ try {
27
+ value = JSON.parse(rawBundle);
28
+ } catch {
29
+ throw new Error("CLI auth bundle must be a JSON object");
30
+ }
31
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("CLI auth bundle must be a JSON object");
32
+ return [{
33
+ path: AUTH_BUNDLE_PATHS[backendType],
34
+ content: rawBundle,
35
+ mode: DEFAULT_MODE
36
+ }];
37
+ }
38
+ const CLI_AUTH_REFERENCE_ENV_VAR = "AGENT_INTERNAL_CLI_AUTH_REF";
39
+ const cliAuthFilesSchema = z.array(z.object({
40
+ path: z.string().min(1).max(4096).refine((value) => !value.startsWith("/") && !/^[A-Za-z]:/.test(value) && !/[\\\0]/.test(value) && value.split("/").every((part) => part !== "" && part !== "." && part !== "..")),
41
+ content: z.string().max(1024 * 1024),
42
+ mode: z.number().int().min(0).max(448).refine((mode) => (mode & 63) === 0).optional()
43
+ }).strict()).min(1).max(128);
44
+ function assertCliAuthReferenceSupported(backendType, model) {
45
+ if (model.cliAuth === void 0) return void 0;
46
+ const parsedReference = cliAuthReferenceSchema.safeParse(model.cliAuth);
47
+ if (!parsedReference.success) throw new Error("Invalid native authentication reference");
48
+ const reference = parsedReference.data;
49
+ if (model.authMode === "api-key" || model.apiKey !== void 0 || model.apiKeyEnv !== void 0 || model.baseUrl !== void 0 || model.authFiles !== void 0) throw new Error("cliAuth cannot be combined with API credentials, baseUrl, or inline authFiles");
50
+ const spec = getSpec(backendType);
51
+ if (!spec?.hasCliAuth) throw new Error(`Native CLI authentication is unsupported by ${backendType}`);
52
+ if (reference.format === "token" && !spec.envVars.oauthToken) throw new Error(`Native subscription tokens are unsupported by ${backendType}`);
53
+ if (reference.format === "bundle" && backendType !== "codex" && backendType !== "claude-code") throw new Error(`Native credential bundles are unsupported by ${backendType}`);
54
+ return reference;
55
+ }
56
+ /** Resolve only the selected injected secret, without copying it into a public config. */
57
+ function resolveCliAuthReference(backendType, model, environment) {
58
+ const reference = assertCliAuthReferenceSupported(backendType, model);
59
+ if (!reference) return void 0;
60
+ const value = environment[reference.secretEnv];
61
+ if (typeof value !== "string" || value.trim().length === 0) throw new Error(`Missing native credential environment variable: ${reference.secretEnv}`);
62
+ if (reference.format === "token") {
63
+ const tokenEnv = getSpec(backendType)?.envVars.oauthToken;
64
+ if (!tokenEnv) throw new Error(`Native subscription tokens are unsupported by ${backendType}`);
65
+ if (/\s/.test(value) || value.startsWith("{") || value.startsWith("[")) throw new Error("Native token authentication requires a raw token, not a credential wrapper");
66
+ return {
67
+ reference,
68
+ authFiles: [],
69
+ tokenEnvironment: { [tokenEnv]: value }
70
+ };
71
+ }
72
+ if (reference.format === "bundle") return {
73
+ reference,
74
+ authFiles: materializeCliAuthBundle(backendType, value),
75
+ tokenEnvironment: {}
76
+ };
77
+ let parsed;
78
+ try {
79
+ parsed = JSON.parse(value);
80
+ } catch {
81
+ throw new Error("Native authFiles secret must contain a JSON array of auth files");
82
+ }
83
+ const files = cliAuthFilesSchema.safeParse(parsed);
84
+ if (!files.success) throw new Error("Native authFiles secret must contain a JSON array of auth files");
85
+ if (backendType === "codex" && (files.data.length !== 1 || files.data[0]?.path !== AUTH_BUNDLE_PATHS.codex || files.data[0]?.content.trim().length === 0)) throw new Error("Codex native auth files require only .codex/auth.json");
86
+ return {
87
+ reference,
88
+ authFiles: files.data,
89
+ tokenEnvironment: {}
90
+ };
91
+ }
92
+ //#endregion
93
+ export { materializeCliAuthBundle as a, cliAuthFilesSchema as i, CLI_AUTH_REFERENCE_ENV_VAR as n, resolveCliAuthReference as o, assertCliAuthReferenceSupported as r, cliAuthReferenceSchema as s, AUTH_BUNDLE_PATHS as t };
94
+
95
+ //# sourceMappingURL=cli-auth-bundle-C6DtK7GX.mjs.map
@@ -0,0 +1,51 @@
1
+ import { z } from "zod";
2
+
3
+ //#region ../runtime-contracts/dist/public-profile-request.d.ts
4
+ declare const cliAuthReferenceSchema: z.ZodObject<{
5
+ account: z.ZodString;
6
+ secretEnv: z.ZodString;
7
+ format: z.ZodEnum<{
8
+ files: "files";
9
+ token: "token";
10
+ bundle: "bundle";
11
+ }>;
12
+ }, z.core.$strict>;
13
+ /** A supplied account binding label, not a verified native account principal. */
14
+ type CliAuthReference = z.infer<typeof cliAuthReferenceSchema>;
15
+ //#endregion
16
+ //#region src/cli-auth-bundle.d.ts
17
+ type LocalCliAuthFile = {
18
+ path: string;
19
+ content: string;
20
+ mode?: number;
21
+ };
22
+ declare const AUTH_BUNDLE_PATHS: Readonly<{
23
+ readonly codex: ".codex/auth.json";
24
+ readonly "claude-code": ".claude/.credentials.json";
25
+ }>;
26
+ /** Convert a native credential JSON bundle without reading host credentials. */
27
+ declare function materializeCliAuthBundle(backendType: string, rawBundle: string): LocalCliAuthFile[];
28
+ declare const CLI_AUTH_REFERENCE_ENV_VAR = "AGENT_INTERNAL_CLI_AUTH_REF";
29
+ type CliAuthMaterial = {
30
+ reference: CliAuthReference;
31
+ authFiles: LocalCliAuthFile[];
32
+ tokenEnvironment: Record<string, string>;
33
+ };
34
+ declare const cliAuthFilesSchema: z.ZodArray<z.ZodObject<{
35
+ path: z.ZodString;
36
+ content: z.ZodString;
37
+ mode: z.ZodOptional<z.ZodNumber>;
38
+ }, z.core.$strict>>;
39
+ declare function assertCliAuthReferenceSupported(backendType: string, model: {
40
+ cliAuth?: CliAuthReference;
41
+ authMode?: string;
42
+ apiKey?: string;
43
+ apiKeyEnv?: string;
44
+ baseUrl?: string;
45
+ authFiles?: LocalCliAuthFile[];
46
+ }): CliAuthReference | undefined;
47
+ /** Resolve only the selected injected secret, without copying it into a public config. */
48
+ declare function resolveCliAuthReference(backendType: string, model: Parameters<typeof assertCliAuthReferenceSupported>[1], environment: Readonly<Record<string, string | undefined>>): CliAuthMaterial | undefined;
49
+ //#endregion
50
+ export { assertCliAuthReferenceSupported as a, resolveCliAuthReference as c, LocalCliAuthFile as i, CliAuthReference as l, CLI_AUTH_REFERENCE_ENV_VAR as n, cliAuthFilesSchema as o, CliAuthMaterial as r, materializeCliAuthBundle as s, AUTH_BUNDLE_PATHS as t, cliAuthReferenceSchema as u };
51
+ //# sourceMappingURL=cli-auth-bundle-CwAaH0Ap.d.mts.map
@@ -1,49 +1,2 @@
1
- import { z } from "zod";
2
-
3
- //#region src/cli-auth-bundle.d.ts
4
- type LocalCliAuthFile = {
5
- path: string;
6
- content: string;
7
- mode?: number;
8
- };
9
- declare const AUTH_BUNDLE_PATHS: Readonly<{
10
- readonly codex: ".codex/auth.json";
11
- readonly "claude-code": ".claude/.credentials.json";
12
- }>;
13
- /** Convert a native credential JSON bundle without reading host credentials. */
14
- declare function materializeCliAuthBundle(backendType: string, rawBundle: string): LocalCliAuthFile[];
15
- declare const CLI_AUTH_REFERENCE_ENV_VAR = "AGENT_INTERNAL_CLI_AUTH_REF";
16
- declare const cliAuthReferenceSchema: z.ZodObject<{
17
- account: z.ZodString;
18
- secretEnv: z.ZodString;
19
- format: z.ZodEnum<{
20
- token: "token";
21
- bundle: "bundle";
22
- files: "files";
23
- }>;
24
- }, z.core.$strict>;
25
- /** A supplied account binding label, not a verified native account principal. */
26
- type CliAuthReference = z.infer<typeof cliAuthReferenceSchema>;
27
- type CliAuthMaterial = {
28
- reference: CliAuthReference;
29
- authFiles: LocalCliAuthFile[];
30
- tokenEnvironment: Record<string, string>;
31
- };
32
- declare const cliAuthFilesSchema: z.ZodArray<z.ZodObject<{
33
- path: z.ZodString;
34
- content: z.ZodString;
35
- mode: z.ZodOptional<z.ZodNumber>;
36
- }, z.core.$strict>>;
37
- declare function assertCliAuthReferenceSupported(backendType: string, model: {
38
- cliAuth?: CliAuthReference;
39
- authMode?: string;
40
- apiKey?: string;
41
- apiKeyEnv?: string;
42
- baseUrl?: string;
43
- authFiles?: LocalCliAuthFile[];
44
- }): CliAuthReference | undefined;
45
- /** Resolve only the selected injected secret, without copying it into a public config. */
46
- declare function resolveCliAuthReference(backendType: string, model: Parameters<typeof assertCliAuthReferenceSupported>[1], environment: Readonly<Record<string, string | undefined>>): CliAuthMaterial | undefined;
47
- //#endregion
48
- export { AUTH_BUNDLE_PATHS, CLI_AUTH_REFERENCE_ENV_VAR, CliAuthMaterial, CliAuthReference, LocalCliAuthFile, assertCliAuthReferenceSupported, cliAuthFilesSchema, cliAuthReferenceSchema, materializeCliAuthBundle, resolveCliAuthReference };
49
- //# sourceMappingURL=cli-auth-bundle.d.mts.map
1
+ import { a as assertCliAuthReferenceSupported, c as resolveCliAuthReference, i as LocalCliAuthFile, l as CliAuthReference, n as CLI_AUTH_REFERENCE_ENV_VAR, o as cliAuthFilesSchema, r as CliAuthMaterial, s as materializeCliAuthBundle, t as AUTH_BUNDLE_PATHS, u as cliAuthReferenceSchema } from "./cli-auth-bundle-CwAaH0Ap.mjs";
2
+ export { AUTH_BUNDLE_PATHS, CLI_AUTH_REFERENCE_ENV_VAR, CliAuthMaterial, CliAuthReference, LocalCliAuthFile, assertCliAuthReferenceSupported, cliAuthFilesSchema, cliAuthReferenceSchema, materializeCliAuthBundle, resolveCliAuthReference };
@@ -1,92 +1,2 @@
1
- import { l as getSpec } from "./specs-Bbiay_8K.mjs";
2
- import { z } from "zod";
3
- //#region src/cli-auth-bundle.ts
4
- const DEFAULT_MODE = 384;
5
- const AUTH_BUNDLE_PATHS = Object.freeze({
6
- codex: ".codex/auth.json",
7
- "claude-code": ".claude/.credentials.json"
8
- });
9
- /** Convert a native credential JSON bundle without reading host credentials. */
10
- function materializeCliAuthBundle(backendType, rawBundle) {
11
- if (backendType !== "codex" && backendType !== "claude-code") throw new Error("CLI auth bundle is not supported for the selected backend");
12
- if (typeof rawBundle !== "string") throw new Error("CLI auth bundle must be a JSON object");
13
- let value;
14
- try {
15
- value = JSON.parse(rawBundle);
16
- } catch {
17
- throw new Error("CLI auth bundle must be a JSON object");
18
- }
19
- if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("CLI auth bundle must be a JSON object");
20
- return [{
21
- path: AUTH_BUNDLE_PATHS[backendType],
22
- content: rawBundle,
23
- mode: DEFAULT_MODE
24
- }];
25
- }
26
- const CLI_AUTH_REFERENCE_ENV_VAR = "AGENT_INTERNAL_CLI_AUTH_REF";
27
- const cliAuthReferenceSchema = z.object({
28
- account: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9@._+-]{0,127}$/),
29
- secretEnv: z.string().regex(/^[A-Za-z_][A-Za-z0-9_]{0,63}$/),
30
- format: z.enum([
31
- "token",
32
- "bundle",
33
- "files"
34
- ])
35
- }).strict();
36
- const cliAuthFilesSchema = z.array(z.object({
37
- path: z.string().min(1).max(4096).refine((value) => !value.startsWith("/") && !/^[A-Za-z]:/.test(value) && !/[\\\0]/.test(value) && value.split("/").every((part) => part !== "" && part !== "." && part !== "..")),
38
- content: z.string().max(1024 * 1024),
39
- mode: z.number().int().min(0).max(448).refine((mode) => (mode & 63) === 0).optional()
40
- }).strict()).min(1).max(128);
41
- function assertCliAuthReferenceSupported(backendType, model) {
42
- if (model.cliAuth === void 0) return void 0;
43
- const parsedReference = cliAuthReferenceSchema.safeParse(model.cliAuth);
44
- if (!parsedReference.success) throw new Error("Invalid native authentication reference");
45
- const reference = parsedReference.data;
46
- if (model.authMode === "api-key" || model.apiKey !== void 0 || model.apiKeyEnv !== void 0 || model.baseUrl !== void 0 || model.authFiles !== void 0) throw new Error("cliAuth cannot be combined with API credentials, baseUrl, or inline authFiles");
47
- const spec = getSpec(backendType);
48
- if (!spec?.hasCliAuth) throw new Error(`Native CLI authentication is unsupported by ${backendType}`);
49
- if (reference.format === "token" && !spec.envVars.oauthToken) throw new Error(`Native subscription tokens are unsupported by ${backendType}`);
50
- if (reference.format === "bundle" && backendType !== "codex" && backendType !== "claude-code") throw new Error(`Native credential bundles are unsupported by ${backendType}`);
51
- return reference;
52
- }
53
- /** Resolve only the selected injected secret, without copying it into a public config. */
54
- function resolveCliAuthReference(backendType, model, environment) {
55
- const reference = assertCliAuthReferenceSupported(backendType, model);
56
- if (!reference) return void 0;
57
- const value = environment[reference.secretEnv];
58
- if (typeof value !== "string" || value.trim().length === 0) throw new Error(`Missing native credential environment variable: ${reference.secretEnv}`);
59
- if (reference.format === "token") {
60
- const tokenEnv = getSpec(backendType)?.envVars.oauthToken;
61
- if (!tokenEnv) throw new Error(`Native subscription tokens are unsupported by ${backendType}`);
62
- if (/\s/.test(value) || value.startsWith("{") || value.startsWith("[")) throw new Error("Native token authentication requires a raw token, not a credential wrapper");
63
- return {
64
- reference,
65
- authFiles: [],
66
- tokenEnvironment: { [tokenEnv]: value }
67
- };
68
- }
69
- if (reference.format === "bundle") return {
70
- reference,
71
- authFiles: materializeCliAuthBundle(backendType, value),
72
- tokenEnvironment: {}
73
- };
74
- let parsed;
75
- try {
76
- parsed = JSON.parse(value);
77
- } catch {
78
- throw new Error("Native authFiles secret must contain a JSON array of auth files");
79
- }
80
- const files = cliAuthFilesSchema.safeParse(parsed);
81
- if (!files.success) throw new Error("Native authFiles secret must contain a JSON array of auth files");
82
- if (backendType === "codex" && (files.data.length !== 1 || files.data[0]?.path !== AUTH_BUNDLE_PATHS.codex || files.data[0]?.content.trim().length === 0)) throw new Error("Codex native auth files require only .codex/auth.json");
83
- return {
84
- reference,
85
- authFiles: files.data,
86
- tokenEnvironment: {}
87
- };
88
- }
89
- //#endregion
1
+ import { a as materializeCliAuthBundle, i as cliAuthFilesSchema, n as CLI_AUTH_REFERENCE_ENV_VAR, o as resolveCliAuthReference, r as assertCliAuthReferenceSupported, s as cliAuthReferenceSchema, t as AUTH_BUNDLE_PATHS } from "./cli-auth-bundle-C6DtK7GX.mjs";
90
2
  export { AUTH_BUNDLE_PATHS, CLI_AUTH_REFERENCE_ENV_VAR, assertCliAuthReferenceSupported, cliAuthFilesSchema, cliAuthReferenceSchema, materializeCliAuthBundle, resolveCliAuthReference };
91
-
92
- //# sourceMappingURL=cli-auth-bundle.mjs.map
@@ -1,4 +1,4 @@
1
- import { CliAuthMaterial, CliAuthReference } from "./cli-auth-bundle.mjs";
1
+ import { l as CliAuthReference, r as CliAuthMaterial } from "./cli-auth-bundle-CwAaH0Ap.mjs";
2
2
  import { z } from "zod";
3
3
 
4
4
  //#region src/cli-auth-placeholder.d.ts
@@ -1,5 +1,5 @@
1
- import { AUTH_BUNDLE_PATHS, assertCliAuthReferenceSupported, resolveCliAuthReference } from "./cli-auth-bundle.mjs";
2
- import { i as baseProxyToken, r as declaredSecretSlotTokens } from "./harness-DIdVNSwl.mjs";
1
+ import { o as resolveCliAuthReference, r as assertCliAuthReferenceSupported, t as AUTH_BUNDLE_PATHS } from "./cli-auth-bundle-C6DtK7GX.mjs";
2
+ import { i as baseProxyToken, r as declaredSecretSlotTokens } from "./harness-D1fTxnDD.mjs";
3
3
  import { z } from "zod";
4
4
  //#region src/cli-auth-placeholder.ts
5
5
  const identity = z.string().regex(/^[A-Za-z0-9_-]{1,256}$/);
@@ -1,6 +1,6 @@
1
- import { l as getSpec } from "./specs-Bbiay_8K.mjs";
2
- import { CLI_AUTH_REFERENCE_ENV_VAR, cliAuthFilesSchema, cliAuthReferenceSchema, resolveCliAuthReference } from "./cli-auth-bundle.mjs";
3
- import { n as isSafeEnvVarName, t as isForbiddenEnvVarName } from "./harness-DIdVNSwl.mjs";
1
+ import { l as getSpec } from "./specs-BBF55TnM.mjs";
2
+ import { i as cliAuthFilesSchema, n as CLI_AUTH_REFERENCE_ENV_VAR, o as resolveCliAuthReference, s as cliAuthReferenceSchema } from "./cli-auth-bundle-C6DtK7GX.mjs";
3
+ import { n as isSafeEnvVarName, t as isForbiddenEnvVarName } from "./harness-D1fTxnDD.mjs";
4
4
  //#region src/cli-backend-auth-env.ts
5
5
  /** The narrow credential leg shared by the host and sidecar rebind boundary. */
6
6
  function assertCliBackendAuthEnv(backendType, authEnv) {
@@ -1,4 +1,4 @@
1
- import { r as BackendType } from "./backend-types-CJH-wHS3.mjs";
1
+ import { r as BackendType } from "./backend-types-DRmLR1e0.mjs";
2
2
  //#region src/default-backend.d.ts
3
3
  /**
4
4
  * Platform-wide default agent backend, read from `DEFAULT_AGENT_BACKEND`.
@@ -1,5 +1,5 @@
1
- import { i as isBackendType, t as ALL_BACKEND_TYPES } from "./backend-types-CREj4iOY.mjs";
2
- import "./specs-Bbiay_8K.mjs";
1
+ import { i as isBackendType, t as ALL_BACKEND_TYPES } from "./backend-types-CNo_Zj_K.mjs";
2
+ import "./specs-BBF55TnM.mjs";
3
3
  //#region src/default-backend.ts
4
4
  /**
5
5
  * Platform-wide default agent backend, read from `DEFAULT_AGENT_BACKEND`.
@@ -1,22 +1,10 @@
1
- import { o as HARNESS_WARM_TRANSPORT_ENV } from "./native-session-contracts-DWFzgoye.mjs";
2
- import "./backend-types-CREj4iOY.mjs";
1
+ import { n as HARNESS_WARM_TRANSPORT_ENV } from "./harness-contracts-BZoECCMc.mjs";
2
+ import { ProxySecretBindingSchema, ProxySecretGrantSchema, ProxySecretReceiptSchema, ProxySecretUpdateControlsSchema, ProxySecretsSchema, isProxySecretScopeAttenuation, ownPropertyRecordSchema, proxySecretPresentationsEqual } from "@tangle-network/agent-interface";
3
3
  import { z } from "zod";
4
- /**
5
- * Strip the per-sandbox salt, returning the shared base token. The reverse
6
- * lookup (token -> secret env var name) keys on the base, so a salted token must
7
- * be reduced here before lookup. An unsalted token (no separator) is returned
8
- * as-is.
9
- */
10
4
  function baseProxyToken(token) {
11
5
  const i = token.indexOf(".");
12
6
  return i === -1 ? token : token.slice(0, i);
13
7
  }
14
- /**
15
- * The dummy model credential the egress proxy swaps for each env var a box
16
- * may carry. A box holds only these, salted per sandbox; the real keys stay
17
- * with the egress proxy. Host-side proxy configuration adds the non-model
18
- * tokens.
19
- */
20
8
  const MODEL_PROXY_TOKENS = {
21
9
  OPENCODE_MODEL_API_KEY: "proxy-model-token",
22
10
  OPENAI_API_KEY: "proxy-openai-token",
@@ -33,15 +21,14 @@ new Set([
33
21
  "GITHUB_TOKEN",
34
22
  "GH_TOKEN"
35
23
  ]);
36
- /**
37
- * Fixed proxy slot names. The egress layer keys every secret it holds by an
38
- * env-var-shaped name, and its persistence and recovery paths list those
39
- * names; a declaration takes the slot at its index, so a sandbox with
40
- * declarations needs no name the layer has not already listed.
41
- */
24
+ /** Proxy-private slot names shared by legacy and canonical bindings. */
42
25
  function declaredSecretSlotEnvVar(index) {
43
26
  return `TANGLE_DECLARED_SLOT_${index}`;
44
27
  }
28
+ /** True for a slot name, which exists at the proxy and never in a box env. */
29
+ function isDeclaredSecretSlotEnvVar(name) {
30
+ return /^TANGLE_DECLARED_SLOT_\d+$/.test(name);
31
+ }
45
32
  /** The base placeholder for the slot at `index`; the box holds it salted. */
46
33
  function declaredSecretBaseToken(index) {
47
34
  return `proxy-declared-${index}-token`;
@@ -53,6 +40,44 @@ function declaredSecretSlotTokens() {
53
40
  return slots;
54
41
  }
55
42
  //#endregion
43
+ //#region ../runtime-contracts/dist/proxy-secret-materialization.js
44
+ const syntheticHeader = {
45
+ alg: "HS256",
46
+ typ: "JWT"
47
+ };
48
+ const encode = (value) => btoa(value instanceof Uint8Array ? String.fromCharCode(...value) : JSON.stringify(value)).replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
49
+ function placeholderPrefix(slot, format, expiresAt) {
50
+ return format === "jwt" ? `${encode(syntheticHeader)}.${encode({
51
+ sub: "sandbox-placeholder",
52
+ aud: "proxy-secret-placeholder",
53
+ exp: Math.floor(Date.parse(expiresAt) / 1e3)
54
+ })}.` : `proxy-declared-${slot.slice(21)}-token-`;
55
+ }
56
+ function isSyntheticPlaceholder(material) {
57
+ const prefix = placeholderPrefix(material.slot, material.grant.placeholderFormat, material.issuerExpiresAt);
58
+ return material.placeholder.startsWith(prefix) && /^[A-Za-z0-9_-]{43}$/.test(material.placeholder.slice(prefix.length));
59
+ }
60
+ z.array(z.strictObject({
61
+ binding: ProxySecretBindingSchema,
62
+ grant: ProxySecretGrantSchema,
63
+ placeholder: z.string().min(1),
64
+ slot: z.string().refine(isDeclaredSecretSlotEnvVar),
65
+ issuerExpiresAt: z.iso.datetime(),
66
+ native: z.unknown().optional()
67
+ })).superRefine((materials, ctx) => {
68
+ const bindings = ProxySecretsSchema.safeParse(materials.map((m) => m.binding));
69
+ const unique = (values) => new Set(values).size === values.length;
70
+ if (!bindings.success || !unique(materials.map((m) => m.slot)) || !unique(materials.map((m) => m.placeholder)) || !unique(materials.map((m) => m.grant.grantId)) || new Set(materials.map((m) => m.grant.epoch)).size > 1 || new Set(materials.map((m) => m.grant.sandboxId)).size > 1 || materials.some((material) => !isSyntheticPlaceholder(material)) || materials.some(({ binding, grant, issuerExpiresAt }) => !isProxySecretScopeAttenuation(binding, grant.scope) || !proxySecretPresentationsEqual(binding.presentation, grant.presentation) || (binding.placeholderFormat ?? "opaque") !== grant.placeholderFormat || Date.parse(grant.expiresAt) > Date.parse(issuerExpiresAt))) ctx.addIssue({
71
+ code: "custom",
72
+ message: "Invalid proxy secret materialization"
73
+ });
74
+ });
75
+ ProxySecretUpdateControlsSchema.extend({
76
+ resolvedSecrets: ownPropertyRecordSchema(z.string().min(1), { maxEntries: Number.MAX_SAFE_INTEGER }).default({}),
77
+ proxySecretGrants: ProxySecretReceiptSchema.options[0].shape.bindings,
78
+ expectedProxySecretGeneration: ProxySecretUpdateControlsSchema.shape.expectedProxySecretGeneration.unwrap()
79
+ }).strict().refine((body) => new Set(body.proxySecretGrants.map((b) => b.envName)).size === body.proxySecretGrants.length);
80
+ //#endregion
56
81
  //#region ../runtime-contracts/dist/runtime-environment.js
57
82
  const SAFE_ENV_VAR_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
58
83
  function isSafeEnvVarName(name) {
@@ -60,6 +85,23 @@ function isSafeEnvVarName(name) {
60
85
  if (name.length === 0 || name.length > 256) return false;
61
86
  return SAFE_ENV_VAR_NAME_RE.test(name);
62
87
  }
88
+ /** Client proxy URLs first, then bypass names. */
89
+ const EGRESS_PROXY_ENV_NAMES = [
90
+ "HTTPS_PROXY",
91
+ "https_proxy",
92
+ "HTTP_PROXY",
93
+ "http_proxy",
94
+ "NO_PROXY",
95
+ "no_proxy"
96
+ ];
97
+ const CA_TRUST_ENV_NAMES = [
98
+ "NODE_EXTRA_CA_CERTS",
99
+ "SSL_CERT_FILE",
100
+ "CURL_CA_BUNDLE",
101
+ "GIT_SSL_CAINFO",
102
+ "NIX_SSL_CERT_FILE"
103
+ ];
104
+ [...EGRESS_PROXY_ENV_NAMES, ...CA_TRUST_ENV_NAMES];
63
105
  const FORBIDDEN_ENV_VAR_NAMES = new Set([
64
106
  "LD_PRELOAD",
65
107
  "LD_LIBRARY_PATH",
@@ -133,20 +175,10 @@ function isForbiddenEnvVarName(name) {
133
175
  return false;
134
176
  }
135
177
  /**
136
- * Env record schema that enforces POSIX env-var name shape (via
137
- * {@link isSafeEnvVarName}) on every key. Suitable for env that flows
138
- * into a container the caller owns (user code), where names like
139
- * `PATH`, `NODE_OPTIONS`, `LD_PRELOAD`, or `HTTPS_PROXY` are legitimate
140
- * because the user controls the resulting process environment.
141
- *
142
- * Callers that merge env into the runtime's OWN process.env (sidecar
143
- * `/config/env`, orchestrator `/sidecars/start`, project provisioning)
144
- * MUST additionally reject the process-control blocklist via
145
- * {@link isForbiddenEnvVarName} — see
146
- * `apps/orchestrator/src/routes/sidecars.ts` and
147
- * `apps/sidecar/src/routes/agents-config.ts` for the canonical shape.
178
+ * POSIX names for caller-owned container env. Runtime process.env merges must additionally enforce
179
+ * isForbiddenEnvVarName, including project provisioning and Sidecar config.
148
180
  */
149
- const safeEnvRecordSchema = z.record(z.string(), z.string()).refine((value) => Object.keys(value).every(isSafeEnvVarName), { message: "invalid env var name" });
181
+ const safeEnvRecordSchema = ownPropertyRecordSchema(z.string(), { maxEntries: Number.MAX_SAFE_INTEGER }).refine((value) => Object.keys(value).every(isSafeEnvVarName), { message: "invalid env var name" });
150
182
  /** Names only: the caller must keep a separate source and pass values to resume({ env }). */
151
183
  const sandboxEnvRecoverySchema = z.object({ callerResupplies: z.array(z.string().max(256).refine(isSafeEnvVarName, { message: "invalid env var name" })).max(128).refine((keys) => new Set(keys).size === keys.length, { message: "callerResupplies must contain unique keys" }) }).strict();
152
184
  z.object({
@@ -164,4 +196,4 @@ safeEnvRecordSchema.refine((value) => Object.keys(value).every((key) => !isForbi
164
196
  //#endregion
165
197
  export { baseProxyToken as i, isSafeEnvVarName as n, declaredSecretSlotTokens as r, isForbiddenEnvVarName as t };
166
198
 
167
- //# sourceMappingURL=harness-DIdVNSwl.mjs.map
199
+ //# sourceMappingURL=harness-D1fTxnDD.mjs.map