@namzu/sdk 5.1.0 → 5.2.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/CHANGELOG.md +361 -0
- package/dist/agents/__tests__/run-agent-forwarding.test.d.ts +2 -0
- package/dist/agents/__tests__/run-agent-forwarding.test.d.ts.map +1 -0
- package/dist/agents/__tests__/run-agent-forwarding.test.js +76 -0
- package/dist/agents/__tests__/run-agent-forwarding.test.js.map +1 -0
- package/dist/agents/__tests__/run-completed-stop-reason.test.d.ts +2 -0
- package/dist/agents/__tests__/run-completed-stop-reason.test.d.ts.map +1 -0
- package/dist/agents/__tests__/run-completed-stop-reason.test.js +50 -0
- package/dist/agents/__tests__/run-completed-stop-reason.test.js.map +1 -0
- package/dist/agents/index.d.ts +1 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +4 -0
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/runAgent.d.ts +34 -0
- package/dist/agents/runAgent.d.ts.map +1 -1
- package/dist/agents/runAgent.js +5 -3
- package/dist/agents/runAgent.js.map +1 -1
- package/dist/config/runtime.d.ts +30 -30
- package/dist/constants/tools/__tests__/dangerous-patterns.test.d.ts +2 -0
- package/dist/constants/tools/__tests__/dangerous-patterns.test.d.ts.map +1 -0
- package/dist/constants/tools/__tests__/dangerous-patterns.test.js +54 -0
- package/dist/constants/tools/__tests__/dangerous-patterns.test.js.map +1 -0
- package/dist/constants/tools/index.d.ts.map +1 -1
- package/dist/constants/tools/index.js +28 -1
- package/dist/constants/tools/index.js.map +1 -1
- package/dist/contracts/a2a.d.ts +44 -44
- package/dist/directory/__tests__/derive.test.d.ts +2 -0
- package/dist/directory/__tests__/derive.test.d.ts.map +1 -0
- package/dist/directory/__tests__/derive.test.js +111 -0
- package/dist/directory/__tests__/derive.test.js.map +1 -0
- package/dist/directory/__tests__/load-diagnostics.test.d.ts +2 -0
- package/dist/directory/__tests__/load-diagnostics.test.d.ts.map +1 -0
- package/dist/directory/__tests__/load-diagnostics.test.js +106 -0
- package/dist/directory/__tests__/load-diagnostics.test.js.map +1 -0
- package/dist/directory/__tests__/load-directory.test.d.ts +2 -0
- package/dist/directory/__tests__/load-directory.test.d.ts.map +1 -0
- package/dist/directory/__tests__/load-directory.test.js +196 -0
- package/dist/directory/__tests__/load-directory.test.js.map +1 -0
- package/dist/directory/__tests__/subagents.test.d.ts +2 -0
- package/dist/directory/__tests__/subagents.test.d.ts.map +1 -0
- package/dist/directory/__tests__/subagents.test.js +117 -0
- package/dist/directory/__tests__/subagents.test.js.map +1 -0
- package/dist/directory/__tests__/supervisor-budget.test.d.ts +2 -0
- package/dist/directory/__tests__/supervisor-budget.test.d.ts.map +1 -0
- package/dist/directory/__tests__/supervisor-budget.test.js +97 -0
- package/dist/directory/__tests__/supervisor-budget.test.js.map +1 -0
- package/dist/directory/derive-supervisor.d.ts +58 -0
- package/dist/directory/derive-supervisor.d.ts.map +1 -0
- package/dist/directory/derive-supervisor.js +88 -0
- package/dist/directory/derive-supervisor.js.map +1 -0
- package/dist/directory/derive.d.ts +12 -0
- package/dist/directory/derive.d.ts.map +1 -0
- package/dist/directory/derive.js +58 -0
- package/dist/directory/derive.js.map +1 -0
- package/dist/directory/index.d.ts +7 -0
- package/dist/directory/index.d.ts.map +1 -0
- package/dist/directory/index.js +5 -0
- package/dist/directory/index.js.map +1 -0
- package/dist/directory/load.d.ts +14 -0
- package/dist/directory/load.d.ts.map +1 -0
- package/dist/directory/load.js +488 -0
- package/dist/directory/load.js.map +1 -0
- package/dist/directory/scan.d.ts +36 -0
- package/dist/directory/scan.d.ts.map +1 -0
- package/dist/directory/scan.js +136 -0
- package/dist/directory/scan.js.map +1 -0
- package/dist/directory/types.d.ts +215 -0
- package/dist/directory/types.d.ts.map +1 -0
- package/dist/directory/types.js +8 -0
- package/dist/directory/types.js.map +1 -0
- package/dist/plugin/__tests__/path-containment.test.d.ts +2 -0
- package/dist/plugin/__tests__/path-containment.test.d.ts.map +1 -0
- package/dist/plugin/__tests__/path-containment.test.js +91 -0
- package/dist/plugin/__tests__/path-containment.test.js.map +1 -0
- package/dist/plugin/lifecycle.d.ts.map +1 -1
- package/dist/plugin/lifecycle.js +3 -3
- package/dist/plugin/lifecycle.js.map +1 -1
- package/dist/plugin/loader.d.ts.map +1 -1
- package/dist/plugin/loader.js +12 -2
- package/dist/plugin/loader.js.map +1 -1
- package/dist/provider/__tests__/model-version.test.d.ts +2 -0
- package/dist/provider/__tests__/model-version.test.d.ts.map +1 -0
- package/dist/provider/__tests__/model-version.test.js +80 -0
- package/dist/provider/__tests__/model-version.test.js.map +1 -0
- package/dist/provider/__tests__/strict-schema.test.d.ts +2 -0
- package/dist/provider/__tests__/strict-schema.test.d.ts.map +1 -0
- package/dist/provider/__tests__/strict-schema.test.js +109 -0
- package/dist/provider/__tests__/strict-schema.test.js.map +1 -0
- package/dist/provider/model-version.d.ts +60 -0
- package/dist/provider/model-version.d.ts.map +1 -0
- package/dist/provider/model-version.js +64 -0
- package/dist/provider/model-version.js.map +1 -0
- package/dist/provider/strict-schema.d.ts +49 -0
- package/dist/provider/strict-schema.d.ts.map +1 -0
- package/dist/provider/strict-schema.js +112 -0
- package/dist/provider/strict-schema.js.map +1 -0
- package/dist/public-runtime.d.ts +6 -1
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +21 -1
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-types.d.ts +2 -0
- package/dist/public-types.d.ts.map +1 -1
- package/dist/registry/tool/__tests__/strict-registration.test.d.ts +2 -0
- package/dist/registry/tool/__tests__/strict-registration.test.d.ts.map +1 -0
- package/dist/registry/tool/__tests__/strict-registration.test.js +82 -0
- package/dist/registry/tool/__tests__/strict-registration.test.js.map +1 -0
- package/dist/registry/tool/execute.d.ts.map +1 -1
- package/dist/registry/tool/execute.js +16 -0
- package/dist/registry/tool/execute.js.map +1 -1
- package/dist/runtime/query/result.d.ts.map +1 -1
- package/dist/runtime/query/result.js +5 -0
- package/dist/runtime/query/result.js.map +1 -1
- package/dist/tools/builtins/__tests__/edit-insert-reachable.test.js +7 -1
- package/dist/tools/builtins/__tests__/edit-insert-reachable.test.js.map +1 -1
- package/dist/tools/builtins/__tests__/edit.test.js +1 -1
- package/dist/tools/builtins/__tests__/edit.test.js.map +1 -1
- package/dist/tools/builtins/edit.d.ts.map +1 -1
- package/dist/tools/builtins/edit.js +20 -2
- package/dist/tools/builtins/edit.js.map +1 -1
- package/dist/types/plugin/index.d.ts +4 -4
- package/dist/types/run/events.d.ts +17 -2
- package/dist/types/run/events.d.ts.map +1 -1
- package/dist/types/run/events.js.map +1 -1
- package/dist/types/verification/index.d.ts +6 -6
- package/package.json +1 -1
- package/src/agents/__tests__/run-agent-forwarding.test.ts +85 -0
- package/src/agents/__tests__/run-completed-stop-reason.test.ts +59 -0
- package/src/agents/index.ts +8 -0
- package/src/agents/runAgent.ts +30 -4
- package/src/constants/tools/__tests__/dangerous-patterns.test.ts +62 -0
- package/src/constants/tools/index.ts +28 -1
- package/src/directory/__tests__/derive.test.ts +135 -0
- package/src/directory/__tests__/load-diagnostics.test.ts +126 -0
- package/src/directory/__tests__/load-directory.test.ts +243 -0
- package/src/directory/__tests__/subagents.test.ts +155 -0
- package/src/directory/__tests__/supervisor-budget.test.ts +117 -0
- package/src/directory/derive-supervisor.ts +149 -0
- package/src/directory/derive.ts +70 -0
- package/src/directory/index.ts +27 -0
- package/src/directory/load.ts +556 -0
- package/src/directory/scan.ts +163 -0
- package/src/directory/types.ts +254 -0
- package/src/plugin/__tests__/path-containment.test.ts +107 -0
- package/src/plugin/lifecycle.ts +3 -3
- package/src/plugin/loader.ts +12 -2
- package/src/provider/__tests__/model-version.test.ts +93 -0
- package/src/provider/__tests__/strict-schema.test.ts +133 -0
- package/src/provider/model-version.ts +98 -0
- package/src/provider/strict-schema.ts +125 -0
- package/src/public-runtime.ts +31 -0
- package/src/public-types.ts +8 -0
- package/src/registry/tool/__tests__/strict-registration.test.ts +115 -0
- package/src/registry/tool/execute.ts +16 -0
- package/src/runtime/query/result.ts +5 -0
- package/src/tools/builtins/__tests__/edit-insert-reachable.test.ts +8 -2
- package/src/tools/builtins/__tests__/edit.test.ts +1 -1
- package/src/tools/builtins/edit.ts +20 -2
- package/src/types/run/events.ts +15 -2
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { pathToFileURL } from 'node:url';
|
|
3
|
+
import { loadSkill } from '../skills/loader.js';
|
|
4
|
+
import { canonicalRoot, scanSlot } from './scan.js';
|
|
5
|
+
import { ALL_SLOTS } from './types.js';
|
|
6
|
+
const DEFAULT_MODULE_TIMEOUT_MS = 10_000;
|
|
7
|
+
/**
|
|
8
|
+
* Import a module with a deadline that bounds the LOADER, not the module.
|
|
9
|
+
*
|
|
10
|
+
* `import()` cannot be cancelled. When this races out, the module is still
|
|
11
|
+
* executing: it may finish, its top-level side effects may land after
|
|
12
|
+
* `loadDirectory` has returned, and Node caches the result — so a second load in
|
|
13
|
+
* the same process can see the same file resolve instantly. That was verified
|
|
14
|
+
* rather than assumed, and it is why `'abandoned'` exists as an outcome
|
|
15
|
+
* separate from `'failed'`.
|
|
16
|
+
*/
|
|
17
|
+
async function importWithDeadline(fileUrl, importModule, timeoutMs) {
|
|
18
|
+
let timer;
|
|
19
|
+
const deadline = new Promise((resolve) => {
|
|
20
|
+
timer = setTimeout(() => resolve({ status: 'abandoned' }), timeoutMs);
|
|
21
|
+
});
|
|
22
|
+
try {
|
|
23
|
+
const result = await Promise.race([
|
|
24
|
+
importModule(fileUrl).then((module) => ({
|
|
25
|
+
status: 'loaded',
|
|
26
|
+
module,
|
|
27
|
+
})),
|
|
28
|
+
deadline,
|
|
29
|
+
]);
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
const code = err?.code;
|
|
34
|
+
return {
|
|
35
|
+
status: 'failed',
|
|
36
|
+
cause: err instanceof Error ? err.message : String(err),
|
|
37
|
+
...(typeof code === 'string' ? { code } : {}),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
if (timer)
|
|
42
|
+
clearTimeout(timer);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Translate Node's module-loading errors into something an author can act on.
|
|
47
|
+
*
|
|
48
|
+
* The codes matter more than the messages: `ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX`
|
|
49
|
+
* means the file used a construct type STRIPPING cannot express (an `enum`, a
|
|
50
|
+
* decorator, a parameter property) — stripping erases types, it does not
|
|
51
|
+
* transform code, and no flag rescues those. That is a different problem from
|
|
52
|
+
* a plain syntax error, and pointing at the wrong one costs an author an hour.
|
|
53
|
+
*
|
|
54
|
+
* That sentence was true and this function still matched on `cause`, which is
|
|
55
|
+
* `err.message` — and Node does not put the code in the message. Probed:
|
|
56
|
+
* `ERR_MODULE_NOT_FOUND` arrives as *"Cannot find module …"*, and
|
|
57
|
+
* `ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX` as *"TypeScript enum is not supported in
|
|
58
|
+
* strip-only mode"*. Neither contains its code, so every branch below was
|
|
59
|
+
* unreachable and every author got the bare message the doc-comment was
|
|
60
|
+
* explaining why not to give them. The code is read from `err.code` now, which
|
|
61
|
+
* is where it always was.
|
|
62
|
+
*/
|
|
63
|
+
function explainImportFailure(cause, code) {
|
|
64
|
+
if (code === 'ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX') {
|
|
65
|
+
return `${cause}\n\nNode strips types, it does not compile them: enums, decorators, parameter properties and runtime namespaces have no stripped form. Rewrite as plain TypeScript, or pass \`importModule\` with a transforming loader.`;
|
|
66
|
+
}
|
|
67
|
+
if (code === 'ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING') {
|
|
68
|
+
return `${cause}\n\nNode refuses to strip types from any .ts file resolved under node_modules/. If this is a workspace package, have it ship built .js.`;
|
|
69
|
+
}
|
|
70
|
+
if (code === 'ERR_MODULE_NOT_FOUND') {
|
|
71
|
+
return `${cause}\n\nRelative imports need their real extension here — write "./util.ts", not "./util". tsconfig "paths" aliases are not resolved; pass \`importModule\` if you need them.`;
|
|
72
|
+
}
|
|
73
|
+
// Node ≥20 but <22.6 has no type stripping at all, so the golden path — a
|
|
74
|
+
// `.ts` tool — dies here rather than at any of the codes above.
|
|
75
|
+
if (code === 'ERR_UNKNOWN_FILE_EXTENSION' && /\.[cm]?ts"?$/.test(cause)) {
|
|
76
|
+
return `${cause}\n\nThis Node cannot run TypeScript directly. Use Node 22.18 or newer, or pass \`importModule\` with a loader that transpiles.`;
|
|
77
|
+
}
|
|
78
|
+
return cause;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* The fields `ToolDefinition` declares without a `?`.
|
|
82
|
+
*
|
|
83
|
+
* Checking `name` and `execute` alone was not a weaker version of this check,
|
|
84
|
+
* it was a check that let the failure through and moved it: a default export
|
|
85
|
+
* with no `inputSchema` passed here, registered clean, and then died inside
|
|
86
|
+
* `toLLMTools()` reading `inputSchema._def` — a `TypeError` naming a file this
|
|
87
|
+
* loader never mentions, at a point where the author is no longer looking at
|
|
88
|
+
* their tool. A loader whose job is to report bad files must reject the ones
|
|
89
|
+
* that crash later, not only the ones that are obviously not tools.
|
|
90
|
+
*
|
|
91
|
+
* Exactly the required set, and no more. `isReadOnly`, `isDestructive` and the
|
|
92
|
+
* other `defineTool` niceties are not on the interface, so demanding them would
|
|
93
|
+
* make this loader refuse a hand-written object that satisfies the SDK's own
|
|
94
|
+
* published type — the loader overruling the SDK.
|
|
95
|
+
*/
|
|
96
|
+
function isToolDefinition(value) {
|
|
97
|
+
if (typeof value !== 'object' || value === null)
|
|
98
|
+
return false;
|
|
99
|
+
const c = value;
|
|
100
|
+
return (typeof c.name === 'string' &&
|
|
101
|
+
typeof c.description === 'string' &&
|
|
102
|
+
typeof c.execute === 'function' &&
|
|
103
|
+
typeof c.inputSchema === 'object' &&
|
|
104
|
+
c.inputSchema !== null);
|
|
105
|
+
}
|
|
106
|
+
/** The default export, tolerating a namespace that only has named exports. */
|
|
107
|
+
function defaultExport(module) {
|
|
108
|
+
if (typeof module !== 'object' || module === null)
|
|
109
|
+
return undefined;
|
|
110
|
+
return module.default;
|
|
111
|
+
}
|
|
112
|
+
function readConfig(value, diagnostics, path) {
|
|
113
|
+
if (value === undefined)
|
|
114
|
+
return {};
|
|
115
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
116
|
+
diagnostics.push({
|
|
117
|
+
code: 'invalid_config',
|
|
118
|
+
severity: 'error',
|
|
119
|
+
message: 'agent.ts must default-export a plain object.',
|
|
120
|
+
path,
|
|
121
|
+
});
|
|
122
|
+
return {};
|
|
123
|
+
}
|
|
124
|
+
// Read field by field rather than spread: an unknown key is the author's
|
|
125
|
+
// business, but a known key of the wrong type would reach `runAgent` and
|
|
126
|
+
// fail somewhere with no mention of this file.
|
|
127
|
+
const raw = value;
|
|
128
|
+
const config = {};
|
|
129
|
+
const take = (key, ok, expected) => {
|
|
130
|
+
const found = raw[key];
|
|
131
|
+
if (found === undefined)
|
|
132
|
+
return;
|
|
133
|
+
if (!ok(found)) {
|
|
134
|
+
diagnostics.push({
|
|
135
|
+
code: 'invalid_config',
|
|
136
|
+
severity: 'error',
|
|
137
|
+
message: `agent.ts: "${key}" must be a ${expected}, received ${typeof found}.`,
|
|
138
|
+
path,
|
|
139
|
+
});
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
config[key] = found;
|
|
143
|
+
};
|
|
144
|
+
const isString = (v) => typeof v === 'string';
|
|
145
|
+
// Rejects NaN and Infinity too. A budget of NaN compares false against
|
|
146
|
+
// every limit, so it would read as "no cap" rather than as a bad value.
|
|
147
|
+
const isNumber = (v) => typeof v === 'number' && Number.isFinite(v);
|
|
148
|
+
take('model', isString, 'string');
|
|
149
|
+
take('name', isString, 'string');
|
|
150
|
+
take('temperature', isNumber, 'finite number');
|
|
151
|
+
take('maxIterations', isNumber, 'finite number');
|
|
152
|
+
take('tokenBudget', isNumber, 'finite number');
|
|
153
|
+
take('timeoutMs', isNumber, 'finite number');
|
|
154
|
+
// `metadata` is typed `Record<string, string>` and was admitted on
|
|
155
|
+
// `typeof === 'object'` alone — which an array also satisfies, and which
|
|
156
|
+
// says nothing about the values. So `{ tags: ['a'] }` and `{ n: 1 }` both
|
|
157
|
+
// reached a consumer that had been promised strings, and the type was a
|
|
158
|
+
// claim this loader did not keep. Every other field here is checked; this
|
|
159
|
+
// one is the reason to check the values too, since it is the only field
|
|
160
|
+
// whose contents are forwarded verbatim to an inspector.
|
|
161
|
+
if (raw.metadata !== undefined) {
|
|
162
|
+
const m = raw.metadata;
|
|
163
|
+
if (typeof m !== 'object' || m === null || Array.isArray(m)) {
|
|
164
|
+
diagnostics.push({
|
|
165
|
+
code: 'invalid_config',
|
|
166
|
+
severity: 'error',
|
|
167
|
+
message: `agent.ts: "metadata" must be an object of string values, received ${Array.isArray(m) ? 'array' : typeof m}.`,
|
|
168
|
+
path,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
const bad = Object.entries(m).filter(([, v]) => typeof v !== 'string');
|
|
173
|
+
if (bad.length > 0) {
|
|
174
|
+
diagnostics.push({
|
|
175
|
+
code: 'invalid_config',
|
|
176
|
+
severity: 'error',
|
|
177
|
+
message: `agent.ts: "metadata" values must be strings; ${bad
|
|
178
|
+
.map(([k, v]) => `"${k}" is ${v === null ? 'null' : typeof v}`)
|
|
179
|
+
.join(', ')}.`,
|
|
180
|
+
path,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
config.metadata = m;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return config;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Read a conventional agent directory into typed, inspectable definitions.
|
|
192
|
+
*
|
|
193
|
+
* A LOADER, not a runner: it produces what is there and hands it back. Running
|
|
194
|
+
* it — a turn, a server, a schedule — is the host's job, which is what keeps
|
|
195
|
+
* this package free of any hosting model.
|
|
196
|
+
*
|
|
197
|
+
* It never throws on authored content. A broken tool, a missing file, a
|
|
198
|
+
* malformed config all come back as diagnostics, because a loader that throws
|
|
199
|
+
* on the first bad file tells you about one problem when you wanted the list.
|
|
200
|
+
*/
|
|
201
|
+
export async function loadDirectory(dir, options = {}) {
|
|
202
|
+
return loadAt(dir, options, 0);
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Depth 0 is the project the caller named; 1 is a delegate it declares.
|
|
206
|
+
*
|
|
207
|
+
* A delegate does not get delegates of its own. The cap is a real decision,
|
|
208
|
+
* not a missing feature: unbounded nesting is a topology question — who may
|
|
209
|
+
* spawn whom, and how deep a run may fan out — and answering it by default is
|
|
210
|
+
* how a directory layout ends up deciding a system's shape. It also removes
|
|
211
|
+
* the cycle: `agents/a/agents/b/agents/a` cannot be built if the second level
|
|
212
|
+
* is never read.
|
|
213
|
+
*/
|
|
214
|
+
const MAX_DEPTH = 1;
|
|
215
|
+
async function loadAt(dir, options, depth) {
|
|
216
|
+
if (typeof dir !== 'string' || dir.length === 0) {
|
|
217
|
+
throw new TypeError('loadDirectory(dir): dir must be a non-empty string.');
|
|
218
|
+
}
|
|
219
|
+
const modules = options.modules ?? 'evaluate';
|
|
220
|
+
const importModule = options.importModule ?? ((url) => import(url));
|
|
221
|
+
const timeoutMs = options.moduleTimeoutMs ?? DEFAULT_MODULE_TIMEOUT_MS;
|
|
222
|
+
// `?? ALL_SLOTS`, never `|| ALL_SLOTS`: an empty list means "scan nothing",
|
|
223
|
+
// which is the closed reading of an allow-list. The tuple type keeps a
|
|
224
|
+
// TypeScript caller from writing it at all.
|
|
225
|
+
const included = options.include ?? ALL_SLOTS;
|
|
226
|
+
const diagnostics = [];
|
|
227
|
+
const sources = [];
|
|
228
|
+
const tools = [];
|
|
229
|
+
const skills = [];
|
|
230
|
+
const agents = [];
|
|
231
|
+
let config = {};
|
|
232
|
+
let instructions = '';
|
|
233
|
+
const root = await canonicalRoot(dir);
|
|
234
|
+
if (!root) {
|
|
235
|
+
diagnostics.push({
|
|
236
|
+
code: 'root_missing',
|
|
237
|
+
severity: 'error',
|
|
238
|
+
message: `No directory at ${dir}.`,
|
|
239
|
+
});
|
|
240
|
+
return {
|
|
241
|
+
manifest: {
|
|
242
|
+
root: dir,
|
|
243
|
+
name: 'agent',
|
|
244
|
+
instructions: '',
|
|
245
|
+
config: {},
|
|
246
|
+
tools: [],
|
|
247
|
+
skills: [],
|
|
248
|
+
agents: [],
|
|
249
|
+
sources: [],
|
|
250
|
+
included,
|
|
251
|
+
modules,
|
|
252
|
+
},
|
|
253
|
+
diagnostics,
|
|
254
|
+
ok: false,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
const record = (file, slot, outcome) => {
|
|
258
|
+
const ref = { ...file, slot, outcome };
|
|
259
|
+
sources.push(ref);
|
|
260
|
+
return ref;
|
|
261
|
+
};
|
|
262
|
+
// ─── instructions ─────────────────────────────────────────────────────
|
|
263
|
+
if (included.includes('instructions')) {
|
|
264
|
+
try {
|
|
265
|
+
const body = await readFile(`${root}/instructions.md`, 'utf8');
|
|
266
|
+
instructions = body.trimEnd();
|
|
267
|
+
if (instructions.length === 0) {
|
|
268
|
+
// Asymmetric on purpose: an absent file is a choice, a present
|
|
269
|
+
// file that says nothing is a mistake.
|
|
270
|
+
diagnostics.push({
|
|
271
|
+
code: 'instructions_empty',
|
|
272
|
+
severity: 'error',
|
|
273
|
+
message: 'instructions.md exists but is empty.',
|
|
274
|
+
path: `${root}/instructions.md`,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
record({
|
|
278
|
+
path: `${root}/instructions.md`,
|
|
279
|
+
relativePath: 'instructions.md',
|
|
280
|
+
id: 'instructions',
|
|
281
|
+
}, 'instructions', 'loaded');
|
|
282
|
+
}
|
|
283
|
+
catch {
|
|
284
|
+
// A warning, not an error: `runAgent` treats instructions as fully
|
|
285
|
+
// optional, and this package does not get to overrule the kernel
|
|
286
|
+
// about what a valid agent is.
|
|
287
|
+
diagnostics.push({
|
|
288
|
+
code: 'instructions_missing',
|
|
289
|
+
severity: 'warning',
|
|
290
|
+
message: 'No instructions.md. The agent will run without a system prompt.',
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
// ─── agent.ts ─────────────────────────────────────────────────────────
|
|
295
|
+
if (included.includes('agent')) {
|
|
296
|
+
const found = (await scanSlot(root, 'agent', '.')).files.find((f) => f.id === 'agent');
|
|
297
|
+
if (found) {
|
|
298
|
+
if (modules === 'skip') {
|
|
299
|
+
record(found, 'agent', 'not_loaded');
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
const outcome = await importWithDeadline(pathToFileURL(found.path).href, importModule, timeoutMs);
|
|
303
|
+
if (outcome.status === 'loaded') {
|
|
304
|
+
config = readConfig(defaultExport(outcome.module), diagnostics, found.path);
|
|
305
|
+
record(found, 'agent', 'loaded');
|
|
306
|
+
}
|
|
307
|
+
else if (outcome.status === 'abandoned') {
|
|
308
|
+
diagnostics.push({
|
|
309
|
+
code: 'module_load_abandoned',
|
|
310
|
+
severity: 'error',
|
|
311
|
+
message: `agent.ts did not finish importing within ${timeoutMs}ms. The import was not cancelled and may still complete.`,
|
|
312
|
+
path: found.path,
|
|
313
|
+
});
|
|
314
|
+
record(found, 'agent', 'abandoned');
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
diagnostics.push({
|
|
318
|
+
code: 'module_load_failed',
|
|
319
|
+
severity: 'error',
|
|
320
|
+
message: 'agent.ts could not be imported.',
|
|
321
|
+
path: found.path,
|
|
322
|
+
cause: explainImportFailure(outcome.cause, outcome.code),
|
|
323
|
+
});
|
|
324
|
+
record(found, 'agent', 'failed');
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
// ─── tools ────────────────────────────────────────────────────────────
|
|
330
|
+
if (included.includes('tools')) {
|
|
331
|
+
const scan = await scanSlot(root, 'tools', 'tools');
|
|
332
|
+
diagnostics.push(...scan.diagnostics);
|
|
333
|
+
const seen = new Map();
|
|
334
|
+
for (const file of scan.files) {
|
|
335
|
+
if (modules === 'skip') {
|
|
336
|
+
record(file, 'tools', 'not_loaded');
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
const outcome = await importWithDeadline(pathToFileURL(file.path).href, importModule, timeoutMs);
|
|
340
|
+
if (outcome.status === 'abandoned') {
|
|
341
|
+
diagnostics.push({
|
|
342
|
+
code: 'module_load_abandoned',
|
|
343
|
+
severity: 'error',
|
|
344
|
+
message: `${file.relativePath} did not finish importing within ${timeoutMs}ms. The import was not cancelled and may still complete.`,
|
|
345
|
+
path: file.path,
|
|
346
|
+
});
|
|
347
|
+
record(file, 'tools', 'abandoned');
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
if (outcome.status === 'failed') {
|
|
351
|
+
diagnostics.push({
|
|
352
|
+
code: 'module_load_failed',
|
|
353
|
+
severity: 'error',
|
|
354
|
+
message: `${file.relativePath} could not be imported.`,
|
|
355
|
+
path: file.path,
|
|
356
|
+
cause: explainImportFailure(outcome.cause, outcome.code),
|
|
357
|
+
});
|
|
358
|
+
record(file, 'tools', 'failed');
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
const exported = defaultExport(outcome.module);
|
|
362
|
+
if (exported === undefined) {
|
|
363
|
+
diagnostics.push({
|
|
364
|
+
code: 'no_default_export',
|
|
365
|
+
severity: 'error',
|
|
366
|
+
message: `${file.relativePath} has no default export. A tool file default-exports the result of defineTool().`,
|
|
367
|
+
path: file.path,
|
|
368
|
+
});
|
|
369
|
+
record(file, 'tools', 'failed');
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
if (!isToolDefinition(exported)) {
|
|
373
|
+
diagnostics.push({
|
|
374
|
+
code: 'not_a_tool',
|
|
375
|
+
severity: 'error',
|
|
376
|
+
message: `${file.relativePath} default-exports something that is not a tool definition (needs a "name" and an "execute").`,
|
|
377
|
+
path: file.path,
|
|
378
|
+
});
|
|
379
|
+
record(file, 'tools', 'failed');
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
const previous = seen.get(exported.name);
|
|
383
|
+
if (previous) {
|
|
384
|
+
// Refuse both rather than let one win. A registry would warn and
|
|
385
|
+
// overwrite; here the author has two files claiming one name and
|
|
386
|
+
// picking either silently is the thing that hides the mistake.
|
|
387
|
+
diagnostics.push({
|
|
388
|
+
code: 'duplicate_tool_name',
|
|
389
|
+
severity: 'error',
|
|
390
|
+
message: `Two tools both call themselves "${exported.name}": ${previous} and ${file.relativePath}. Neither was registered.`,
|
|
391
|
+
path: file.path,
|
|
392
|
+
});
|
|
393
|
+
record(file, 'tools', 'failed');
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
396
|
+
seen.set(exported.name, file.relativePath);
|
|
397
|
+
tools.push({
|
|
398
|
+
source: record(file, 'tools', 'loaded'),
|
|
399
|
+
definition: exported,
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
// ─── skills ───────────────────────────────────────────────────────────
|
|
404
|
+
if (included.includes('skills')) {
|
|
405
|
+
const scan = await scanSlot(root, 'skills', 'skills');
|
|
406
|
+
diagnostics.push(...scan.diagnostics);
|
|
407
|
+
for (const file of scan.files) {
|
|
408
|
+
try {
|
|
409
|
+
// Delegated, not reimplemented. `Skill.dirPath` is required and
|
|
410
|
+
// the prompt assembler renders `<location>{dirPath}/SKILL.md`,
|
|
411
|
+
// so a flat `skills/*.md` would produce a skill the model is
|
|
412
|
+
// told to read at a path that does not exist. Directory form is
|
|
413
|
+
// the only form that survives to runtime.
|
|
414
|
+
// `loadSkill` returns a result wrapper; the Skill is inside it.
|
|
415
|
+
const { skill } = await loadSkill(file.path);
|
|
416
|
+
skills.push({ source: record(file, 'skills', 'loaded'), skill });
|
|
417
|
+
}
|
|
418
|
+
catch (err) {
|
|
419
|
+
diagnostics.push({
|
|
420
|
+
code: 'skill_load_failed',
|
|
421
|
+
severity: 'error',
|
|
422
|
+
message: `${file.relativePath} is not a readable skill.`,
|
|
423
|
+
path: file.path,
|
|
424
|
+
cause: err instanceof Error ? err.message : String(err),
|
|
425
|
+
});
|
|
426
|
+
record(file, 'skills', 'failed');
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
// ─── agents (delegates) ───────────────────────────────────────────────
|
|
431
|
+
if (included.includes('agents')) {
|
|
432
|
+
const scan = await scanSlot(root, 'agents', 'agents');
|
|
433
|
+
diagnostics.push(...scan.diagnostics);
|
|
434
|
+
for (const entry of scan.files) {
|
|
435
|
+
if (depth >= MAX_DEPTH) {
|
|
436
|
+
diagnostics.push({
|
|
437
|
+
code: 'subagent_too_deep',
|
|
438
|
+
severity: 'warning',
|
|
439
|
+
message: entry.relativePath +
|
|
440
|
+
' was not loaded: a delegate may not declare delegates of its own.',
|
|
441
|
+
path: entry.path,
|
|
442
|
+
});
|
|
443
|
+
record(entry, 'agents', 'skipped');
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
const child = await loadAt(entry.path, options, depth + 1);
|
|
447
|
+
// The child's diagnostics are the parent's. A delegate that could
|
|
448
|
+
// not load is a fact about THIS project, and a caller reading one
|
|
449
|
+
// list should not have to walk the tree to find out the run will be
|
|
450
|
+
// short a specialist.
|
|
451
|
+
for (const d of child.diagnostics) {
|
|
452
|
+
diagnostics.push({ ...d, message: entry.relativePath + ': ' + d.message });
|
|
453
|
+
}
|
|
454
|
+
if (!child.ok) {
|
|
455
|
+
record(entry, 'agents', 'failed');
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
agents.push({
|
|
459
|
+
source: record(entry, 'agents', 'loaded'),
|
|
460
|
+
manifest: child.manifest,
|
|
461
|
+
id: entry.id,
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
const name = config.name ?? basenameOf(root);
|
|
466
|
+
return {
|
|
467
|
+
manifest: {
|
|
468
|
+
root,
|
|
469
|
+
name,
|
|
470
|
+
instructions,
|
|
471
|
+
config,
|
|
472
|
+
tools,
|
|
473
|
+
skills,
|
|
474
|
+
agents,
|
|
475
|
+
sources,
|
|
476
|
+
included,
|
|
477
|
+
modules,
|
|
478
|
+
},
|
|
479
|
+
diagnostics,
|
|
480
|
+
ok: diagnostics.every((d) => d.severity !== 'error'),
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
/** Basename, with the filesystem root falling back to a usable label. */
|
|
484
|
+
function basenameOf(root) {
|
|
485
|
+
const parts = root.split(/[\\/]/).filter(Boolean);
|
|
486
|
+
return parts[parts.length - 1] ?? 'agent';
|
|
487
|
+
}
|
|
488
|
+
//# sourceMappingURL=load.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/directory/load.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { DirectoryDiagnostic, DirectorySlot } from './types.js';
|
|
2
|
+
export interface ScannedFile {
|
|
3
|
+
readonly path: string;
|
|
4
|
+
readonly relativePath: string;
|
|
5
|
+
readonly id: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ScanResult {
|
|
8
|
+
readonly files: readonly ScannedFile[];
|
|
9
|
+
readonly diagnostics: readonly DirectoryDiagnostic[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* List the code files directly inside one slot directory.
|
|
13
|
+
*
|
|
14
|
+
* **Symlinks are refused, not followed.** A directory handed to this loader is
|
|
15
|
+
* caller-supplied, and a link inside it pointing anywhere else is the
|
|
16
|
+
* link-following weakness (CWE-59) with the loader as the vehicle: the file
|
|
17
|
+
* that gets imported is not the file that was listed. The estate already
|
|
18
|
+
* decided this for its filesystem tools; the same rule applies to a directory
|
|
19
|
+
* whose author may not be the host.
|
|
20
|
+
*
|
|
21
|
+
* That is stricter than the SDK's own `discoverSkills`, and deliberately so —
|
|
22
|
+
* that function walks a host's own trusted tree, where following a link is a
|
|
23
|
+
* convenience rather than a hole. Reusing it here would have inherited a
|
|
24
|
+
* threat model chosen for a different caller.
|
|
25
|
+
*
|
|
26
|
+
* Only the top level is read. A nested directory is reported so an author
|
|
27
|
+
* learns their file was not picked up, except when its name starts with `.`
|
|
28
|
+
* or `_`, which is the conventional way to say "not for you" and is honoured
|
|
29
|
+
* silently.
|
|
30
|
+
*/
|
|
31
|
+
export declare function scanSlot(root: string, slot: DirectorySlot, dirName: string): Promise<ScanResult>;
|
|
32
|
+
/** Canonical absolute root, or undefined when the directory does not exist. */
|
|
33
|
+
export declare function canonicalRoot(dir: string): Promise<string | undefined>;
|
|
34
|
+
/** Posix-normalised, for a `relativePath` that reads the same on every platform. */
|
|
35
|
+
export declare function toPosix(value: string): string;
|
|
36
|
+
//# sourceMappingURL=scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/directory/scan.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAKpE,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAA;IACtC,QAAQ,CAAC,WAAW,EAAE,SAAS,mBAAmB,EAAE,CAAA;CACpD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,QAAQ,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,UAAU,CAAC,CAoGrB;AAED,+EAA+E;AAC/E,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAQ5E;AAED,oFAAoF;AACpF,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7C"}
|