agents 0.28.1 → 0.29.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/dist/{agent-routing-BMvWTFEp.d.ts → agent-routing-CDbpVjYq.d.ts} +7 -8
- package/dist/agent-routing.d.ts +1 -1
- package/dist/agent-tool-types.d.ts +1 -1
- package/dist/{agent-tools-ohoewW-B.d.ts → agent-tools-C8DH8Yii.d.ts} +2 -2
- package/dist/agent-tools.d.ts +1 -1
- package/dist/{ai-ahruGw7e.d.ts → ai-iXw0uOGj.d.ts} +3 -3
- package/dist/{ai-sdk-C2iTAwUd.js → ai-sdk-DRPh2rRa.js} +185 -125
- package/dist/ai-sdk-DRPh2rRa.js.map +1 -0
- package/dist/browser/ai.d.ts +1 -1
- package/dist/browser/ai.js +2 -2
- package/dist/browser/index.d.ts +8 -8
- package/dist/browser/index.js +3 -3
- package/dist/browser/tools/ai-sdk.d.ts +2 -2
- package/dist/browser/tools/ai-sdk.js +1 -1
- package/dist/browser/tools/pi.d.ts +1 -1
- package/dist/browser/tools/pi.js +3 -3
- package/dist/browser/tools/pi.js.map +1 -1
- package/dist/browser/tools/tanstack-ai.d.ts +2 -2
- package/dist/browser/tools/tanstack-ai.js +1 -1
- package/dist/{browser-CEdNlsaD.js → browser-DccPw_wW.js} +130 -79
- package/dist/browser-DccPw_wW.js.map +1 -0
- package/dist/{browser-D30VlpcA.d.ts → browser-DlXhSAdf.d.ts} +41 -37
- package/dist/{browser-tool-4iomavs_.js → browser-tool-B1mhifin.js} +3 -3
- package/dist/{browser-tool-4iomavs_.js.map → browser-tool-B1mhifin.js.map} +1 -1
- package/dist/{browser-tool-vtrPOV8e.d.ts → browser-tool-Cxjk5sgG.d.ts} +2 -2
- package/dist/chat/index.d.ts +143 -71
- package/dist/chat/index.js +269 -110
- package/dist/chat/index.js.map +1 -1
- package/dist/chat-sdk/index.d.ts +1 -1
- package/dist/chat-sdk/index.js +1 -1
- package/dist/cli.js +33 -33
- package/dist/{client-Bp-JwL3p.d.ts → client-C27CtRZr.d.ts} +2 -2
- package/dist/client.d.ts +1 -1
- package/dist/{connector-DEXzVoaY.d.ts → connector-20DJ6p4k.d.ts} +2 -2
- package/dist/{connector-CtZylXdk.js → connector-DAXBOIIi.js} +2 -2
- package/dist/{connector-CtZylXdk.js.map → connector-DAXBOIIi.js.map} +1 -1
- package/dist/experimental/channels/web/index.js +1 -1
- package/dist/harness/container/index.js +1 -1
- package/dist/harness/container/index.js.map +1 -1
- package/dist/harness/opencode/index.js +1 -1
- package/dist/harness/pi/index.d.ts +13 -5
- package/dist/harness/pi/index.js +8 -214
- package/dist/harness/pi/index.js.map +1 -1
- package/dist/{images-C4hiIexM.js → images-xaDv2Fqe.js} +636 -168
- package/dist/images-xaDv2Fqe.js.map +1 -0
- package/dist/index-DCxk3OSJ.d.ts +378 -0
- package/dist/{index-kbSUIer3.d.ts → index-iv9FTXX9.d.ts} +80 -112
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{input-schema-xBofjBKC.js → input-schema-B0Etuo-o.js} +2 -2
- package/dist/{input-schema-xBofjBKC.js.map → input-schema-B0Etuo-o.js.map} +1 -1
- package/dist/lifecycle/index.js +1 -1
- package/dist/{lifecycle-DGorpAmA.js → lifecycle-ClT4DmF2.js} +11 -3
- package/dist/lifecycle-ClT4DmF2.js.map +1 -0
- package/dist/mcp/client/index.d.ts +1 -1
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/models/ai-sdk/index.d.ts +29 -352
- package/dist/models/ai-sdk/index.js +1 -1
- package/dist/models/opencode/index.d.ts +25 -13
- package/dist/models/opencode/index.js +16 -11
- package/dist/models/opencode/index.js.map +1 -1
- package/dist/models/pi-ai/index.d.ts +13 -14
- package/dist/models/pi-ai/index.js +85 -32
- package/dist/models/pi-ai/index.js.map +1 -1
- package/dist/react.d.ts +2 -2
- package/dist/routing/index.d.ts +1 -1
- package/dist/serializable.d.ts +1 -1
- package/dist/{session-store-DoPY12xM.d.ts → session-store-_IK6dV-w.d.ts} +14 -2
- package/dist/{session-store-Do4xkDcf.js → session-store-yvwq1f9x.js} +55 -2
- package/dist/session-store-yvwq1f9x.js.map +1 -0
- package/dist/{settings-BjAiPd6Z.js → settings-Dk2il2Hf.js} +4 -1
- package/dist/settings-Dk2il2Hf.js.map +1 -0
- package/dist/skills/index.d.ts +22 -28
- package/dist/skills/index.js +183 -143
- package/dist/skills/index.js.map +1 -1
- package/dist/{src-CQxJFv4l.js → src-6lr7MtM_.js} +3 -3
- package/dist/src-6lr7MtM_.js.map +1 -0
- package/dist/sub-routing.d.ts +1 -1
- package/dist/{tool-VF0qiO7q.js → tool-DkT_DJBm.js} +2 -2
- package/dist/tool-DkT_DJBm.js.map +1 -0
- package/dist/transport-CPh7YGiw.d.ts +623 -0
- package/dist/voice/index.d.ts +1 -1
- package/dist/web/fetch/tools/pi.js +2 -2
- package/dist/web/fetch/tools/pi.js.map +1 -1
- package/dist/web/search/index.js +1 -1
- package/dist/web/search/tools/ai-sdk.js +2 -2
- package/dist/web/search/tools/pi.js +3 -3
- package/dist/web/search/tools/pi.js.map +1 -1
- package/dist/web/search/tools/tanstack-ai.js +2 -2
- package/dist/websockets/index.js +1 -1
- package/dist/{websockets-C3zy8YR0.js → websockets-CqxnntmE.js} +2 -2
- package/dist/{websockets-C3zy8YR0.js.map → websockets-CqxnntmE.js.map} +1 -1
- package/dist/workflow-types.d.ts +1 -1
- package/dist/workflows.d.ts +1 -1
- package/dist/workflows.js +1 -1
- package/docs/browse-the-web.md +1 -1
- package/docs/chat-agents.md +19 -18
- package/docs/harnesses/pi.md +47 -18
- package/docs/models-pi-ai.md +62 -20
- package/docs/models.md +197 -172
- package/package.json +7 -7
- package/dist/ai-sdk-C2iTAwUd.js.map +0 -1
- package/dist/browser-CEdNlsaD.js.map +0 -1
- package/dist/images-C4hiIexM.js.map +0 -1
- package/dist/lifecycle-DGorpAmA.js.map +0 -1
- package/dist/session-store-Do4xkDcf.js.map +0 -1
- package/dist/settings-BjAiPd6Z.js.map +0 -1
- package/dist/settings-DnD__xuE.d.ts +0 -349
- package/dist/src-CQxJFv4l.js.map +0 -1
- package/dist/tool-VF0qiO7q.js.map +0 -1
- package/dist/transport-DCyarnwm.d.ts +0 -200
package/dist/skills/index.js
CHANGED
|
@@ -324,6 +324,185 @@ function r2(bucket, options = {}) {
|
|
|
324
324
|
};
|
|
325
325
|
}
|
|
326
326
|
//#endregion
|
|
327
|
+
//#region src/skills/workspace.ts
|
|
328
|
+
/** Directory skill scripts and relative paths resolve against. */
|
|
329
|
+
const WORKSPACE_ROOT = "/workspace";
|
|
330
|
+
const TEXT_ENCODER = new TextEncoder();
|
|
331
|
+
const TEXT_DECODER = new TextDecoder();
|
|
332
|
+
/** @internal Adapt a Workspace for projecting skills into it. */
|
|
333
|
+
function createSkillWorkspaceFiles(workspace, rootOverride) {
|
|
334
|
+
const root = parseRoot(rootOverride ?? `${WORKSPACE_ROOT}/.agents/skills`);
|
|
335
|
+
const access = createSkillWorkspaceAccess(workspace);
|
|
336
|
+
const readBytes = async (path) => {
|
|
337
|
+
try {
|
|
338
|
+
return await drain(await workspace.fs.readFile(path));
|
|
339
|
+
} catch (error) {
|
|
340
|
+
if (isNotFound(error)) return null;
|
|
341
|
+
throw error;
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
return {
|
|
345
|
+
root,
|
|
346
|
+
path(name, relativePath) {
|
|
347
|
+
return `${root}/${parseSkillDirectoryName(name)}/${parseRelativePath(relativePath)}`;
|
|
348
|
+
},
|
|
349
|
+
async exists(path) {
|
|
350
|
+
return await access.stat(path) !== null;
|
|
351
|
+
},
|
|
352
|
+
readText: (path) => access.readFile(path),
|
|
353
|
+
async readResource(path, descriptor) {
|
|
354
|
+
if ((descriptor.encoding ?? "text") === "text") {
|
|
355
|
+
const content = await access.readFile(path);
|
|
356
|
+
return content === null ? null : {
|
|
357
|
+
...descriptor,
|
|
358
|
+
content
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
const bytes = await readBytes(path);
|
|
362
|
+
return bytes === null ? null : {
|
|
363
|
+
...descriptor,
|
|
364
|
+
content: encodeBase64(bytes)
|
|
365
|
+
};
|
|
366
|
+
},
|
|
367
|
+
writeText: (path, content) => access.writeFile(path, content),
|
|
368
|
+
async writeResource(path, resource) {
|
|
369
|
+
await access.writeFile(path, (resource.encoding ?? "text") === "text" ? resource.content : decodeBase64(resource.content));
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* @internal Adapt a Workspace for skill scripts. Relative paths resolve
|
|
375
|
+
* against `/workspace`.
|
|
376
|
+
*/
|
|
377
|
+
function createSkillWorkspaceAccess(workspace) {
|
|
378
|
+
const { fs } = workspace;
|
|
379
|
+
const access = {
|
|
380
|
+
async readFile(path) {
|
|
381
|
+
try {
|
|
382
|
+
return TEXT_DECODER.decode(await drain(await fs.readFile(resolvePath(path))));
|
|
383
|
+
} catch (error) {
|
|
384
|
+
if (isNotFound(error)) return null;
|
|
385
|
+
throw error;
|
|
386
|
+
}
|
|
387
|
+
},
|
|
388
|
+
async listFiles(path) {
|
|
389
|
+
const directory = resolvePath(path);
|
|
390
|
+
return (await fs.readdir(directory)).map((entry) => ({
|
|
391
|
+
path: `${directory.replace(/\/$/, "")}/${entry.name}`,
|
|
392
|
+
name: entry.name,
|
|
393
|
+
type: entry.isDirectory ? "directory" : "file",
|
|
394
|
+
size: entry.size
|
|
395
|
+
}));
|
|
396
|
+
},
|
|
397
|
+
async glob(pattern) {
|
|
398
|
+
const segments = resolvePath(pattern).split("/").filter(Boolean);
|
|
399
|
+
const firstGlob = segments.findIndex((part) => /[*?[\]{}]/.test(part));
|
|
400
|
+
if (firstGlob === -1) {
|
|
401
|
+
const path = `/${segments.join("/")}`;
|
|
402
|
+
const found = await access.stat(path);
|
|
403
|
+
return found === null ? [] : [{
|
|
404
|
+
path,
|
|
405
|
+
...found
|
|
406
|
+
}];
|
|
407
|
+
}
|
|
408
|
+
let matches;
|
|
409
|
+
try {
|
|
410
|
+
matches = await fs.find(`/${segments.slice(0, firstGlob).join("/")}`, segments.slice(firstGlob).join("/"));
|
|
411
|
+
} catch (error) {
|
|
412
|
+
if (isNotFound(error)) return [];
|
|
413
|
+
throw error;
|
|
414
|
+
}
|
|
415
|
+
return Promise.all(matches.map(async (match) => match.type === "dir" ? {
|
|
416
|
+
path: match.path,
|
|
417
|
+
type: "directory",
|
|
418
|
+
size: 0
|
|
419
|
+
} : {
|
|
420
|
+
path: match.path,
|
|
421
|
+
type: "file",
|
|
422
|
+
size: (await fs.stat(match.path)).size
|
|
423
|
+
}));
|
|
424
|
+
},
|
|
425
|
+
async stat(path) {
|
|
426
|
+
try {
|
|
427
|
+
const info = await fs.stat(resolvePath(path));
|
|
428
|
+
return {
|
|
429
|
+
type: info.isDirectory ? "directory" : "file",
|
|
430
|
+
size: info.size
|
|
431
|
+
};
|
|
432
|
+
} catch (error) {
|
|
433
|
+
if (isNotFound(error)) return null;
|
|
434
|
+
throw error;
|
|
435
|
+
}
|
|
436
|
+
},
|
|
437
|
+
async writeFile(path, content) {
|
|
438
|
+
const absolute = resolvePath(path);
|
|
439
|
+
const parent = absolute.slice(0, absolute.lastIndexOf("/"));
|
|
440
|
+
if (parent) await fs.mkdir(parent, { recursive: true });
|
|
441
|
+
await fs.writeFile(absolute, typeof content === "string" ? TEXT_ENCODER.encode(content) : content);
|
|
442
|
+
}
|
|
443
|
+
};
|
|
444
|
+
return access;
|
|
445
|
+
}
|
|
446
|
+
function resolvePath(path) {
|
|
447
|
+
if (path.startsWith("/")) return path;
|
|
448
|
+
const relative = path.replace(/^\.(\/|$)/, "");
|
|
449
|
+
return relative === "" ? WORKSPACE_ROOT : `${WORKSPACE_ROOT}/${relative}`;
|
|
450
|
+
}
|
|
451
|
+
function parseRoot(root) {
|
|
452
|
+
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}`);
|
|
453
|
+
const normalized = root.replace(/\/{2,}/g, "/").replace(/\/$/, "");
|
|
454
|
+
if (!normalized) throw new Error("Skill Workspace root cannot be /");
|
|
455
|
+
return normalized;
|
|
456
|
+
}
|
|
457
|
+
function parseSkillDirectoryName(name) {
|
|
458
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name)) throw new Error(`Skill name must be a safe Workspace directory name: ${name}`);
|
|
459
|
+
return name;
|
|
460
|
+
}
|
|
461
|
+
function parseRelativePath(path) {
|
|
462
|
+
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}`);
|
|
463
|
+
return path;
|
|
464
|
+
}
|
|
465
|
+
function isNotFound(error) {
|
|
466
|
+
if (!error || typeof error !== "object") return false;
|
|
467
|
+
const record = error;
|
|
468
|
+
return record.code === "ENOENT" || typeof record.message === "string" && /ENOENT|no such file|not found/i.test(record.message);
|
|
469
|
+
}
|
|
470
|
+
async function drain(stream) {
|
|
471
|
+
const parts = [];
|
|
472
|
+
let total = 0;
|
|
473
|
+
const reader = stream.getReader();
|
|
474
|
+
try {
|
|
475
|
+
while (true) {
|
|
476
|
+
const { value, done } = await reader.read();
|
|
477
|
+
if (done) break;
|
|
478
|
+
if (!value || value.byteLength === 0) continue;
|
|
479
|
+
parts.push(value);
|
|
480
|
+
total += value.byteLength;
|
|
481
|
+
}
|
|
482
|
+
} finally {
|
|
483
|
+
reader.releaseLock();
|
|
484
|
+
}
|
|
485
|
+
if (parts.length === 1) return parts[0];
|
|
486
|
+
const bytes = new Uint8Array(total);
|
|
487
|
+
let offset = 0;
|
|
488
|
+
for (const part of parts) {
|
|
489
|
+
bytes.set(part, offset);
|
|
490
|
+
offset += part.byteLength;
|
|
491
|
+
}
|
|
492
|
+
return bytes;
|
|
493
|
+
}
|
|
494
|
+
function decodeBase64(value) {
|
|
495
|
+
const binary = atob(value);
|
|
496
|
+
const bytes = new Uint8Array(binary.length);
|
|
497
|
+
for (let index = 0; index < binary.length; index++) bytes[index] = binary.charCodeAt(index);
|
|
498
|
+
return bytes;
|
|
499
|
+
}
|
|
500
|
+
function encodeBase64(bytes) {
|
|
501
|
+
const parts = [];
|
|
502
|
+
for (let offset = 0; offset < bytes.byteLength; offset += 32768) parts.push(String.fromCharCode(...bytes.subarray(offset, offset + 32768)));
|
|
503
|
+
return btoa(parts.join(""));
|
|
504
|
+
}
|
|
505
|
+
//#endregion
|
|
327
506
|
//#region src/skills/runner.ts
|
|
328
507
|
const DEFAULT_SCRIPT_TIMEOUT_MS = 3e4;
|
|
329
508
|
const MAX_OUTPUT_ARTIFACT_BYTES = 64e3;
|
|
@@ -579,7 +758,7 @@ var SkillScriptHostBridge = class extends RpcTarget {
|
|
|
579
758
|
_classPrivateFieldInitSpec(this, _workspaceAccess, void 0);
|
|
580
759
|
_classPrivateFieldInitSpec(this, _outputs, /* @__PURE__ */ new Map());
|
|
581
760
|
_classPrivateFieldSet2(_tools, this, tools);
|
|
582
|
-
_classPrivateFieldSet2(_workspace, this, workspace);
|
|
761
|
+
_classPrivateFieldSet2(_workspace, this, workspace === void 0 ? void 0 : createSkillWorkspaceAccess(workspace));
|
|
583
762
|
_classPrivateFieldSet2(_workspaceAccess, this, workspaceAccess);
|
|
584
763
|
}
|
|
585
764
|
get workspaceAccess() {
|
|
@@ -595,18 +774,13 @@ var SkillScriptHostBridge = class extends RpcTarget {
|
|
|
595
774
|
return _assertClassBrand(_SkillScriptHostBridge_brand, this, _requireWorkspace).call(this, "read").readFile(path);
|
|
596
775
|
}
|
|
597
776
|
async listFiles(path = ".") {
|
|
598
|
-
return _assertClassBrand(_SkillScriptHostBridge_brand, this, _requireWorkspace).call(this, "read").
|
|
777
|
+
return _assertClassBrand(_SkillScriptHostBridge_brand, this, _requireWorkspace).call(this, "read").listFiles(path);
|
|
599
778
|
}
|
|
600
779
|
async glob(pattern) {
|
|
601
780
|
return _assertClassBrand(_SkillScriptHostBridge_brand, this, _requireWorkspace).call(this, "read").glob(pattern);
|
|
602
781
|
}
|
|
603
782
|
async stat(path) {
|
|
604
|
-
|
|
605
|
-
if (!info) return null;
|
|
606
|
-
return {
|
|
607
|
-
type: info.type,
|
|
608
|
-
size: info.size ?? 0
|
|
609
|
-
};
|
|
783
|
+
return _assertClassBrand(_SkillScriptHostBridge_brand, this, _requireWorkspace).call(this, "read").stat(path);
|
|
610
784
|
}
|
|
611
785
|
async writeFile(path, content) {
|
|
612
786
|
await _assertClassBrand(_SkillScriptHostBridge_brand, this, _requireWorkspace).call(this, "read-write").writeFile(path, content);
|
|
@@ -1097,140 +1271,6 @@ function runner(options) {
|
|
|
1097
1271
|
} };
|
|
1098
1272
|
}
|
|
1099
1273
|
//#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
|
|
1234
1274
|
//#region src/skills/registry.ts
|
|
1235
1275
|
const SKILL_CONTEXT_LABEL = "think_skills";
|
|
1236
1276
|
function stableSourceFingerprint(sources) {
|
|
@@ -1335,7 +1375,7 @@ var SkillRegistry = class {
|
|
|
1335
1375
|
this.warnings.push(...refreshErrors);
|
|
1336
1376
|
}
|
|
1337
1377
|
/**
|
|
1338
|
-
* Seed resolved Agent Skills into
|
|
1378
|
+
* Seed resolved Agent Skills into a Workspace.
|
|
1339
1379
|
* Existing files are preserved by default, and become authoritative for
|
|
1340
1380
|
* activation, resource reads, and script execution.
|
|
1341
1381
|
*/
|