@tangle-network/agent-interface 0.36.0 → 0.38.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 (31) hide show
  1. package/README.md +2 -2
  2. package/dist/agent-candidate-artifact-schema.d.ts +504 -0
  3. package/dist/agent-candidate-artifact-schema.js +16 -1
  4. package/dist/agent-candidate-execution-plan-schema.d.ts +50 -27
  5. package/dist/agent-candidate-execution-plan-schema.js +4 -16
  6. package/dist/agent-candidate-profile-schema.d.ts +341 -25
  7. package/dist/agent-candidate-promotion-schema.d.ts +2320 -287
  8. package/dist/agent-candidate-receipt-schema.d.ts +50 -27
  9. package/dist/agent-candidate-schema-common.js +1 -1
  10. package/dist/agent-candidate-schema.d.ts +341 -25
  11. package/dist/agent-candidate.d.ts +7 -8
  12. package/dist/agent-execution-preparation.d.ts +366 -0
  13. package/dist/agent-execution-preparation.js +793 -0
  14. package/dist/agent-improvement-source.d.ts +61 -3
  15. package/dist/agent-improvement-source.js +122 -8
  16. package/dist/agent-profile-activation.d.ts +41 -0
  17. package/dist/agent-profile-activation.js +24 -0
  18. package/dist/agent-profile-improvement-schema.d.ts +48 -4
  19. package/dist/agent-profile-materialization.d.ts +34 -0
  20. package/dist/agent-profile-materialization.js +243 -0
  21. package/dist/agent-profile.d.ts +44 -7
  22. package/dist/agent-profile.js +39 -2
  23. package/dist/agent-workspace-lease.d.ts +138 -0
  24. package/dist/agent-workspace-lease.js +203 -0
  25. package/dist/harness-capabilities.d.ts +1 -1
  26. package/dist/harness-capabilities.js +2 -9
  27. package/dist/index.d.ts +4 -0
  28. package/dist/index.js +4 -0
  29. package/dist/profile-schema.d.ts +142 -84
  30. package/dist/profile-schema.js +152 -41
  31. package/package.json +3 -1
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import type { AgentProfile, AgentProfileMcpServer } from "./agent-profile.js";
2
+ import { type AgentProfile, type AgentProfileMcpServer } from "./agent-profile.js";
3
3
  import type { AgentProfileDiff } from "./profile-diff.js";
4
4
  import { type SandboxSizePreset } from "./sandbox-size.js";
