@tangle-network/agent-interface 1.9.0 → 2.0.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.
package/README.md CHANGED
@@ -27,6 +27,17 @@ The portable contract owns only inline profile and harness selection, shared or
27
27
 
28
28
  `shared` means ordinary same-computer file visibility. It is not automatic merge behavior or tenant isolation. `isolated` asks the provider for a private writable view and explicit inspect or commit behavior. Providers must reject unsatisfied machine requirements rather than silently replacing or migrating a live environment.
29
29
 
30
+ `WorkspaceRequest.cwd` is an explicitly based path reference.
31
+ Use `base: "repository"` for a portable repository-relative POSIX path.
32
+ Use `base: "host"` for a provider-owned native host path.
33
+ The shared schema rejects unsafe repository paths and control characters in both path forms.
34
+ It canonicalizes redundant `.` segments and separators for repository paths.
35
+ Use `.` for the repository root.
36
+ Providers advertise accepted path bases under `AgentEnvironmentCapabilities.workspace.cwdBases`.
37
+ To migrate a string cwd, wrap it in the base that owns its path.
38
+ Use the repository base for Tangle and other portable workspace providers.
39
+ Use the host base for CLI Bridge native process paths.
40
+
30
41
  The public `AgentInstanceRecord` contains a credential-free profile identity, not the full profile or provider request. Existing session APIs can implement this contract without a new service: one instance maps to one managed session, compatible sessions may reuse a backend process, and stop maps to idempotent session deletion or process release.
31
42
 
32
43
  ## Durable runs, interactions, and context
@@ -1,5 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import type { Sha256Digest } from "./agent-candidate.js";
3
+ export type RelativePathSafetyIssue = "empty" | "control-character" | "malformed-unicode" | "absolute" | "backslash" | "parent-traversal";
4
+ export type PathSafetyIssue = "control-character" | "malformed-unicode";
3
5
  export declare const sha256DigestSchema: z.ZodType<Sha256Digest>;
4
6
  export declare const gitObjectSchema: z.ZodString;
5
7
  export declare const environmentNameSchema: z.ZodString;
@@ -15,6 +17,10 @@ export declare function omitTopLevelDigest<T extends {
15
17
  digest: Sha256Digest;
16
18
  }>(value: T): Omit<T, "digest">;
17
19
  export declare function isWellFormedUnicode(value: string): boolean;
20
+ /** Return shared boundary violations for path strings. */
21
+ export declare function pathSafetyIssues(value: string): PathSafetyIssue[];
22
+ /** Return shared boundary violations for paths that must stay inside a workspace. */
23
+ export declare function relativePathSafetyIssues(value: string): RelativePathSafetyIssue[];
18
24
  export declare function isSafeRelativePath(value: string, allowDot: boolean): boolean;
19
25
  export declare function isSafeExecutable(value: string): boolean;
20
26
  export declare function isObviouslyPrivateHostname(rawHostname: string): boolean;
@@ -1,4 +1,4 @@
1
- import { sha256 } from "@noble/hashes/sha256";
1
+ import { sha256 } from "@noble/hashes/sha2.js";
2
2
  import { z } from "zod";
3
3
  const sha256Pattern = /^sha256:[a-f0-9]{64}$/;
4
4
  const gitObjectPattern = /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/;
@@ -86,20 +86,35 @@ export function isWellFormedUnicode(value) {
86
86
  }
87
87
  return true;
88
88
  }
