@dotobokuri/fleet-console 1.69.0 → 1.71.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.
Files changed (69) hide show
  1. package/dist/cli.mjs +38 -4
  2. package/dist/client/assets/{_baseUniq-BPBd-J9P.js → _baseUniq--GYoaiDn.js} +1 -1
  3. package/dist/client/assets/{arc-spHqy4X3.js → arc-ioTPutEb.js} +1 -1
  4. package/dist/client/assets/{architectureDiagram-Q4EWVU46-7CHqKfxu.js → architectureDiagram-Q4EWVU46-DLfH6cdt.js} +1 -1
  5. package/dist/client/assets/{blockDiagram-DXYQGD6D-YasFDgl_.js → blockDiagram-DXYQGD6D-ZM6X_dlD.js} +1 -1
  6. package/dist/client/assets/{c4Diagram-AHTNJAMY-CcoPJq56.js → c4Diagram-AHTNJAMY-DDPTnZGS.js} +1 -1
  7. package/dist/client/assets/channel-BvAoE0IP.js +1 -0
  8. package/dist/client/assets/{chunk-4BX2VUAB-MYBJn9BE.js → chunk-4BX2VUAB-0ShpcAto.js} +1 -1
  9. package/dist/client/assets/{chunk-4TB4RGXK-C1wg6GR_.js → chunk-4TB4RGXK-CvMAl5bA.js} +1 -1
  10. package/dist/client/assets/{chunk-55IACEB6-BoufMT1O.js → chunk-55IACEB6-CgV8t6TS.js} +1 -1
  11. package/dist/client/assets/{chunk-EDXVE4YY-BzAhAIl3.js → chunk-EDXVE4YY-DQkbYjs9.js} +1 -1
  12. package/dist/client/assets/{chunk-FMBD7UC4-yVrLsKzP.js → chunk-FMBD7UC4-D4Pm3UM-.js} +1 -1
  13. package/dist/client/assets/{chunk-OYMX7WX6-YiiKaqRQ.js → chunk-OYMX7WX6-BrWIgOQ6.js} +1 -1
  14. package/dist/client/assets/{chunk-QZHKN3VN-CqWQlGHT.js → chunk-QZHKN3VN-BC-GEuDl.js} +1 -1
  15. package/dist/client/assets/{chunk-YZCP3GAM-9yLOmU5k.js → chunk-YZCP3GAM-Dst--QPc.js} +1 -1
  16. package/dist/client/assets/classDiagram-6PBFFD2Q-BeVFxENS.js +1 -0
  17. package/dist/client/assets/classDiagram-v2-HSJHXN6E-BeVFxENS.js +1 -0
  18. package/dist/client/assets/clone-TnYsvJuQ.js +1 -0
  19. package/dist/client/assets/{cose-bilkent-S5V4N54A-XkTuSq7v.js → cose-bilkent-S5V4N54A-D87Ru6Nw.js} +1 -1
  20. package/dist/client/assets/{dagre-KV5264BT-DyzXIEAe.js → dagre-KV5264BT-CUG8AIPS.js} +1 -1
  21. package/dist/client/assets/{diagram-5BDNPKRD-DF24YlCa.js → diagram-5BDNPKRD-DrhhXUdy.js} +1 -1
  22. package/dist/client/assets/{diagram-G4DWMVQ6-CVhcj9RK.js → diagram-G4DWMVQ6-DgGQFVlD.js} +1 -1
  23. package/dist/client/assets/{diagram-MMDJMWI5-C-kGKk4K.js → diagram-MMDJMWI5-DEyFyzNg.js} +1 -1
  24. package/dist/client/assets/{diagram-TYMM5635-mr285WbR.js → diagram-TYMM5635-ari8AKd5.js} +1 -1
  25. package/dist/client/assets/{erDiagram-SMLLAGMA-BtEx-XlU.js → erDiagram-SMLLAGMA-Aywt-vx8.js} +1 -1
  26. package/dist/client/assets/{flowDiagram-DWJPFMVM-DuWy3xzN.js → flowDiagram-DWJPFMVM-FO46vDh_.js} +1 -1
  27. package/dist/client/assets/{ganttDiagram-T4ZO3ILL-B2-xEikU.js → ganttDiagram-T4ZO3ILL-C0m3r6C5.js} +1 -1
  28. package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-EM17u_t7.js → gitGraphDiagram-UUTBAWPF-CTUKGfIc.js} +1 -1
  29. package/dist/client/assets/{graph-xuE12FIq.js → graph-PzhNFXt_.js} +1 -1
  30. package/dist/client/assets/index-Bcc3Exng.css +1 -0
  31. package/dist/client/assets/index-DkOT93yC.js +467 -0
  32. package/dist/client/assets/{infoDiagram-42DDH7IO-B3MF4XtW.js → infoDiagram-42DDH7IO-CFry6eYn.js} +1 -1
  33. package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-DoQ2mGyh.js → ishikawaDiagram-UXIWVN3A-BBJvVjTh.js} +1 -1
  34. package/dist/client/assets/{journeyDiagram-VCZTEJTY-GeR9sFH-.js → journeyDiagram-VCZTEJTY-glHJeITG.js} +1 -1
  35. package/dist/client/assets/{kanban-definition-6JOO6SKY-DrrYMuvL.js → kanban-definition-6JOO6SKY-Dp7IjAmS.js} +1 -1
  36. package/dist/client/assets/{layout-DH63A-3u.js → layout-PhtOMDDE.js} +1 -1
  37. package/dist/client/assets/{linear-BIjE6zB1.js → linear-B3pjuRWl.js} +1 -1
  38. package/dist/client/assets/{mermaid.core-yrrC2Lqo.js → mermaid.core-DDurtDWt.js} +4 -4
  39. package/dist/client/assets/{min-CR-H8E6U.js → min-ZS3oLuaq.js} +1 -1
  40. package/dist/client/assets/{mindmap-definition-QFDTVHPH-BzSC43J-.js → mindmap-definition-QFDTVHPH-D67iQI4K.js} +1 -1
  41. package/dist/client/assets/{pieDiagram-DEJITSTG-BdghNtCc.js → pieDiagram-DEJITSTG-B95nftHb.js} +1 -1
  42. package/dist/client/assets/{quadrantDiagram-34T5L4WZ-s_zN2epw.js → quadrantDiagram-34T5L4WZ-BbBVDSwm.js} +1 -1
  43. package/dist/client/assets/{requirementDiagram-MS252O5E-DuiGG6Tx.js → requirementDiagram-MS252O5E-Dbtcs04o.js} +1 -1
  44. package/dist/client/assets/{sankeyDiagram-XADWPNL6-Bp0JBk2g.js → sankeyDiagram-XADWPNL6-BuqmxYyX.js} +1 -1
  45. package/dist/client/assets/{sequenceDiagram-FGHM5R23-AzQ3M31V.js → sequenceDiagram-FGHM5R23-DmLihX3U.js} +1 -1
  46. package/dist/client/assets/{stateDiagram-FHFEXIEX-BGgm44ev.js → stateDiagram-FHFEXIEX-D3Z_iYXj.js} +1 -1
  47. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-BbUn16lr.js +1 -0
  48. package/dist/client/assets/{timeline-definition-GMOUNBTQ-UqfsiBJY.js → timeline-definition-GMOUNBTQ-witmATQr.js} +1 -1
  49. package/dist/client/assets/{vennDiagram-DHZGUBPP-PsCGF9nR.js → vennDiagram-DHZGUBPP-BDI4z0F-.js} +1 -1
  50. package/dist/client/assets/{wardley-RL74JXVD-BDQbnh-d.js → wardley-RL74JXVD-oYmBD5eO.js} +1 -1
  51. package/dist/client/assets/{wardleyDiagram-NUSXRM2D-CtVA1JMs.js → wardleyDiagram-NUSXRM2D-DhnyRjSq.js} +1 -1
  52. package/dist/client/assets/{xychartDiagram-5P7HB3ND-BsLlZWbc.js → xychartDiagram-5P7HB3ND-DUY-bU_6.js} +1 -1
  53. package/dist/client/index.html +2 -2
  54. package/dist/fleet-plugins/file-explorer/routes.mjs +138 -96
  55. package/dist/fleet-plugins/ledger/routes.mjs +33 -2
  56. package/dist/fleet-plugins/quota/routes.mjs +33 -2
  57. package/dist/fleet-plugins/repository/routes.mjs +41 -5
  58. package/dist/fleet-plugins/scuttlebutt/routes.mjs +34 -2
  59. package/dist/fleet-plugins/skills/routes.mjs +126 -60
  60. package/dist/fleet-plugins/terminal/routes.mjs +1482 -786
  61. package/dist/fleet.mjs +1462 -705
  62. package/package.json +1 -1
  63. package/dist/client/assets/channel-DfEjadrw.js +0 -1
  64. package/dist/client/assets/classDiagram-6PBFFD2Q-D9vQdv0q.js +0 -1
  65. package/dist/client/assets/classDiagram-v2-HSJHXN6E-D9vQdv0q.js +0 -1
  66. package/dist/client/assets/clone-Ck2x5JX2.js +0 -1
  67. package/dist/client/assets/index-C5EOZGlC.js +0 -466
  68. package/dist/client/assets/index-CHHE3nPw.css +0 -1
  69. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-CZDbnuN-.js +0 -1
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import path from 'node:path';
3
3
  import { execFile } from 'node:child_process';