5
5
  export declare const agentProfilePermissionValueSchema: z.ZodEnum<{
@@ -11,11 +11,7 @@ export declare const agentProfilePermissionSchema: z.ZodUnion<readonly [z.ZodEnu
11
11
  allow: "allow";
12
12
  ask: "ask";
13
13
  deny: "deny";
14
- }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
15
- allow: "allow";
16
- ask: "ask";
17
- deny: "deny";
18
- }>>]>;
14
+ }>, z.ZodType<Record<string, "allow" | "ask" | "deny">, unknown, z.core.$ZodTypeInternals<Record<string, "allow" | "ask" | "deny">, unknown>>]>;
19
15
  export declare const agentProfileResourceRefSchema: z.ZodUnion<readonly [z.ZodObject<{
20
16
  kind: z.ZodLiteral<"inline">;
21
17
  name: z.ZodString;
@@ -137,51 +133,102 @@ export declare const agentProfileModelHintsSchema: z.ZodObject<{
137
133
  xhigh: "xhigh";
138
134
  ultracode: "ultracode";
139
135
  }>>;
140
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
136
+ metadata: z.ZodOptional<z.ZodType<Record<string, unknown>, unknown, z.core.$ZodTypeInternals<Record<string, unknown>, unknown>>>;
141
137
  }, z.core.$strict>;
142
138
  export declare const agentProfilePromptSchema: z.ZodObject<{
143
139
  systemPrompt: z.ZodOptional<z.ZodString>;
144
140
  instructions: z.ZodOptional<z.ZodArray<z.ZodString>>;
145
141
  }, z.core.$strict>;
142
+ export declare const agentProfilePublicConfigValueSchema: z.ZodObject<{
143
+ kind: z.ZodLiteral<"public">;
144
+ value: z.ZodString;
145
+ }, z.core.$strict>;
146
+ export declare const agentProfileSecretRefSchema: z.ZodObject<{
147
+ kind: z.ZodLiteral<"secret-ref">;
148
+ key: z.ZodString;
149
+ format: z.ZodOptional<z.ZodEnum<{
150
+ raw: "raw";
151
+ bearer: "bearer";
152
+ }>>;
153
+ }, z.core.$strict>;
154
+ export declare const agentProfileConfigValueSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
155
+ kind: z.ZodLiteral<"public">;
156
+ value: z.ZodString;
157
+ }, z.core.$strict>, z.ZodObject<{
158
+ kind: z.ZodLiteral<"secret-ref">;
159
+ key: z.ZodString;
160
+ format: z.ZodOptional<z.ZodEnum<{
161
+ raw: "raw";
162
+ bearer: "bearer";
163
+ }>>;
164
+ }, z.core.$strict>], "kind">;
165
+ export declare const agentProfileEnvironmentSchema: z.ZodType<Record<string, {
166
+ kind: "public";
167
+ value: string;
168
+ } | {
169
+ kind: "secret-ref";
170
+ key: string;
171
+ format?: "raw" | "bearer" | undefined;
172
+ }>, unknown, z.core.$ZodTypeInternals<Record<string, {
173
+ kind: "public";
174
+ value: string;
175
+ } | {
176
+ kind: "secret-ref";
177
+ key: string;
178
+ format?: "raw" | "bearer" | undefined;
179
+ }>, unknown>>;
180
+ export declare const agentProfileHeaderSchema: z.ZodType<Record<string, {
181
+ kind: "public";
182
+ value: string;
183
+ } | {
184
+ kind: "secret-ref";
185
+ key: string;
186
+ format?: "raw" | "bearer" | undefined;
187
+ }>, unknown, z.core.$ZodTypeInternals<Record<string, {
188
+ kind: "public";
189
+ value: string;
190
+ } | {
191
+ kind: "secret-ref";
192
+ key: string;
193
+ format?: "raw" | "bearer" | undefined;
194
+ }>, unknown>>;
146
195
  export declare const agentSubagentProfileSchema: z.ZodObject<{
147
196
  description: z.ZodOptional<z.ZodString>;
148
197
  prompt: z.ZodOptional<z.ZodString>;
149
198
  model: z.ZodOptional<z.ZodString>;
150
- tools: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
151
- permissions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodEnum<{
152
- allow: "allow";
153
- ask: "ask";
154
- deny: "deny";
155
- }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
156
- allow: "allow";
157
- ask: "ask";
158
- deny: "deny";
159
- }>>]>>>;
199
+ tools: z.ZodOptional<z.ZodType<Record<string, boolean>, unknown, z.core.$ZodTypeInternals<Record<string, boolean>, unknown>>>;
200
+ permissions: z.ZodOptional<z.ZodType<Record<string, "allow" | "ask" | "deny" | Record<string, "allow" | "ask" | "deny">>, unknown, z.core.$ZodTypeInternals<Record<string, "allow" | "ask" | "deny" | Record<string, "allow" | "ask" | "deny">>, unknown>>>;
160
201
  maxSteps: z.ZodOptional<z.ZodNumber>;
161
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
202
+ metadata: z.ZodOptional<z.ZodType<Record<string, unknown>, unknown, z.core.$ZodTypeInternals<Record<string, unknown>, unknown>>>;
162
203
  }, z.core.$strict>;
163
204
  export declare const agentProfileHookCommandSchema: z.ZodObject<{
164
205
  command: z.ZodString;
165
206
  timeoutMs: z.ZodOptional<z.ZodNumber>;
166
207
  blocking: z.ZodOptional<z.ZodBoolean>;
167
208
  matcher: z.ZodOptional<z.ZodString>;
168
- env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
209
+ env: z.ZodOptional<z.ZodType<Record<string, {
210
+ kind: "public";
211
+ value: string;
212
+ } | {
213
+ kind: "secret-ref";
214
+ key: string;
215
+ format?: "raw" | "bearer" | undefined;
216
+ }>, unknown, z.core.$ZodTypeInternals<Record<string, {
217
+ kind: "public";
218
+ value: string;
219
+ } | {
220
+ kind: "secret-ref";
221
+ key: string;
222
+ format?: "raw" | "bearer" | undefined;
223
+ }>, unknown>>>;
169
224
  }, z.core.$strict>;
