agents 0.22.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -1
- package/dist/{agent-routing-CnkaHb-v.d.ts → agent-routing-DE5zmCQ8.d.ts} +1038 -394
- package/dist/agent-routing.d.ts +1 -1
- package/dist/agent-tool-types.d.ts +26 -26
- package/dist/{agent-tools-C0XJqWzB.d.ts → agent-tools-DtXMTDGM.d.ts} +7 -7
- package/dist/agent-tools.d.ts +21 -21
- package/dist/browser/ai.js +4 -1
- package/dist/browser/ai.js.map +1 -1
- package/dist/browser/tanstack-ai.js.map +1 -1
- package/dist/callable-decorator-DP__HhBA.d.ts +72 -0
- package/dist/callable-decorator.d.ts +18 -0
- package/dist/callable-decorator.js +71 -0
- package/dist/callable-decorator.js.map +1 -0
- package/dist/capability-BjSKYpzg.js.map +1 -1
- package/dist/capability-runner-Be_-PLR1.d.ts +459 -0
- package/dist/channel-Bnm4S7T2.d.ts +491 -0
- package/dist/channels/ai-sdk.d.ts +46 -0
- package/dist/channels/ai-sdk.js +120 -0
- package/dist/channels/ai-sdk.js.map +1 -0
- package/dist/channels/email.d.ts +95 -0
- package/dist/channels/email.js +323 -0
- package/dist/channels/email.js.map +1 -0
- package/dist/channels/index.d.ts +233 -0
- package/dist/channels/index.js +608 -0
- package/dist/channels/index.js.map +1 -0
- package/dist/channels/slack.d.ts +140 -0
- package/dist/channels/slack.js +614 -0
- package/dist/channels/slack.js.map +1 -0
- package/dist/channels/tanstack-ai.d.ts +39 -0
- package/dist/channels/tanstack-ai.js +17 -0
- package/dist/channels/tanstack-ai.js.map +1 -0
- package/dist/channels/telegram.d.ts +106 -0
- package/dist/channels/telegram.js +427 -0
- package/dist/channels/telegram.js.map +1 -0
- package/dist/channels/voice.d.ts +45 -0
- package/dist/channels/voice.js +122 -0
- package/dist/channels/voice.js.map +1 -0
- package/dist/chat/index.d.ts +2325 -2019
- package/dist/chat/index.js +888 -518
- package/dist/chat/index.js.map +1 -1
- package/dist/chat-sdk/index.d.ts +7 -7
- package/dist/chat-sdk/index.js +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/context/index.d.ts +216 -0
- package/dist/context/index.js +454 -0
- package/dist/context/index.js.map +1 -0
- package/dist/{current-agent-CuMErtly.d.ts → current-agent-Da_C9a3b.d.ts} +90 -107
- package/dist/current-agent-DhoDkSnH.js.map +1 -1
- package/dist/{diagnostics-CaBjfz4J.js → diagnostics-BzvaX2UT.js} +5 -1
- package/dist/diagnostics-BzvaX2UT.js.map +1 -0
- package/dist/diagnostics-C4jcz3VK.js +360 -0
- package/dist/diagnostics-C4jcz3VK.js.map +1 -0
- package/dist/index-BB0kqhIz.d.ts +101 -0
- package/dist/index-BVVgDSdq.d.ts +1 -0
- package/dist/index-XDkuQ7zm.d.ts +89 -0
- package/dist/{index-DcSAZKsB.d.ts → index-YSKgfgg9.d.ts} +3 -1
- package/dist/index.d.ts +91 -82
- package/dist/index.js +3 -2
- package/dist/ingress-BfetZbMO.js +83 -0
- package/dist/ingress-BfetZbMO.js.map +1 -0
- package/dist/internal-CYlgHl1l.js +59 -0
- package/dist/internal-CYlgHl1l.js.map +1 -0
- package/dist/internal_context.d.ts +1 -1
- package/dist/lifecycle/index.d.ts +35 -17
- package/dist/lifecycle/index.js +1 -1
- package/dist/lifecycle-CMRGjZdw.js +1299 -0
- package/dist/lifecycle-CMRGjZdw.js.map +1 -0
- package/dist/mcp/client/index.d.ts +20 -20
- package/dist/mcp/index.d.ts +35 -35
- package/dist/mcp/index.js +1 -1
- package/dist/observability/index.d.ts +1 -1
- package/dist/observability/index.js +1 -1
- package/dist/react.d.ts +4 -4
- package/dist/{retries-CAvxtG9d.d.ts → retries-D9Ds-1lz.d.ts} +17 -6
- package/dist/retries.d.ts +8 -6
- package/dist/retries.js +13 -1
- package/dist/retries.js.map +1 -1
- package/dist/routing/index.d.ts +137 -0
- package/dist/routing/index.js +244 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/sanitize-D9TujEK8.js +79 -0
- package/dist/sanitize-D9TujEK8.js.map +1 -0
- package/dist/scheduler-DD9NdYbF.js +665 -0
- package/dist/scheduler-DD9NdYbF.js.map +1 -0
- package/dist/{scheduler-DQoTGoAW.d.ts → scheduler-Dwh85ZGl.d.ts} +21 -22
- package/dist/schedules/index.d.ts +1 -1
- package/dist/schedules/index.js +1 -1
- package/dist/sentence-chunker-BAidJ4DA.d.ts +68 -0
- package/dist/serializable.d.ts +1 -1
- package/dist/sessions/index.d.ts +441 -0
- package/dist/sessions/index.js +2063 -0
- package/dist/sessions/index.js.map +1 -0
- package/dist/skills/index.d.ts +99 -0
- package/dist/skills/index.js +254 -5
- package/dist/skills/index.js.map +1 -1
- package/dist/{src-5W6JNKVb.js → src-DlSHshb2.js} +1460 -1110
- package/dist/src-DlSHshb2.js.map +1 -0
- package/dist/streams/index.d.ts +120 -0
- package/dist/streams/index.js +107 -0
- package/dist/streams/index.js.map +1 -0
- package/dist/streams-D6tJ0NN9.d.ts +370 -0
- package/dist/streams-DZKgAj9b.js +709 -0
- package/dist/streams-DZKgAj9b.js.map +1 -0
- package/dist/sub-routing.d.ts +12 -12
- package/dist/surface-bZZJqBka.js +17 -0
- package/dist/surface-bZZJqBka.js.map +1 -0
- package/dist/tasks/index.d.ts +64 -0
- package/dist/tasks/index.js +2 -0
- package/dist/tasks-BRJ5zgya.d.ts +517 -0
- package/dist/tasks-ylZgBjhj.js +1656 -0
- package/dist/tasks-ylZgBjhj.js.map +1 -0
- package/dist/text-segment-joiner-BtAFQSA_.js +57 -0
- package/dist/text-segment-joiner-BtAFQSA_.js.map +1 -0
- package/dist/text-stream-CpdiKrJB.js +272 -0
- package/dist/text-stream-CpdiKrJB.js.map +1 -0
- package/dist/tokens-nHAKcN6M.js +52 -0
- package/dist/tokens-nHAKcN6M.js.map +1 -0
- package/dist/tool-schema-CBjGPrsQ.js +31 -0
- package/dist/tool-schema-CBjGPrsQ.js.map +1 -0
- package/dist/types-B7LojTe4.d.ts +202 -0
- package/dist/types-_Faxb570.d.ts +439 -0
- package/dist/voice/client.d.ts +226 -0
- package/dist/voice/client.js +932 -0
- package/dist/voice/client.js.map +1 -0
- package/dist/voice/errors.d.ts +43 -0
- package/dist/voice/errors.js +41 -0
- package/dist/voice/errors.js.map +1 -0
- package/dist/voice/index.d.ts +271 -0
- package/dist/voice/index.js +1812 -0
- package/dist/voice/index.js.map +1 -0
- package/dist/voice/react.d.ts +167 -0
- package/dist/voice/react.js +234 -0
- package/dist/voice/react.js.map +1 -0
- package/dist/voice/sfu.d.ts +71 -0
- package/dist/voice/sfu.js +157 -0
- package/dist/voice/sfu.js.map +1 -0
- package/dist/voice/text.d.ts +6 -0
- package/dist/voice/text.js +2 -0
- package/dist/voice/types.d.ts +58 -0
- package/dist/voice/types.js +18 -0
- package/dist/voice/types.js.map +1 -0
- package/dist/voice/workers-ai.d.ts +136 -0
- package/dist/voice/workers-ai.js +568 -0
- package/dist/voice/workers-ai.js.map +1 -0
- package/dist/websockets/index.d.ts +192 -0
- package/dist/websockets/index.js +2 -0
- package/dist/websockets-DUfRHPRq.js +502 -0
- package/dist/websockets-DUfRHPRq.js.map +1 -0
- package/dist/workflow-types.d.ts +25 -25
- package/dist/workflows.d.ts +21 -21
- package/dist/workflows.js +1 -1
- package/docs/agent-class.md +2 -2
- package/docs/agent-tools.md +2 -1
- package/docs/channels.md +323 -0
- package/docs/chat-agents.md +6 -13
- package/docs/context.md +131 -0
- package/docs/index.md +15 -12
- package/docs/lifecycle.md +102 -55
- package/docs/long-running-agents.md +2 -2
- package/docs/mcp-servers.md +5 -1
- package/docs/resumable-streaming.md +1 -1
- package/docs/routing.md +105 -0
- package/docs/sessions.md +237 -871
- package/docs/streams.md +213 -0
- package/docs/sub-agents.md +184 -124
- package/docs/tasks.md +246 -0
- package/docs/voice.md +745 -0
- package/package.json +115 -13
- package/dist/capability-runner-CvHGZqUu.d.ts +0 -150
- package/dist/compaction-helpers-iiKMr2TQ.js +0 -340
- package/dist/compaction-helpers-iiKMr2TQ.js.map +0 -1
- package/dist/compaction-helpers-wUz6M3us.d.ts +0 -621
- package/dist/diagnostics-CaBjfz4J.js.map +0 -1
- package/dist/durable-object-lifecycle-D6nNQJJd.js +0 -862
- package/dist/durable-object-lifecycle-D6nNQJJd.js.map +0 -1
- package/dist/experimental/memory/session/index.d.ts +0 -671
- package/dist/experimental/memory/session/index.js +0 -2379
- package/dist/experimental/memory/session/index.js.map +0 -1
- package/dist/experimental/memory/utils/index.d.ts +0 -96
- package/dist/experimental/memory/utils/index.js +0 -79
- package/dist/experimental/memory/utils/index.js.map +0 -1
- package/dist/scheduler-CR9RHGos.js +0 -857
- package/dist/scheduler-CR9RHGos.js.map +0 -1
- package/dist/src-5W6JNKVb.js.map +0 -1
- package/dist/tool-output-truncation-CNnnGZQ3.js +0 -98
- package/dist/tool-output-truncation-CNnnGZQ3.js.map +0 -1
package/dist/skills/index.js
CHANGED
|
@@ -1097,11 +1097,158 @@ function runner(options) {
|
|
|
1097
1097
|
} };
|
|
1098
1098
|
}
|
|
1099
1099
|
//#endregion
|
|
1100
|
+
//#region src/skills/workspace.ts
|
|
1101
|
+
/** @internal Parse and adapt a Computer or legacy Shell Workspace. */
|
|
1102
|
+
function createSkillWorkspaceFiles(workspace, rootOverride) {
|
|
1103
|
+
const computer = isComputerWorkspace(workspace);
|
|
1104
|
+
const root = parseRoot(rootOverride ?? (computer ? "/workspace/.agents/skills" : "/.agents/skills"));
|
|
1105
|
+
const exists = async (path) => {
|
|
1106
|
+
try {
|
|
1107
|
+
const stat = computer ? await workspace.fs.stat(path) : await workspace.stat(path);
|
|
1108
|
+
return stat !== null && stat !== void 0;
|
|
1109
|
+
} catch (error) {
|
|
1110
|
+
if (isNotFound(error)) return false;
|
|
1111
|
+
throw error;
|
|
1112
|
+
}
|
|
1113
|
+
};
|
|
1114
|
+
const readText = async (path) => {
|
|
1115
|
+
try {
|
|
1116
|
+
return computer ? await workspace.fs.readFile(path, "utf8") : await workspace.readFile(path);
|
|
1117
|
+
} catch (error) {
|
|
1118
|
+
if (isNotFound(error)) return null;
|
|
1119
|
+
throw error;
|
|
1120
|
+
}
|
|
1121
|
+
};
|
|
1122
|
+
const readBytes = async (path) => {
|
|
1123
|
+
if (!computer) return workspace.readFileBytes(path);
|
|
1124
|
+
try {
|
|
1125
|
+
return await drain(await workspace.fs.readFile(path));
|
|
1126
|
+
} catch (error) {
|
|
1127
|
+
if (isNotFound(error)) return null;
|
|
1128
|
+
throw error;
|
|
1129
|
+
}
|
|
1130
|
+
};
|
|
1131
|
+
const mkdirParent = async (path) => {
|
|
1132
|
+
const parent = path.slice(0, path.lastIndexOf("/"));
|
|
1133
|
+
if (!parent) return;
|
|
1134
|
+
if (computer) await workspace.fs.mkdir(parent, { recursive: true });
|
|
1135
|
+
else await workspace.mkdir(parent, { recursive: true });
|
|
1136
|
+
};
|
|
1137
|
+
return {
|
|
1138
|
+
root,
|
|
1139
|
+
path(name, relativePath) {
|
|
1140
|
+
return `${root}/${parseSkillDirectoryName(name)}/${parseRelativePath(relativePath)}`;
|
|
1141
|
+
},
|
|
1142
|
+
exists,
|
|
1143
|
+
readText,
|
|
1144
|
+
async readResource(path, descriptor) {
|
|
1145
|
+
if ((descriptor.encoding ?? "text") === "text") {
|
|
1146
|
+
const content = await readText(path);
|
|
1147
|
+
return content === null ? null : {
|
|
1148
|
+
...descriptor,
|
|
1149
|
+
content
|
|
1150
|
+
};
|
|
1151
|
+
}
|
|
1152
|
+
const bytes = await readBytes(path);
|
|
1153
|
+
return bytes === null ? null : {
|
|
1154
|
+
...descriptor,
|
|
1155
|
+
content: encodeBase64(bytes)
|
|
1156
|
+
};
|
|
1157
|
+
},
|
|
1158
|
+
async writeText(path, content) {
|
|
1159
|
+
await mkdirParent(path);
|
|
1160
|
+
if (computer) await workspace.fs.writeFile(path, content);
|
|
1161
|
+
else await workspace.writeFile(path, content);
|
|
1162
|
+
},
|
|
1163
|
+
async writeResource(path, resource) {
|
|
1164
|
+
await mkdirParent(path);
|
|
1165
|
+
if ((resource.encoding ?? "text") === "text") {
|
|
1166
|
+
if (computer) await workspace.fs.writeFile(path, resource.content);
|
|
1167
|
+
else await workspace.writeFile(path, resource.content);
|
|
1168
|
+
return;
|
|
1169
|
+
}
|
|
1170
|
+
const bytes = decodeBase64(resource.content);
|
|
1171
|
+
if (computer) await workspace.fs.writeFile(path, bytes);
|
|
1172
|
+
else await workspace.writeFileBytes(path, bytes, resource.mimeType);
|
|
1173
|
+
}
|
|
1174
|
+
};
|
|
1175
|
+
}
|
|
1176
|
+
function isComputerWorkspace(workspace) {
|
|
1177
|
+
return "fs" in workspace;
|
|
1178
|
+
}
|
|
1179
|
+
function parseRoot(root) {
|
|
1180
|
+
if (!root.startsWith("/") || root.includes("\0") || root.split("/").some((part) => part === "." || part === "..")) throw new Error(`Skill Workspace root must be a normalized absolute path: ${root}`);
|
|
1181
|
+
const normalized = root.replace(/\/{2,}/g, "/").replace(/\/$/, "");
|
|
1182
|
+
if (!normalized) throw new Error("Skill Workspace root cannot be /");
|
|
1183
|
+
return normalized;
|
|
1184
|
+
}
|
|
1185
|
+
function parseSkillDirectoryName(name) {
|
|
1186
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name)) throw new Error(`Skill name must be a safe Workspace directory name: ${name}`);
|
|
1187
|
+
return name;
|
|
1188
|
+
}
|
|
1189
|
+
function parseRelativePath(path) {
|
|
1190
|
+
if (path.startsWith("/") || path.includes("\0") || path.split("/").some((part) => part === "" || part === "." || part === "..")) throw new Error(`Skill file path must be normalized and relative: ${path}`);
|
|
1191
|
+
return path;
|
|
1192
|
+
}
|
|
1193
|
+
function isNotFound(error) {
|
|
1194
|
+
if (!error || typeof error !== "object") return false;
|
|
1195
|
+
const record = error;
|
|
1196
|
+
return record.code === "ENOENT" || typeof record.message === "string" && /ENOENT|no such file|not found/i.test(record.message);
|
|
1197
|
+
}
|
|
1198
|
+
async function drain(stream) {
|
|
1199
|
+
const parts = [];
|
|
1200
|
+
let total = 0;
|
|
1201
|
+
const reader = stream.getReader();
|
|
1202
|
+
try {
|
|
1203
|
+
while (true) {
|
|
1204
|
+
const { value, done } = await reader.read();
|
|
1205
|
+
if (done) break;
|
|
1206
|
+
if (!value || value.byteLength === 0) continue;
|
|
1207
|
+
parts.push(value);
|
|
1208
|
+
total += value.byteLength;
|
|
1209
|
+
}
|
|
1210
|
+
} finally {
|
|
1211
|
+
reader.releaseLock();
|
|
1212
|
+
}
|
|
1213
|
+
if (parts.length === 1) return parts[0];
|
|
1214
|
+
const bytes = new Uint8Array(total);
|
|
1215
|
+
let offset = 0;
|
|
1216
|
+
for (const part of parts) {
|
|
1217
|
+
bytes.set(part, offset);
|
|
1218
|
+
offset += part.byteLength;
|
|
1219
|
+
}
|
|
1220
|
+
return bytes;
|
|
1221
|
+
}
|
|
1222
|
+
function decodeBase64(value) {
|
|
1223
|
+
const binary = atob(value);
|
|
1224
|
+
const bytes = new Uint8Array(binary.length);
|
|
1225
|
+
for (let index = 0; index < binary.length; index++) bytes[index] = binary.charCodeAt(index);
|
|
1226
|
+
return bytes;
|
|
1227
|
+
}
|
|
1228
|
+
function encodeBase64(bytes) {
|
|
1229
|
+
const parts = [];
|
|
1230
|
+
for (let offset = 0; offset < bytes.byteLength; offset += 32768) parts.push(String.fromCharCode(...bytes.subarray(offset, offset + 32768)));
|
|
1231
|
+
return btoa(parts.join(""));
|
|
1232
|
+
}
|
|
1233
|
+
//#endregion
|
|
1100
1234
|
//#region src/skills/registry.ts
|
|
1101
1235
|
const SKILL_CONTEXT_LABEL = "think_skills";
|
|
1102
1236
|
function stableSourceFingerprint(sources) {
|
|
1103
1237
|
return sources.map((source) => `${source.id}:${source.fingerprint}`).join("|");
|
|
1104
1238
|
}
|
|
1239
|
+
function renderSkillMarkdown(skill) {
|
|
1240
|
+
const lines = [
|
|
1241
|
+
"---",
|
|
1242
|
+
`name: ${JSON.stringify(skill.name)}`,
|
|
1243
|
+
`description: ${JSON.stringify(skill.description)}`
|
|
1244
|
+
];
|
|
1245
|
+
if (skill.compatibility) lines.push(`compatibility: ${JSON.stringify(skill.compatibility)}`);
|
|
1246
|
+
if (skill.license) lines.push(`license: ${JSON.stringify(skill.license)}`);
|
|
1247
|
+
if (skill.allowedTools) lines.push(`allowed-tools: ${JSON.stringify(skill.allowedTools)}`);
|
|
1248
|
+
if (skill.metadata) lines.push(`metadata: ${JSON.stringify(skill.metadata)}`);
|
|
1249
|
+
lines.push("---", "", skill.body);
|
|
1250
|
+
return lines.join("\n");
|
|
1251
|
+
}
|
|
1105
1252
|
function wrapSkillContent(skill) {
|
|
1106
1253
|
const version = skill.version ? ` version="${skill.version}"` : "";
|
|
1107
1254
|
const resourceList = skill.resources?.length ? [
|
|
@@ -1137,6 +1284,9 @@ var SkillRegistry = class {
|
|
|
1137
1284
|
this.descriptors = /* @__PURE__ */ new Map();
|
|
1138
1285
|
this.sourceBySkill = /* @__PURE__ */ new Map();
|
|
1139
1286
|
this.loaded = false;
|
|
1287
|
+
this.workspaceFiles = null;
|
|
1288
|
+
this.workspaceSkillNames = /* @__PURE__ */ new Set();
|
|
1289
|
+
this.workspaceResources = /* @__PURE__ */ new Map();
|
|
1140
1290
|
this.sources = sources;
|
|
1141
1291
|
this.scriptRunner = scriptRunner;
|
|
1142
1292
|
}
|
|
@@ -1184,6 +1334,72 @@ var SkillRegistry = class {
|
|
|
1184
1334
|
await this.load();
|
|
1185
1335
|
this.warnings.push(...refreshErrors);
|
|
1186
1336
|
}
|
|
1337
|
+
/**
|
|
1338
|
+
* Seed resolved Agent Skills into Computer or legacy Shell storage.
|
|
1339
|
+
* Existing files are preserved by default, and become authoritative for
|
|
1340
|
+
* activation, resource reads, and script execution.
|
|
1341
|
+
*/
|
|
1342
|
+
async seedWorkspace(workspace, options = {}) {
|
|
1343
|
+
await this.load();
|
|
1344
|
+
const files = createSkillWorkspaceFiles(workspace, options.root);
|
|
1345
|
+
const result = {
|
|
1346
|
+
written: 0,
|
|
1347
|
+
preserved: 0,
|
|
1348
|
+
skipped: 0,
|
|
1349
|
+
warnings: [],
|
|
1350
|
+
root: files.root
|
|
1351
|
+
};
|
|
1352
|
+
const seeded = /* @__PURE__ */ new Set();
|
|
1353
|
+
const resources = /* @__PURE__ */ new Map();
|
|
1354
|
+
for (const descriptor of this.descriptors.values()) {
|
|
1355
|
+
const source = this.sourceBySkill.get(descriptor.name);
|
|
1356
|
+
let skill = null;
|
|
1357
|
+
try {
|
|
1358
|
+
skill = await source?.load(descriptor.name) ?? null;
|
|
1359
|
+
} catch (error) {
|
|
1360
|
+
result.skipped++;
|
|
1361
|
+
result.warnings.push(`Could not load skill "${descriptor.name}" for Workspace seeding: ${error instanceof Error ? error.message : String(error)}`);
|
|
1362
|
+
continue;
|
|
1363
|
+
}
|
|
1364
|
+
if (!skill) {
|
|
1365
|
+
result.skipped++;
|
|
1366
|
+
result.warnings.push(`Could not load skill "${descriptor.name}" for Workspace seeding.`);
|
|
1367
|
+
continue;
|
|
1368
|
+
}
|
|
1369
|
+
resources.set(descriptor.name, new Map((skill.resources ?? []).map((resource) => [resource.path, resource])));
|
|
1370
|
+
const skillPath = files.path(descriptor.name, "SKILL.md");
|
|
1371
|
+
if (await this.writeSeedFile(files, skillPath, skill.rawContent ?? renderSkillMarkdown(skill), options, result)) seeded.add(descriptor.name);
|
|
1372
|
+
}
|
|
1373
|
+
this.workspaceFiles = files;
|
|
1374
|
+
this.workspaceSkillNames = seeded;
|
|
1375
|
+
this.workspaceResources = resources;
|
|
1376
|
+
return result;
|
|
1377
|
+
}
|
|
1378
|
+
/**
|
|
1379
|
+
* Route skill reads through an already-seeded Workspace without probing or
|
|
1380
|
+
* rewriting its files. Hosts use this when the durable source fingerprint
|
|
1381
|
+
* matches the recorded projection fingerprint.
|
|
1382
|
+
*/
|
|
1383
|
+
async useWorkspace(workspace, options = {}) {
|
|
1384
|
+
await this.load();
|
|
1385
|
+
this.workspaceFiles = createSkillWorkspaceFiles(workspace, options.root);
|
|
1386
|
+
this.workspaceSkillNames = new Set(this.descriptors.keys());
|
|
1387
|
+
this.workspaceResources.clear();
|
|
1388
|
+
}
|
|
1389
|
+
async writeSeedFile(files, path, content, options, result) {
|
|
1390
|
+
try {
|
|
1391
|
+
if (options.onConflict !== "replace" && await files.exists(path)) {
|
|
1392
|
+
result.preserved++;
|
|
1393
|
+
return true;
|
|
1394
|
+
}
|
|
1395
|
+
await files.writeText(path, content);
|
|
1396
|
+
result.written++;
|
|
1397
|
+
return true;
|
|
1398
|
+
} catch {
|
|
1399
|
+
result.skipped++;
|
|
1400
|
+
return false;
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1187
1403
|
async snapshot() {
|
|
1188
1404
|
await this.load();
|
|
1189
1405
|
const catalog = [];
|
|
@@ -1192,6 +1408,7 @@ var SkillRegistry = class {
|
|
|
1192
1408
|
fingerprint: this.fingerprint,
|
|
1193
1409
|
catalogPrompt: catalog.length ? [
|
|
1194
1410
|
"Available skills. When a task matches a skill, use activate_skill with its name before proceeding.",
|
|
1411
|
+
...this.workspaceFiles ? [`Skill files are available at ${this.workspaceFiles.root}. Workspace edits affect later activations and resource reads.`] : [],
|
|
1195
1412
|
"",
|
|
1196
1413
|
...catalog
|
|
1197
1414
|
].join("\n") : null
|
|
@@ -1203,7 +1420,23 @@ var SkillRegistry = class {
|
|
|
1203
1420
|
async loadSkill(name) {
|
|
1204
1421
|
await this.load();
|
|
1205
1422
|
const source = this.sourceBySkill.get(name);
|
|
1206
|
-
|
|
1423
|
+
if (!source) return null;
|
|
1424
|
+
const original = await source.load(name);
|
|
1425
|
+
if (!original) return null;
|
|
1426
|
+
this.workspaceResources.set(name, new Map((original.resources ?? []).map((resource) => [resource.path, resource])));
|
|
1427
|
+
if (!this.workspaceSkillNames.has(name)) return original;
|
|
1428
|
+
const rawContent = await this.workspaceFiles?.readText(this.workspaceFiles.path(name, "SKILL.md"));
|
|
1429
|
+
if (rawContent === null || rawContent === void 0) return null;
|
|
1430
|
+
const parsed = parseSkillMarkdown(rawContent);
|
|
1431
|
+
if (!parsed) return null;
|
|
1432
|
+
return {
|
|
1433
|
+
...original,
|
|
1434
|
+
...parsed,
|
|
1435
|
+
rawContent,
|
|
1436
|
+
sourceId: original.sourceId,
|
|
1437
|
+
version: original.version,
|
|
1438
|
+
resources: original.resources
|
|
1439
|
+
};
|
|
1207
1440
|
}
|
|
1208
1441
|
resolveResourceTarget(name, path) {
|
|
1209
1442
|
const pathError = validateResourcePath(path);
|
|
@@ -1233,6 +1466,24 @@ var SkillRegistry = class {
|
|
|
1233
1466
|
}
|
|
1234
1467
|
async readResource(name, path) {
|
|
1235
1468
|
const source = this.sourceBySkill.get(name);
|
|
1469
|
+
if (this.workspaceSkillNames.has(name) && this.workspaceFiles) {
|
|
1470
|
+
let descriptor = this.workspaceResources.get(name)?.get(path);
|
|
1471
|
+
if (!descriptor) {
|
|
1472
|
+
const skill = await source?.load(name);
|
|
1473
|
+
const resources = new Map((skill?.resources ?? []).map((resource) => [resource.path, resource]));
|
|
1474
|
+
this.workspaceResources.set(name, resources);
|
|
1475
|
+
descriptor = resources.get(path);
|
|
1476
|
+
}
|
|
1477
|
+
if (!descriptor) return `Resource not found: ${name}/${path}`;
|
|
1478
|
+
const workspacePath = this.workspaceFiles.path(name, path);
|
|
1479
|
+
const existing = await this.workspaceFiles.readResource(workspacePath, descriptor);
|
|
1480
|
+
if (existing) return existing;
|
|
1481
|
+
if (!source?.readResource) return `Skill "${name}" has no readable resources.`;
|
|
1482
|
+
const resource = await source.readResource(name, path);
|
|
1483
|
+
if (!resource) return `Resource not found: ${name}/${path}`;
|
|
1484
|
+
await this.workspaceFiles.writeResource(workspacePath, resource);
|
|
1485
|
+
return resource;
|
|
1486
|
+
}
|
|
1236
1487
|
if (!source?.readResource) return `Skill "${name}" has no readable resources.`;
|
|
1237
1488
|
return await source.readResource(name, path) ?? `Resource not found: ${name}/${path}`;
|
|
1238
1489
|
}
|
|
@@ -1296,10 +1547,8 @@ var SkillRegistry = class {
|
|
|
1296
1547
|
const script = skill.resources?.find((resource) => resource.path === path);
|
|
1297
1548
|
if (!script) return `Script not found: ${name}/${path}`;
|
|
1298
1549
|
if (script.kind !== "script") return `Resource is not a script: ${name}/${path}`;
|
|
1299
|
-
const
|
|
1300
|
-
if (
|
|
1301
|
-
const resource = await source.readResource(name, path);
|
|
1302
|
-
if (!resource) return `Script not found: ${name}/${path}`;
|
|
1550
|
+
const resource = await this.readResource(name, path);
|
|
1551
|
+
if (typeof resource === "string") return resource;
|
|
1303
1552
|
if ((resource.encoding ?? "text") !== "text") return `Script resource must be text, got ${resource.encoding}: ${name}/${path}`;
|
|
1304
1553
|
try {
|
|
1305
1554
|
return await this.scriptRunner.run({
|