subharness 0.0.4 → 0.0.5
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 +36 -6
- package/dist/adapters/claude-process.d.ts +3 -0
- package/dist/adapters/claude-process.js +11 -1
- package/dist/adapters/claude-process.js.map +1 -1
- package/dist/adapters/claude-result.d.ts +2 -0
- package/dist/adapters/claude-result.js +22 -0
- package/dist/adapters/claude-result.js.map +1 -0
- package/dist/adapters/claude.js +30 -11
- package/dist/adapters/claude.js.map +1 -1
- package/dist/adapters/codex.js +4 -1
- package/dist/adapters/codex.js.map +1 -1
- package/dist/adapters/copilot-permissions.d.ts +26 -0
- package/dist/adapters/copilot-permissions.js +121 -0
- package/dist/adapters/copilot-permissions.js.map +1 -0
- package/dist/adapters/copilot-tools.d.ts +12 -0
- package/dist/adapters/copilot-tools.js +61 -0
- package/dist/adapters/copilot-tools.js.map +1 -0
- package/dist/adapters/copilot.d.ts +108 -0
- package/dist/adapters/copilot.js +819 -0
- package/dist/adapters/copilot.js.map +1 -0
- package/dist/adapters/cursor-cli-approvals.d.ts +2 -0
- package/dist/adapters/cursor-cli-approvals.js +83 -0
- package/dist/adapters/cursor-cli-approvals.js.map +1 -0
- package/dist/adapters/cursor-cli-model.d.ts +4 -0
- package/dist/adapters/cursor-cli-model.js +64 -0
- package/dist/adapters/cursor-cli-model.js.map +1 -0
- package/dist/adapters/cursor-cli-session.d.ts +32 -0
- package/dist/adapters/cursor-cli-session.js +316 -0
- package/dist/adapters/cursor-cli-session.js.map +1 -0
- package/dist/adapters/cursor-cli-tools.d.ts +20 -0
- package/dist/adapters/cursor-cli-tools.js +181 -0
- package/dist/adapters/cursor-cli-tools.js.map +1 -0
- package/dist/adapters/cursor-cli.d.ts +2 -0
- package/dist/adapters/cursor-cli.js +306 -0
- package/dist/adapters/cursor-cli.js.map +1 -0
- package/dist/adapters/cursor-model.d.ts +7 -0
- package/dist/adapters/cursor-model.js +67 -0
- package/dist/adapters/cursor-model.js.map +1 -0
- package/dist/adapters/cursor-rpc.d.ts +42 -0
- package/dist/adapters/cursor-rpc.js +271 -0
- package/dist/adapters/cursor-rpc.js.map +1 -0
- package/dist/adapters/cursor-session.d.ts +4 -0
- package/dist/adapters/cursor-session.js +327 -0
- package/dist/adapters/cursor-session.js.map +1 -0
- package/dist/adapters/cursor-startup.d.ts +16 -0
- package/dist/adapters/cursor-startup.js +74 -0
- package/dist/adapters/cursor-startup.js.map +1 -0
- package/dist/adapters/cursor-tools.d.ts +11 -0
- package/dist/adapters/cursor-tools.js +49 -0
- package/dist/adapters/cursor-tools.js.map +1 -0
- package/dist/adapters/cursor.d.ts +6 -0
- package/dist/adapters/cursor.js +17 -0
- package/dist/adapters/cursor.js.map +1 -0
- package/dist/adapters/fx-auth.d.ts +12 -2
- package/dist/adapters/fx-auth.js +51 -61
- package/dist/adapters/fx-auth.js.map +1 -1
- package/dist/adapters/fx-profile.d.ts +8 -0
- package/dist/adapters/fx-profile.js +101 -0
- package/dist/adapters/fx-profile.js.map +1 -0
- package/dist/adapters/fx-rpc.d.ts +2 -0
- package/dist/adapters/fx-rpc.js +30 -4
- package/dist/adapters/fx-rpc.js.map +1 -1
- package/dist/adapters/fx-status.d.ts +2 -0
- package/dist/adapters/fx-status.js +96 -0
- package/dist/adapters/fx-status.js.map +1 -0
- package/dist/adapters/fx.js +28 -12
- package/dist/adapters/fx.js.map +1 -1
- package/dist/adapters/opencode-access.d.ts +13 -0
- package/dist/adapters/opencode-access.js +76 -0
- package/dist/adapters/opencode-access.js.map +1 -0
- package/dist/adapters/opencode-config.d.ts +11 -0
- package/dist/adapters/opencode-config.js +238 -0
- package/dist/adapters/opencode-config.js.map +1 -0
- package/dist/adapters/opencode-http.d.ts +28 -0
- package/dist/adapters/opencode-http.js +297 -0
- package/dist/adapters/opencode-http.js.map +1 -0
- package/dist/adapters/opencode-tools.d.ts +19 -0
- package/dist/adapters/opencode-tools.js +127 -0
- package/dist/adapters/opencode-tools.js.map +1 -0
- package/dist/adapters/opencode.d.ts +2 -0
- package/dist/adapters/opencode.js +569 -0
- package/dist/adapters/opencode.js.map +1 -0
- package/dist/adapters/rpc.d.ts +3 -0
- package/dist/adapters/rpc.js +45 -4
- package/dist/adapters/rpc.js.map +1 -1
- package/dist/adapters/types.d.ts +5 -0
- package/dist/adapters/types.js.map +1 -1
- package/dist/approvals/types.d.ts +1 -1
- package/dist/approvals/types.js.map +1 -1
- package/dist/cli/args.d.ts +1 -1
- package/dist/cli/args.js +4 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/dashboard-client.js +1 -1
- package/dist/cli/dashboard-client.js.map +1 -1
- package/dist/cli/dashboard-controller.d.ts +7 -0
- package/dist/cli/dashboard-controller.js +27 -0
- package/dist/cli/dashboard-controller.js.map +1 -0
- package/dist/cli/dashboard-detail-view.d.ts +1 -1
- package/dist/cli/dashboard-detail-view.js +3 -4
- package/dist/cli/dashboard-detail-view.js.map +1 -1
- package/dist/cli/dashboard-history-view.js.map +1 -1
- package/dist/cli/dashboard-input.d.ts +1 -1
- package/dist/cli/dashboard-input.js +11 -1
- package/dist/cli/dashboard-input.js.map +1 -1
- package/dist/cli/dashboard-layout.js +3 -3
- package/dist/cli/dashboard-layout.js.map +1 -1
- package/dist/cli/dashboard-renderer.js.map +1 -1
- package/dist/cli/dashboard-style.js +2 -2
- package/dist/cli/dashboard-style.js.map +1 -1
- package/dist/cli/dashboard.d.ts +2 -2
- package/dist/cli/dashboard.js +7 -32
- package/dist/cli/dashboard.js.map +1 -1
- package/dist/cli/help.d.ts +1 -1
- package/dist/cli/help.js +30 -12
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/main.js +5 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/config/access-provenance.d.ts +10 -0
- package/dist/config/access-provenance.js +31 -0
- package/dist/config/access-provenance.js.map +1 -0
- package/dist/config/access.d.ts +12 -2
- package/dist/config/access.js +125 -27
- package/dist/config/access.js.map +1 -1
- package/dist/config/loader.js +1 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/config/oidc.js +4 -2
- package/dist/config/oidc.js.map +1 -1
- package/dist/config/project.js +2 -1
- package/dist/config/project.js.map +1 -1
- package/dist/config/resolve-access.js +24 -10
- package/dist/config/resolve-access.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/process-diagnostics.d.ts +2 -0
- package/dist/process-diagnostics.js +11 -0
- package/dist/process-diagnostics.js.map +1 -0
- package/dist/runtime/access-errors.d.ts +4 -0
- package/dist/runtime/access-errors.js +25 -0
- package/dist/runtime/access-errors.js.map +1 -0
- package/dist/runtime/approval-registry.js +1 -1
- package/dist/runtime/approval-registry.js.map +1 -1
- package/dist/runtime/client.js +54 -14
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/dashboard-sanitize.d.ts +2 -0
- package/dist/runtime/dashboard-sanitize.js +7 -0
- package/dist/runtime/dashboard-sanitize.js.map +1 -0
- package/dist/runtime/dashboard.d.ts +1 -1
- package/dist/runtime/dashboard.js +2 -3
- package/dist/runtime/dashboard.js.map +1 -1
- package/dist/runtime/definition.js +11 -1
- package/dist/runtime/definition.js.map +1 -1
- package/dist/runtime/select-native.js +26 -8
- package/dist/runtime/select-native.js.map +1 -1
- package/dist/runtime/worker-client.js +38 -13
- package/dist/runtime/worker-client.js.map +1 -1
- package/dist/sdk/definitions.d.ts +4 -1
- package/dist/sdk/definitions.js +16 -2
- package/dist/sdk/definitions.js.map +1 -1
- package/dist/sdk/permission-validation.js +10 -1
- package/dist/sdk/permission-validation.js.map +1 -1
- package/dist/sdk/types.d.ts +29 -1
- package/dist/sdk/types.js.map +1 -1
- package/package.json +4 -1
- package/sdk/access-config.md +58 -4
- package/sdk/adapter-contract.md +5 -3
- package/sdk/additional-harnesses.md +43 -0
- package/sdk/agent-skill.md +2 -2
- package/sdk/agent.md +5 -3
- package/sdk/approvals.md +3 -1
- package/sdk/authentication.md +1 -1
- package/sdk/cli/dashboard-design.md +6 -0
- package/sdk/cli/index.md +9 -6
- package/sdk/cli/output.md +3 -1
- package/sdk/config.md +1 -1
- package/sdk/copilot.md +53 -0
- package/sdk/cursor.md +68 -0
- package/sdk/diagnostics.md +29 -0
- package/sdk/distribution.md +1 -1
- package/sdk/evals.md +1 -1
- package/sdk/fx.md +50 -5
- package/sdk/harnesses.md +13 -13
- package/sdk/index.md +3 -2
- package/sdk/opencode.md +57 -0
- package/sdk/permissions.md +4 -2
- package/sdk/project-team.md +2 -0
- package/sdk/tools.md +1 -1
- package/sdk/v1-runtime.md +3 -3
package/dist/config/access.js
CHANGED
|
@@ -1,62 +1,145 @@
|
|
|
1
|
-
import { appendFile, mkdir, readFile } from "node:fs/promises";
|
|
1
|
+
import { appendFile, lstat, mkdir, readFile } from "node:fs/promises";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { AgentError } from "../errors.js";
|
|
4
4
|
import { git, resolveProject } from "./project.js";
|
|
5
|
+
import { quoteDiagnosticPath, recordAccessProvenance } from "./access-provenance.js";
|
|
5
6
|
export { resolveAccess } from "./resolve-access.js";
|
|
6
7
|
export function configError(message) {
|
|
7
8
|
throw new AgentError("INVALID_CONFIG", message);
|
|
8
9
|
}
|
|
10
|
+
function schemaError(location, message, file, code = "INVALID_CONFIG") {
|
|
11
|
+
const settings = file === undefined
|
|
12
|
+
? "Personal access settings"
|
|
13
|
+
: `Personal access settings at ${quoteDiagnosticPath(file)}`;
|
|
14
|
+
throw new AgentError(code, `${settings} are invalid at ${location}: ${message}`);
|
|
15
|
+
}
|
|
9
16
|
function record(value) {
|
|
10
17
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
11
18
|
}
|
|
12
|
-
|
|
13
|
-
if (!record(value)
|
|
14
|
-
|
|
15
|
-
|
|
19
|
+
function parseConnectionAt(value, location, file, harness) {
|
|
20
|
+
if (!record(value))
|
|
21
|
+
schemaError(location, "Connection must be an object.", file);
|
|
22
|
+
if (!["subscription", "api-key", "vercel-api-key", "vercel-oidc"].includes(value.type))
|
|
23
|
+
schemaError(`${location}.type`, "Unknown access connection type.", file);
|
|
24
|
+
const allowed = value.type === "subscription" ? ["type", "provider"] : ["type", "env", "envFile", ...(value.type === "api-key" ? ["provider", "baseUrl", "wireApi", "apiVersion", "wireModel"] : value.type === "vercel-oidc" ? ["project"] : [])];
|
|
16
25
|
if (Object.keys(value).some((key) => !allowed.includes(key)))
|
|
17
|
-
|
|
26
|
+
schemaError(location, "Unknown access connection field; secrets must be supplied through environment references.", file);
|
|
18
27
|
if (value.env !== undefined && (typeof value.env !== "string" || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(value.env)))
|
|
19
|
-
|
|
20
|
-
for (const field of ["envFile", "project"]) {
|
|
28
|
+
schemaError(`${location}.env`, "Invalid credential variable name.", file);
|
|
29
|
+
for (const field of ["envFile", "project", "provider", "baseUrl", "apiVersion", "wireModel"]) {
|
|
21
30
|
if (value[field] !== undefined && (typeof value[field] !== "string" || !value[field].trim()))
|
|
22
|
-
|
|
31
|
+
schemaError(`${location}.${field}`, field === "envFile" || field === "project" ? "Value must be a nonempty path." : "Value must be a nonempty string.", file);
|
|
23
32
|
}
|
|
33
|
+
if (value.wireApi !== undefined && !["completions", "responses"].includes(value.wireApi))
|
|
34
|
+
schemaError(`${location}.wireApi`, "Invalid wire API selection.", file);
|
|
35
|
+
if (value.baseUrl !== undefined)
|
|
36
|
+
validateBaseUrl(value.baseUrl, `${location}.baseUrl`, file);
|
|
37
|
+
if (harness)
|
|
38
|
+
validateHarnessConnection(value, harness, location, file);
|
|
24
39
|
return value;
|
|
25
40
|
}
|
|
26
|
-
|
|
41
|
+
function validateBaseUrl(value, location, file) {
|
|
42
|
+
let url;
|
|
43
|
+
try {
|
|
44
|
+
url = new URL(value);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return schemaError(location, "baseUrl must be an absolute HTTP or HTTPS URL without credentials, query, or fragment.", file);
|
|
48
|
+
}
|
|
49
|
+
if (!/^https?:\/\//iu.test(value) || value.trim() !== value || /[\s?#\\]/u.test(value)
|
|
50
|
+
|| !["http:", "https:"].includes(url.protocol) || !url.hostname || url.username || url.password
|
|
51
|
+
|| /^https?:\/\/[^/]*@/iu.test(value)) {
|
|
52
|
+
schemaError(location, "baseUrl must be an absolute HTTP or HTTPS URL without credentials, query, or fragment.", file);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function validateHarnessConnection(connection, kind, location, file) {
|
|
56
|
+
if (connection.type === "vercel-api-key" || connection.type === "vercel-oidc") {
|
|
57
|
+
if (kind === "cursor")
|
|
58
|
+
schemaError(`${location}.type`, `cursor does not support ${connection.type} access.`, file, "UNSUPPORTED_OPTION");
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (connection.type === "subscription") {
|
|
62
|
+
const providers = kind === "fx" ? ["gateway", "codex", "grok"]
|
|
63
|
+
: kind === "opencode" ? ["openai", "github-copilot", "xai"] : undefined;
|
|
64
|
+
if (providers ? !providers.includes(connection.provider ?? "") : connection.provider !== undefined) {
|
|
65
|
+
schemaError(`${location}.provider`, `${kind} requires its documented native login provider selection.`, file);
|
|
66
|
+
}
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
let allowed = ["type", "env", "envFile"];
|
|
70
|
+
if (kind === "fx" || kind === "opencode") {
|
|
71
|
+
if (!connection.provider)
|
|
72
|
+
schemaError(`${location}.provider`, `${kind} direct API keys require provider and env.`, file);
|
|
73
|
+
if (!connection.env)
|
|
74
|
+
schemaError(`${location}.env`, `${kind} direct API keys require provider and env.`, file);
|
|
75
|
+
allowed.push("provider");
|
|
76
|
+
if (kind === "fx" && ["gateway", "codex", "grok"].includes(connection.provider))
|
|
77
|
+
schemaError(`${location}.provider`, "fx direct API keys require a named custom connection.", file);
|
|
78
|
+
if (kind === "opencode") {
|
|
79
|
+
if (!["anthropic", "openai", "google", "groq", "openrouter", "xai", "mistral", "cohere", "opencode", "opencode-go"].includes(connection.provider))
|
|
80
|
+
schemaError(`${location}.provider`, "Unsupported OpenCode API-key provider.", file);
|
|
81
|
+
allowed.push("baseUrl");
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else if (kind === "copilot") {
|
|
85
|
+
if (!["github", "openai", "anthropic", "azure"].includes(connection.provider ?? ""))
|
|
86
|
+
schemaError(`${location}.provider`, "Copilot API keys require a supported provider.", file);
|
|
87
|
+
allowed.push("provider");
|
|
88
|
+
if (connection.provider !== "github")
|
|
89
|
+
allowed.push("baseUrl", "wireModel");
|
|
90
|
+
if (connection.provider === "openai" || connection.provider === "azure")
|
|
91
|
+
allowed.push("wireApi");
|
|
92
|
+
if (connection.provider === "azure") {
|
|
93
|
+
allowed.push("apiVersion");
|
|
94
|
+
if (!connection.baseUrl)
|
|
95
|
+
schemaError(`${location}.baseUrl`, "Copilot Azure API keys require baseUrl.", file);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const inapplicable = ["provider", "baseUrl", "wireApi", "apiVersion", "wireModel"]
|
|
99
|
+
.find(field => Object.hasOwn(connection, field) && !allowed.includes(field));
|
|
100
|
+
if (inapplicable)
|
|
101
|
+
schemaError(`${location}.${inapplicable}`, `Inapplicable ${kind} API-key connection field.`, file);
|
|
102
|
+
}
|
|
103
|
+
export function parseConnection(value, harness) {
|
|
104
|
+
return parseConnectionAt(value, "connection", undefined, harness);
|
|
105
|
+
}
|
|
106
|
+
function parseAccessAt(value, file) {
|
|
27
107
|
if (!record(value) || Object.keys(value).some((key) => key !== "access"))
|
|
28
|
-
|
|
108
|
+
schemaError("root object", "Expected only an optional access map.", file);
|
|
29
109
|
if (value.access === undefined)
|
|
30
110
|
return {};
|
|
31
111
|
if (!record(value.access))
|
|
32
|
-
|
|
112
|
+
schemaError("access", "Value must be an object.", file);
|
|
33
113
|
for (const [kind, connections] of Object.entries(value.access)) {
|
|
34
|
-
if (
|
|
35
|
-
|
|
114
|
+
if (!["codex", "claudeCode", "fx", "opencode", "copilot", "cursor"].includes(kind))
|
|
115
|
+
schemaError("access", "Unsupported harness entry.", file);
|
|
36
116
|
if (!Array.isArray(connections))
|
|
37
|
-
|
|
38
|
-
connections.forEach(
|
|
117
|
+
schemaError(`access.${kind}`, "Harness access selection must be an array.", file);
|
|
118
|
+
connections.forEach((connection, index) => parseConnectionAt(connection, `access.${kind}[${index}]`, file, kind));
|
|
39
119
|
}
|
|
40
120
|
return value;
|
|
41
121
|
}
|
|
42
|
-
|
|
122
|
+
export function parseAccess(value) {
|
|
123
|
+
return parseAccessAt(value);
|
|
124
|
+
}
|
|
125
|
+
async function ensureExcluded(mainRoot, file) {
|
|
43
126
|
try {
|
|
44
127
|
await git(mainRoot, ["rev-parse", "--git-dir"]);
|
|
45
128
|
}
|
|
46
129
|
catch (error) {
|
|
47
130
|
if (error instanceof Error && error.message.includes("not a git repository"))
|
|
48
131
|
return;
|
|
49
|
-
|
|
132
|
+
settingsFileError(file, "Cannot inspect Git configuration for personal settings");
|
|
50
133
|
}
|
|
51
134
|
let tracked = false;
|
|
52
135
|
try {
|
|
53
136
|
tracked = !!await git(mainRoot, ["ls-files", "--", ".subharness/agents.local.json"]);
|
|
54
137
|
}
|
|
55
138
|
catch {
|
|
56
|
-
|
|
139
|
+
settingsFileError(file, "Cannot inspect whether personal access settings are tracked by Git");
|
|
57
140
|
}
|
|
58
141
|
if (tracked)
|
|
59
|
-
|
|
142
|
+
settingsFileError(file, "Personal access settings are tracked. Remove .subharness/agents.local.json from the Git index before using it");
|
|
60
143
|
const exclude = await git(mainRoot, ["rev-parse", "--path-format=absolute", "--git-path", "info/exclude"]);
|
|
61
144
|
let contents = "";
|
|
62
145
|
try {
|
|
@@ -64,7 +147,7 @@ async function ensureExcluded(mainRoot) {
|
|
|
64
147
|
}
|
|
65
148
|
catch (error) {
|
|
66
149
|
if (error.code !== "ENOENT")
|
|
67
|
-
|
|
150
|
+
settingsFileError(file, "Cannot read Git's local exclude file");
|
|
68
151
|
}
|
|
69
152
|
const pattern = "/.subharness/agents.local.json";
|
|
70
153
|
if (!contents.split(/\r?\n/).includes(pattern)) {
|
|
@@ -72,6 +155,9 @@ async function ensureExcluded(mainRoot) {
|
|
|
72
155
|
await appendFile(exclude, `${contents.endsWith("\n") || !contents ? "" : "\n"}${pattern}\n`);
|
|
73
156
|
}
|
|
74
157
|
}
|
|
158
|
+
function settingsFileError(file, message) {
|
|
159
|
+
configError(`${message}. Personal access settings file: ${quoteDiagnosticPath(file)}.`);
|
|
160
|
+
}
|
|
75
161
|
export async function loadAccess(cwd) {
|
|
76
162
|
const { mainRoot } = await resolveProject(cwd);
|
|
77
163
|
const file = join(mainRoot, ".subharness", "agents.local.json");
|
|
@@ -80,18 +166,30 @@ export async function loadAccess(cwd) {
|
|
|
80
166
|
contents = await readFile(file, "utf8");
|
|
81
167
|
}
|
|
82
168
|
catch (error) {
|
|
83
|
-
if (error.code === "ENOENT")
|
|
84
|
-
|
|
85
|
-
|
|
169
|
+
if (error.code === "ENOENT") {
|
|
170
|
+
const settings = {};
|
|
171
|
+
const legacyFile = join(mainRoot, ".agents", "agents.local.json");
|
|
172
|
+
let legacyEntry;
|
|
173
|
+
try {
|
|
174
|
+
await lstat(legacyFile);
|
|
175
|
+
legacyEntry = legacyFile;
|
|
176
|
+
}
|
|
177
|
+
catch { /* Legacy inspection must not replace the original startup error. */ }
|
|
178
|
+
recordAccessProvenance(settings, { file, present: false, ...(legacyEntry ? { legacyFile: legacyEntry } : {}) });
|
|
179
|
+
return settings;
|
|
180
|
+
}
|
|
181
|
+
settingsFileError(file, "Cannot read personal settings");
|
|
86
182
|
}
|
|
87
|
-
await ensureExcluded(mainRoot);
|
|
183
|
+
await ensureExcluded(mainRoot, file);
|
|
88
184
|
let value;
|
|
89
185
|
try {
|
|
90
186
|
value = JSON.parse(contents);
|
|
91
187
|
}
|
|
92
188
|
catch {
|
|
93
|
-
|
|
189
|
+
settingsFileError(file, "Invalid JSON in personal settings");
|
|
94
190
|
}
|
|
95
|
-
|
|
191
|
+
const settings = parseAccessAt(value, file);
|
|
192
|
+
recordAccessProvenance(settings, { file, present: true });
|
|
193
|
+
return settings;
|
|
96
194
|
}
|
|
97
195
|
//# sourceMappingURL=access.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"access.js","sourceRoot":"","sources":["../../src/config/access.ts"],"names":[],"mappings":"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","sourcesContent":["import { appendFile, mkdir, readFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { AgentError } from \"../errors.js\";\nimport type { HarnessKind } from \"../sdk/types.js\";\nimport { git, resolveProject } from \"./project.js\";\nexport { resolveAccess } from \"./resolve-access.js\";\n\nexport type AccessConnection =\n | { type: \"subscription\" }\n | { type: \"api-key\" | \"vercel-api-key\"; env?: string; envFile?: string }\n | { type: \"vercel-oidc\"; env?: string; envFile?: string; project?: string };\n\nexport interface AccessConfig {\n access?: Partial<Record<HarnessKind, AccessConnection[]>>;\n}\n\nexport function configError(message: string): never {\n throw new AgentError(\"INVALID_CONFIG\", message);\n}\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function parseConnection(value: unknown): AccessConnection {\n if (!record(value) || ![\"subscription\", \"api-key\", \"vercel-api-key\", \"vercel-oidc\"].includes(value.type as string)) configError(\"Unknown access connection type.\");\n const allowed = value.type === \"subscription\" ? [\"type\"] : [\"type\", \"env\", \"envFile\", ...(value.type === \"vercel-oidc\" ? [\"project\"] : [])];\n if (Object.keys(value).some((key) => !allowed.includes(key))) configError(\"Unknown access connection field; secrets must be supplied through environment references.\");\n if (value.env !== undefined && (typeof value.env !== \"string\" || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(value.env))) configError(\"Invalid credential variable name.\");\n for (const field of [\"envFile\", \"project\"]) {\n if (value[field] !== undefined && (typeof value[field] !== \"string\" || !value[field].trim())) configError(`${field} must be a nonempty path.`);\n }\n return value as AccessConnection;\n}\n\nexport function parseAccess(value: unknown): AccessConfig {\n if (!record(value) || Object.keys(value).some((key) => key !== \"access\")) configError(\"Personal settings must contain only an optional access map.\");\n if (value.access === undefined) return {};\n if (!record(value.access)) configError(\"access must be an object.\");\n for (const [kind, connections] of Object.entries(value.access)) {\n if (kind !== \"codex\" && kind !== \"claudeCode\" && kind !== \"fx\") configError(\"Unsupported harness in personal access settings.\");\n if (!Array.isArray(connections)) configError(\"Each harness access selection must be an array.\");\n connections.forEach(parseConnection);\n }\n return value as AccessConfig;\n}\n\nasync function ensureExcluded(mainRoot: string): Promise<void> {\n try { await git(mainRoot, [\"rev-parse\", \"--git-dir\"]); }\n catch (error) {\n if (error instanceof Error && error.message.includes(\"not a git repository\")) return;\n configError(\"Cannot inspect Git configuration for personal settings.\");\n }\n let tracked = false;\n try { tracked = !!await git(mainRoot, [\"ls-files\", \"--\", \".subharness/agents.local.json\"]); }\n catch { configError(\"Cannot inspect whether personal access settings are tracked by Git.\"); }\n if (tracked) configError(\"Personal access settings are tracked. Remove .subharness/agents.local.json from the Git index before using it.\");\n const exclude = await git(mainRoot, [\"rev-parse\", \"--path-format=absolute\", \"--git-path\", \"info/exclude\"]);\n let contents = \"\";\n try { contents = await readFile(exclude, \"utf8\"); }\n catch (error) { if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") configError(\"Cannot read Git's local exclude file.\"); }\n const pattern = \"/.subharness/agents.local.json\";\n if (!contents.split(/\\r?\\n/).includes(pattern)) {\n await mkdir(dirname(exclude), { recursive: true });\n await appendFile(exclude, `${contents.endsWith(\"\\n\") || !contents ? \"\" : \"\\n\"}${pattern}\\n`);\n }\n}\n\nexport async function loadAccess(cwd: string): Promise<AccessConfig> {\n const { mainRoot } = await resolveProject(cwd);\n const file = join(mainRoot, \".subharness\", \"agents.local.json\");\n let contents: string;\n try { contents = await readFile(file, \"utf8\"); }\n catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return {};\n configError(`Cannot read personal settings: ${file}`);\n }\n await ensureExcluded(mainRoot);\n let value: unknown;\n try { value = JSON.parse(contents); }\n catch { configError(`Invalid JSON in personal settings: ${file}`); }\n return parseAccess(value);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"access.js","sourceRoot":"","sources":["../../src/config/access.ts"],"names":[],"mappings":"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","sourcesContent":["import { appendFile, lstat, mkdir, readFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { AgentError } from \"../errors.js\";\nimport type { HarnessKind } from \"../sdk/types.js\";\nimport { git, resolveProject } from \"./project.js\";\nimport { quoteDiagnosticPath, recordAccessProvenance } from \"./access-provenance.js\";\nexport { resolveAccess } from \"./resolve-access.js\";\n\nexport type AccessConnection =\n | { type: \"subscription\"; provider?: string }\n | { type: \"api-key\"; provider?: string; env?: string; envFile?: string; baseUrl?: string;\n wireApi?: \"completions\" | \"responses\"; apiVersion?: string; wireModel?: string }\n | { type: \"vercel-api-key\"; env?: string; envFile?: string }\n | { type: \"vercel-oidc\"; env?: string; envFile?: string; project?: string };\n\nexport interface AccessConfig {\n access?: Partial<Record<HarnessKind, AccessConnection[]>>;\n}\n\nexport function configError(message: string): never {\n throw new AgentError(\"INVALID_CONFIG\", message);\n}\n\nfunction schemaError(location: string, message: string, file?: string, code = \"INVALID_CONFIG\"): never {\n const settings = file === undefined\n ? \"Personal access settings\"\n : `Personal access settings at ${quoteDiagnosticPath(file)}`;\n throw new AgentError(code, `${settings} are invalid at ${location}: ${message}`);\n}\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction parseConnectionAt(value: unknown, location: string, file?: string, harness?: HarnessKind): AccessConnection {\n if (!record(value)) schemaError(location, \"Connection must be an object.\", file);\n if (![\"subscription\", \"api-key\", \"vercel-api-key\", \"vercel-oidc\"].includes(value.type as string)) schemaError(`${location}.type`, \"Unknown access connection type.\", file);\n const allowed = value.type === \"subscription\" ? [\"type\", \"provider\"] : [\"type\", \"env\", \"envFile\", ...(value.type === \"api-key\" ? [\"provider\", \"baseUrl\", \"wireApi\", \"apiVersion\", \"wireModel\"] : value.type === \"vercel-oidc\" ? [\"project\"] : [])];\n if (Object.keys(value).some((key) => !allowed.includes(key))) schemaError(location, \"Unknown access connection field; secrets must be supplied through environment references.\", file);\n if (value.env !== undefined && (typeof value.env !== \"string\" || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(value.env))) schemaError(`${location}.env`, \"Invalid credential variable name.\", file);\n for (const field of [\"envFile\", \"project\", \"provider\", \"baseUrl\", \"apiVersion\", \"wireModel\"]) {\n if (value[field] !== undefined && (typeof value[field] !== \"string\" || !value[field].trim())) schemaError(`${location}.${field}`, field === \"envFile\" || field === \"project\" ? \"Value must be a nonempty path.\" : \"Value must be a nonempty string.\", file);\n }\n if (value.wireApi !== undefined && ![\"completions\", \"responses\"].includes(value.wireApi as string)) schemaError(`${location}.wireApi`, \"Invalid wire API selection.\", file);\n if (value.baseUrl !== undefined) validateBaseUrl(value.baseUrl as string, `${location}.baseUrl`, file);\n if (harness) validateHarnessConnection(value as AccessConnection, harness, location, file);\n return value as AccessConnection;\n}\n\nfunction validateBaseUrl(value: string, location: string, file?: string): void {\n let url: URL;\n try { url = new URL(value); } catch { return schemaError(location, \"baseUrl must be an absolute HTTP or HTTPS URL without credentials, query, or fragment.\", file); }\n if (!/^https?:\\/\\//iu.test(value) || value.trim() !== value || /[\\s?#\\\\]/u.test(value)\n || ![\"http:\", \"https:\"].includes(url.protocol) || !url.hostname || url.username || url.password\n || /^https?:\\/\\/[^/]*@/iu.test(value)) {\n schemaError(location, \"baseUrl must be an absolute HTTP or HTTPS URL without credentials, query, or fragment.\", file);\n }\n}\n\nfunction validateHarnessConnection(connection: AccessConnection, kind: HarnessKind, location: string, file?: string): void {\n if (connection.type === \"vercel-api-key\" || connection.type === \"vercel-oidc\") {\n if (kind === \"cursor\") schemaError(`${location}.type`, `cursor does not support ${connection.type} access.`, file, \"UNSUPPORTED_OPTION\");\n return;\n }\n if (connection.type === \"subscription\") {\n const providers = kind === \"fx\" ? [\"gateway\", \"codex\", \"grok\"]\n : kind === \"opencode\" ? [\"openai\", \"github-copilot\", \"xai\"] : undefined;\n if (providers ? !providers.includes(connection.provider ?? \"\") : connection.provider !== undefined) {\n schemaError(`${location}.provider`, `${kind} requires its documented native login provider selection.`, file);\n }\n return;\n }\n let allowed: string[] = [\"type\", \"env\", \"envFile\"];\n if (kind === \"fx\" || kind === \"opencode\") {\n if (!connection.provider) schemaError(`${location}.provider`, `${kind} direct API keys require provider and env.`, file);\n if (!connection.env) schemaError(`${location}.env`, `${kind} direct API keys require provider and env.`, file);\n allowed.push(\"provider\");\n if (kind === \"fx\" && [\"gateway\", \"codex\", \"grok\"].includes(connection.provider)) schemaError(`${location}.provider`, \"fx direct API keys require a named custom connection.\", file);\n if (kind === \"opencode\") {\n if (![\"anthropic\", \"openai\", \"google\", \"groq\", \"openrouter\", \"xai\", \"mistral\", \"cohere\", \"opencode\", \"opencode-go\"].includes(connection.provider)) schemaError(`${location}.provider`, \"Unsupported OpenCode API-key provider.\", file);\n allowed.push(\"baseUrl\");\n }\n } else if (kind === \"copilot\") {\n if (![\"github\", \"openai\", \"anthropic\", \"azure\"].includes(connection.provider ?? \"\")) schemaError(`${location}.provider`, \"Copilot API keys require a supported provider.\", file);\n allowed.push(\"provider\");\n if (connection.provider !== \"github\") allowed.push(\"baseUrl\", \"wireModel\");\n if (connection.provider === \"openai\" || connection.provider === \"azure\") allowed.push(\"wireApi\");\n if (connection.provider === \"azure\") {\n allowed.push(\"apiVersion\");\n if (!connection.baseUrl) schemaError(`${location}.baseUrl`, \"Copilot Azure API keys require baseUrl.\", file);\n }\n }\n const inapplicable = [\"provider\", \"baseUrl\", \"wireApi\", \"apiVersion\", \"wireModel\"]\n .find(field => Object.hasOwn(connection, field) && !allowed.includes(field));\n if (inapplicable) schemaError(`${location}.${inapplicable}`, `Inapplicable ${kind} API-key connection field.`, file);\n}\n\nexport function parseConnection(value: unknown, harness?: HarnessKind): AccessConnection {\n return parseConnectionAt(value, \"connection\", undefined, harness);\n}\n\nfunction parseAccessAt(value: unknown, file?: string): AccessConfig {\n if (!record(value) || Object.keys(value).some((key) => key !== \"access\")) schemaError(\"root object\", \"Expected only an optional access map.\", file);\n if (value.access === undefined) return {};\n if (!record(value.access)) schemaError(\"access\", \"Value must be an object.\", file);\n for (const [kind, connections] of Object.entries(value.access)) {\n if (![\"codex\", \"claudeCode\", \"fx\", \"opencode\", \"copilot\", \"cursor\"].includes(kind)) schemaError(\"access\", \"Unsupported harness entry.\", file);\n if (!Array.isArray(connections)) schemaError(`access.${kind}`, \"Harness access selection must be an array.\", file);\n connections.forEach((connection, index) => parseConnectionAt(connection, `access.${kind}[${index}]`, file, kind as HarnessKind));\n }\n return value as AccessConfig;\n}\n\nexport function parseAccess(value: unknown): AccessConfig {\n return parseAccessAt(value);\n}\n\nasync function ensureExcluded(mainRoot: string, file: string): Promise<void> {\n try { await git(mainRoot, [\"rev-parse\", \"--git-dir\"]); }\n catch (error) {\n if (error instanceof Error && error.message.includes(\"not a git repository\")) return;\n settingsFileError(file, \"Cannot inspect Git configuration for personal settings\");\n }\n let tracked = false;\n try { tracked = !!await git(mainRoot, [\"ls-files\", \"--\", \".subharness/agents.local.json\"]); }\n catch { settingsFileError(file, \"Cannot inspect whether personal access settings are tracked by Git\"); }\n if (tracked) settingsFileError(file, \"Personal access settings are tracked. Remove .subharness/agents.local.json from the Git index before using it\");\n const exclude = await git(mainRoot, [\"rev-parse\", \"--path-format=absolute\", \"--git-path\", \"info/exclude\"]);\n let contents = \"\";\n try { contents = await readFile(exclude, \"utf8\"); }\n catch (error) { if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") settingsFileError(file, \"Cannot read Git's local exclude file\"); }\n const pattern = \"/.subharness/agents.local.json\";\n if (!contents.split(/\\r?\\n/).includes(pattern)) {\n await mkdir(dirname(exclude), { recursive: true });\n await appendFile(exclude, `${contents.endsWith(\"\\n\") || !contents ? \"\" : \"\\n\"}${pattern}\\n`);\n }\n}\n\nfunction settingsFileError(file: string, message: string): never {\n configError(`${message}. Personal access settings file: ${quoteDiagnosticPath(file)}.`);\n}\n\nexport async function loadAccess(cwd: string): Promise<AccessConfig> {\n const { mainRoot } = await resolveProject(cwd);\n const file = join(mainRoot, \".subharness\", \"agents.local.json\");\n let contents: string;\n try { contents = await readFile(file, \"utf8\"); }\n catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n const settings: AccessConfig = {};\n const legacyFile = join(mainRoot, \".agents\", \"agents.local.json\");\n let legacyEntry: string | undefined;\n try { await lstat(legacyFile); legacyEntry = legacyFile; }\n catch { /* Legacy inspection must not replace the original startup error. */ }\n recordAccessProvenance(settings, {file, present: false, ...(legacyEntry ? {legacyFile: legacyEntry} : {})});\n return settings;\n }\n settingsFileError(file, \"Cannot read personal settings\");\n }\n await ensureExcluded(mainRoot, file);\n let value: unknown;\n try { value = JSON.parse(contents); }\n catch { settingsFileError(file, \"Invalid JSON in personal settings\"); }\n const settings = parseAccessAt(value, file);\n recordAccessProvenance(settings, {file, present: true});\n return settings;\n}\n"]}
|
package/dist/config/loader.js
CHANGED
|
@@ -13,6 +13,7 @@ const safeDiagnostics = new Set([
|
|
|
13
13
|
"Names must start with a letter and contain at most 64 letters, digits, underscores, or hyphens.",
|
|
14
14
|
"fast must be a boolean.", "Unsupported harness kind.", "At least one harness is required.",
|
|
15
15
|
"Claude effort must be low, medium, high, xhigh, or max.",
|
|
16
|
+
"Cursor sandboxMode must be enabled or disabled.",
|
|
16
17
|
"Subagent definitions cannot contain recursive references.",
|
|
17
18
|
"Tools require a Zod 4 object schema.", "Tool execute must be a function.",
|
|
18
19
|
"Tool input schema cannot be represented as JSON Schema.",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"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","sourcesContent":["import { readdir } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { tsImport } from \"tsx/esm/api\";\nimport { AgentError } from \"../errors.js\";\nimport { agent } from \"../sdk/definitions.js\";\nimport type { AgentDefinition } from \"../sdk/types.js\";\nimport { resolveProject } from \"./project.js\";\n\nexport interface CatalogEntry {\n id: string;\n name: string;\n description: string;\n scope: \"repo\" | \"global\";\n file: string;\n definition: AgentDefinition;\n}\n\n// Only fixed SDK diagnostics may cross the module-evaluation boundary.\n// User exceptions can contain credential values, including exceptions named AgentError.\nconst safeDiagnostics = new Set([\n \"Expected a configuration object.\", \"Unknown configuration field.\",\n \"Names must start with a letter and contain at most 64 letters, digits, underscores, or hyphens.\",\n \"fast must be a boolean.\", \"Unsupported harness kind.\", \"At least one harness is required.\",\n \"Claude effort must be low, medium, high, xhigh, or max.\",\n \"Subagent definitions cannot contain recursive references.\",\n \"Tools require a Zod 4 object schema.\", \"Tool execute must be a function.\",\n \"Tool input schema cannot be represented as JSON Schema.\",\n ...[\"Model\", \"Effort\", \"Description\", \"Instructions\", \"Tool description\"].map(label => `${label} must be a nonempty string.`),\n]);\n\nexport async function loadDefinition(file: string, subagents: string[] = []): Promise<AgentDefinition> {\n let definition: AgentDefinition;\n try {\n const url = pathToFileURL(resolve(file));\n url.searchParams.set(\"load\", crypto.randomUUID());\n const loaded = await tsImport(url.href, import.meta.url);\n const exported = loaded.default?.__esModule ? loaded.default.default : loaded.default;\n definition = agent(exported);\n } catch (error) {\n const reason = error instanceof Error && safeDiagnostics.has(error.message)\n && (error as AgentError).code === \"INVALID_DEFINITION\" ? error.message\n : \"Definition could not be loaded. Check its imports, dependencies, and module initialization.\";\n throw new AgentError(\"INVALID_DEFINITION\", `${file}: ${reason}`);\n }\n for (const name of subagents) {\n const children = definition.subagents ?? {};\n const child = Object.hasOwn(children, name) ? children[name] : undefined;\n if (!child) throw new AgentError(\"INVALID_DEFINITION\", `${file}: Subagent '${name}' is not declared.`);\n definition = child;\n }\n return definition;\n}\n\nasync function files(directory: string): Promise<string[]> {\n let entries;\n try { entries = await readdir(directory, { withFileTypes: true }); }\n catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n throw new AgentError(\"INVALID_CONFIG\", `Cannot read agent directory: ${directory}`);\n }\n const found: string[] = [];\n for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {\n const file = join(directory, entry.name);\n if (entry.isDirectory()) found.push(...await files(file));\n else if (entry.isFile() && entry.name.endsWith(\".ts\") && !entry.name.endsWith(\".d.ts\")) found.push(file);\n }\n return found;\n}\n\nexport async function discover(cwd: string, options: { home?: string } = {}): Promise<CatalogEntry[]> {\n const { root } = await resolveProject(cwd);\n const entries: CatalogEntry[] = [];\n for (const [scope, base] of [[\"repo\", root], [\"global\", options.home ?? homedir()]] as const) {\n const names = new Set<string>();\n for (const file of await files(join(base, \".subharness\", \"agents\"))) {\n const definition = await loadDefinition(file);\n if (names.has(definition.name)) throw new AgentError(\"INVALID_DEFINITION\", `${file}: Duplicate agent name '${definition.name}' in ${scope} scope.`);\n names.add(definition.name);\n entries.push({ id: `${scope}:${definition.name}`, name: definition.name, description: definition.description, scope, file, definition });\n }\n }\n return entries;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"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","sourcesContent":["import { readdir } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { tsImport } from \"tsx/esm/api\";\nimport { AgentError } from \"../errors.js\";\nimport { agent } from \"../sdk/definitions.js\";\nimport type { AgentDefinition } from \"../sdk/types.js\";\nimport { resolveProject } from \"./project.js\";\n\nexport interface CatalogEntry {\n id: string;\n name: string;\n description: string;\n scope: \"repo\" | \"global\";\n file: string;\n definition: AgentDefinition;\n}\n\n// Only fixed SDK diagnostics may cross the module-evaluation boundary.\n// User exceptions can contain credential values, including exceptions named AgentError.\nconst safeDiagnostics = new Set([\n \"Expected a configuration object.\", \"Unknown configuration field.\",\n \"Names must start with a letter and contain at most 64 letters, digits, underscores, or hyphens.\",\n \"fast must be a boolean.\", \"Unsupported harness kind.\", \"At least one harness is required.\",\n \"Claude effort must be low, medium, high, xhigh, or max.\",\n \"Cursor sandboxMode must be enabled or disabled.\",\n \"Subagent definitions cannot contain recursive references.\",\n \"Tools require a Zod 4 object schema.\", \"Tool execute must be a function.\",\n \"Tool input schema cannot be represented as JSON Schema.\",\n ...[\"Model\", \"Effort\", \"Description\", \"Instructions\", \"Tool description\"].map(label => `${label} must be a nonempty string.`),\n]);\n\nexport async function loadDefinition(file: string, subagents: string[] = []): Promise<AgentDefinition> {\n let definition: AgentDefinition;\n try {\n const url = pathToFileURL(resolve(file));\n url.searchParams.set(\"load\", crypto.randomUUID());\n const loaded = await tsImport(url.href, import.meta.url);\n const exported = loaded.default?.__esModule ? loaded.default.default : loaded.default;\n definition = agent(exported);\n } catch (error) {\n const reason = error instanceof Error && safeDiagnostics.has(error.message)\n && (error as AgentError).code === \"INVALID_DEFINITION\" ? error.message\n : \"Definition could not be loaded. Check its imports, dependencies, and module initialization.\";\n throw new AgentError(\"INVALID_DEFINITION\", `${file}: ${reason}`);\n }\n for (const name of subagents) {\n const children = definition.subagents ?? {};\n const child = Object.hasOwn(children, name) ? children[name] : undefined;\n if (!child) throw new AgentError(\"INVALID_DEFINITION\", `${file}: Subagent '${name}' is not declared.`);\n definition = child;\n }\n return definition;\n}\n\nasync function files(directory: string): Promise<string[]> {\n let entries;\n try { entries = await readdir(directory, { withFileTypes: true }); }\n catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n throw new AgentError(\"INVALID_CONFIG\", `Cannot read agent directory: ${directory}`);\n }\n const found: string[] = [];\n for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {\n const file = join(directory, entry.name);\n if (entry.isDirectory()) found.push(...await files(file));\n else if (entry.isFile() && entry.name.endsWith(\".ts\") && !entry.name.endsWith(\".d.ts\")) found.push(file);\n }\n return found;\n}\n\nexport async function discover(cwd: string, options: { home?: string } = {}): Promise<CatalogEntry[]> {\n const { root } = await resolveProject(cwd);\n const entries: CatalogEntry[] = [];\n for (const [scope, base] of [[\"repo\", root], [\"global\", options.home ?? homedir()]] as const) {\n const names = new Set<string>();\n for (const file of await files(join(base, \".subharness\", \"agents\"))) {\n const definition = await loadDefinition(file);\n if (names.has(definition.name)) throw new AgentError(\"INVALID_DEFINITION\", `${file}: Duplicate agent name '${definition.name}' in ${scope} scope.`);\n names.add(definition.name);\n entries.push({ id: `${scope}:${definition.name}`, name: definition.name, description: definition.description, scope, file, definition });\n }\n }\n return entries;\n}\n"]}
|
package/dist/config/oidc.js
CHANGED
|
@@ -44,8 +44,10 @@ export async function validateOidc(token, mainRoot, project, env) {
|
|
|
44
44
|
|| (claims.nbf !== undefined && (typeof claims.nbf !== "number" || !Number.isFinite(claims.nbf)))) {
|
|
45
45
|
configError("Configured OIDC token has invalid validity claims.");
|
|
46
46
|
}
|
|
47
|
-
if (claims.exp <= now
|
|
48
|
-
configError("Configured OIDC token
|
|
47
|
+
if (claims.exp <= now)
|
|
48
|
+
configError("Configured OIDC token has expired; refresh the configured credential source.");
|
|
49
|
+
if (claims.nbf !== undefined && claims.nbf > now)
|
|
50
|
+
configError("Configured OIDC token is not yet valid; check the system clock or wait until validity begins.");
|
|
49
51
|
const expected = await projectIdentity(mainRoot, project, env);
|
|
50
52
|
if (claims.project_id !== expected.projectId || claims.owner_id !== expected.orgId)
|
|
51
53
|
configError("Configured OIDC token does not match the selected Vercel project and organization.");
|
package/dist/config/oidc.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oidc.js","sourceRoot":"","sources":["../../src/config/oidc.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"oidc.js","sourceRoot":"","sources":["../../src/config/oidc.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { configError } from \"./access.js\";\n\ninterface ProjectIdentity { projectId: string; orgId: string }\n\nasync function projectIdentity(mainRoot: string, project: string | undefined, env: NodeJS.ProcessEnv): Promise<ProjectIdentity> {\n let content: string;\n try { content = await readFile(resolve(mainRoot, project ?? \".\", \".vercel/project.json\"), \"utf8\"); }\n catch (error) {\n if (project === undefined && (error as NodeJS.ErrnoException).code === \"ENOENT\" && env.VERCEL_PROJECT_ID && env.VERCEL_ORG_ID) {\n return { projectId: env.VERCEL_PROJECT_ID, orgId: env.VERCEL_ORG_ID };\n }\n configError(\"Selected OIDC project requires accessible .vercel/project.json linkage.\");\n }\n let identity;\n try { identity = JSON.parse(content); }\n catch { configError(\"Selected Vercel project linkage is not valid JSON.\"); }\n if (typeof identity?.projectId !== \"string\" || !identity.projectId || typeof identity.orgId !== \"string\" || !identity.orgId) {\n configError(\"Selected Vercel project linkage requires projectId and orgId.\");\n }\n return identity;\n}\n\nexport async function validateOidc(token: string, mainRoot: string, project: string | undefined, env: NodeJS.ProcessEnv): Promise<void> {\n const parts = token.split(\".\");\n if (parts.length !== 3 || parts.some((part) => !/^[A-Za-z0-9_-]+$/.test(part))) configError(\"Configured OIDC token is malformed.\");\n let claims;\n try {\n const header = JSON.parse(Buffer.from(parts[0]!, \"base64url\").toString(\"utf8\"));\n if (!header || typeof header !== \"object\" || Array.isArray(header)) throw new Error();\n claims = JSON.parse(Buffer.from(parts[1]!, \"base64url\").toString(\"utf8\"));\n } catch { configError(\"Configured OIDC token is malformed.\"); }\n const now = Date.now() / 1000;\n if (!claims || typeof claims !== \"object\" || Array.isArray(claims)\n || typeof claims.exp !== \"number\" || !Number.isFinite(claims.exp)\n || (claims.nbf !== undefined && (typeof claims.nbf !== \"number\" || !Number.isFinite(claims.nbf)))) {\n configError(\"Configured OIDC token has invalid validity claims.\");\n }\n if (claims.exp <= now) configError(\"Configured OIDC token has expired; refresh the configured credential source.\");\n if (claims.nbf !== undefined && claims.nbf > now) configError(\"Configured OIDC token is not yet valid; check the system clock or wait until validity begins.\");\n const expected = await projectIdentity(mainRoot, project, env);\n if (claims.project_id !== expected.projectId || claims.owner_id !== expected.orgId) configError(\"Configured OIDC token does not match the selected Vercel project and organization.\");\n}\n"]}
|
package/dist/config/project.js
CHANGED
|
@@ -2,6 +2,7 @@ import { execFile } from "node:child_process";
|
|
|
2
2
|
import { realpath, stat } from "node:fs/promises";
|
|
3
3
|
import { promisify } from "node:util";
|
|
4
4
|
import { AgentError } from "../errors.js";
|
|
5
|
+
import { quoteDiagnosticPath } from "./access-provenance.js";
|
|
5
6
|
const execute = promisify(execFile);
|
|
6
7
|
// These variables describe a caller's repository, not the explicit execution directory.
|
|
7
8
|
// Keep normal user/system Git configuration and leave the caller's environment untouched.
|
|
@@ -30,7 +31,7 @@ export async function resolveProject(cwd) {
|
|
|
30
31
|
throw new Error();
|
|
31
32
|
}
|
|
32
33
|
catch {
|
|
33
|
-
throw new AgentError("INVALID_CONFIG", `Execution directory is not accessible: ${cwd}`);
|
|
34
|
+
throw new AgentError("INVALID_CONFIG", `Execution directory is not accessible: ${quoteDiagnosticPath(cwd)}`);
|
|
34
35
|
}
|
|
35
36
|
try {
|
|
36
37
|
if ((await git(directory, ["rev-parse", "--is-bare-repository"])) === "true") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/config/project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/config/project.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile } from \"node:child_process\";\nimport { realpath, stat } from \"node:fs/promises\";\nimport { promisify } from \"node:util\";\nimport { AgentError } from \"../errors.js\";\nimport { quoteDiagnosticPath } from \"./access-provenance.js\";\n\nconst execute = promisify(execFile);\n\n// These variables describe a caller's repository, not the explicit execution directory.\n// Keep normal user/system Git configuration and leave the caller's environment untouched.\nconst repositoryVariables = new Set([\n \"GIT_DIR\", \"GIT_WORK_TREE\", \"GIT_COMMON_DIR\", \"GIT_IMPLICIT_WORK_TREE\",\n \"GIT_INDEX_FILE\", \"GIT_OBJECT_DIRECTORY\", \"GIT_ALTERNATE_OBJECT_DIRECTORIES\",\n \"GIT_GRAFT_FILE\", \"GIT_SHALLOW_FILE\", \"GIT_NAMESPACE\", \"GIT_QUARANTINE_PATH\",\n \"GIT_PREFIX\", \"GIT_INTERNAL_SUPER_PREFIX\", \"GIT_NO_REPLACE_OBJECTS\", \"GIT_REPLACE_REF_BASE\",\n \"GIT_CEILING_DIRECTORIES\", \"GIT_DISCOVERY_ACROSS_FILESYSTEM\", \"GIT_REFERENCE_BACKEND\",\n \"GIT_CONFIG\", \"GIT_CONFIG_PARAMETERS\", \"GIT_CONFIG_COUNT\",\n]);\n\nexport async function git(cwd: string, args: string[]): Promise<string> {\n const env = { ...process.env };\n for (const key of Object.keys(env)) {\n if (repositoryVariables.has(key) || /^GIT_CONFIG_(KEY|VALUE)_\\d+$/.test(key)) delete env[key];\n }\n const { stdout } = await execute(\"git\", [\"-C\", cwd, ...args], { env, maxBuffer: 1024 * 1024 });\n return stdout.trim();\n}\n\nexport async function resolveProject(cwd: string): Promise<{ root: string; mainRoot: string }> {\n let directory: string;\n try {\n directory = await realpath(cwd);\n if (!(await stat(directory)).isDirectory()) throw new Error();\n } catch {\n throw new AgentError(\"INVALID_CONFIG\", `Execution directory is not accessible: ${quoteDiagnosticPath(cwd)}`);\n }\n try {\n if ((await git(directory, [\"rev-parse\", \"--is-bare-repository\"])) === \"true\") {\n throw new AgentError(\"INVALID_CONFIG\", \"Bare repositories are unsupported execution directories.\");\n }\n const root = await git(directory, [\"rev-parse\", \"--show-toplevel\"]);\n const worktrees = await git(directory, [\"worktree\", \"list\", \"--porcelain\", \"-z\"]);\n const first = worktrees.split(\"\\0\").find((line) => line.startsWith(\"worktree \"));\n if (!first) throw new Error();\n const mainRoot = await realpath(first.slice(\"worktree \".length));\n return { root: await realpath(root), mainRoot };\n } catch (error) {\n if (error instanceof AgentError) throw error;\n const message = error instanceof Error ? error.message : \"\";\n if (message.includes(\"not a git repository\")) return { root: directory, mainRoot: directory };\n throw new AgentError(\"INVALID_CONFIG\", \"The Git project or its main checkout cannot be accessed.\");\n }\n}\n"]}
|
|
@@ -3,21 +3,17 @@ import { resolve } from "node:path";
|
|
|
3
3
|
import { parseEnv } from "node:util";
|
|
4
4
|
import { AgentError } from "../errors.js";
|
|
5
5
|
import { configError, parseConnection } from "./access.js";
|
|
6
|
+
import { quoteDiagnosticPath } from "./access-provenance.js";
|
|
6
7
|
import { resolveProject } from "./project.js";
|
|
7
8
|
import { validateOidc } from "./oidc.js";
|
|
8
9
|
export async function resolveAccess(connection, harness, cwd, env = process.env) {
|
|
9
|
-
parseConnection(connection);
|
|
10
10
|
const kind = typeof harness === "string" ? harness : harness.kind;
|
|
11
|
+
parseConnection(connection, kind);
|
|
11
12
|
if (connection.type === "subscription") {
|
|
12
|
-
|
|
13
|
-
throw new AgentError("ACCESS_UNAVAILABLE", "fx does not support subscription access.");
|
|
14
|
-
return { type: "subscription" };
|
|
15
|
-
}
|
|
16
|
-
if (kind === "fx" && connection.type === "api-key") {
|
|
17
|
-
throw new AgentError("UNSUPPORTED_OPTION", "fx does not support direct provider API keys.");
|
|
13
|
+
return { ...connection };
|
|
18
14
|
}
|
|
19
15
|
const variable = connection.env ?? (connection.type === "api-key"
|
|
20
|
-
? kind
|
|
16
|
+
? defaultApiKeyVariable(kind, connection.provider)
|
|
21
17
|
: connection.type === "vercel-api-key" ? "AI_GATEWAY_API_KEY" : "VERCEL_OIDC_TOKEN");
|
|
22
18
|
const { mainRoot } = await resolveProject(cwd);
|
|
23
19
|
let token;
|
|
@@ -27,7 +23,7 @@ export async function resolveAccess(connection, harness, cwd, env = process.env)
|
|
|
27
23
|
}
|
|
28
24
|
catch (error) {
|
|
29
25
|
if (error.code === "ENOENT")
|
|
30
|
-
throw new AgentError("ACCESS_UNAVAILABLE", `Credential file is missing: ${connection.envFile}`);
|
|
26
|
+
throw new AgentError("ACCESS_UNAVAILABLE", `Credential file is missing: ${quoteDiagnosticPath(connection.envFile)}`);
|
|
31
27
|
configError(`Cannot read credential variable ${variable} from its configured file.`);
|
|
32
28
|
}
|
|
33
29
|
}
|
|
@@ -37,6 +33,24 @@ export async function resolveAccess(connection, harness, cwd, env = process.env)
|
|
|
37
33
|
throw new AgentError("ACCESS_UNAVAILABLE", `Credential variable ${variable} is missing or empty.`);
|
|
38
34
|
if (connection.type === "vercel-oidc")
|
|
39
35
|
await validateOidc(token, mainRoot, connection.project, env);
|
|
40
|
-
|
|
36
|
+
const access = { type: connection.type, token };
|
|
37
|
+
if (connection.type === "api-key") {
|
|
38
|
+
for (const field of ["provider", "baseUrl", "wireApi", "apiVersion", "wireModel"]) {
|
|
39
|
+
if (connection[field] !== undefined)
|
|
40
|
+
Object.assign(access, { [field]: connection[field] });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return access;
|
|
44
|
+
}
|
|
45
|
+
function defaultApiKeyVariable(kind, provider) {
|
|
46
|
+
if (kind === "copilot")
|
|
47
|
+
return ({ github: "COPILOT_GITHUB_TOKEN", openai: "OPENAI_API_KEY", anthropic: "ANTHROPIC_API_KEY", azure: "AZURE_OPENAI_API_KEY" })[provider];
|
|
48
|
+
if (kind === "codex")
|
|
49
|
+
return "OPENAI_API_KEY";
|
|
50
|
+
if (kind === "cursor")
|
|
51
|
+
return "CURSOR_API_KEY";
|
|
52
|
+
if (kind === "claudeCode")
|
|
53
|
+
return "ANTHROPIC_API_KEY";
|
|
54
|
+
return configError(`${kind} direct API keys require env.`);
|
|
41
55
|
}
|
|
42
56
|
//# sourceMappingURL=resolve-access.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-access.js","sourceRoot":"","sources":["../../src/config/resolve-access.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAyB,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,UAA4B,EAC5B,OAAoC,EACpC,GAAW,EACX,GAAG,GAAsB,OAAO,CAAC,GAAG;IAEpC,
|
|
1
|
+
{"version":3,"file":"resolve-access.js","sourceRoot":"","sources":["../../src/config/resolve-access.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { parseEnv } from \"node:util\";\nimport type { ResolvedAccess } from \"../adapters/types.js\";\nimport { AgentError } from \"../errors.js\";\nimport type { HarnessConfig, HarnessKind } from \"../sdk/types.js\";\nimport { type AccessConnection, configError, parseConnection } from \"./access.js\";\nimport { quoteDiagnosticPath } from \"./access-provenance.js\";\nimport { resolveProject } from \"./project.js\";\nimport { validateOidc } from \"./oidc.js\";\n\nexport async function resolveAccess(\n connection: AccessConnection,\n harness: HarnessKind | HarnessConfig,\n cwd: string,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<ResolvedAccess> {\n const kind = typeof harness === \"string\" ? harness : harness.kind;\n parseConnection(connection, kind);\n if (connection.type === \"subscription\") {\n return { ...connection };\n }\n const variable = connection.env ?? (connection.type === \"api-key\"\n ? defaultApiKeyVariable(kind, connection.provider)\n : connection.type === \"vercel-api-key\" ? \"AI_GATEWAY_API_KEY\" : \"VERCEL_OIDC_TOKEN\");\n const { mainRoot } = await resolveProject(cwd);\n let token: string | undefined;\n if (connection.envFile !== undefined) {\n try { token = parseEnv(await readFile(resolve(mainRoot, connection.envFile), \"utf8\"))[variable]; }\n catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") throw new AgentError(\"ACCESS_UNAVAILABLE\", `Credential file is missing: ${quoteDiagnosticPath(connection.envFile)}`);\n configError(`Cannot read credential variable ${variable} from its configured file.`);\n }\n } else token = env[variable];\n if (!token?.trim()) throw new AgentError(\"ACCESS_UNAVAILABLE\", `Credential variable ${variable} is missing or empty.`);\n if (connection.type === \"vercel-oidc\") await validateOidc(token, mainRoot, connection.project, env);\n const access: ResolvedAccess = { type: connection.type, token };\n if (connection.type === \"api-key\") {\n for (const field of [\"provider\", \"baseUrl\", \"wireApi\", \"apiVersion\", \"wireModel\"] as const) {\n if (connection[field] !== undefined) Object.assign(access, { [field]: connection[field] });\n }\n }\n return access;\n}\n\nfunction defaultApiKeyVariable(kind: HarnessKind, provider?: string): string {\n if (kind === \"copilot\") return ({ github: \"COPILOT_GITHUB_TOKEN\", openai: \"OPENAI_API_KEY\", anthropic: \"ANTHROPIC_API_KEY\", azure: \"AZURE_OPENAI_API_KEY\" })[provider as \"github\" | \"openai\" | \"anthropic\" | \"azure\"];\n if (kind === \"codex\") return \"OPENAI_API_KEY\";\n if (kind === \"cursor\") return \"CURSOR_API_KEY\";\n if (kind === \"claudeCode\") return \"ANTHROPIC_API_KEY\";\n return configError(`${kind} direct API keys require env.`);\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { agent, codex, claudeCode, fx } from "./sdk/definitions.js";
|
|
1
|
+
export { agent, codex, claudeCode, fx, opencode, copilot, cursor } from "./sdk/definitions.js";
|
|
2
2
|
export { tool, toolResult } from "./sdk/tools.js";
|
|
3
3
|
export type { ToolContent, ToolResult } from "./sdk/tools.js";
|
|
4
|
-
export type { AgentDefinition, ClaudeCodeConfig, ClaudeCodeOptions, CodexConfig, CodexOptions, FxConfig, FxOptions, HarnessConfig, HarnessKind, ToolDefinition, } from "./sdk/types.js";
|
|
4
|
+
export type { AgentDefinition, ClaudeCodeConfig, ClaudeCodeOptions, CodexConfig, CodexOptions, FxConfig, FxOptions, OpencodeConfig, OpencodeOptions, CopilotConfig, CopilotOptions, CursorConfig, CursorOptions, HarnessConfig, HarnessKind, ToolDefinition, } from "./sdk/types.js";
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC","sourcesContent":["export { agent, codex, claudeCode, fx, opencode, copilot, cursor } from \"./sdk/definitions.js\";\nexport { tool, toolResult } from \"./sdk/tools.js\";\nexport type { ToolContent, ToolResult } from \"./sdk/tools.js\";\nexport type {\n AgentDefinition,\n ClaudeCodeConfig,\n ClaudeCodeOptions,\n CodexConfig,\n CodexOptions,\n FxConfig,\n FxOptions,\n OpencodeConfig,\n OpencodeOptions,\n CopilotConfig,\n CopilotOptions,\n CursorConfig,\n CursorOptions,\n HarnessConfig,\n HarnessKind,\n ToolDefinition,\n} from \"./sdk/types.js\";\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { constants } from "node:os";
|
|
2
|
+
/** Formats only bounded, observed child-process termination metadata. */
|
|
3
|
+
export function processExitDescription(code, signal) {
|
|
4
|
+
if (typeof signal === "string" && Object.hasOwn(constants.signals, signal)) {
|
|
5
|
+
return ` (signal ${signal})`;
|
|
6
|
+
}
|
|
7
|
+
return typeof code === "number" && Number.isSafeInteger(code)
|
|
8
|
+
? ` (exit code ${code})`
|
|
9
|
+
: "";
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=process-diagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-diagnostics.js","sourceRoot":"","sources":["../src/process-diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC,yEAAyE;AACzE,MAAM,UAAU,sBAAsB,CAAC,IAAa,EAAE,MAAe;IACnE,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC;QAC3E,OAAO,YAAY,MAAM,GAAG,CAAC;IAC/B,CAAC;IACD,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;QAC3D,CAAC,CAAC,eAAe,IAAI,GAAG;QACxB,CAAC,CAAC,EAAE,CAAC;AACT,CAAC","sourcesContent":["import { constants } from \"node:os\";\n\n/** Formats only bounded, observed child-process termination metadata. */\nexport function processExitDescription(code: unknown, signal: unknown): string {\n if (typeof signal === \"string\" && Object.hasOwn(constants.signals, signal)) {\n return ` (signal ${signal})`;\n }\n return typeof code === \"number\" && Number.isSafeInteger(code)\n ? ` (exit code ${code})`\n : \"\";\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { NativeSession } from "../adapters/types.js";
|
|
2
|
+
import { AgentError } from "../errors.js";
|
|
3
|
+
export declare function withAccessContext(error: AgentError, context: string): AgentError;
|
|
4
|
+
export declare function withSessionAccessContext(native: NativeSession, context: string): NativeSession;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { AgentError } from "../errors.js";
|
|
2
|
+
export function withAccessContext(error, context) {
|
|
3
|
+
return new AgentError(error.code, `${error.message}\n${context}`);
|
|
4
|
+
}
|
|
5
|
+
async function sessionCall(operation, context) {
|
|
6
|
+
try {
|
|
7
|
+
return await operation();
|
|
8
|
+
}
|
|
9
|
+
catch (error) {
|
|
10
|
+
if (error instanceof AgentError && error.code === "INVALID_CONFIG") {
|
|
11
|
+
throw withAccessContext(error, context);
|
|
12
|
+
}
|
|
13
|
+
throw error;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function withSessionAccessContext(native, context) {
|
|
17
|
+
return {
|
|
18
|
+
turn: prompt => sessionCall(() => native.turn(prompt), context),
|
|
19
|
+
steer: prompt => sessionCall(() => native.steer(prompt), context),
|
|
20
|
+
interrupt: () => sessionCall(() => native.interrupt(), context),
|
|
21
|
+
resume: () => sessionCall(() => native.resume(), context),
|
|
22
|
+
close: () => sessionCall(() => native.close(), context),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=access-errors.js.map
|