170
225
  export declare const agentProfileModeSchema: z.ZodObject<{
171
226
  description: z.ZodOptional<z.ZodString>;
172
227
  model: z.ZodOptional<z.ZodString>;
173
228
  prompt: z.ZodOptional<z.ZodString>;
174
- tools: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
175
- permissions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodEnum<{
176
- allow: "allow";
177
- ask: "ask";
178
- deny: "deny";
179
- }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
180
- allow: "allow";
181
- ask: "ask";
182
- deny: "deny";
183
- }>>]>>>;
184
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
229
+ tools: z.ZodOptional<z.ZodType<Record<string, boolean>, unknown, z.core.$ZodTypeInternals<Record<string, boolean>, unknown>>>;
230
+ permissions: z.ZodOptional<z.ZodType<Record<string, "allow" | "ask" | "deny" | Record<string, "allow" | "ask" | "deny">>, unknown, z.core.$ZodTypeInternals<Record<string, "allow" | "ask" | "deny" | Record<string, "allow" | "ask" | "deny">>, unknown>>>;
231
+ metadata: z.ZodOptional<z.ZodType<Record<string, unknown>, unknown, z.core.$ZodTypeInternals<Record<string, unknown>, unknown>>>;
185
232
  }, z.core.$strict>;
186
233
  export declare const agentProfileConfidentialSchema: z.ZodObject<{
187
234
  tee: z.ZodOptional<z.ZodString>;
@@ -264,7 +311,7 @@ export declare const agentProfileSchema: z.ZodObject<{
264
311
  xhigh: "xhigh";
265
312
  ultracode: "ultracode";
266
313
  }>>;
267
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
314
+ metadata: z.ZodOptional<z.ZodType<Record<string, unknown>, unknown, z.core.$ZodTypeInternals<Record<string, unknown>, unknown>>>;
268
315
  }, z.core.$strict>>;
269
316
  harness: z.ZodOptional<z.ZodEnum<{
270
317
  "claude-code": "claude-code";
@@ -281,39 +328,31 @@ export declare const agentProfileSchema: z.ZodObject<{
281
328
  acp: "acp";
282
329
  "cli-base": "cli-base";
283
330
  }>>;
284
- permissions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodEnum<{
285
- allow: "allow";
286
- ask: "ask";
287
- deny: "deny";
288
- }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
289
- allow: "allow";
290
- ask: "ask";
291
- deny: "deny";
292
- }>>]>>>;
293
- tools: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
294
- mcp: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<AgentProfileMcpServer, unknown, z.core.$ZodTypeInternals<AgentProfileMcpServer, unknown>>>>;
331
+ permissions: z.ZodOptional<z.ZodType<Record<string, "allow" | "ask" | "deny" | Record<string, "allow" | "ask" | "deny">>, unknown, z.core.$ZodTypeInternals<Record<string, "allow" | "ask" | "deny" | Record<string, "allow" | "ask" | "deny">>, unknown>>>;
332
+ tools: z.ZodOptional<z.ZodType<Record<string, boolean>, unknown, z.core.$ZodTypeInternals<Record<string, boolean>, unknown>>>;
333
+ mcp: z.ZodOptional<z.ZodType<Record<string, AgentProfileMcpServer>, unknown, z.core.$ZodTypeInternals<Record<string, AgentProfileMcpServer>, unknown>>>;
295
334
  connections: z.ZodOptional<z.ZodArray<z.ZodObject<{
296
335
  connectionId: z.ZodString;
297
336
  capabilities: z.ZodArray<z.ZodString>;
298
337
  alias: z.ZodOptional<z.ZodString>;
299
338
  }, z.core.$strict>>>;