4
- import fs3 from 'node:fs/promises';
4
+ import fs4 from 'node:fs/promises';
5
5
  import os2 from 'node:os';
6
6
  import { existsSync, accessSync, constants } from 'node:fs';
7
7
  import crypto from 'node:crypto';
@@ -10,16 +10,16 @@ import crypto from 'node:crypto';
10
10
  function definePlugin(definition) {
11
11
  return definition;
12
12
  }
13
- function registerRouter(ctx, path6, handler, catalog) {
13
+ function registerRouter(ctx, path7, handler, catalog) {
14
14
  if (catalog) {
15
- ctx.registerRouter(normalizePath(path6), handler, catalog);
15
+ ctx.registerRouter(normalizePath(path7), handler, catalog);
16
16
  return;
17
17
  }
18
- ctx.registerRouter(normalizePath(path6), handler);
18
+ ctx.registerRouter(normalizePath(path7), handler);
19
19
  }
20
- function normalizePath(path6) {
21
- if (path6.length === 0 || path6 === "/") return "/";
22
- return path6;
20
+ function normalizePath(path7) {
21
+ if (path7.length === 0 || path7 === "/") return "/";
22
+ return path7;
23
23
  }
24
24
  var DEFAULT_WINDOWS_PATHEXT = ".COM;.EXE;.BAT;.CMD";
25
25
  var WINDOWS_PATH_SEPARATOR = ";";
@@ -161,14 +161,14 @@ async function ensureCliMjs(cliHome, onBootstrap) {
161
161
  const pkgPath = path.join(cliHome, "node_modules", SKILLS_PACKAGE, "package.json");
162
162
  let needsInstall = true;
163
163
  try {
164
- const raw = await fs3.readFile(pkgPath, "utf-8");
164
+ const raw = await fs4.readFile(pkgPath, "utf-8");
165
165
  const pkg = JSON.parse(raw);
166
166
  if (pkg.version === SKILLS_VERSION) needsInstall = false;
167
167
  } catch {
168
168
  }
169
169
  if (needsInstall) {
170
170
  onBootstrap?.(WARMUP_LINE);
171
- await fs3.mkdir(cliHome, { recursive: true });
171
+ await fs4.mkdir(cliHome, { recursive: true });
172
172
  await runNpmInstall(cliHome);
173
173
  }
174
174
  _cliMjsPath = mjsPath;
@@ -293,6 +293,55 @@ function getJobResult(id, cursor) {
293
293
  exitCode: job.exitCode
294
294
  };
295
295
  }
296
+ var HEAD_BYTES = 8192;
297
+ var MAX_DESCRIPTION = 500;
298
+ function parseSkillDescription(head) {
299
+ const text = head.charCodeAt(0) === 65279 ? head.slice(1) : head;
300
+ if (!/^---\r?\n/.test(text)) return void 0;
301
+ const body = text.slice(text.indexOf("\n") + 1);
302
+ const endIndex = body.search(/^---\s*$/m);
303
+ if (endIndex === -1) return void 0;
304
+ const lines = body.slice(0, endIndex).split(/\r?\n/);
305
+ const startLine = lines.findIndex((line) => /^description\s*:/.test(line));
306
+ if (startLine === -1) return void 0;
307
+ const first = (lines[startLine] ?? "").replace(/^description\s*:\s*/, "");
308
+ if (/^[>|]/.test(first.trim())) return void 0;
309
+ const parts = [first.trim()];
310
+ for (let i = startLine + 1; i < lines.length; i += 1) {
311
+ const line = lines[i] ?? "";
312
+ if (!/^\s+\S/.test(line)) break;
313
+ parts.push(line.trim());
314
+ }
315
+ let value = parts.filter(Boolean).join(" ").trim();
316
+ if (value.startsWith('"') && value.endsWith('"') && value.length > 1 || value.startsWith("'") && value.endsWith("'") && value.length > 1) {
317
+ value = value.slice(1, -1).trim();
318
+ }
319
+ if (!value) return void 0;
320
+ return value.length > MAX_DESCRIPTION ? value.slice(0, MAX_DESCRIPTION) : value;
321
+ }
322
+ async function readSkillDescription(skillRoot, allowedRoot) {
323
+ let handle;
324
+ try {
325
+ const [realAllowedRoot, realRoot] = await Promise.all([
326
+ fs4.realpath(allowedRoot),
327
+ fs4.realpath(skillRoot)
328
+ ]);
329
+ if (realRoot !== realAllowedRoot && !realRoot.startsWith(realAllowedRoot + path.sep)) {
330
+ return void 0;
331
+ }
332
+ const realMd = await fs4.realpath(path.join(realRoot, "SKILL.md"));
333
+ if (!realMd.startsWith(realRoot + path.sep)) return void 0;
334
+ handle = await fs4.open(realMd, "r");
335
+ const buffer = Buffer.alloc(HEAD_BYTES);
336
+ const { bytesRead } = await handle.read(buffer, 0, HEAD_BYTES, 0);
337
+ return parseSkillDescription(buffer.subarray(0, bytesRead).toString("utf-8"));
338
+ } catch {
339
+ return void 0;
340
+ } finally {
341
+ await handle?.close().catch(() => {
342
+ });
343
+ }
344
+ }
296
345
  var ProjectPathError = class extends Error {
297
346
  code;
298
347
  constructor(code) {
@@ -305,12 +354,12 @@ async function resolveProjectCwd(theaterRoot) {
305
354
  const lexicalRoot = path.resolve(theaterRoot);
306
355
  let realRoot;
307
356
  try {
308
- realRoot = await fs3.realpath(lexicalRoot);
357
+ realRoot = await fs4.realpath(lexicalRoot);
309
358
  } catch (error) {
310
359
  throw mapFilesystemError(error);
311
360
  }
312
361
  try {
313
- if (!(await fs3.stat(realRoot)).isDirectory()) {
362
+ if (!(await fs4.stat(realRoot)).isDirectory()) {
314
363
  throw new ProjectPathError("invalid_path");
315
364
  }
316
365
  } catch (error) {
@@ -402,30 +451,47 @@ var CLI_TIMEOUT_MS = 12e4;
402
451
  var USERINFO_URL_RE = /\b[a-z][a-z0-9+.-]*:\/\/[^\s/@]+@[^\s]+/gi;
403
452
  var TOKEN_URL_PARAM_RE = /([?&](?:access_?token|token|api_?key|apikey|auth(?:orization)?|password|secret|credential)=)[^&#\s]*/gi;
404
453
  var installedSkillsByTheater = /* @__PURE__ */ new Map();
454
+ function isRecord(value) {
455
+ return typeof value === "object" && value !== null && !Array.isArray(value);
456
+ }
457
+ function hasSourceEntry(table) {
458
+ return Object.values(table).some((entry) => isRecord(entry) && typeof entry["source"] === "string");
459
+ }
460
+ function isLockShape(parsed) {
461
+ if (!isRecord(parsed)) return false;
462
+ if ("skills" in parsed) return isRecord(parsed["skills"]);
463
+ return hasSourceEntry(parsed);
464
+ }
465
+ function collectLockSources(lock, sources) {
466
+ const table = isRecord(lock.skills) ? lock.skills : lock;
467
+ for (const [name, entry] of Object.entries(table)) {
468
+ if (isRecord(entry) && typeof entry["source"] === "string") {
469
+ sources.set(name, entry["source"]);
470
+ }
471
+ }
472
+ }
405
473
  async function readSkillSources(cwd) {
406
474
  const sources = /* @__PURE__ */ new Map();
407
- try {
408
- const raw = await fs3.readFile(path.join(cwd, "skills-lock.json"), "utf-8");
409
- const parsed = JSON.parse(raw);
410
- if (typeof parsed === "object" && parsed !== null) {
411
- for (const [name, entry] of Object.entries(parsed)) {
412
- if (entry && typeof entry.source === "string") sources.set(name, entry.source);
413
- }
414
- return sources;
475
+ for (const candidate of [
476
+ path.join(cwd, "skills-lock.json"),
477
+ path.join(cwd, ".agents", ".skill-lock.json")
478
+ ]) {
479
+ let raw;
480
+ try {
481
+ raw = await fs4.readFile(candidate, "utf-8");
482
+ } catch {
483
+ continue;
415
484
  }
416
- } catch {
417
- }
418
- try {
419
- const raw = await fs3.readFile(path.join(cwd, ".agents", ".skill-lock.json"), "utf-8");
420
- const parsed = JSON.parse(raw);
421
- if (typeof parsed === "object" && parsed !== null) {
422
- for (const [name, entry] of Object.entries(parsed)) {
423
- if (entry && typeof entry.source === "string") sources.set(name, entry.source);
485
+ try {
486
+ const parsed = JSON.parse(raw);
487
+ if (isLockShape(parsed)) {
488
+ collectLockSources(parsed, sources);
489
+ return { sources, lockRead: true };
424
490
  }
491
+ } catch {
425
492
  }
426
- } catch {
427
493
  }
428
- return sources;
494
+ return { sources, lockRead: false };
429
495
  }
430
496
  async function runListCommand(args, cwd, executor) {
431
497
  const result = await executor(args, { cwd, timeout: CLI_TIMEOUT_MS });
@@ -488,42 +554,42 @@ function spawnJobAsync(jobId, args, cwd, redactionPaths, executor) {
488
554
  }).then((result) => finishJob(jobId, result.exitCode)).catch(() => finishJob(jobId, 1));
489
555
  });
490
556
  }
557
+ async function toListItems(raw, scope, lock, allowedRoot) {
558
+ return Promise.all(raw.map(async (entry) => {
559
+ const description = entry.path ? await readSkillDescription(entry.path, allowedRoot) : void 0;
560
+ const source = lock.sources.get(entry.name);
561
+ const unmanaged = !source && lock.lockRead;
562
+ return {
563
+ name: entry.name,
564
+ scope,
565
+ agents: entry.agents,
566
+ ...source ? { source } : {},
567
+ ...unmanaged ? { unmanaged: true } : {},
568
+ ...description ? { description } : {},
569
+ displayPath: buildDisplayPath(scope, entry.name)
570
+ };
571
+ }));
572
+ }
491
573
  async function listInstalledSkills(projectCwd, executor) {
574
+ const homeDir = os2.homedir();
492
575
  if (projectCwd) {
493
576
  const [projectRaw, globalRaw2, projectSources, globalSources2] = await Promise.all([
494
577
  runListCommand(["list", "--json"], projectCwd, executor),
495
- runListCommand(["list", "-g", "--json"], os2.homedir(), executor),
578
+ runListCommand(["list", "-g", "--json"], homeDir, executor),
496
579
  readSkillSources(projectCwd),
497
- readSkillSources(os2.homedir())
580
+ readSkillSources(homeDir)
581
+ ]);
582
+ const [projectItems, globalItems] = await Promise.all([
583
+ toListItems(projectRaw, "project", projectSources, projectCwd),
584
+ toListItems(globalRaw2, "global", globalSources2, homeDir)
498
585
  ]);
499
- return [
500
- ...projectRaw.map((entry) => ({
501
- name: entry.name,
502
- scope: "project",
503
- agents: entry.agents,
504
- source: projectSources.get(entry.name),
505
- displayPath: buildDisplayPath("project", entry.name)
506
- })),
507
- ...globalRaw2.map((entry) => ({
508
- name: entry.name,
509
- scope: "global",
510
- agents: entry.agents,
511
- source: globalSources2.get(entry.name),
512
- displayPath: buildDisplayPath("global", entry.name)
513
- }))
514
- ];
586
+ return [...projectItems, ...globalItems];
515
587
  }
516
588
  const [globalRaw, globalSources] = await Promise.all([
517
- runListCommand(["list", "-g", "--json"], os2.homedir(), executor),
518
- readSkillSources(os2.homedir())
589
+ runListCommand(["list", "-g", "--json"], homeDir, executor),
590
+ readSkillSources(homeDir)
519
591
  ]);
520
- return globalRaw.map((entry) => ({
521
- name: entry.name,
522
- scope: "global",
523
- agents: entry.agents,
524
- source: globalSources.get(entry.name),
525
- displayPath: buildDisplayPath("global", entry.name)
526
- }));
592
+ return toListItems(globalRaw, "global", globalSources, homeDir);
527
593
  }
528
594
  async function handleList(req, res, ctx, executor) {
529
595
  if (req.method !== "GET") {
@@ -900,9 +966,9 @@ async function handleInstalledFile(req, res, ctx, executor) {
900
966
  // CLI가 보고한 skillRoot 자체도 신뢰하지 않는다 — scope의 정당한 상위 경계
901
967
  // (project=theater 루트, global=홈)를 벗어나면 읽지 않는다. `.agents/skills`로
902
968
  // 고정하지 않는 이유: claude 단독 설치는 `.claude/skills` 아래에 놓인다.
903
- fs3.realpath(cwd),
904
- fs3.realpath(skillRoot),
905
- fs3.realpath(skillMdPath).catch(() => null)
969
+ fs4.realpath(cwd),
970
+ fs4.realpath(skillRoot),
971
+ fs4.realpath(skillMdPath).catch(() => null)
906
972
  ]);
907
973
  if (!realMd) {
908
974
  ctx.host.http.writeJson(res, 404, { error: "skill_not_found" });
@@ -916,7 +982,7 @@ async function handleInstalledFile(req, res, ctx, executor) {
916
982
  ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
917
983
  return;
918
984
  }
919
- const markdown = await fs3.readFile(realMd, "utf-8");
985
+ const markdown = await fs4.readFile(realMd, "utf-8");
920
986
  ctx.host.http.writeJson(res, 200, { markdown });
921
987
  } catch {
922
988
  ctx.host.http.writeJson(res, 502, { error: "read_failed" });