@dotobokuri/fleet-console 1.22.1 → 1.24.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/AGENTS.md +41 -255
- package/README.md +8 -0
- package/dist/cli.d.ts +11 -1
- package/dist/cli.mjs +1866 -515
- package/dist/client/assets/{_baseUniq-cap0P4FK.js → _baseUniq-yooYbTgN.js} +1 -1
- package/dist/client/assets/{arc-yBqa09aK.js → arc-D4mme5Ts.js} +1 -1
- package/dist/client/assets/{architectureDiagram-Q4EWVU46-Bug4qdr-.js → architectureDiagram-Q4EWVU46-BAJOviEX.js} +1 -1
- package/dist/client/assets/{blockDiagram-DXYQGD6D-BkiIL2xt.js → blockDiagram-DXYQGD6D-DuObpxQ3.js} +1 -1
- package/dist/client/assets/{c4Diagram-AHTNJAMY-DYY200Al.js → c4Diagram-AHTNJAMY-BOT-SD34.js} +1 -1
- package/dist/client/assets/channel-TZYyAq1v.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-DQKmhVxn.js → chunk-4BX2VUAB-BF_aMTes.js} +1 -1
- package/dist/client/assets/{chunk-4TB4RGXK-DHpmA3Zl.js → chunk-4TB4RGXK-M4brBcnD.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-DeRDuQXE.js → chunk-55IACEB6-CrG-4b2Z.js} +1 -1
- package/dist/client/assets/{chunk-EDXVE4YY-CNpnhSJm.js → chunk-EDXVE4YY-BxDSygH1.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-BXGVABL-.js → chunk-FMBD7UC4-Bh7MEX7E.js} +1 -1
- package/dist/client/assets/{chunk-OYMX7WX6-WbJs4VwZ.js → chunk-OYMX7WX6-DBnBwxer.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-u3BLl6Sl.js → chunk-QZHKN3VN-bjAogQwW.js} +1 -1
- package/dist/client/assets/{chunk-YZCP3GAM-BFESuhuJ.js → chunk-YZCP3GAM-l4FGlk_c.js} +1 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-Dh6hZUl4.js +1 -0
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-Dh6hZUl4.js +1 -0
- package/dist/client/assets/clone-DgWGnVWH.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-rouOsZjT.js → cose-bilkent-S5V4N54A-Bm5QA4zo.js} +1 -1
- package/dist/client/assets/{dagre-KV5264BT-QCUeCVpM.js → dagre-KV5264BT-PzXQN-5Q.js} +1 -1
- package/dist/client/assets/{diagram-5BDNPKRD-DqerlFb_.js → diagram-5BDNPKRD-KhaAKPtX.js} +1 -1
- package/dist/client/assets/{diagram-G4DWMVQ6-BS3a1YGN.js → diagram-G4DWMVQ6-DBbjfiR8.js} +1 -1
- package/dist/client/assets/{diagram-MMDJMWI5-BeauTcSV.js → diagram-MMDJMWI5-QWro7PRX.js} +1 -1
- package/dist/client/assets/{diagram-TYMM5635-Ci2wLUUE.js → diagram-TYMM5635-B9LqWrbF.js} +1 -1
- package/dist/client/assets/{erDiagram-SMLLAGMA-9MnmiKch.js → erDiagram-SMLLAGMA-b0VkMMN4.js} +1 -1
- package/dist/client/assets/{flowDiagram-DWJPFMVM-CiV9p5EU.js → flowDiagram-DWJPFMVM-edxBAbe6.js} +1 -1
- package/dist/client/assets/{ganttDiagram-T4ZO3ILL-D6oNoENl.js → ganttDiagram-T4ZO3ILL-ks2Gg1_V.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-DESO385F.js → gitGraphDiagram-UUTBAWPF-DymUyYNl.js} +1 -1
- package/dist/client/assets/{graph-BZdl-RHy.js → graph-B-B_mqfh.js} +1 -1
- package/dist/client/assets/index-BgLzfg-v.css +1 -0
- package/dist/client/assets/index-pDnb-q6f.js +380 -0
- package/dist/client/assets/{infoDiagram-42DDH7IO-lc8vZnyi.js → infoDiagram-42DDH7IO-B5iLIYAc.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-BfzvQXhn.js → ishikawaDiagram-UXIWVN3A-DnztLLn7.js} +1 -1
- package/dist/client/assets/{journeyDiagram-VCZTEJTY-BS_Dr0EV.js → journeyDiagram-VCZTEJTY-BKDRfH1Y.js} +1 -1
- package/dist/client/assets/{kanban-definition-6JOO6SKY-Cw7oTQJN.js → kanban-definition-6JOO6SKY-DPB3Phvr.js} +1 -1
- package/dist/client/assets/{layout-ChwcDQm8.js → layout-BEeRhYTG.js} +1 -1
- package/dist/client/assets/{linear-C7GLbmND.js → linear-QzmfWKSq.js} +1 -1
- package/dist/client/assets/{mermaid.core-D9phfpQo.js → mermaid.core-BVka5dgm.js} +4 -4
- package/dist/client/assets/{min-p7Whc_Wi.js → min-CfXk9kSN.js} +1 -1
- package/dist/client/assets/{mindmap-definition-QFDTVHPH-fl_SJKrw.js → mindmap-definition-QFDTVHPH-tGrGhr6Z.js} +1 -1
- package/dist/client/assets/{pieDiagram-DEJITSTG-Btw7ckA5.js → pieDiagram-DEJITSTG-ZRBqRiRK.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-34T5L4WZ-DB4iJlTI.js → quadrantDiagram-34T5L4WZ-VCINZgct.js} +1 -1
- package/dist/client/assets/{requirementDiagram-MS252O5E-hXwV5Nhy.js → requirementDiagram-MS252O5E-DFLzADh3.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-XADWPNL6-DC-fizCk.js → sankeyDiagram-XADWPNL6-BbouN8Ji.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-FGHM5R23-RrfrroR5.js → sequenceDiagram-FGHM5R23-B58_LF0R.js} +1 -1
- package/dist/client/assets/{stateDiagram-FHFEXIEX-q8FUPV_e.js → stateDiagram-FHFEXIEX-pk-OHHuL.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-xsN122JA.js +1 -0
- package/dist/client/assets/{timeline-definition-GMOUNBTQ-tegMd8Od.js → timeline-definition-GMOUNBTQ-4jQdCvaj.js} +1 -1
- package/dist/client/assets/{vennDiagram-DHZGUBPP-CXx5oN2X.js → vennDiagram-DHZGUBPP-CUr1fH6N.js} +1 -1
- package/dist/client/assets/{wardley-RL74JXVD-CxSJ3P_7.js → wardley-RL74JXVD-D0cfvvNA.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-NUSXRM2D-DN1P180Z.js → wardleyDiagram-NUSXRM2D-D0l_Rp_Z.js} +1 -1
- package/dist/client/assets/{xychartDiagram-5P7HB3ND-Dcn9ukv5.js → xychartDiagram-5P7HB3ND-BdR8OEuJ.js} +1 -1
- package/dist/client/index.html +3 -3
- package/dist/desktop-protocol.d.ts +49 -0
- package/dist/desktop-protocol.mjs +99 -0
- package/dist/fleet-plugins/diff/routes.mjs +124 -225
- package/dist/fleet-plugins/skills/routes.mjs +218 -85
- package/dist/fleet-plugins/terminal/routes.mjs +573 -536
- package/package.json +7 -2
- package/dist/client/assets/channel-B3EqY8ya.js +0 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-BekEZLVJ.js +0 -1
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-BekEZLVJ.js +0 -1
- package/dist/client/assets/clone-CsVi9-Ni.js +0 -1
- package/dist/client/assets/index-BKpCMFrm.js +0 -380
- package/dist/client/assets/index-cg8Uxys9.css +0 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-BErzXGq7.js +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
2
|
+
import path5 from 'path';
|
|
3
3
|
import { execFile } from 'child_process';
|
|
4
|
-
import
|
|
4
|
+
import fs4 from 'fs/promises';
|
|
5
5
|
import os2 from 'os';
|
|
6
6
|
import crypto4 from 'crypto';
|
|
7
7
|
import 'http';
|
|
@@ -18,12 +18,12 @@ var __export = (target, all) => {
|
|
|
18
18
|
function definePlugin(definition) {
|
|
19
19
|
return definition;
|
|
20
20
|
}
|
|
21
|
-
function registerRouter(ctx,
|
|
22
|
-
ctx.registerRouter(normalizePath(
|
|
21
|
+
function registerRouter(ctx, path8, handler) {
|
|
22
|
+
ctx.registerRouter(normalizePath(path8), handler);
|
|
23
23
|
}
|
|
24
|
-
function normalizePath(
|
|
25
|
-
if (
|
|
26
|
-
return
|
|
24
|
+
function normalizePath(path8) {
|
|
25
|
+
if (path8.length === 0 || path8 === "/") return "/";
|
|
26
|
+
return path8;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
// ../../node_modules/.pnpm/@agentclientprotocol+sdk@1.2.1_zod@4.4.1/node_modules/@agentclientprotocol/sdk/dist/schema/index.js
|
|
@@ -832,10 +832,10 @@ function mergeDefs(...defs) {
|
|
|
832
832
|
function cloneDef(schema) {
|
|
833
833
|
return mergeDefs(schema._zod.def);
|
|
834
834
|
}
|
|
835
|
-
function getElementAtPath(obj,
|
|
836
|
-
if (!
|
|
835
|
+
function getElementAtPath(obj, path8) {
|
|
836
|
+
if (!path8)
|
|
837
837
|
return obj;
|
|
838
|
-
return
|
|
838
|
+
return path8.reduce((acc, key) => acc?.[key], obj);
|
|
839
839
|
}
|
|
840
840
|
function promiseAllObject(promisesObj) {
|
|
841
841
|
const keys = Object.keys(promisesObj);
|
|
@@ -1244,11 +1244,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
1244
1244
|
}
|
|
1245
1245
|
return false;
|
|
1246
1246
|
}
|
|
1247
|
-
function prefixIssues(
|
|
1247
|
+
function prefixIssues(path8, issues) {
|
|
1248
1248
|
return issues.map((iss) => {
|
|
1249
1249
|
var _a3;
|
|
1250
1250
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
1251
|
-
iss.path.unshift(
|
|
1251
|
+
iss.path.unshift(path8);
|
|
1252
1252
|
return iss;
|
|
1253
1253
|
});
|
|
1254
1254
|
}
|
|
@@ -1395,16 +1395,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1395
1395
|
}
|
|
1396
1396
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
1397
1397
|
const fieldErrors = { _errors: [] };
|
|
1398
|
-
const processError = (error52,
|
|
1398
|
+
const processError = (error52, path8 = []) => {
|
|
1399
1399
|
for (const issue2 of error52.issues) {
|
|
1400
1400
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1401
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1401
|
+
issue2.errors.map((issues) => processError({ issues }, [...path8, ...issue2.path]));
|
|
1402
1402
|
} else if (issue2.code === "invalid_key") {
|
|
1403
|
-
processError({ issues: issue2.issues }, [...
|
|
1403
|
+
processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
|
|
1404
1404
|
} else if (issue2.code === "invalid_element") {
|
|
1405
|
-
processError({ issues: issue2.issues }, [...
|
|
1405
|
+
processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
|
|
1406
1406
|
} else {
|
|
1407
|
-
const fullpath = [...
|
|
1407
|
+
const fullpath = [...path8, ...issue2.path];
|
|
1408
1408
|
if (fullpath.length === 0) {
|
|
1409
1409
|
fieldErrors._errors.push(mapper(issue2));
|
|
1410
1410
|
} else {
|
|
@@ -1431,17 +1431,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1431
1431
|
}
|
|
1432
1432
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
1433
1433
|
const result = { errors: [] };
|
|
1434
|
-
const processError = (error52,
|
|
1434
|
+
const processError = (error52, path8 = []) => {
|
|
1435
1435
|
var _a3, _b;
|
|
1436
1436
|
for (const issue2 of error52.issues) {
|
|
1437
1437
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1438
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1438
|
+
issue2.errors.map((issues) => processError({ issues }, [...path8, ...issue2.path]));
|
|
1439
1439
|
} else if (issue2.code === "invalid_key") {
|
|
1440
|
-
processError({ issues: issue2.issues }, [...
|
|
1440
|
+
processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
|
|
1441
1441
|
} else if (issue2.code === "invalid_element") {
|
|
1442
|
-
processError({ issues: issue2.issues }, [...
|
|
1442
|
+
processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
|
|
1443
1443
|
} else {
|
|
1444
|
-
const fullpath = [...
|
|
1444
|
+
const fullpath = [...path8, ...issue2.path];
|
|
1445
1445
|
if (fullpath.length === 0) {
|
|
1446
1446
|
result.errors.push(mapper(issue2));
|
|
1447
1447
|
continue;
|
|
@@ -1473,8 +1473,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1473
1473
|
}
|
|
1474
1474
|
function toDotPath(_path) {
|
|
1475
1475
|
const segs = [];
|
|
1476
|
-
const
|
|
1477
|
-
for (const seg of
|
|
1476
|
+
const path8 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
1477
|
+
for (const seg of path8) {
|
|
1478
1478
|
if (typeof seg === "number")
|
|
1479
1479
|
segs.push(`[${seg}]`);
|
|
1480
1480
|
else if (typeof seg === "symbol")
|
|
@@ -14138,13 +14138,13 @@ function resolveRef(ref, ctx) {
|
|
|
14138
14138
|
if (!ref.startsWith("#")) {
|
|
14139
14139
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
14140
14140
|
}
|
|
14141
|
-
const
|
|
14142
|
-
if (
|
|
14141
|
+
const path8 = ref.slice(1).split("/").filter(Boolean);
|
|
14142
|
+
if (path8.length === 0) {
|
|
14143
14143
|
return ctx.rootSchema;
|
|
14144
14144
|
}
|
|
14145
14145
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
14146
|
-
if (
|
|
14147
|
-
const key =
|
|
14146
|
+
if (path8[0] === defsKey) {
|
|
14147
|
+
const key = path8[1];
|
|
14148
14148
|
if (!key || !ctx.defs[key]) {
|
|
14149
14149
|
throw new Error(`Reference not found: ${ref}`);
|
|
14150
14150
|
}
|
|
@@ -16312,7 +16312,7 @@ function findBinaryPath(command, env, options = {}) {
|
|
|
16312
16312
|
return findOnPath(command, pathValue, pathExts, platform);
|
|
16313
16313
|
}
|
|
16314
16314
|
function wrapWindowsShim(resolved, env, platform) {
|
|
16315
|
-
if (platform !== "win32" || !WINDOWS_SHIM_EXTENSIONS.has(
|
|
16315
|
+
if (platform !== "win32" || !WINDOWS_SHIM_EXTENSIONS.has(path5.extname(resolved).toLowerCase())) {
|
|
16316
16316
|
return { bin: resolved, prefixArgs: [] };
|
|
16317
16317
|
}
|
|
16318
16318
|
rejectCmdExpansionSensitiveShim(resolved);
|
|
@@ -16330,13 +16330,13 @@ function forceWindowsArgQuoting(value) {
|
|
|
16330
16330
|
return `${value} `;
|
|
16331
16331
|
}
|
|
16332
16332
|
function findOnPath(bin, pathValue, pathExts, platform) {
|
|
16333
|
-
const pathSeparator = platform === "win32" ? WINDOWS_PATH_SEPARATOR :
|
|
16334
|
-
if (hasPathSeparator(bin, platform) ||
|
|
16333
|
+
const pathSeparator = platform === "win32" ? WINDOWS_PATH_SEPARATOR : path5.delimiter;
|
|
16334
|
+
if (hasPathSeparator(bin, platform) || path5.isAbsolute(bin)) {
|
|
16335
16335
|
return resolveWithExtensions(bin, pathExts, platform);
|
|
16336
16336
|
}
|
|
16337
16337
|
for (const entry of pathValue.split(pathSeparator)) {
|
|
16338
16338
|
const searchDir = entry.length === 0 ? "." : entry;
|
|
16339
|
-
const candidate = resolveWithExtensions(
|
|
16339
|
+
const candidate = resolveWithExtensions(path5.join(searchDir, bin), pathExts, platform);
|
|
16340
16340
|
if (candidate) {
|
|
16341
16341
|
return candidate;
|
|
16342
16342
|
}
|
|
@@ -16344,7 +16344,7 @@ function findOnPath(bin, pathValue, pathExts, platform) {
|
|
|
16344
16344
|
return void 0;
|
|
16345
16345
|
}
|
|
16346
16346
|
function resolveWithExtensions(candidate, pathExts, platform) {
|
|
16347
|
-
if (platform !== "win32" ||
|
|
16347
|
+
if (platform !== "win32" || path5.extname(candidate).length > 0) {
|
|
16348
16348
|
return isAccessibleExecutable(candidate, platform) ? candidate : void 0;
|
|
16349
16349
|
}
|
|
16350
16350
|
for (const ext of pathExts) {
|
|
@@ -16613,9 +16613,6 @@ Object.entries(CLI_BACKENDS).map(([id, backend]) => ({
|
|
|
16613
16613
|
protocols: [backend.protocol]
|
|
16614
16614
|
}));
|
|
16615
16615
|
|
|
16616
|
-
// ../../packages/core-unified-agent/src/client/UnifiedCodexAgentClient.ts
|
|
16617
|
-
process.platform === "win32";
|
|
16618
|
-
|
|
16619
16616
|
// ../fleet-plugins/skills/server/cli.ts
|
|
16620
16617
|
var SKILLS_VERSION = "1.5.14";
|
|
16621
16618
|
var SKILLS_PACKAGE = "skills";
|
|
@@ -16666,18 +16663,18 @@ async function ensureCliMjs(cliHome, onBootstrap) {
|
|
|
16666
16663
|
if (_cliMjsPath) return _cliMjsPath;
|
|
16667
16664
|
if (_bootstrapPromise) return _bootstrapPromise;
|
|
16668
16665
|
_bootstrapPromise = (async () => {
|
|
16669
|
-
const mjsPath =
|
|
16670
|
-
const pkgPath =
|
|
16666
|
+
const mjsPath = path5.join(cliHome, "node_modules", SKILLS_PACKAGE, "bin", "cli.mjs");
|
|
16667
|
+
const pkgPath = path5.join(cliHome, "node_modules", SKILLS_PACKAGE, "package.json");
|
|
16671
16668
|
let needsInstall = true;
|
|
16672
16669
|
try {
|
|
16673
|
-
const raw = await
|
|
16670
|
+
const raw = await fs4.readFile(pkgPath, "utf-8");
|
|
16674
16671
|
const pkg = JSON.parse(raw);
|
|
16675
16672
|
if (pkg.version === SKILLS_VERSION) needsInstall = false;
|
|
16676
16673
|
} catch {
|
|
16677
16674
|
}
|
|
16678
16675
|
if (needsInstall) {
|
|
16679
16676
|
onBootstrap?.(WARMUP_LINE);
|
|
16680
|
-
await
|
|
16677
|
+
await fs4.mkdir(cliHome, { recursive: true });
|
|
16681
16678
|
await runNpmInstall(cliHome);
|
|
16682
16679
|
}
|
|
16683
16680
|
_cliMjsPath = mjsPath;
|
|
@@ -16802,6 +16799,61 @@ function getJobResult(id, cursor) {
|
|
|
16802
16799
|
exitCode: job.exitCode
|
|
16803
16800
|
};
|
|
16804
16801
|
}
|
|
16802
|
+
var ProjectPathError = class extends Error {
|
|
16803
|
+
code;
|
|
16804
|
+
constructor(code) {
|
|
16805
|
+
super(code);
|
|
16806
|
+
this.name = "ProjectPathError";
|
|
16807
|
+
this.code = code;
|
|
16808
|
+
}
|
|
16809
|
+
};
|
|
16810
|
+
async function resolveProjectCwd(theaterRoot, relPath) {
|
|
16811
|
+
if (relPath !== null && !isSafeRelativePath(relPath)) {
|
|
16812
|
+
throw new ProjectPathError("invalid_rel_path");
|
|
16813
|
+
}
|
|
16814
|
+
const lexicalRoot = path5.resolve(theaterRoot);
|
|
16815
|
+
const lexicalTarget = path5.resolve(lexicalRoot, relPath ?? ".");
|
|
16816
|
+
if (!isContainedBy(lexicalRoot, lexicalTarget)) {
|
|
16817
|
+
throw new ProjectPathError("path_outside_theater");
|
|
16818
|
+
}
|
|
16819
|
+
let realRoot;
|
|
16820
|
+
let realTarget;
|
|
16821
|
+
try {
|
|
16822
|
+
[realRoot, realTarget] = await Promise.all([
|
|
16823
|
+
fs4.realpath(lexicalRoot),
|
|
16824
|
+
fs4.realpath(lexicalTarget)
|
|
16825
|
+
]);
|
|
16826
|
+
} catch (error51) {
|
|
16827
|
+
throw mapFilesystemError(error51);
|
|
16828
|
+
}
|
|
16829
|
+
if (!isContainedBy(realRoot, realTarget)) {
|
|
16830
|
+
throw new ProjectPathError("path_outside_theater");
|
|
16831
|
+
}
|
|
16832
|
+
try {
|
|
16833
|
+
if (!(await fs4.stat(realTarget)).isDirectory()) {
|
|
16834
|
+
throw new ProjectPathError("invalid_rel_path");
|
|
16835
|
+
}
|
|
16836
|
+
} catch (error51) {
|
|
16837
|
+
if (error51 instanceof ProjectPathError) throw error51;
|
|
16838
|
+
throw mapFilesystemError(error51);
|
|
16839
|
+
}
|
|
16840
|
+
return realTarget;
|
|
16841
|
+
}
|
|
16842
|
+
function isSafeRelativePath(value) {
|
|
16843
|
+
if (!value || value.includes("\0") || path5.isAbsolute(value) || path5.posix.isAbsolute(value) || path5.win32.isAbsolute(value)) {
|
|
16844
|
+
return false;
|
|
16845
|
+
}
|
|
16846
|
+
return value.split(/[\\/]/).every((segment) => segment !== "" && segment !== "." && segment !== "..");
|
|
16847
|
+
}
|
|
16848
|
+
function isContainedBy(root, target) {
|
|
16849
|
+
return target === root || target.startsWith(root.endsWith(path5.sep) ? root : root + path5.sep);
|
|
16850
|
+
}
|
|
16851
|
+
function mapFilesystemError(error51) {
|
|
16852
|
+
const code = error51.code;
|
|
16853
|
+
if (code === "EACCES" || code === "EPERM") return new ProjectPathError("path_outside_theater");
|
|
16854
|
+
if (code === "ENOENT" || code === "ENOTDIR") return new ProjectPathError("not_found");
|
|
16855
|
+
return new ProjectPathError("invalid_rel_path");
|
|
16856
|
+
}
|
|
16805
16857
|
|
|
16806
16858
|
// ../fleet-plugins/skills/server/registry-search.ts
|
|
16807
16859
|
var DEFAULT_SKILLS_API_URL = "https://skills.sh";
|
|
@@ -16876,10 +16928,12 @@ function validateScope(scope) {
|
|
|
16876
16928
|
// ../fleet-plugins/skills/server/handlers.ts
|
|
16877
16929
|
var PREVIEW_TIMEOUT_MS = 3e4;
|
|
16878
16930
|
var CLI_TIMEOUT_MS = 12e4;
|
|
16931
|
+
var USERINFO_URL_RE = /\b[a-z][a-z0-9+.-]*:\/\/[^\s/@]+@[^\s]+/gi;
|
|
16932
|
+
var TOKEN_URL_PARAM_RE = /([?&](?:access_?token|token|api_?key|apikey|auth(?:orization)?|password|secret|credential)=)[^&#\s]*/gi;
|
|
16879
16933
|
async function readSkillSources(cwd) {
|
|
16880
16934
|
const sources = /* @__PURE__ */ new Map();
|
|
16881
16935
|
try {
|
|
16882
|
-
const raw = await
|
|
16936
|
+
const raw = await fs4.readFile(path5.join(cwd, "skills-lock.json"), "utf-8");
|
|
16883
16937
|
const parsed = JSON.parse(raw);
|
|
16884
16938
|
if (typeof parsed === "object" && parsed !== null) {
|
|
16885
16939
|
for (const [name, entry] of Object.entries(parsed)) {
|
|
@@ -16890,7 +16944,7 @@ async function readSkillSources(cwd) {
|
|
|
16890
16944
|
} catch {
|
|
16891
16945
|
}
|
|
16892
16946
|
try {
|
|
16893
|
-
const raw = await
|
|
16947
|
+
const raw = await fs4.readFile(path5.join(cwd, ".agents", ".skill-lock.json"), "utf-8");
|
|
16894
16948
|
const parsed = JSON.parse(raw);
|
|
16895
16949
|
if (typeof parsed === "object" && parsed !== null) {
|
|
16896
16950
|
for (const [name, entry] of Object.entries(parsed)) {
|
|
@@ -16916,6 +16970,21 @@ async function runListCommand(args, cwd, executor) {
|
|
|
16916
16970
|
function buildDisplayPath(scope, name) {
|
|
16917
16971
|
return scope === "global" ? `~/.agents/skills/${name}` : `.agents/skills/${name}`;
|
|
16918
16972
|
}
|
|
16973
|
+
function parseOptionalRelPath(value) {
|
|
16974
|
+
if (value === void 0 || value === null) return null;
|
|
16975
|
+
return typeof value === "string" ? value : void 0;
|
|
16976
|
+
}
|
|
16977
|
+
async function resolveProjectScopeCwd(ctx, theaterId, relPath) {
|
|
16978
|
+
if (!theaterId) return null;
|
|
16979
|
+
if (relPath === void 0) throw new ProjectPathError("invalid_rel_path");
|
|
16980
|
+
const theaterRoot = ctx.host.paths.resolveTheaterPath(theaterId);
|
|
16981
|
+
return theaterRoot ? resolveProjectCwd(theaterRoot, relPath) : null;
|
|
16982
|
+
}
|
|
16983
|
+
function writeProjectPathError(res, ctx, error51) {
|
|
16984
|
+
if (!(error51 instanceof ProjectPathError)) throw error51;
|
|
16985
|
+
const status = error51.code === "path_outside_theater" ? 403 : error51.code === "not_found" ? 404 : 400;
|
|
16986
|
+
ctx.host.http.writeJson(res, status, { error: error51.code });
|
|
16987
|
+
}
|
|
16919
16988
|
function extractSkillMarkdown(raw) {
|
|
16920
16989
|
const text = stripAnsi(raw);
|
|
16921
16990
|
const openTag = "<SKILL.md>";
|
|
@@ -16927,13 +16996,28 @@ function extractSkillMarkdown(raw) {
|
|
|
16927
16996
|
}
|
|
16928
16997
|
return text.trim();
|
|
16929
16998
|
}
|
|
16930
|
-
function
|
|
16999
|
+
function redactJobOutput(chunk, paths) {
|
|
17000
|
+
let redacted = chunk.replace(USERINFO_URL_RE, "[redacted credential URL]").replace(TOKEN_URL_PARAM_RE, "$1[redacted]");
|
|
17001
|
+
const sensitivePaths = [.../* @__PURE__ */ new Set([paths.cwd, paths.homeDir, paths.pluginDataDir])].filter(Boolean).sort((a, b) => b.length - a.length);
|
|
17002
|
+
for (const sensitivePath of sensitivePaths) {
|
|
17003
|
+
redacted = redacted.replaceAll(sensitivePath, "[redacted path]");
|
|
17004
|
+
}
|
|
17005
|
+
return redacted;
|
|
17006
|
+
}
|
|
17007
|
+
function getJobOutputRedactionPaths(ctx, cwd) {
|
|
17008
|
+
return {
|
|
17009
|
+
cwd,
|
|
17010
|
+
homeDir: os2.homedir(),
|
|
17011
|
+
pluginDataDir: ctx.host.paths.pluginDataDir("skills")
|
|
17012
|
+
};
|
|
17013
|
+
}
|
|
17014
|
+
function spawnJobAsync(jobId, args, cwd, redactionPaths, executor) {
|
|
16931
17015
|
setImmediate(() => {
|
|
16932
17016
|
void executor(args, {
|
|
16933
17017
|
cwd,
|
|
16934
17018
|
timeout: CLI_TIMEOUT_MS,
|
|
16935
|
-
onChunk: (chunk) => appendChunk(jobId, chunk),
|
|
16936
|
-
onBootstrap: (line) => appendChunk(jobId, line + "\n")
|
|
17019
|
+
onChunk: (chunk) => appendChunk(jobId, redactJobOutput(chunk, redactionPaths)),
|
|
17020
|
+
onBootstrap: (line) => appendChunk(jobId, redactJobOutput(line + "\n", redactionPaths))
|
|
16937
17021
|
}).then((result) => finishJob(jobId, result.exitCode)).catch(() => finishJob(jobId, 1));
|
|
16938
17022
|
});
|
|
16939
17023
|
}
|
|
@@ -16948,13 +17032,26 @@ async function handleList(req, res, ctx, executor) {
|
|
|
16948
17032
|
}
|
|
16949
17033
|
const url2 = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
16950
17034
|
const theaterId = url2.searchParams.get("theaterId") ?? void 0;
|
|
16951
|
-
const
|
|
17035
|
+
const relPath = url2.searchParams.has("relPath") ? url2.searchParams.get("relPath") || null : null;
|
|
17036
|
+
let projectCwd = null;
|
|
17037
|
+
if (theaterId) {
|
|
17038
|
+
try {
|
|
17039
|
+
projectCwd = await resolveProjectScopeCwd(ctx, theaterId, relPath);
|
|
17040
|
+
} catch (error51) {
|
|
17041
|
+
writeProjectPathError(res, ctx, error51);
|
|
17042
|
+
return;
|
|
17043
|
+
}
|
|
17044
|
+
if (!projectCwd) {
|
|
17045
|
+
ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
|
|
17046
|
+
return;
|
|
17047
|
+
}
|
|
17048
|
+
}
|
|
16952
17049
|
try {
|
|
16953
|
-
if (
|
|
17050
|
+
if (projectCwd) {
|
|
16954
17051
|
const [projectRaw, globalRaw, projectSources, globalSources] = await Promise.all([
|
|
16955
|
-
runListCommand(["list", "--json"],
|
|
17052
|
+
runListCommand(["list", "--json"], projectCwd, executor),
|
|
16956
17053
|
runListCommand(["list", "-g", "--json"], os2.homedir(), executor),
|
|
16957
|
-
readSkillSources(
|
|
17054
|
+
readSkillSources(projectCwd),
|
|
16958
17055
|
readSkillSources(os2.homedir())
|
|
16959
17056
|
]);
|
|
16960
17057
|
const projectSkills = projectRaw.map((entry) => ({
|
|
@@ -17028,8 +17125,9 @@ async function handleInstall(req, res, ctx, executor) {
|
|
|
17028
17125
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17029
17126
|
return;
|
|
17030
17127
|
}
|
|
17031
|
-
const { source, skill, scope, agents, theaterId: rawTheaterId } = body;
|
|
17128
|
+
const { source, skill, scope, agents, theaterId: rawTheaterId, relPath: rawRelPath } = body;
|
|
17032
17129
|
const theaterId = typeof rawTheaterId === "string" ? rawTheaterId : void 0;
|
|
17130
|
+
const relPath = parseOptionalRelPath(rawRelPath);
|
|
17033
17131
|
if (!validateSource(source)) {
|
|
17034
17132
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17035
17133
|
return;
|
|
@@ -17052,12 +17150,16 @@ async function handleInstall(req, res, ctx, executor) {
|
|
|
17052
17150
|
return;
|
|
17053
17151
|
}
|
|
17054
17152
|
}
|
|
17055
|
-
|
|
17056
|
-
if (scope === "project"
|
|
17057
|
-
|
|
17058
|
-
|
|
17153
|
+
let projectCwd = null;
|
|
17154
|
+
if (scope === "project") {
|
|
17155
|
+
try {
|
|
17156
|
+
projectCwd = await resolveProjectScopeCwd(ctx, theaterId, relPath);
|
|
17157
|
+
} catch (error51) {
|
|
17158
|
+
writeProjectPathError(res, ctx, error51);
|
|
17159
|
+
return;
|
|
17160
|
+
}
|
|
17059
17161
|
}
|
|
17060
|
-
const cwd = scope === "global" ? defaultCwd() :
|
|
17162
|
+
const cwd = scope === "global" ? defaultCwd() : projectCwd;
|
|
17061
17163
|
if (!cwd) {
|
|
17062
17164
|
ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
|
|
17063
17165
|
return;
|
|
@@ -17070,7 +17172,7 @@ async function handleInstall(req, res, ctx, executor) {
|
|
|
17070
17172
|
const agentArgs = agents.flatMap((a) => ["--agent", a]);
|
|
17071
17173
|
const scopeFlag = scope === "global" ? ["-g"] : [];
|
|
17072
17174
|
const args = ["add", source, "-y", "--skill", skill, ...scopeFlag, ...agentArgs];
|
|
17073
|
-
spawnJobAsync(jobId, args, cwd, executor);
|
|
17175
|
+
spawnJobAsync(jobId, args, cwd, getJobOutputRedactionPaths(ctx, cwd), executor);
|
|
17074
17176
|
ctx.host.http.writeJson(res, 202, { jobId });
|
|
17075
17177
|
}
|
|
17076
17178
|
async function handleUpdate(req, res, ctx, executor) {
|
|
@@ -17087,18 +17189,23 @@ async function handleUpdate(req, res, ctx, executor) {
|
|
|
17087
17189
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17088
17190
|
return;
|
|
17089
17191
|
}
|
|
17090
|
-
const { scope, theaterId: rawTheaterId } = body;
|
|
17192
|
+
const { scope, theaterId: rawTheaterId, relPath: rawRelPath } = body;
|
|
17091
17193
|
const theaterId = typeof rawTheaterId === "string" ? rawTheaterId : void 0;
|
|
17194
|
+
const relPath = parseOptionalRelPath(rawRelPath);
|
|
17092
17195
|
if (!validateScope(scope)) {
|
|
17093
17196
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17094
17197
|
return;
|
|
17095
17198
|
}
|
|
17096
|
-
|
|
17097
|
-
if (scope === "project"
|
|
17098
|
-
|
|
17099
|
-
|
|
17199
|
+
let projectCwd = null;
|
|
17200
|
+
if (scope === "project") {
|
|
17201
|
+
try {
|
|
17202
|
+
projectCwd = await resolveProjectScopeCwd(ctx, theaterId, relPath);
|
|
17203
|
+
} catch (error51) {
|
|
17204
|
+
writeProjectPathError(res, ctx, error51);
|
|
17205
|
+
return;
|
|
17206
|
+
}
|
|
17100
17207
|
}
|
|
17101
|
-
const cwd = scope === "global" ? defaultCwd() :
|
|
17208
|
+
const cwd = scope === "global" ? defaultCwd() : projectCwd;
|
|
17102
17209
|
if (!cwd) {
|
|
17103
17210
|
ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
|
|
17104
17211
|
return;
|
|
@@ -17110,7 +17217,7 @@ async function handleUpdate(req, res, ctx, executor) {
|
|
|
17110
17217
|
}
|
|
17111
17218
|
const scopeFlag = scope === "global" ? "-g" : "-p";
|
|
17112
17219
|
const args = ["update", "-y", scopeFlag];
|
|
17113
|
-
spawnJobAsync(jobId, args, cwd, executor);
|
|
17220
|
+
spawnJobAsync(jobId, args, cwd, getJobOutputRedactionPaths(ctx, cwd), executor);
|
|
17114
17221
|
ctx.host.http.writeJson(res, 202, { jobId });
|
|
17115
17222
|
}
|
|
17116
17223
|
async function handleGetJob(req, res, ctx) {
|
|
@@ -17151,8 +17258,9 @@ async function handleRemove(req, res, ctx, executor) {
|
|
|
17151
17258
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17152
17259
|
return;
|
|
17153
17260
|
}
|
|
17154
|
-
const { scope, skill, theaterId: rawTheaterId } = body;
|
|
17261
|
+
const { scope, skill, theaterId: rawTheaterId, relPath: rawRelPath } = body;
|
|
17155
17262
|
const theaterId = typeof rawTheaterId === "string" ? rawTheaterId : void 0;
|
|
17263
|
+
const relPath = parseOptionalRelPath(rawRelPath);
|
|
17156
17264
|
if (!validateScope(scope)) {
|
|
17157
17265
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17158
17266
|
return;
|
|
@@ -17161,12 +17269,16 @@ async function handleRemove(req, res, ctx, executor) {
|
|
|
17161
17269
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17162
17270
|
return;
|
|
17163
17271
|
}
|
|
17164
|
-
|
|
17165
|
-
if (scope === "project"
|
|
17166
|
-
|
|
17167
|
-
|
|
17272
|
+
let projectCwd = null;
|
|
17273
|
+
if (scope === "project") {
|
|
17274
|
+
try {
|
|
17275
|
+
projectCwd = await resolveProjectScopeCwd(ctx, theaterId, relPath);
|
|
17276
|
+
} catch (error51) {
|
|
17277
|
+
writeProjectPathError(res, ctx, error51);
|
|
17278
|
+
return;
|
|
17279
|
+
}
|
|
17168
17280
|
}
|
|
17169
|
-
const cwd = scope === "global" ? defaultCwd() :
|
|
17281
|
+
const cwd = scope === "global" ? defaultCwd() : projectCwd;
|
|
17170
17282
|
if (!cwd) {
|
|
17171
17283
|
ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
|
|
17172
17284
|
return;
|
|
@@ -17196,7 +17308,9 @@ async function handlePreview(req, res, ctx, executor) {
|
|
|
17196
17308
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17197
17309
|
return;
|
|
17198
17310
|
}
|
|
17199
|
-
const { source, skill } = body;
|
|
17311
|
+
const { source, skill, theaterId: rawTheaterId, relPath: rawRelPath } = body;
|
|
17312
|
+
const theaterId = typeof rawTheaterId === "string" ? rawTheaterId : void 0;
|
|
17313
|
+
const relPath = parseOptionalRelPath(rawRelPath);
|
|
17200
17314
|
if (!validateSource(source)) {
|
|
17201
17315
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17202
17316
|
return;
|
|
@@ -17205,8 +17319,22 @@ async function handlePreview(req, res, ctx, executor) {
|
|
|
17205
17319
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17206
17320
|
return;
|
|
17207
17321
|
}
|
|
17322
|
+
let cwd = defaultCwd();
|
|
17323
|
+
if (theaterId) {
|
|
17324
|
+
try {
|
|
17325
|
+
const projectCwd = await resolveProjectScopeCwd(ctx, theaterId, relPath);
|
|
17326
|
+
if (!projectCwd) {
|
|
17327
|
+
ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
|
|
17328
|
+
return;
|
|
17329
|
+
}
|
|
17330
|
+
cwd = projectCwd;
|
|
17331
|
+
} catch (error51) {
|
|
17332
|
+
writeProjectPathError(res, ctx, error51);
|
|
17333
|
+
return;
|
|
17334
|
+
}
|
|
17335
|
+
}
|
|
17208
17336
|
try {
|
|
17209
|
-
const result = await executor([`use`, `${source}@${skill}`], { cwd
|
|
17337
|
+
const result = await executor([`use`, `${source}@${skill}`], { cwd, timeout: PREVIEW_TIMEOUT_MS });
|
|
17210
17338
|
ctx.host.http.writeJson(res, 200, { markdown: extractSkillMarkdown(result.stdout) });
|
|
17211
17339
|
} catch {
|
|
17212
17340
|
ctx.host.http.writeJson(res, 502, { error: "preview_failed" });
|
|
@@ -17226,8 +17354,9 @@ async function handleInstalledFile(req, res, ctx, executor) {
|
|
|
17226
17354
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17227
17355
|
return;
|
|
17228
17356
|
}
|
|
17229
|
-
const { scope, skill, theaterId: rawTheaterId } = body;
|
|
17357
|
+
const { scope, skill, theaterId: rawTheaterId, relPath: rawRelPath } = body;
|
|
17230
17358
|
const theaterId = typeof rawTheaterId === "string" ? rawTheaterId : void 0;
|
|
17359
|
+
const relPath = parseOptionalRelPath(rawRelPath);
|
|
17231
17360
|
if (!validateScope(scope)) {
|
|
17232
17361
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17233
17362
|
return;
|
|
@@ -17236,12 +17365,16 @@ async function handleInstalledFile(req, res, ctx, executor) {
|
|
|
17236
17365
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17237
17366
|
return;
|
|
17238
17367
|
}
|
|
17239
|
-
|
|
17240
|
-
if (scope === "project"
|
|
17241
|
-
|
|
17242
|
-
|
|
17368
|
+
let projectCwd = null;
|
|
17369
|
+
if (scope === "project") {
|
|
17370
|
+
try {
|
|
17371
|
+
projectCwd = await resolveProjectScopeCwd(ctx, theaterId, relPath);
|
|
17372
|
+
} catch (error51) {
|
|
17373
|
+
writeProjectPathError(res, ctx, error51);
|
|
17374
|
+
return;
|
|
17375
|
+
}
|
|
17243
17376
|
}
|
|
17244
|
-
const cwd = scope === "global" ? defaultCwd() :
|
|
17377
|
+
const cwd = scope === "global" ? defaultCwd() : projectCwd;
|
|
17245
17378
|
if (!cwd) {
|
|
17246
17379
|
ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
|
|
17247
17380
|
return;
|
|
@@ -17255,28 +17388,28 @@ async function handleInstalledFile(req, res, ctx, executor) {
|
|
|
17255
17388
|
return;
|
|
17256
17389
|
}
|
|
17257
17390
|
const skillRoot = entry.path;
|
|
17258
|
-
const skillMdPath =
|
|
17391
|
+
const skillMdPath = path5.join(skillRoot, "SKILL.md");
|
|
17259
17392
|
const [realAllowedRoot, realRoot, realMd] = await Promise.all([
|
|
17260
17393
|
// CLI가 보고한 skillRoot 자체도 신뢰하지 않는다 — scope의 정당한 상위 경계
|
|
17261
17394
|
// (project=theater 루트, global=홈)를 벗어나면 읽지 않는다. `.agents/skills`로
|
|
17262
17395
|
// 고정하지 않는 이유: claude 단독 설치는 `.claude/skills` 아래에 놓인다.
|
|
17263
|
-
|
|
17264
|
-
|
|
17265
|
-
|
|
17396
|
+
fs4.realpath(cwd),
|
|
17397
|
+
fs4.realpath(skillRoot),
|
|
17398
|
+
fs4.realpath(skillMdPath).catch(() => null)
|
|
17266
17399
|
]);
|
|
17267
17400
|
if (!realMd) {
|
|
17268
17401
|
ctx.host.http.writeJson(res, 404, { error: "skill_not_found" });
|
|
17269
17402
|
return;
|
|
17270
17403
|
}
|
|
17271
|
-
if (realRoot !== realAllowedRoot && !realRoot.startsWith(realAllowedRoot +
|
|
17404
|
+
if (realRoot !== realAllowedRoot && !realRoot.startsWith(realAllowedRoot + path5.sep)) {
|
|
17272
17405
|
ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
|
|
17273
17406
|
return;
|
|
17274
17407
|
}
|
|
17275
|
-
if (realMd !== realRoot && !realMd.startsWith(realRoot +
|
|
17408
|
+
if (realMd !== realRoot && !realMd.startsWith(realRoot + path5.sep)) {
|
|
17276
17409
|
ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
|
|
17277
17410
|
return;
|
|
17278
17411
|
}
|
|
17279
|
-
const markdown = await
|
|
17412
|
+
const markdown = await fs4.readFile(realMd, "utf-8");
|
|
17280
17413
|
ctx.host.http.writeJson(res, 200, { markdown });
|
|
17281
17414
|
} catch {
|
|
17282
17415
|
ctx.host.http.writeJson(res, 502, { error: "read_failed" });
|
|
@@ -17287,7 +17420,7 @@ async function handleInstalledFile(req, res, ctx, executor) {
|
|
|
17287
17420
|
var routes_default = definePlugin({
|
|
17288
17421
|
id: "skills",
|
|
17289
17422
|
register(ctx) {
|
|
17290
|
-
const cliHome =
|
|
17423
|
+
const cliHome = path5.join(ctx.host.paths.pluginDataDir("skills"), "cli");
|
|
17291
17424
|
const executor = createDefaultExecutor(cliHome);
|
|
17292
17425
|
registerRouter(ctx, "list", async ({ req, res }) => {
|
|
17293
17426
|
await handleList(req, res, ctx, executor);
|