300
- subagents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
301
- description: z.ZodOptional<z.ZodString>;
302
- prompt: z.ZodOptional<z.ZodString>;
303
- model: z.ZodOptional<z.ZodString>;
304
- tools: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
305
- permissions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodEnum<{
306
- allow: "allow";
307
- ask: "ask";
308
- deny: "deny";
309
- }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
310
- allow: "allow";
311
- ask: "ask";
312
- deny: "deny";
313
- }>>]>>>;
314
- maxSteps: z.ZodOptional<z.ZodNumber>;
315
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
316
- }, z.core.$strict>>>;
339
+ subagents: z.ZodOptional<z.ZodType<Record<string, {
340
+ description?: string | undefined;
341
+ prompt?: string | undefined;
342
+ model?: string | undefined;
343
+ tools?: Record<string, boolean> | undefined;
344
+ permissions?: Record<string, "allow" | "ask" | "deny" | Record<string, "allow" | "ask" | "deny">> | undefined;
345
+ maxSteps?: number | undefined;
346
+ metadata?: Record<string, unknown> | undefined;
347
+ }>, unknown, z.core.$ZodTypeInternals<Record<string, {
348
+ description?: string | undefined;
349
+ prompt?: string | undefined;
350
+ model?: string | undefined;
351
+ tools?: Record<string, boolean> | undefined;
352
+ permissions?: Record<string, "allow" | "ask" | "deny" | Record<string, "allow" | "ask" | "deny">> | undefined;
353
+ maxSteps?: number | undefined;
354
+ metadata?: Record<string, unknown> | undefined;
355
+ }>, unknown>>>;
317
356
  resources: z.ZodOptional<z.ZodObject<{
318
357
  files: z.ZodOptional<z.ZodArray<z.ZodObject<{
319
358
  path: z.ZodString;
@@ -387,37 +426,56 @@ export declare const agentProfileSchema: z.ZodObject<{
387
426
  }, z.core.$strict>]>]>>;
388
427
  failOnError: z.ZodOptional<z.ZodBoolean>;
389
428
  }, z.core.$strict>>;
390
- hooks: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodObject<{
391
- command: z.ZodString;
392
- timeoutMs: z.ZodOptional<z.ZodNumber>;
393
- blocking: z.ZodOptional<z.ZodBoolean>;
394
- matcher: z.ZodOptional<z.ZodString>;
395
- env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
396
- }, z.core.$strict>>>>;
397
- modes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
398
- description: z.ZodOptional<z.ZodString>;
399
- model: z.ZodOptional<z.ZodString>;
400
- prompt: z.ZodOptional<z.ZodString>;
401
- tools: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
402
- permissions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodEnum<{
403
- allow: "allow";
404
- ask: "ask";
405
- deny: "deny";
406
- }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
407
- allow: "allow";
408
- ask: "ask";
409
- deny: "deny";
410
- }>>]>>>;
411
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
412
- }, z.core.$strict>>>;
429
+ hooks: z.ZodOptional<z.ZodType<Record<string, {
430
+ command: string;
431
+ timeoutMs?: number | undefined;
432
+ blocking?: boolean | undefined;
433
+ matcher?: string | undefined;
434
+ env?: Record<string, {
435
+ kind: "public";
436
+ value: string;
437
+ } | {
438
+ kind: "secret-ref";
439
+ key: string;
440
+ format?: "raw" | "bearer" | undefined;
441
+ }> | undefined;
442
+ }[]>, unknown, z.core.$ZodTypeInternals<Record<string, {
443
+ command: string;
444
+ timeoutMs?: number | undefined;
445
+ blocking?: boolean | undefined;
446
+ matcher?: string | undefined;
447
+ env?: Record<string, {
448
+ kind: "public";
449
+ value: string;
450
+ } | {
451
+ kind: "secret-ref";
452
+ key: string;
453
+ format?: "raw" | "bearer" | undefined;
454
+ }> | undefined;
455
+ }[]>, unknown>>>;
456
+ modes: z.ZodOptional<z.ZodType<Record<string, {
457
+ description?: string | undefined;
458
+ model?: string | undefined;
459
+ prompt?: string | undefined;
460
+ tools?: Record<string, boolean> | undefined;
461
+ permissions?: Record<string, "allow" | "ask" | "deny" | Record<string, "allow" | "ask" | "deny">> | undefined;
462
+ metadata?: Record<string, unknown> | undefined;
463
+ }>, unknown, z.core.$ZodTypeInternals<Record<string, {
464
+ description?: string | undefined;
465
+ model?: string | undefined;
466
+ prompt?: string | undefined;
467
+ tools?: Record<string, boolean> | undefined;
468
+ permissions?: Record<string, "allow" | "ask" | "deny" | Record<string, "allow" | "ask" | "deny">> | undefined;
469
+ metadata?: Record<string, unknown> | undefined;
470
+ }>, unknown>>>;
413
471
  confidential: z.ZodOptional<z.ZodObject<{
414
472
  tee: z.ZodOptional<z.ZodString>;
415
473
  attestationNonce: z.ZodOptional<z.ZodString>;
416
474
  sealed: z.ZodOptional<z.ZodBoolean>;
417
475
  attestationRefresh: z.ZodOptional<z.ZodBoolean>;
418
476
  }, z.core.$strict>>;
