@dotobokuri/fleet-console 1.23.0 → 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 -257
- package/README.md +8 -0
- package/dist/cli.d.ts +11 -1
- package/dist/cli.mjs +1738 -453
- package/dist/client/assets/{_baseUniq-BjOe5yYF.js → _baseUniq-yooYbTgN.js} +1 -1
- package/dist/client/assets/{arc-bFUuO3jf.js → arc-D4mme5Ts.js} +1 -1
- package/dist/client/assets/{architectureDiagram-Q4EWVU46-Ba7nimQq.js → architectureDiagram-Q4EWVU46-BAJOviEX.js} +1 -1
- package/dist/client/assets/{blockDiagram-DXYQGD6D-CQGf47hl.js → blockDiagram-DXYQGD6D-DuObpxQ3.js} +1 -1
- package/dist/client/assets/{c4Diagram-AHTNJAMY-DZF_cAK4.js → c4Diagram-AHTNJAMY-BOT-SD34.js} +1 -1
- package/dist/client/assets/channel-TZYyAq1v.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-DjUUHSQ5.js → chunk-4BX2VUAB-BF_aMTes.js} +1 -1
- package/dist/client/assets/{chunk-4TB4RGXK-Dvqti8bd.js → chunk-4TB4RGXK-M4brBcnD.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-2BxiBvkp.js → chunk-55IACEB6-CrG-4b2Z.js} +1 -1
- package/dist/client/assets/{chunk-EDXVE4YY-CqCjol5O.js → chunk-EDXVE4YY-BxDSygH1.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-eoCfIbly.js → chunk-FMBD7UC4-Bh7MEX7E.js} +1 -1
- package/dist/client/assets/{chunk-OYMX7WX6-CoC86V_1.js → chunk-OYMX7WX6-DBnBwxer.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-CJQA5mlQ.js → chunk-QZHKN3VN-bjAogQwW.js} +1 -1
- package/dist/client/assets/{chunk-YZCP3GAM-C5C4kbLu.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-CahuunpL.js → cose-bilkent-S5V4N54A-Bm5QA4zo.js} +1 -1
- package/dist/client/assets/{dagre-KV5264BT-Cbv5kSi5.js → dagre-KV5264BT-PzXQN-5Q.js} +1 -1
- package/dist/client/assets/{diagram-5BDNPKRD-CNm40ZGB.js → diagram-5BDNPKRD-KhaAKPtX.js} +1 -1
- package/dist/client/assets/{diagram-G4DWMVQ6-DrlGNT3i.js → diagram-G4DWMVQ6-DBbjfiR8.js} +1 -1
- package/dist/client/assets/{diagram-MMDJMWI5-r8Y2oqmw.js → diagram-MMDJMWI5-QWro7PRX.js} +1 -1
- package/dist/client/assets/{diagram-TYMM5635-CMzEhXup.js → diagram-TYMM5635-B9LqWrbF.js} +1 -1
- package/dist/client/assets/{erDiagram-SMLLAGMA-UFjUUMPz.js → erDiagram-SMLLAGMA-b0VkMMN4.js} +1 -1
- package/dist/client/assets/{flowDiagram-DWJPFMVM-Dd1STmYc.js → flowDiagram-DWJPFMVM-edxBAbe6.js} +1 -1
- package/dist/client/assets/{ganttDiagram-T4ZO3ILL-CHHU0hVd.js → ganttDiagram-T4ZO3ILL-ks2Gg1_V.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-vj2HukAF.js → gitGraphDiagram-UUTBAWPF-DymUyYNl.js} +1 -1
- package/dist/client/assets/{graph-DhjfEbEb.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-CC7AEgDm.js → infoDiagram-42DDH7IO-B5iLIYAc.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-DlRw2B9G.js → ishikawaDiagram-UXIWVN3A-DnztLLn7.js} +1 -1
- package/dist/client/assets/{journeyDiagram-VCZTEJTY-BbRXANKQ.js → journeyDiagram-VCZTEJTY-BKDRfH1Y.js} +1 -1
- package/dist/client/assets/{kanban-definition-6JOO6SKY-DtvdCxGN.js → kanban-definition-6JOO6SKY-DPB3Phvr.js} +1 -1
- package/dist/client/assets/{layout-Dg5cvw5v.js → layout-BEeRhYTG.js} +1 -1
- package/dist/client/assets/{linear-BvVlQLqF.js → linear-QzmfWKSq.js} +1 -1
- package/dist/client/assets/{mermaid.core-DzrV8sC-.js → mermaid.core-BVka5dgm.js} +4 -4
- package/dist/client/assets/{min-DNGQ1Ciz.js → min-CfXk9kSN.js} +1 -1
- package/dist/client/assets/{mindmap-definition-QFDTVHPH-DxJCNZbg.js → mindmap-definition-QFDTVHPH-tGrGhr6Z.js} +1 -1
- package/dist/client/assets/{pieDiagram-DEJITSTG-B75XHG-s.js → pieDiagram-DEJITSTG-ZRBqRiRK.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-34T5L4WZ-CL4yoF0m.js → quadrantDiagram-34T5L4WZ-VCINZgct.js} +1 -1
- package/dist/client/assets/{requirementDiagram-MS252O5E-kGV4vcr1.js → requirementDiagram-MS252O5E-DFLzADh3.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-XADWPNL6-DoA4u7wI.js → sankeyDiagram-XADWPNL6-BbouN8Ji.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-FGHM5R23-ZpNDf1bS.js → sequenceDiagram-FGHM5R23-B58_LF0R.js} +1 -1
- package/dist/client/assets/{stateDiagram-FHFEXIEX-BzgKcVAG.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-B_DkUDsD.js → timeline-definition-GMOUNBTQ-4jQdCvaj.js} +1 -1
- package/dist/client/assets/{vennDiagram-DHZGUBPP-MCUnnsKb.js → vennDiagram-DHZGUBPP-CUr1fH6N.js} +1 -1
- package/dist/client/assets/{wardley-RL74JXVD-D_JAMSxj.js → wardley-RL74JXVD-D0cfvvNA.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-NUSXRM2D-BHCwZGLq.js → wardleyDiagram-NUSXRM2D-D0l_Rp_Z.js} +1 -1
- package/dist/client/assets/{xychartDiagram-5P7HB3ND-FbGwbD3V.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 -82
- package/dist/fleet-plugins/terminal/routes.mjs +190 -176
- package/package.json +7 -2
- package/dist/client/assets/channel-D2BahVp1.js +0 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-DsDAVLhS.js +0 -1
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-DsDAVLhS.js +0 -1
- package/dist/client/assets/clone-CdZy2Xzf.js +0 -1
- package/dist/client/assets/index-Dq9EKm2G.css +0 -1
- package/dist/client/assets/index-DtzbOdd7.js +0 -380
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-yRK5hzZ4.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) {
|
|
@@ -16663,18 +16663,18 @@ async function ensureCliMjs(cliHome, onBootstrap) {
|
|
|
16663
16663
|
if (_cliMjsPath) return _cliMjsPath;
|
|
16664
16664
|
if (_bootstrapPromise) return _bootstrapPromise;
|
|
16665
16665
|
_bootstrapPromise = (async () => {
|
|
16666
|
-
const mjsPath =
|
|
16667
|
-
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");
|
|
16668
16668
|
let needsInstall = true;
|
|
16669
16669
|
try {
|
|
16670
|
-
const raw = await
|
|
16670
|
+
const raw = await fs4.readFile(pkgPath, "utf-8");
|
|
16671
16671
|
const pkg = JSON.parse(raw);
|
|
16672
16672
|
if (pkg.version === SKILLS_VERSION) needsInstall = false;
|
|
16673
16673
|
} catch {
|
|
16674
16674
|
}
|
|
16675
16675
|
if (needsInstall) {
|
|
16676
16676
|
onBootstrap?.(WARMUP_LINE);
|
|
16677
|
-
await
|
|
16677
|
+
await fs4.mkdir(cliHome, { recursive: true });
|
|
16678
16678
|
await runNpmInstall(cliHome);
|
|
16679
16679
|
}
|
|
16680
16680
|
_cliMjsPath = mjsPath;
|
|
@@ -16799,6 +16799,61 @@ function getJobResult(id, cursor) {
|
|
|
16799
16799
|
exitCode: job.exitCode
|
|
16800
16800
|
};
|
|
16801
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
|
+
}
|
|
16802
16857
|
|
|
16803
16858
|
// ../fleet-plugins/skills/server/registry-search.ts
|
|
16804
16859
|
var DEFAULT_SKILLS_API_URL = "https://skills.sh";
|
|
@@ -16873,10 +16928,12 @@ function validateScope(scope) {
|
|
|
16873
16928
|
// ../fleet-plugins/skills/server/handlers.ts
|
|
16874
16929
|
var PREVIEW_TIMEOUT_MS = 3e4;
|
|
16875
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;
|
|
16876
16933
|
async function readSkillSources(cwd) {
|
|
16877
16934
|
const sources = /* @__PURE__ */ new Map();
|
|
16878
16935
|
try {
|
|
16879
|
-
const raw = await
|
|
16936
|
+
const raw = await fs4.readFile(path5.join(cwd, "skills-lock.json"), "utf-8");
|
|
16880
16937
|
const parsed = JSON.parse(raw);
|
|
16881
16938
|
if (typeof parsed === "object" && parsed !== null) {
|
|
16882
16939
|
for (const [name, entry] of Object.entries(parsed)) {
|
|
@@ -16887,7 +16944,7 @@ async function readSkillSources(cwd) {
|
|
|
16887
16944
|
} catch {
|
|
16888
16945
|
}
|
|
16889
16946
|
try {
|
|
16890
|
-
const raw = await
|
|
16947
|
+
const raw = await fs4.readFile(path5.join(cwd, ".agents", ".skill-lock.json"), "utf-8");
|
|
16891
16948
|
const parsed = JSON.parse(raw);
|
|
16892
16949
|
if (typeof parsed === "object" && parsed !== null) {
|
|
16893
16950
|
for (const [name, entry] of Object.entries(parsed)) {
|
|
@@ -16913,6 +16970,21 @@ async function runListCommand(args, cwd, executor) {
|
|
|
16913
16970
|
function buildDisplayPath(scope, name) {
|
|
16914
16971
|
return scope === "global" ? `~/.agents/skills/${name}` : `.agents/skills/${name}`;
|
|
16915
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
|
+
}
|
|
16916
16988
|
function extractSkillMarkdown(raw) {
|
|
16917
16989
|
const text = stripAnsi(raw);
|
|
16918
16990
|
const openTag = "<SKILL.md>";
|
|
@@ -16924,13 +16996,28 @@ function extractSkillMarkdown(raw) {
|
|
|
16924
16996
|
}
|
|
16925
16997
|
return text.trim();
|
|
16926
16998
|
}
|
|
16927
|
-
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) {
|
|
16928
17015
|
setImmediate(() => {
|
|
16929
17016
|
void executor(args, {
|
|
16930
17017
|
cwd,
|
|
16931
17018
|
timeout: CLI_TIMEOUT_MS,
|
|
16932
|
-
onChunk: (chunk) => appendChunk(jobId, chunk),
|
|
16933
|
-
onBootstrap: (line) => appendChunk(jobId, line + "\n")
|
|
17019
|
+
onChunk: (chunk) => appendChunk(jobId, redactJobOutput(chunk, redactionPaths)),
|
|
17020
|
+
onBootstrap: (line) => appendChunk(jobId, redactJobOutput(line + "\n", redactionPaths))
|
|
16934
17021
|
}).then((result) => finishJob(jobId, result.exitCode)).catch(() => finishJob(jobId, 1));
|
|
16935
17022
|
});
|
|
16936
17023
|
}
|
|
@@ -16945,13 +17032,26 @@ async function handleList(req, res, ctx, executor) {
|
|
|
16945
17032
|
}
|
|
16946
17033
|
const url2 = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
16947
17034
|
const theaterId = url2.searchParams.get("theaterId") ?? void 0;
|
|
16948
|
-
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
|
+
}
|
|
16949
17049
|
try {
|
|
16950
|
-
if (
|
|
17050
|
+
if (projectCwd) {
|
|
16951
17051
|
const [projectRaw, globalRaw, projectSources, globalSources] = await Promise.all([
|
|
16952
|
-
runListCommand(["list", "--json"],
|
|
17052
|
+
runListCommand(["list", "--json"], projectCwd, executor),
|
|
16953
17053
|
runListCommand(["list", "-g", "--json"], os2.homedir(), executor),
|
|
16954
|
-
readSkillSources(
|
|
17054
|
+
readSkillSources(projectCwd),
|
|
16955
17055
|
readSkillSources(os2.homedir())
|
|
16956
17056
|
]);
|
|
16957
17057
|
const projectSkills = projectRaw.map((entry) => ({
|
|
@@ -17025,8 +17125,9 @@ async function handleInstall(req, res, ctx, executor) {
|
|
|
17025
17125
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17026
17126
|
return;
|
|
17027
17127
|
}
|
|
17028
|
-
const { source, skill, scope, agents, theaterId: rawTheaterId } = body;
|
|
17128
|
+
const { source, skill, scope, agents, theaterId: rawTheaterId, relPath: rawRelPath } = body;
|
|
17029
17129
|
const theaterId = typeof rawTheaterId === "string" ? rawTheaterId : void 0;
|
|
17130
|
+
const relPath = parseOptionalRelPath(rawRelPath);
|
|
17030
17131
|
if (!validateSource(source)) {
|
|
17031
17132
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17032
17133
|
return;
|
|
@@ -17049,12 +17150,16 @@ async function handleInstall(req, res, ctx, executor) {
|
|
|
17049
17150
|
return;
|
|
17050
17151
|
}
|
|
17051
17152
|
}
|
|
17052
|
-
|
|
17053
|
-
if (scope === "project"
|
|
17054
|
-
|
|
17055
|
-
|
|
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
|
+
}
|
|
17056
17161
|
}
|
|
17057
|
-
const cwd = scope === "global" ? defaultCwd() :
|
|
17162
|
+
const cwd = scope === "global" ? defaultCwd() : projectCwd;
|
|
17058
17163
|
if (!cwd) {
|
|
17059
17164
|
ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
|
|
17060
17165
|
return;
|
|
@@ -17067,7 +17172,7 @@ async function handleInstall(req, res, ctx, executor) {
|
|
|
17067
17172
|
const agentArgs = agents.flatMap((a) => ["--agent", a]);
|
|
17068
17173
|
const scopeFlag = scope === "global" ? ["-g"] : [];
|
|
17069
17174
|
const args = ["add", source, "-y", "--skill", skill, ...scopeFlag, ...agentArgs];
|
|
17070
|
-
spawnJobAsync(jobId, args, cwd, executor);
|
|
17175
|
+
spawnJobAsync(jobId, args, cwd, getJobOutputRedactionPaths(ctx, cwd), executor);
|
|
17071
17176
|
ctx.host.http.writeJson(res, 202, { jobId });
|
|
17072
17177
|
}
|
|
17073
17178
|
async function handleUpdate(req, res, ctx, executor) {
|
|
@@ -17084,18 +17189,23 @@ async function handleUpdate(req, res, ctx, executor) {
|
|
|
17084
17189
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17085
17190
|
return;
|
|
17086
17191
|
}
|
|
17087
|
-
const { scope, theaterId: rawTheaterId } = body;
|
|
17192
|
+
const { scope, theaterId: rawTheaterId, relPath: rawRelPath } = body;
|
|
17088
17193
|
const theaterId = typeof rawTheaterId === "string" ? rawTheaterId : void 0;
|
|
17194
|
+
const relPath = parseOptionalRelPath(rawRelPath);
|
|
17089
17195
|
if (!validateScope(scope)) {
|
|
17090
17196
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17091
17197
|
return;
|
|
17092
17198
|
}
|
|
17093
|
-
|
|
17094
|
-
if (scope === "project"
|
|
17095
|
-
|
|
17096
|
-
|
|
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
|
+
}
|
|
17097
17207
|
}
|
|
17098
|
-
const cwd = scope === "global" ? defaultCwd() :
|
|
17208
|
+
const cwd = scope === "global" ? defaultCwd() : projectCwd;
|
|
17099
17209
|
if (!cwd) {
|
|
17100
17210
|
ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
|
|
17101
17211
|
return;
|
|
@@ -17107,7 +17217,7 @@ async function handleUpdate(req, res, ctx, executor) {
|
|
|
17107
17217
|
}
|
|
17108
17218
|
const scopeFlag = scope === "global" ? "-g" : "-p";
|
|
17109
17219
|
const args = ["update", "-y", scopeFlag];
|
|
17110
|
-
spawnJobAsync(jobId, args, cwd, executor);
|
|
17220
|
+
spawnJobAsync(jobId, args, cwd, getJobOutputRedactionPaths(ctx, cwd), executor);
|
|
17111
17221
|
ctx.host.http.writeJson(res, 202, { jobId });
|
|
17112
17222
|
}
|
|
17113
17223
|
async function handleGetJob(req, res, ctx) {
|
|
@@ -17148,8 +17258,9 @@ async function handleRemove(req, res, ctx, executor) {
|
|
|
17148
17258
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17149
17259
|
return;
|
|
17150
17260
|
}
|
|
17151
|
-
const { scope, skill, theaterId: rawTheaterId } = body;
|
|
17261
|
+
const { scope, skill, theaterId: rawTheaterId, relPath: rawRelPath } = body;
|
|
17152
17262
|
const theaterId = typeof rawTheaterId === "string" ? rawTheaterId : void 0;
|
|
17263
|
+
const relPath = parseOptionalRelPath(rawRelPath);
|
|
17153
17264
|
if (!validateScope(scope)) {
|
|
17154
17265
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17155
17266
|
return;
|
|
@@ -17158,12 +17269,16 @@ async function handleRemove(req, res, ctx, executor) {
|
|
|
17158
17269
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17159
17270
|
return;
|
|
17160
17271
|
}
|
|
17161
|
-
|
|
17162
|
-
if (scope === "project"
|
|
17163
|
-
|
|
17164
|
-
|
|
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
|
+
}
|
|
17165
17280
|
}
|
|
17166
|
-
const cwd = scope === "global" ? defaultCwd() :
|
|
17281
|
+
const cwd = scope === "global" ? defaultCwd() : projectCwd;
|
|
17167
17282
|
if (!cwd) {
|
|
17168
17283
|
ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
|
|
17169
17284
|
return;
|
|
@@ -17193,7 +17308,9 @@ async function handlePreview(req, res, ctx, executor) {
|
|
|
17193
17308
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17194
17309
|
return;
|
|
17195
17310
|
}
|
|
17196
|
-
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);
|
|
17197
17314
|
if (!validateSource(source)) {
|
|
17198
17315
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17199
17316
|
return;
|
|
@@ -17202,8 +17319,22 @@ async function handlePreview(req, res, ctx, executor) {
|
|
|
17202
17319
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17203
17320
|
return;
|
|
17204
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
|
+
}
|
|
17205
17336
|
try {
|
|
17206
|
-
const result = await executor([`use`, `${source}@${skill}`], { cwd
|
|
17337
|
+
const result = await executor([`use`, `${source}@${skill}`], { cwd, timeout: PREVIEW_TIMEOUT_MS });
|
|
17207
17338
|
ctx.host.http.writeJson(res, 200, { markdown: extractSkillMarkdown(result.stdout) });
|
|
17208
17339
|
} catch {
|
|
17209
17340
|
ctx.host.http.writeJson(res, 502, { error: "preview_failed" });
|
|
@@ -17223,8 +17354,9 @@ async function handleInstalledFile(req, res, ctx, executor) {
|
|
|
17223
17354
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17224
17355
|
return;
|
|
17225
17356
|
}
|
|
17226
|
-
const { scope, skill, theaterId: rawTheaterId } = body;
|
|
17357
|
+
const { scope, skill, theaterId: rawTheaterId, relPath: rawRelPath } = body;
|
|
17227
17358
|
const theaterId = typeof rawTheaterId === "string" ? rawTheaterId : void 0;
|
|
17359
|
+
const relPath = parseOptionalRelPath(rawRelPath);
|
|
17228
17360
|
if (!validateScope(scope)) {
|
|
17229
17361
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17230
17362
|
return;
|
|
@@ -17233,12 +17365,16 @@ async function handleInstalledFile(req, res, ctx, executor) {
|
|
|
17233
17365
|
ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
|
|
17234
17366
|
return;
|
|
17235
17367
|
}
|
|
17236
|
-
|
|
17237
|
-
if (scope === "project"
|
|
17238
|
-
|
|
17239
|
-
|
|
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
|
+
}
|
|
17240
17376
|
}
|
|
17241
|
-
const cwd = scope === "global" ? defaultCwd() :
|
|
17377
|
+
const cwd = scope === "global" ? defaultCwd() : projectCwd;
|
|
17242
17378
|
if (!cwd) {
|
|
17243
17379
|
ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
|
|
17244
17380
|
return;
|
|
@@ -17252,28 +17388,28 @@ async function handleInstalledFile(req, res, ctx, executor) {
|
|
|
17252
17388
|
return;
|
|
17253
17389
|
}
|
|
17254
17390
|
const skillRoot = entry.path;
|
|
17255
|
-
const skillMdPath =
|
|
17391
|
+
const skillMdPath = path5.join(skillRoot, "SKILL.md");
|
|
17256
17392
|
const [realAllowedRoot, realRoot, realMd] = await Promise.all([
|
|
17257
17393
|
// CLI가 보고한 skillRoot 자체도 신뢰하지 않는다 — scope의 정당한 상위 경계
|
|
17258
17394
|
// (project=theater 루트, global=홈)를 벗어나면 읽지 않는다. `.agents/skills`로
|
|
17259
17395
|
// 고정하지 않는 이유: claude 단독 설치는 `.claude/skills` 아래에 놓인다.
|
|
17260
|
-
|
|
17261
|
-
|
|
17262
|
-
|
|
17396
|
+
fs4.realpath(cwd),
|
|
17397
|
+
fs4.realpath(skillRoot),
|
|
17398
|
+
fs4.realpath(skillMdPath).catch(() => null)
|
|
17263
17399
|
]);
|
|
17264
17400
|
if (!realMd) {
|
|
17265
17401
|
ctx.host.http.writeJson(res, 404, { error: "skill_not_found" });
|
|
17266
17402
|
return;
|
|
17267
17403
|
}
|
|
17268
|
-
if (realRoot !== realAllowedRoot && !realRoot.startsWith(realAllowedRoot +
|
|
17404
|
+
if (realRoot !== realAllowedRoot && !realRoot.startsWith(realAllowedRoot + path5.sep)) {
|
|
17269
17405
|
ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
|
|
17270
17406
|
return;
|
|
17271
17407
|
}
|
|
17272
|
-
if (realMd !== realRoot && !realMd.startsWith(realRoot +
|
|
17408
|
+
if (realMd !== realRoot && !realMd.startsWith(realRoot + path5.sep)) {
|
|
17273
17409
|
ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
|
|
17274
17410
|
return;
|
|
17275
17411
|
}
|
|
17276
|
-
const markdown = await
|
|
17412
|
+
const markdown = await fs4.readFile(realMd, "utf-8");
|
|
17277
17413
|
ctx.host.http.writeJson(res, 200, { markdown });
|
|
17278
17414
|
} catch {
|
|
17279
17415
|
ctx.host.http.writeJson(res, 502, { error: "read_failed" });
|
|
@@ -17284,7 +17420,7 @@ async function handleInstalledFile(req, res, ctx, executor) {
|
|
|
17284
17420
|
var routes_default = definePlugin({
|
|
17285
17421
|
id: "skills",
|
|
17286
17422
|
register(ctx) {
|
|
17287
|
-
const cliHome =
|
|
17423
|
+
const cliHome = path5.join(ctx.host.paths.pluginDataDir("skills"), "cli");
|
|
17288
17424
|
const executor = createDefaultExecutor(cliHome);
|
|
17289
17425
|
registerRouter(ctx, "list", async ({ req, res }) => {
|
|
17290
17426
|
await handleList(req, res, ctx, executor);
|