89
+ /** Return shared boundary violations for path strings. */
90
+ export function pathSafetyIssues(value) {
91
+ const issues = [];
92
+ if (controlCharacterPattern.test(value))
93
+ issues.push("control-character");
94
+ if (!isWellFormedUnicode(value))
95
+ issues.push("malformed-unicode");
96
+ return issues;
97
+ }
98
+ /** Return shared boundary violations for paths that must stay inside a workspace. */
99
+ export function relativePathSafetyIssues(value) {
100
+ const issues = [...pathSafetyIssues(value)];
101
+ if (value.length === 0)
102
+ issues.push("empty");
103
+ if (value.startsWith("/") || /^[A-Za-z]:/.test(value))
104
+ issues.push("absolute");
105
+ if (value.includes("\\"))
106
+ issues.push("backslash");
107
+ if (value.split("/").includes(".."))
108
+ issues.push("parent-traversal");
109
+ return issues;
110
+ }
89
111
  export function isSafeRelativePath(value, allowDot) {
90
- if (value.length === 0 ||
91
- controlCharacterPattern.test(value) ||
92
- !isWellFormedUnicode(value) ||
93
- value.startsWith("/") ||
94
- value.startsWith("\\") ||
95
- value.includes("\\") ||
96
- /^[A-Za-z]:/.test(value)) {
112
+ if (relativePathSafetyIssues(value).length > 0)
97
113
  return false;
98
- }
99
114
  if (value === ".")
100
115
  return allowDot;
101
116
  const parts = value.split("/");
102
- return (parts.every((part) => part.length > 0 && part !== "." && part !== "..") &&
117
+ return (parts.every((part) => part.length > 0 && part !== ".") &&
103
118
  !parts.some((part) => reservedWorkspaceRoots.has(part)));
104
119
  }
105
120
  export function isSafeExecutable(value) {
@@ -119,7 +119,10 @@ export function execOnlyEnvironmentCapabilities(workspace) {
119
119
  turnIdempotency: false,
120
120
  },
121
121
  sessions: { continue: false, list: false, messages: false },
122
- workspace: { ...workspace },
122
+ workspace: {
123
+ cwdBases: { repository: false, host: false },
124
+ ...workspace,
125
+ },
123
126
  branching: { checkpoint: false, fork: false },
124
127
  placement: true,
125
128
  usage: false,
@@ -5,3 +5,4 @@ export * from "./environment-observation.js";
5
5
  export * from "./environment-terminal.js";
6
6
  export * from "./environment-runtime.js";
7
7
  export * from "./environment-command-turn.js";
8
+ export * from "./workspace-cwd.js";
@@ -5,3 +5,4 @@ export * from "./environment-observation.js";
5
5
  export * from "./environment-terminal.js";
6
6
  export * from "./environment-runtime.js";
7
7
  export * from "./environment-command-turn.js";
8
+ export * from "./workspace-cwd.js";
@@ -1,3 +1,5 @@
1
+ import { z } from "zod";
2
+ import type { WorkspaceCwd } from "./workspace-cwd.js";
1
3
  import type { AgentProfile } from "./agent-profile.js";
2
4
  /** Portable profile reference: inline profile or provider catalog id. */
3
5
  export type AgentProfileRef = AgentProfile | string;
@@ -12,11 +14,29 @@ export interface WorkspaceRequest {
12
14
  repoUrl?: string;
13
15
  /** Git ref for {@link repoUrl}. */
14
16
  gitRef?: string;
15
- /** Initial working directory inside the environment. */
16
- cwd?: string;
17
+ /**
18
+ * Explicitly based working directory inside the environment or on the host.
19
+ * Repository paths use `base: "repository"`; host paths use `base: "host"`.
20
+ */
21
+ cwd?: WorkspaceCwd;
17
22
  /** Opaque provider-native workspace fields. */
18
23
  providerOptions?: Record<string, unknown>;
19
24
  }
25
+ /** Runtime contract for the portable workspace request carried by providers. */
26
+ export declare const WorkspaceRequestSchema: z.ZodObject<{
27
+ environment: z.ZodOptional<z.ZodString>;
28
+ image: z.ZodOptional<z.ZodString>;
29
+ repoUrl: z.ZodOptional<z.ZodString>;
30
+ gitRef: z.ZodOptional<z.ZodString>;
31
+ cwd: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
32
+ base: z.ZodLiteral<"repository">;
33
+ path: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
34
+ }, z.core.$strict>, z.ZodObject<{
35
+ base: z.ZodLiteral<"host">;
36
+ path: z.ZodString;
37
+ }, z.core.$strict>], "base">>;
38
+ providerOptions: z.ZodOptional<z.ZodCustom<Record<string, unknown>, Record<string, unknown>>>;
39
+ }, z.core.$strict>;
20
40
  export interface ResourceRequest {
21
41
  cpu?: number;
22
42
  memoryMb?: number;
@@ -1 +1,29 @@
1
- export {};
1
+ import { z } from "zod";
2
+ import { boundedIdentifierSchema, boundedJsonRecordSchema, boundedStringSchema, } from "./contract-limits.js";
3
+ import { workspaceCwdSchema } from "./workspace-cwd.js";
4
+ /** Runtime contract for the portable workspace request carried by providers. */
5
+ export const WorkspaceRequestSchema = z
6
+ .strictObject({
7
+ environment: boundedIdentifierSchema.optional(),
8
+ image: boundedStringSchema.min(1).optional(),
9
+ repoUrl: boundedStringSchema.min(1).optional(),
10
+ gitRef: boundedIdentifierSchema.optional(),
11
+ cwd: workspaceCwdSchema.optional(),
12
+ providerOptions: boundedJsonRecordSchema.optional(),
13
+ })
14
+ .superRefine((workspace, refinement) => {
15
+ if (workspace.environment !== undefined && workspace.image !== undefined) {
16
+ refinement.addIssue({
17
+ code: "custom",
18
+ path: ["image"],
19
+ message: "workspace cannot specify both environment and image",
20
+ });
21
+ }
22
+ if (workspace.gitRef !== undefined && workspace.repoUrl === undefined) {
23
+ refinement.addIssue({
24
+ code: "custom",
25
+ path: ["gitRef"],
26
+ message: "workspace gitRef requires repoUrl",
27
+ });
28
+ }
29
+ });
@@ -818,6 +818,11 @@ export interface AgentEnvironmentCapabilities {
818
818
  git: boolean;
819
819
  upload: boolean;
820
820
  download: boolean;
821
+ /** Path bases accepted by the provider's workspace create contract. */
822
+ cwdBases?: {
823
+ repository: boolean;
824
+ host: boolean;
825
+ };
821
826
  };
822
827
  branching: {
823
828
  checkpoint: boolean;
@@ -949,6 +954,10 @@ export declare const AgentEnvironmentCapabilitiesSchema: z.ZodObject<{
949
954
  git: z.ZodBoolean;
950
955
  upload: z.ZodBoolean;
951
956
  download: z.ZodBoolean;
957
+ cwdBases: z.ZodOptional<z.ZodObject<{
958
+ repository: z.ZodBoolean;
959
+ host: z.ZodBoolean;
960
+ }, z.core.$strict>>;
952
961
  }, z.core.$strict>;
953
962
  branching: z.ZodObject<{
954
963
  checkpoint: z.ZodBoolean;
@@ -205,6 +205,12 @@ export const AgentEnvironmentCapabilitiesSchema = z
205
205
  git: z.boolean(),
206
206
  upload: z.boolean(),
207
207
  download: z.boolean(),
208
+ cwdBases: z
209
+ .strictObject({
210
+ repository: z.boolean(),
211
+ host: z.boolean(),
212
+ })
213
+ .optional(),
208
214
  }),
209
215
  branching: z.strictObject({
210
216
  checkpoint: z.boolean(),
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@ export * from "./host-services.js";
8
8
  export * from "./mcp.js";
9
9
  export * from "./provider-adapter.js";
10
10
  export type * from "./environment-provider.js";
11
- export { AgentEnvironmentCapabilitiesSchema, AgentNativeContextContinuationAdmissionSchema, AgentNativeContextContinuationResultSchema, AgentTurnInputSchema, AgentTurnResultSchema, agentEnvironmentCreateInputDigest, agentNativeContextContinuationAdmissionMatchesRequest, agentNativeContextContinuationResultMatchesRequest, AccountUsageSchema, AgentEnvironmentObservationSchema, AgentEnvironmentStatusSchema, ComputeBillingSchema, EnvironmentLifecycleSchema, ModelUsageSchema, ObservationProvenanceSchema, ObservationStateSchema, PlacementDescriptorSchema, ProviderIdentitySchema, ResourceProfileSchema, ResourceUseSampleSchema, SafeEndpointSchema, agentEnvironmentObservationIdentityMatches, assertObservationCredentialFree, observationContainsCredential, observationOf, AgentInteractiveSessionAttachSchema, AgentInteractiveSessionControlClaimAcknowledgementSchema, AgentInteractiveSessionControlClaimRequestSchema, AgentInteractiveSessionControlClaimSchema, AgentInteractiveSessionPromptAcknowledgementSchema, AgentInteractiveSessionPromptCommandSchema, AgentInteractiveSessionRefSchema, AgentInteractiveSessionStartSchema, AgentInteractiveSessionStopAcknowledgementSchema, AgentInteractiveSessionStopCommandSchema, AgentInteractiveSessionStatusSchema, agentInteractiveSessionControlClaimAcknowledgementMatchesRequest, agentInteractiveSessionControlClaimRequestDigest, agentInteractiveSessionControlClaimMatchesRef, agentInteractiveSessionControlClaimIsNewer, agentInteractiveSessionPromptAcknowledgementMatchesCommand, agentInteractiveSessionPromptRequestDigest, agentInteractiveSessionStopAcknowledgementMatchesCommand, agentInteractiveSessionStopRequestDigest, agentInteractiveSessionRequestDigest, agentInteractiveSessionRefMatchesStart, agentInteractiveSessionRunRef, agentInteractiveSessionStatusMatchesRef, exactAgentInteractiveSessionStart, AgentEnvironmentCreationSchema, createAgentEnvironmentWithIdempotency, replayedAgentEnvironmentView, TerminalAttachRequestSchema, TerminalAttachResultSchema, TerminalDetachAckSchema, TerminalInputSchema, TerminalOutputEventSchema, TerminalReplayWindowSchema, TerminalResizeSchema, TerminalSessionRefSchema, terminalAttachResultMatchesRequest, terminalSessionUsable, } from "./environment-provider.js";
11
+ export { AgentEnvironmentCapabilitiesSchema, AgentNativeContextContinuationAdmissionSchema, AgentNativeContextContinuationResultSchema, AgentTurnInputSchema, AgentTurnResultSchema, agentEnvironmentCreateInputDigest, agentNativeContextContinuationAdmissionMatchesRequest, agentNativeContextContinuationResultMatchesRequest, AccountUsageSchema, AgentEnvironmentObservationSchema, AgentEnvironmentStatusSchema, ComputeBillingSchema, EnvironmentLifecycleSchema, ModelUsageSchema, ObservationProvenanceSchema, ObservationStateSchema, PlacementDescriptorSchema, ProviderIdentitySchema, ResourceProfileSchema, ResourceUseSampleSchema, SafeEndpointSchema, agentEnvironmentObservationIdentityMatches, assertObservationCredentialFree, observationContainsCredential, observationOf, AgentInteractiveSessionAttachSchema, AgentInteractiveSessionControlClaimAcknowledgementSchema, AgentInteractiveSessionControlClaimRequestSchema, AgentInteractiveSessionControlClaimSchema, AgentInteractiveSessionPromptAcknowledgementSchema, AgentInteractiveSessionPromptCommandSchema, AgentInteractiveSessionRefSchema, AgentInteractiveSessionStartSchema, AgentInteractiveSessionStopAcknowledgementSchema, AgentInteractiveSessionStopCommandSchema, AgentInteractiveSessionStatusSchema, agentInteractiveSessionControlClaimAcknowledgementMatchesRequest, agentInteractiveSessionControlClaimRequestDigest, agentInteractiveSessionControlClaimMatchesRef, agentInteractiveSessionControlClaimIsNewer, agentInteractiveSessionPromptAcknowledgementMatchesCommand, agentInteractiveSessionPromptRequestDigest, agentInteractiveSessionStopAcknowledgementMatchesCommand, agentInteractiveSessionStopRequestDigest, agentInteractiveSessionRequestDigest, agentInteractiveSessionRefMatchesStart, agentInteractiveSessionRunRef, agentInteractiveSessionStatusMatchesRef, exactAgentInteractiveSessionStart, AgentEnvironmentCreationSchema, createAgentEnvironmentWithIdempotency, replayedAgentEnvironmentView, canonicalWorkspaceCwd, MAX_WORKSPACE_CWD_LENGTH, workspaceCwdSchema, workspaceCwdPathForBase, WorkspaceRequestSchema, TerminalAttachRequestSchema, TerminalAttachResultSchema, TerminalDetachAckSchema, TerminalInputSchema, TerminalOutputEventSchema, TerminalReplayWindowSchema, TerminalResizeSchema, TerminalSessionRefSchema, terminalAttachResultMatchesRequest, terminalSessionUsable, } from "./environment-provider.js";
12
12
  export * from "./plan.js";
13
13
  export * from "./runtime-control.js";
14
14
  export * from "./portable-context.js";
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ export * from "./provider-config.js";
7
7
  export * from "./host-services.js";
8
8
  export * from "./mcp.js";
9
9
  export * from "./provider-adapter.js";
10
- export { AgentEnvironmentCapabilitiesSchema, AgentNativeContextContinuationAdmissionSchema, AgentNativeContextContinuationResultSchema, AgentTurnInputSchema, AgentTurnResultSchema, agentEnvironmentCreateInputDigest, agentNativeContextContinuationAdmissionMatchesRequest, agentNativeContextContinuationResultMatchesRequest, AccountUsageSchema, AgentEnvironmentObservationSchema, AgentEnvironmentStatusSchema, ComputeBillingSchema, EnvironmentLifecycleSchema, ModelUsageSchema, ObservationProvenanceSchema, ObservationStateSchema, PlacementDescriptorSchema, ProviderIdentitySchema, ResourceProfileSchema, ResourceUseSampleSchema, SafeEndpointSchema, agentEnvironmentObservationIdentityMatches, assertObservationCredentialFree, observationContainsCredential, observationOf, AgentInteractiveSessionAttachSchema, AgentInteractiveSessionControlClaimAcknowledgementSchema, AgentInteractiveSessionControlClaimRequestSchema, AgentInteractiveSessionControlClaimSchema, AgentInteractiveSessionPromptAcknowledgementSchema, AgentInteractiveSessionPromptCommandSchema, AgentInteractiveSessionRefSchema, AgentInteractiveSessionStartSchema, AgentInteractiveSessionStopAcknowledgementSchema, AgentInteractiveSessionStopCommandSchema, AgentInteractiveSessionStatusSchema, agentInteractiveSessionControlClaimAcknowledgementMatchesRequest, agentInteractiveSessionControlClaimRequestDigest, agentInteractiveSessionControlClaimMatchesRef, agentInteractiveSessionControlClaimIsNewer, agentInteractiveSessionPromptAcknowledgementMatchesCommand, agentInteractiveSessionPromptRequestDigest, agentInteractiveSessionStopAcknowledgementMatchesCommand, agentInteractiveSessionStopRequestDigest, agentInteractiveSessionRequestDigest, agentInteractiveSessionRefMatchesStart, agentInteractiveSessionRunRef, agentInteractiveSessionStatusMatchesRef, exactAgentInteractiveSessionStart, AgentEnvironmentCreationSchema, createAgentEnvironmentWithIdempotency, replayedAgentEnvironmentView, TerminalAttachRequestSchema, TerminalAttachResultSchema, TerminalDetachAckSchema, TerminalInputSchema, TerminalOutputEventSchema, TerminalReplayWindowSchema, TerminalResizeSchema, TerminalSessionRefSchema, terminalAttachResultMatchesRequest, terminalSessionUsable, } from "./environment-provider.js";
10
+ export { AgentEnvironmentCapabilitiesSchema, AgentNativeContextContinuationAdmissionSchema, AgentNativeContextContinuationResultSchema, AgentTurnInputSchema, AgentTurnResultSchema, agentEnvironmentCreateInputDigest, agentNativeContextContinuationAdmissionMatchesRequest, agentNativeContextContinuationResultMatchesRequest, AccountUsageSchema, AgentEnvironmentObservationSchema, AgentEnvironmentStatusSchema, ComputeBillingSchema, EnvironmentLifecycleSchema, ModelUsageSchema, ObservationProvenanceSchema, ObservationStateSchema, PlacementDescriptorSchema, ProviderIdentitySchema, ResourceProfileSchema, ResourceUseSampleSchema, SafeEndpointSchema, agentEnvironmentObservationIdentityMatches, assertObservationCredentialFree, observationContainsCredential, observationOf, AgentInteractiveSessionAttachSchema, AgentInteractiveSessionControlClaimAcknowledgementSchema, AgentInteractiveSessionControlClaimRequestSchema, AgentInteractiveSessionControlClaimSchema, AgentInteractiveSessionPromptAcknowledgementSchema, AgentInteractiveSessionPromptCommandSchema, AgentInteractiveSessionRefSchema, AgentInteractiveSessionStartSchema, AgentInteractiveSessionStopAcknowledgementSchema, AgentInteractiveSessionStopCommandSchema, AgentInteractiveSessionStatusSchema, agentInteractiveSessionControlClaimAcknowledgementMatchesRequest, agentInteractiveSessionControlClaimRequestDigest, agentInteractiveSessionControlClaimMatchesRef, agentInteractiveSessionControlClaimIsNewer, agentInteractiveSessionPromptAcknowledgementMatchesCommand, agentInteractiveSessionPromptRequestDigest, agentInteractiveSessionStopAcknowledgementMatchesCommand, agentInteractiveSessionStopRequestDigest, agentInteractiveSessionRequestDigest, agentInteractiveSessionRefMatchesStart, agentInteractiveSessionRunRef, agentInteractiveSessionStatusMatchesRef, exactAgentInteractiveSessionStart, AgentEnvironmentCreationSchema, createAgentEnvironmentWithIdempotency, replayedAgentEnvironmentView, canonicalWorkspaceCwd, MAX_WORKSPACE_CWD_LENGTH, workspaceCwdSchema, workspaceCwdPathForBase, WorkspaceRequestSchema, TerminalAttachRequestSchema, TerminalAttachResultSchema, TerminalDetachAckSchema, TerminalInputSchema, TerminalOutputEventSchema, TerminalReplayWindowSchema, TerminalResizeSchema, TerminalSessionRefSchema, terminalAttachResultMatchesRequest, terminalSessionUsable, } from "./environment-provider.js";
11
11
  export * from "./plan.js";
12
12
  export * from "./runtime-control.js";
13
13
  export * from "./portable-context.js";
@@ -0,0 +1,28 @@
1
+ import { z } from "zod";
2
+ /** Maximum number of UTF-16 code units accepted in a workspace cwd path. */
3
+ export declare const MAX_WORKSPACE_CWD_LENGTH = 4096;
4
+ export type WorkspaceCwdBase = "repository" | "host";
5
+ export type WorkspaceCwd = {
6
+ base: "repository";
7
+ path: string;
8
+ } | {
9
+ base: "host";
10
+ path: string;
11
+ };
12
+ /**
13
+ * Validate and canonicalize an explicitly based workspace path.
14
+ *
15
+ * Repository paths never start with `./`, contain duplicate separators, or
16
+ * leave the workspace root. Host paths preserve native separators and values.
17
+ */
18
+ export declare const workspaceCwdSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
19
+ base: z.ZodLiteral<"repository">;
20
+ path: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
21
+ }, z.core.$strict>, z.ZodObject<{
22
+ base: z.ZodLiteral<"host">;
23
+ path: z.ZodString;
24
+ }, z.core.$strict>], "base">;
25
+ /** Validate and return the canonical form of a workspace cwd. */
26
+ export declare function canonicalWorkspaceCwd(value: WorkspaceCwd): WorkspaceCwd;
27
+ /** Return a provider path only when its explicit base is supported. */
28
+ export declare function workspaceCwdPathForBase(value: WorkspaceCwd | undefined, base: WorkspaceCwdBase, providerLabel: string): string | undefined;
@@ -0,0 +1,77 @@
1
+ import { z } from "zod";
2
+ import { pathSafetyIssues, relativePathSafetyIssues, } from "./agent-candidate-schema-common.js";
3
+ /** Maximum number of UTF-16 code units accepted in a workspace cwd path. */
4
+ export const MAX_WORKSPACE_CWD_LENGTH = 4_096;
5
+ const workspaceCwdIssueMessages = {
6
+ absolute: "Workspace cwd must be relative",
7
+ backslash: "Workspace cwd must use POSIX separators",
8
+ "control-character": "Workspace cwd cannot contain control characters",
9
+ "parent-traversal": "Workspace cwd cannot leave the workspace root",
10
+ "malformed-unicode": "Workspace cwd must contain well-formed Unicode",
11
+ };
12
+ function normalizeWorkspaceCwd(value) {
13
+ const segments = value
14
+ .split("/")
15
+ .filter((segment) => segment.length > 0 && segment !== ".");
16
+ return segments.join("/") || ".";
17
+ }
18
+ const pathIssueMessages = {
19
+ "control-character": "Workspace cwd cannot contain control characters",
20
+ "malformed-unicode": "Workspace cwd must contain well-formed Unicode",
21
+ };
22
+ const repositoryWorkspaceCwdPathSchema = z
23
+ .string()
24
+ .min(1)
25
+ .max(MAX_WORKSPACE_CWD_LENGTH)
26
+ .superRefine((value, refinement) => {
27
+ for (const issue of relativePathSafetyIssues(value)) {
28
+ const message = workspaceCwdIssueMessages[issue];
29
+ if (message === undefined)
30
+ continue;
31
+ refinement.addIssue({
32
+ code: "custom",
33
+ message,
34
+ });
35
+ }
36
+ })
37
+ .transform(normalizeWorkspaceCwd);
38
+ const hostWorkspaceCwdPathSchema = z
39
+ .string()
40
+ .max(MAX_WORKSPACE_CWD_LENGTH)
41
+ .superRefine((value, refinement) => {
42
+ for (const issue of pathSafetyIssues(value)) {
43
+ refinement.addIssue({
44
+ code: "custom",
45
+ message: pathIssueMessages[issue],
46
+ });
47
+ }
48
+ });
49
+ /**
50
+ * Validate and canonicalize an explicitly based workspace path.
51
+ *
52
+ * Repository paths never start with `./`, contain duplicate separators, or
53
+ * leave the workspace root. Host paths preserve native separators and values.
54
+ */
55
+ export const workspaceCwdSchema = z.discriminatedUnion("base", [
56
+ z.strictObject({
57
+ base: z.literal("repository"),
58
+ path: repositoryWorkspaceCwdPathSchema,
59
+ }),
60
+ z.strictObject({
61
+ base: z.literal("host"),
62
+ path: hostWorkspaceCwdPathSchema,
63
+ }),
64
+ ]);
65
+ /** Validate and return the canonical form of a workspace cwd. */
66
+ export function canonicalWorkspaceCwd(value) {
67
+ return workspaceCwdSchema.parse(value);
68
+ }
69
+ /** Return a provider path only when its explicit base is supported. */
70
+ export function workspaceCwdPathForBase(value, base, providerLabel) {
71
+ if (value === undefined)
72
+ return undefined;
73
+ if (value.base !== base) {
74
+ throw new Error(`${providerLabel} supports workspace cwd base "${base}", not "${value.base}"`);
75
+ }
76
+ return value.path;
77
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-interface",
3
- "version": "1.9.0",
3
+ "version": "2.0.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",
@@ -83,9 +83,9 @@
83
83
  "LICENSE"
84
84
  ],
85
85
  "dependencies": {
86
- "@noble/hashes": "1.8.0",
86
+ "@noble/hashes": "2.4.0",
87
87
  "spdx-expression-parse": "5.0.0",
88
- "zod": "4.4.3"
88
+ "zod": "4.5.4"
89
89
  },
90
90
  "devDependencies": {
91
91
  "@types/node": "26.4.0",