419
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
420
- extensions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodUndefined]>>>;
477
+ metadata: z.ZodOptional<z.ZodType<Record<string, unknown>, unknown, z.core.$ZodTypeInternals<Record<string, unknown>, unknown>>>;
478
+ extensions: z.ZodOptional<z.ZodType<Record<string, Record<string, unknown> | undefined>, unknown, z.core.$ZodTypeInternals<Record<string, Record<string, unknown> | undefined>, unknown>>>;
421
479
  }, z.core.$strict>;
422
480
  export declare const agentProfileDiffSchema: z.ZodType<AgentProfileDiff>;
423
481
  /**
@@ -1,6 +1,55 @@
1
1
  import { z } from "zod";
2
+ import { REASONING_EFFORTS, } from "./agent-profile.js";
3
+ import { environmentNameSchema, headerNameSchema, isSafeExecutable, isSafeRelativePath, isWellFormedUnicode, looksLikeCredential, } from "./agent-candidate-schema-common.js";
2
4
  import { harnessTypeSchema } from "./harness.js";
3
5
  import { SANDBOX_SIZE_PRESET_NAMES, } from "./sandbox-size.js";
6
+ /**
7
+ * Zod records currently assign parsed values onto an ordinary object. The
8
+ * special own key `__proto__` therefore invokes the legacy prototype setter
9
+ * and disappears instead of being validated. Encode every own key before Zod
10
+ * sees it, then restore the exact UTF-16 key with defineProperty so all string
11
+ * keys allowed by `Record<string, ...>` remain data rather than object syntax.
12
+ */
13
+ function ownPropertyRecordSchema(valueSchema) {
14
+ return z.preprocess(encodeOwnRecordKeys, z.record(z
15
+ .string()
16
+ .regex(/^u(?:[0-9a-f]{4})*$/, "record keys must contain valid Unicode"), valueSchema).transform((record) => {
17
+ const restored = {};
18
+ for (const [encodedKey, value] of Object.entries(record)) {
19
+ Object.defineProperty(restored, decodeRecordKey(encodedKey), {
20
+ value,
21
+ enumerable: true,
22
+ configurable: true,
23
+ writable: true,
24
+ });
25
+ }
26
+ return restored;
27
+ }));
28
+ }
29
+ function encodeOwnRecordKeys(value) {
30
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
31
+ return value;
32
+ }
33
+ const encoded = Object.create(null);
34
+ for (const [key, entry] of Object.entries(value)) {
35
+ encoded[encodeRecordKey(key)] = entry;
36
+ }
37
+ return encoded;
38
+ }
39
+ function encodeRecordKey(value) {
40
+ let encoded = isWellFormedUnicode(value) ? "u" : "i";
41
+ for (let index = 0; index < value.length; index += 1) {
42
+ encoded += value.charCodeAt(index).toString(16).padStart(4, "0");
43
+ }
44
+ return encoded;
45
+ }
46
+ function decodeRecordKey(value) {
47
+ let decoded = "";
48
+ for (let index = 1; index < value.length; index += 4) {
49
+ decoded += String.fromCharCode(Number.parseInt(value.slice(index, index + 4), 16));
50
+ }
51
+ return decoded;
52
+ }
4
53
  export const agentProfilePermissionValueSchema = z.enum([
5
54
  "allow",
6
55
  "deny",
@@ -8,7 +57,7 @@ export const agentProfilePermissionValueSchema = z.enum([
8
57
  ]);
9
58
  export const agentProfilePermissionSchema = z.union([
10
59
  agentProfilePermissionValueSchema,
11
- z.record(z.string(), agentProfilePermissionValueSchema),
60
+ ownPropertyRecordSchema(agentProfilePermissionValueSchema),
12
61
  ]);
13
62
  // Mirrors the canonical AgentProfileResourceRef (inline | github), kind-discriminated.
14
63
  export const agentProfileResourceRefSchema = z.union([
@@ -41,49 +90,93 @@ export const agentProfileResourcesSchema = z.strictObject({
41
90
  .optional(),
42
91
  failOnError: z.boolean().optional(),
43
92
  });
44
- export const reasoningEffortSchema = z.enum([
45
- "none",
46
- "minimal",
47
- "low",
48
- "medium",
49
- "high",
50
- "xhigh",
51
- "ultracode",
52
- ]);
93
+ export const reasoningEffortSchema = z.enum(REASONING_EFFORTS);
53
94
  export const agentProfileModelHintsSchema = z.strictObject({
54
95
  default: z.string().optional(),
55
96
  small: z.string().optional(),
56
97
  provider: z.string().optional(),
57
98
  reasoningEffort: reasoningEffortSchema.optional(),
58
- metadata: z.record(z.string(), z.unknown()).optional(),
99
+ metadata: ownPropertyRecordSchema(z.unknown()).optional(),
59
100
  });
60
101
  export const agentProfilePromptSchema = z.strictObject({
61
102
  systemPrompt: z.string().optional(),
62
103
  instructions: z.array(z.string()).optional(),
63
104
  });
105
+ const controlCharacterPattern = /[\u0000-\u001f\u007f]/;
106
+ const secretCapableNamePattern = /(?:^|[_-])(?:api[_-]?key|access[_-]?key|private[_-]?key|token|secret|password|credentials?|authorization|cookie|database[_-]?url|dsn|pat)(?:[_-]|$)/i;
107
+ const publicProfileConfigStringSchema = z
108
+ .string()
109
+ .refine((value) => isWellFormedUnicode(value) &&
110
+ !controlCharacterPattern.test(value) &&
111
+ !looksLikeCredential(value), "public profile config cannot carry credential-like material");
112
+ const secretReferenceKeySchema = z
113
+ .string()
114
+ .min(1)
115
+ .max(500)
116
+ .refine((value) => value.trim().length > 0 &&
117
+ isWellFormedUnicode(value) &&
118
+ !controlCharacterPattern.test(value) &&
119
+ !looksLikeCredential(value), "secret reference key must be a public non-credential identity");
120
+ export const agentProfilePublicConfigValueSchema = z.strictObject({
121
+ kind: z.literal("public"),
122
+ value: publicProfileConfigStringSchema,
123
+ });
124
+ export const agentProfileSecretRefSchema = z.strictObject({
125
+ kind: z.literal("secret-ref"),
126
+ key: secretReferenceKeySchema,
127
+ format: z.enum(["raw", "bearer"]).optional(),
128
+ });
129
+ export const agentProfileConfigValueSchema = z.discriminatedUnion("kind", [
130
+ agentProfilePublicConfigValueSchema,
131
+ agentProfileSecretRefSchema,
132
+ ]);
133
+ function profileConfigRecordSchema(keySchema) {
134
+ return ownPropertyRecordSchema(agentProfileConfigValueSchema).superRefine((record, context) => {
135
+ for (const [name, value] of Object.entries(record)) {
136
+ const keyResult = keySchema.safeParse(name);
137
+ if (!keyResult.success) {
138
+ context.addIssue({
139
+ code: "custom",
140
+ path: [name],
141
+ message: "profile config key is invalid for this field",
142
+ });
143
+ }
144
+ if (value.kind === "public" &&
145
+ secretCapableNamePattern.test(name)) {
146
+ context.addIssue({
147
+ code: "custom",
148
+ path: [name],
149
+ message: "credential-bearing config names require a secret-ref",
150
+ });
151
+ }
152
+ }
153
+ });
154
+ }
155
+ export const agentProfileEnvironmentSchema = profileConfigRecordSchema(environmentNameSchema);
156
+ export const agentProfileHeaderSchema = profileConfigRecordSchema(headerNameSchema);
64
157
  export const agentSubagentProfileSchema = z.strictObject({
65
158
  description: z.string().optional(),
66
159
  prompt: z.string().optional(),
67
160
  model: z.string().optional(),
68
- tools: z.record(z.string(), z.boolean()).optional(),
69
- permissions: z.record(z.string(), agentProfilePermissionSchema).optional(),
161
+ tools: ownPropertyRecordSchema(z.boolean()).optional(),
162
+ permissions: ownPropertyRecordSchema(agentProfilePermissionSchema).optional(),
70
163
  maxSteps: z.number().optional(),
71
- metadata: z.record(z.string(), z.unknown()).optional(),
164
+ metadata: ownPropertyRecordSchema(z.unknown()).optional(),
72
165
  });
73
166
  export const agentProfileHookCommandSchema = z.strictObject({
74
167
  command: z.string(),
75
168
  timeoutMs: z.number().positive().optional(),
76
169
  blocking: z.boolean().optional(),
77
170
  matcher: z.string().optional(),
78
- env: z.record(z.string(), z.string()).optional(),
171
+ env: agentProfileEnvironmentSchema.optional(),
79
172
  });
80
173
  export const agentProfileModeSchema = z.strictObject({
81
174
  description: z.string().optional(),
82
175
  model: z.string().optional(),
83
176
  prompt: z.string().optional(),
84
- tools: z.record(z.string(), z.boolean()).optional(),
85
- permissions: z.record(z.string(), agentProfilePermissionSchema).optional(),
86
- metadata: z.record(z.string(), z.unknown()).optional(),
177
+ tools: ownPropertyRecordSchema(z.boolean()).optional(),
178
+ permissions: ownPropertyRecordSchema(agentProfilePermissionSchema).optional(),
179
+ metadata: ownPropertyRecordSchema(z.unknown()).optional(),
87
180
  });
88
181
  export const agentProfileConfidentialSchema = z.strictObject({
89
182
  tee: z.string().optional(),
@@ -102,17 +195,20 @@ const remoteMcpUrlSchema = nonBlankMcpValueSchema.refine((value) => {
102
195
  catch {
103
196
  return false;
104
197
  }
105
- }, "remote MCP url must be an absolute HTTP(S) URL");
198
+ }, "remote MCP url must be an absolute HTTP(S) URL").refine((value) => !looksLikeCredential(value), "remote MCP url cannot contain credentials or credential-named query parameters");
106
199
  const agentProfileLocalMcpServerSchema = z.strictObject({
107
200
  transport: z.literal("stdio").optional(),
108
- command: nonBlankMcpValueSchema,
109
- args: z.array(z.string()).optional(),
110
- env: z.record(z.string(), z.string()).optional(),
111
- cwd: z.string().optional(),
201
+ command: nonBlankMcpValueSchema.refine(isSafeExecutable, "local MCP command must be a canonical public executable"),
202
+ args: z.array(agentProfileConfigValueSchema).optional(),
203
+ env: agentProfileEnvironmentSchema.optional(),
204
+ cwd: z
205
+ .string()
206
+ .refine((value) => isSafeRelativePath(value, true), "local MCP cwd must be a canonical workspace-relative path")
207
+ .optional(),
112
208
  url: z.undefined().optional(),
113
209
  headers: z.undefined().optional(),
114
210
  enabled: z.literal(true).optional(),
115
- metadata: z.record(z.string(), z.unknown()).optional(),
211
+ metadata: ownPropertyRecordSchema(z.unknown()).optional(),
116
212
  });
117
213
  const agentProfileRemoteMcpServerSchema = z.strictObject({
118
214
  transport: z.enum(["sse", "http"]).optional(),
@@ -121,9 +217,9 @@ const agentProfileRemoteMcpServerSchema = z.strictObject({
121
217
  env: z.undefined().optional(),
122
218
  cwd: z.undefined().optional(),
123
219
  url: remoteMcpUrlSchema,
124
- headers: z.record(z.string(), z.string()).optional(),
220
+ headers: agentProfileHeaderSchema.optional(),
125
221
  enabled: z.literal(true).optional(),
126
- metadata: z.record(z.string(), z.unknown()).optional(),
222
+ metadata: ownPropertyRecordSchema(z.unknown()).optional(),
127
223
  });
128
224
  const agentProfileDisabledMcpServerSchema = z.strictObject({
129
225
  enabled: z.literal(false),
@@ -134,7 +230,7 @@ const agentProfileDisabledMcpServerSchema = z.strictObject({
134
230
  cwd: z.undefined().optional(),
135
231
  url: z.undefined().optional(),
136
232
  headers: z.undefined().optional(),
137
- metadata: z.record(z.string(), z.unknown()).optional(),
233
+ metadata: ownPropertyRecordSchema(z.unknown()).optional(),
138
234
  });
139
235
  export const agentProfileMcpServerSchema = z.union([
140
236
  agentProfileLocalMcpServerSchema,
@@ -187,7 +283,8 @@ export const agentProfileDiffRemovalSchema = z.strictObject({
187
283
  * the canonical {@link AgentProfile} TS contract. Kept structurally in lock-step
188
284
  * with that interface by the compile-time guard at the bottom of this file.
189
285
  */
190
- export const agentProfileSchema = z.strictObject({
286
+ export const agentProfileSchema = z
287
+ .strictObject({
191
288
  name: z.string().optional(),
192
289
  description: z.string().optional(),
193
290
  version: z.string().optional(),
@@ -195,22 +292,36 @@ export const agentProfileSchema = z.strictObject({
195
292
  prompt: agentProfilePromptSchema.optional(),
196
293
  model: agentProfileModelHintsSchema.optional(),
197
294
  harness: harnessTypeSchema.optional(),
198
- permissions: z.record(z.string(), agentProfilePermissionSchema).optional(),
199
- tools: z.record(z.string(), z.boolean()).optional(),
200
- mcp: z.record(z.string(), agentProfileMcpServerSchema).optional(),
295
+ permissions: ownPropertyRecordSchema(agentProfilePermissionSchema).optional(),
296
+ tools: ownPropertyRecordSchema(z.boolean()).optional(),
297
+ mcp: ownPropertyRecordSchema(agentProfileMcpServerSchema).optional(),
201
298
  connections: z.array(agentProfileConnectionSchema).optional(),
202
- subagents: z.record(z.string(), agentSubagentProfileSchema).optional(),
299
+ subagents: ownPropertyRecordSchema(agentSubagentProfileSchema).optional(),
203
300
  resources: agentProfileResourcesSchema.optional(),
204
- hooks: z
205
- .record(z.string(), z.array(agentProfileHookCommandSchema))
206
- .optional(),
207
- modes: z.record(z.string(), agentProfileModeSchema).optional(),
301
+ hooks: ownPropertyRecordSchema(z.array(agentProfileHookCommandSchema)).optional(),
302
+ modes: ownPropertyRecordSchema(agentProfileModeSchema).optional(),
208
303
  confidential: agentProfileConfidentialSchema.optional(),
209
- metadata: z.record(z.string(), z.unknown()).optional(),
210
- extensions: z
211
- .record(z.string(), z.union([z.record(z.string(), z.unknown()), z.undefined()]))
212
- .optional(),
304
+ metadata: ownPropertyRecordSchema(z.unknown()).optional(),
305
+ extensions: ownPropertyRecordSchema(z.union([ownPropertyRecordSchema(z.unknown()), z.undefined()])).optional(),
306
+ })
307
+ .superRefine((profile, context) => {
308
+ validateNestedRecordKeys(profile, context, [], new Set());
213
309
  });
310
+ function validateNestedRecordKeys(value, context, path, seen) {
311
+ if (value === null || typeof value !== "object" || seen.has(value))
312
+ return;
313
+ seen.add(value);
314
+ for (const [key, entry] of Object.entries(value)) {
315
+ if (!isWellFormedUnicode(key)) {
316
+ context.addIssue({
317
+ code: "custom",
318
+ path: [...path, key],
319
+ message: "record keys must contain valid Unicode",
320
+ });
321
+ }
322
+ validateNestedRecordKeys(entry, context, [...path, key], seen);
323
+ }
324
+ }
214
325
  export const agentProfileDiffSchema = z.strictObject({
215
326
  kind: z.literal("agent-profile-diff"),
216
327
  id: z.string().min(1).optional(),
@@ -232,7 +343,7 @@ export const agentProfileDiffSchema = z.strictObject({
232
343
  .optional(),
233
344
  set: agentProfileSchema.optional(),
234
345
  remove: agentProfileDiffRemovalSchema.optional(),
235
- metadata: z.record(z.string(), z.unknown()).optional(),
346
+ metadata: ownPropertyRecordSchema(z.unknown()).optional(),
236
347
  });
237
348
  const _agentProfileSchemaMatchesInterface = true;
238
349
  void _agentProfileSchemaMatchesInterface;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-interface",
3
- "version": "0.36.0",
3
+ "version": "0.38.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",
@@ -34,10 +34,12 @@
34
34
  ],
35
35
  "dependencies": {
36
36
  "@noble/hashes": "1.8.0",
37
+ "spdx-expression-parse": "5.0.0",
37
38
  "zod": "4.4.3"
38
39
  },
39
40
  "devDependencies": {
40
41
  "@types/node": "25.6.0",
42
+ "@types/spdx-expression-parse": "4.0.0",
41
43
  "typescript": "^6.0.3",
42
44
  "vitest": "^4.1.5"
43
45
  },