@dotobokuri/fleet-console 1.18.0 → 1.19.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 (67) hide show
  1. package/AGENTS.md +6 -5
  2. package/dist/cli.d.ts +13 -12
  3. package/dist/cli.mjs +143 -175
  4. package/dist/client/assets/SymbolsNerdFontMono-Regular-CoUzE12l.woff2 +0 -0
  5. package/dist/client/assets/{_baseUniq-DFEDX4NY.js → _baseUniq-C4_iQlZS.js} +1 -1
  6. package/dist/client/assets/{arc-CGwMrR6o.js → arc-BBAWxYi5.js} +1 -1
  7. package/dist/client/assets/{architectureDiagram-Q4EWVU46-BqLyvIOK.js → architectureDiagram-Q4EWVU46-_oQqhexV.js} +1 -1
  8. package/dist/client/assets/{blockDiagram-DXYQGD6D-DoiPMLdv.js → blockDiagram-DXYQGD6D-3xT9VFiD.js} +1 -1
  9. package/dist/client/assets/{c4Diagram-AHTNJAMY-DfGxDkah.js → c4Diagram-AHTNJAMY-S-IMcMW2.js} +1 -1
  10. package/dist/client/assets/channel-5tV1napa.js +1 -0
  11. package/dist/client/assets/{chunk-4BX2VUAB-3zXv74oY.js → chunk-4BX2VUAB-tS9Ys0P9.js} +1 -1
  12. package/dist/client/assets/{chunk-4TB4RGXK-MkXUmjUE.js → chunk-4TB4RGXK-YZgAG7SW.js} +1 -1
  13. package/dist/client/assets/{chunk-55IACEB6-mhkgqlI_.js → chunk-55IACEB6-m-CtqHoO.js} +1 -1
  14. package/dist/client/assets/{chunk-EDXVE4YY-B0_ZDihs.js → chunk-EDXVE4YY-yoymxaEV.js} +1 -1
  15. package/dist/client/assets/{chunk-FMBD7UC4-BQAuE4pL.js → chunk-FMBD7UC4-REUkrQAG.js} +1 -1
  16. package/dist/client/assets/{chunk-OYMX7WX6-CY8Eyj9X.js → chunk-OYMX7WX6-DzMuL105.js} +1 -1
  17. package/dist/client/assets/{chunk-QZHKN3VN-CaZoMwKH.js → chunk-QZHKN3VN-DXFFll8-.js} +1 -1
  18. package/dist/client/assets/{chunk-YZCP3GAM-DV1YOEUH.js → chunk-YZCP3GAM-CmY7W-gg.js} +1 -1
  19. package/dist/client/assets/classDiagram-6PBFFD2Q-WDM904ap.js +1 -0
  20. package/dist/client/assets/classDiagram-v2-HSJHXN6E-WDM904ap.js +1 -0
  21. package/dist/client/assets/clone-BJg9p0cC.js +1 -0
  22. package/dist/client/assets/{cose-bilkent-S5V4N54A-Cy3v0C_N.js → cose-bilkent-S5V4N54A-BupE-a40.js} +1 -1
  23. package/dist/client/assets/{dagre-KV5264BT-CGJ6x_VR.js → dagre-KV5264BT-Jn67LxMS.js} +1 -1
  24. package/dist/client/assets/{diagram-5BDNPKRD-MyyXeHKQ.js → diagram-5BDNPKRD-BAeFEORH.js} +1 -1
  25. package/dist/client/assets/{diagram-G4DWMVQ6-D52Q2132.js → diagram-G4DWMVQ6-CnZrDABY.js} +1 -1
  26. package/dist/client/assets/{diagram-MMDJMWI5-DCypusCr.js → diagram-MMDJMWI5-DefG-kXU.js} +1 -1
  27. package/dist/client/assets/{diagram-TYMM5635-c5UBqE9-.js → diagram-TYMM5635-BPkXKB-Q.js} +1 -1
  28. package/dist/client/assets/{erDiagram-SMLLAGMA-BlF0Lxy7.js → erDiagram-SMLLAGMA-Bi4jlild.js} +1 -1
  29. package/dist/client/assets/{flowDiagram-DWJPFMVM-lo8xyzfx.js → flowDiagram-DWJPFMVM-BoZyLO7h.js} +1 -1
  30. package/dist/client/assets/{ganttDiagram-T4ZO3ILL-BXVZMpon.js → ganttDiagram-T4ZO3ILL-LgzSNjrh.js} +1 -1
  31. package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-DB1A6uYk.js → gitGraphDiagram-UUTBAWPF-B4fH-hPT.js} +1 -1
  32. package/dist/client/assets/{graph-Ck2AX1p2.js → graph-D3ZAYMLG.js} +1 -1
  33. package/dist/client/assets/{index-Cf9MmpwN.css → index-DctP_CJP.css} +1 -1
  34. package/dist/client/assets/index-vgEn_EkG.js +404 -0
  35. package/dist/client/assets/{infoDiagram-42DDH7IO-NEVE42fw.js → infoDiagram-42DDH7IO-pENdunXd.js} +1 -1
  36. package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-MbFr_8pL.js → ishikawaDiagram-UXIWVN3A-WakLHKte.js} +1 -1
  37. package/dist/client/assets/{journeyDiagram-VCZTEJTY-Sq2ja3q8.js → journeyDiagram-VCZTEJTY-CrqXKtzk.js} +1 -1
  38. package/dist/client/assets/{kanban-definition-6JOO6SKY-C63qPhtK.js → kanban-definition-6JOO6SKY-DdSC9eJ-.js} +1 -1
  39. package/dist/client/assets/{layout-CFEuVj4N.js → layout-BI1Oko_a.js} +1 -1
  40. package/dist/client/assets/{linear-B626G8Op.js → linear-KUjZtfMe.js} +1 -1
  41. package/dist/client/assets/{mermaid.core-BT7SVKBR.js → mermaid.core-DNlIf4_3.js} +4 -4
  42. package/dist/client/assets/{min-MbEOApMw.js → min-DCAecveI.js} +1 -1
  43. package/dist/client/assets/{mindmap-definition-QFDTVHPH-DMpht5Mg.js → mindmap-definition-QFDTVHPH-BSCyQA-4.js} +1 -1
  44. package/dist/client/assets/{pieDiagram-DEJITSTG-B4XS0haZ.js → pieDiagram-DEJITSTG-C_1I63z5.js} +1 -1
  45. package/dist/client/assets/{quadrantDiagram-34T5L4WZ-CReo5Ajb.js → quadrantDiagram-34T5L4WZ-CtqeYPcA.js} +1 -1
  46. package/dist/client/assets/{requirementDiagram-MS252O5E-A50aqG-K.js → requirementDiagram-MS252O5E-Cpakdg-s.js} +1 -1
  47. package/dist/client/assets/{sankeyDiagram-XADWPNL6-471VOdlW.js → sankeyDiagram-XADWPNL6-CK_eMH3e.js} +1 -1
  48. package/dist/client/assets/{sequenceDiagram-FGHM5R23-BAvOyUC-.js → sequenceDiagram-FGHM5R23-D2YygHqF.js} +1 -1
  49. package/dist/client/assets/{stateDiagram-FHFEXIEX-gCtZrvR-.js → stateDiagram-FHFEXIEX-DEDhnbhU.js} +1 -1
  50. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-ji50PgJQ.js +1 -0
  51. package/dist/client/assets/{timeline-definition-GMOUNBTQ-CTHf-uxq.js → timeline-definition-GMOUNBTQ-Brgny70W.js} +1 -1
  52. package/dist/client/assets/{vennDiagram-DHZGUBPP-5gvXi0dO.js → vennDiagram-DHZGUBPP-B1I5E8Hy.js} +1 -1
  53. package/dist/client/assets/{wardley-RL74JXVD-XR-qQTWZ.js → wardley-RL74JXVD-P0VCYfKI.js} +1 -1
  54. package/dist/client/assets/{wardleyDiagram-NUSXRM2D-EwPsMHdt.js → wardleyDiagram-NUSXRM2D-DhYC5Sus.js} +1 -1
  55. package/dist/client/assets/{xychartDiagram-5P7HB3ND-CePwuUb7.js → xychartDiagram-5P7HB3ND-ByJX99rJ.js} +1 -1
  56. package/dist/client/index.html +2 -2
  57. package/dist/fleet-plugins/diff/routes.mjs +207 -34
  58. package/dist/fleet-plugins/file-explorer/routes.mjs +1 -1
  59. package/dist/fleet-plugins/skills/routes.mjs +101 -83
  60. package/dist/fleet-plugins/terminal/routes.mjs +556 -325
  61. package/package.json +1 -1
  62. package/dist/client/assets/channel-DlT8zCVq.js +0 -1
  63. package/dist/client/assets/classDiagram-6PBFFD2Q-B-UN9f9r.js +0 -1
  64. package/dist/client/assets/classDiagram-v2-HSJHXN6E-B-UN9f9r.js +0 -1
  65. package/dist/client/assets/clone-CDPRFCO0.js +0 -1
  66. package/dist/client/assets/index-DWgndVkX.js +0 -404
  67. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-Bdb0YU66.js +0 -1
@@ -1,19 +1,27 @@
1
1
  #!/usr/bin/env node
2
- import fs from 'fs/promises';
3
- import path2 from 'path';
4
2
  import { spawn } from 'child_process';
3
+ import 'fs';
4
+ import path3 from 'path';
5
+ import fs from 'fs/promises';
5
6
 
6
7
  // sdk/plugin/node.ts
7
8
  function definePlugin(definition) {
8
9
  return definition;
9
10
  }
10
- function registerRouter(ctx, path3, handler) {
11
- ctx.registerRouter(normalizePath(path3), handler);
11
+ function registerRouter(ctx, path4, handler) {
12
+ ctx.registerRouter(normalizePath(path4), handler);
12
13
  }
13
- function normalizePath(path3) {
14
- if (path3.length === 0 || path3 === "/") return "/";
15
- return path3;
14
+ function normalizePath(path4) {
15
+ if (path4.length === 0 || path4 === "/") return "/";
16
+ return path4;
17
+ }
18
+
19
+ // ../../packages/core-process/src/hidden.ts
20
+ function withHidden(options) {
21
+ return { ...options ?? {}, windowsHide: true };
16
22
  }
23
+
24
+ // ../fleet-plugins/diff/server/git-executor.ts
17
25
  var GitExecutorError = class extends Error {
18
26
  code;
19
27
  exitCode;
@@ -34,7 +42,7 @@ function runGit(args, opts) {
34
42
  return new Promise((resolve, reject) => {
35
43
  let child;
36
44
  try {
37
- child = spawn("git", args, { cwd: opts.cwd, shell: false, windowsHide: true });
45
+ child = spawn("git", args, withHidden({ cwd: opts.cwd, shell: false }));
38
46
  } catch (error) {
39
47
  const code = error.code === "ENOENT" ? "git_unavailable" : "spawn_failed";
40
48
  reject(new GitExecutorError(code, String(error)));
@@ -89,8 +97,6 @@ function runGit(args, opts) {
89
97
  });
90
98
  });
91
99
  }
92
-
93
- // ../fleet-plugins/diff/server/diff.ts
94
100
  function isPlainObject(value) {
95
101
  return typeof value === "object" && value !== null && !Array.isArray(value);
96
102
  }
@@ -141,9 +147,9 @@ function isNoHeadError(error) {
141
147
  }
142
148
  async function resolveGitCwd(theaterPath, rawSubPath) {
143
149
  if (rawSubPath === "") return { gitCwd: theaterPath };
144
- const resolvedSub = path2.resolve(theaterPath, rawSubPath);
145
- if (!resolvedSub.startsWith(theaterPath + path2.sep) && resolvedSub !== theaterPath) return null;
146
- if (path2.normalize(rawSubPath).startsWith("..")) return null;
150
+ const resolvedSub = path3.resolve(theaterPath, rawSubPath);
151
+ if (!resolvedSub.startsWith(theaterPath + path3.sep) && resolvedSub !== theaterPath) return null;
152
+ if (path3.normalize(rawSubPath).startsWith("..")) return null;
147
153
  let realTheater;
148
154
  let realSub;
149
155
  try {
@@ -154,7 +160,7 @@ async function resolveGitCwd(theaterPath, rawSubPath) {
154
160
  } catch {
155
161
  return null;
156
162
  }
157
- const norm = realTheater.endsWith(path2.sep) ? realTheater : realTheater + path2.sep;
163
+ const norm = realTheater.endsWith(path3.sep) ? realTheater : realTheater + path3.sep;
158
164
  if (realSub !== realTheater && !realSub.startsWith(norm)) return null;
159
165
  return { gitCwd: resolvedSub };
160
166
  }
@@ -263,12 +269,12 @@ async function handleDiffFile(req, res, ctx) {
263
269
  }
264
270
  const { gitCwd } = cwdResult;
265
271
  const rawFilePath = body.filePath;
266
- const resolvedFilePath = path2.resolve(gitCwd, rawFilePath);
267
- if (!resolvedFilePath.startsWith(gitCwd + path2.sep) && resolvedFilePath !== gitCwd) {
272
+ const resolvedFilePath = path3.resolve(gitCwd, rawFilePath);
273
+ if (!resolvedFilePath.startsWith(gitCwd + path3.sep) && resolvedFilePath !== gitCwd) {
268
274
  ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
269
275
  return;
270
276
  }
271
- const relativePath = path2.normalize(rawFilePath);
277
+ const relativePath = path3.normalize(rawFilePath);
272
278
  if (relativePath.startsWith("..")) {
273
279
  ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
274
280
  return;
@@ -286,7 +292,7 @@ async function handleDiffFile(req, res, ctx) {
286
292
  ctx.host.http.writeJson(res, 404, { error: "file_not_found" });
287
293
  return;
288
294
  }
289
- if (realFile !== realGitCwd && !realFile.startsWith(realGitCwd + path2.sep)) {
295
+ if (realFile !== realGitCwd && !realFile.startsWith(realGitCwd + path3.sep)) {
290
296
  ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
291
297
  return;
292
298
  }
@@ -302,7 +308,7 @@ async function handleDiffFile(req, res, ctx) {
302
308
  fs.realpath(gitCwd),
303
309
  fs.realpath(resolvedFilePath)
304
310
  ]);
305
- if (realFile !== realGitCwd && !realFile.startsWith(realGitCwd + path2.sep)) {
311
+ if (realFile !== realGitCwd && !realFile.startsWith(realGitCwd + path3.sep)) {
306
312
  ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
307
313
  return;
308
314
  }
@@ -328,10 +334,169 @@ async function handleDiffFile(req, res, ctx) {
328
334
  throw error;
329
335
  }
330
336
  }
337
+
338
+ // ../fleet-plugins/diff/server/commit.ts
339
+ var REF_RE = /^[0-9a-f]{7,40}$/i;
340
+ function isPlainObject2(value) {
341
+ return typeof value === "object" && value !== null && !Array.isArray(value);
342
+ }
343
+ async function handleDiffCommit(req, res, ctx) {
344
+ if (req.method !== "POST") {
345
+ ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
346
+ return;
347
+ }
348
+ if (!ctx.host.security.isTerminalAuthorized(req)) {
349
+ ctx.host.http.writeJson(res, 401, { error: "unauthorized" });
350
+ return;
351
+ }
352
+ const body = await ctx.host.http.readJsonBody(req);
353
+ if (!isPlainObject2(body)) {
354
+ ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
355
+ return;
356
+ }
357
+ const theaterId = body.theaterId;
358
+ if (typeof theaterId !== "string") {
359
+ ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
360
+ return;
361
+ }
362
+ const ref = body.ref;
363
+ if (typeof ref !== "string" || !REF_RE.test(ref)) {
364
+ ctx.host.http.writeJson(res, 400, { error: "invalid_ref" });
365
+ return;
366
+ }
367
+ const theaterPath = ctx.host.paths.resolveTheaterPath(theaterId);
368
+ if (!theaterPath) {
369
+ ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
370
+ return;
371
+ }
372
+ const rawSubPath = typeof body.subPath === "string" ? body.subPath : "";
373
+ const cwdResult = await resolveGitCwd(theaterPath, rawSubPath);
374
+ if (!cwdResult) {
375
+ ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
376
+ return;
377
+ }
378
+ const { gitCwd } = cwdResult;
379
+ try {
380
+ const result = await runGit(["show", ref, "--unified=3", "--format="], { cwd: gitCwd });
381
+ ctx.host.http.writeJson(res, 200, { content: result.stdout, ...result.truncated ? { truncated: true } : {} });
382
+ } catch (error) {
383
+ if (error instanceof GitExecutorError) {
384
+ if (error.code === "no_git_repo" || error.code === "git_unavailable") {
385
+ ctx.host.http.writeJson(res, 422, { error: error.code });
386
+ return;
387
+ }
388
+ ctx.host.http.writeJson(res, 500, { error: "git_failed" });
389
+ return;
390
+ }
391
+ throw error;
392
+ }
393
+ }
394
+
395
+ // ../fleet-plugins/diff/server/log.ts
396
+ function isPlainObject3(value) {
397
+ return typeof value === "object" && value !== null && !Array.isArray(value);
398
+ }
399
+ function parseLogOutput(stdout) {
400
+ if (!stdout.trim()) return [];
401
+ const commits = [];
402
+ for (const chunk of stdout.split("")) {
403
+ const trimmed = chunk.trimStart();
404
+ if (!trimmed) continue;
405
+ const lines = trimmed.split("\n");
406
+ const firstLine = lines[0] ?? "";
407
+ const fields = firstLine.split("\0");
408
+ const fullHash = fields[0] ?? "";
409
+ const shortHash = fields[1] ?? "";
410
+ const subject = fields[2] ?? "";
411
+ const authorName = fields[3] ?? "";
412
+ const relTime = fields[4] ?? "";
413
+ const refsRaw = fields[5] ?? "";
414
+ const parentsRaw = fields[6] ?? "";
415
+ if (!fullHash) continue;
416
+ const refs = refsRaw.split(",").map((r) => r.trim()).filter(Boolean);
417
+ const parents = parentsRaw.split(" ").map((p) => p.trim()).filter(Boolean);
418
+ let additions = 0;
419
+ let deletions = 0;
420
+ for (const line of lines.slice(1)) {
421
+ if (!line.trim()) continue;
422
+ const parts = line.split(" ");
423
+ if (parts.length < 2) continue;
424
+ const a = parseInt(parts[0] ?? "0", 10);
425
+ const d = parseInt(parts[1] ?? "0", 10);
426
+ if (!isNaN(a)) additions += a;
427
+ if (!isNaN(d)) deletions += d;
428
+ }
429
+ commits.push({ shortHash, fullHash, subject, authorName, relTime, refs, parents, additions, deletions });
430
+ }
431
+ return commits;
432
+ }
433
+ function isNoHeadError2(error) {
434
+ if (!(error instanceof GitExecutorError)) return false;
435
+ if (error.code !== "non_zero_exit") return false;
436
+ return error.stderr.includes("unknown revision") || error.stderr.includes("bad revision");
437
+ }
438
+ async function handleDiffLog(req, res, ctx) {
439
+ if (req.method !== "POST") {
440
+ ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
441
+ return;
442
+ }
443
+ if (!ctx.host.security.isTerminalAuthorized(req)) {
444
+ ctx.host.http.writeJson(res, 401, { error: "unauthorized" });
445
+ return;
446
+ }
447
+ const body = await ctx.host.http.readJsonBody(req);
448
+ if (!isPlainObject3(body)) {
449
+ ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
450
+ return;
451
+ }
452
+ const theaterId = body.theaterId;
453
+ if (typeof theaterId !== "string") {
454
+ ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
455
+ return;
456
+ }
457
+ const theaterPath = ctx.host.paths.resolveTheaterPath(theaterId);
458
+ if (!theaterPath) {
459
+ ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
460
+ return;
461
+ }
462
+ const rawSubPath = typeof body.subPath === "string" ? body.subPath : "";
463
+ const cwdResult = await resolveGitCwd(theaterPath, rawSubPath);
464
+ if (!cwdResult) {
465
+ ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
466
+ return;
467
+ }
468
+ const { gitCwd } = cwdResult;
469
+ try {
470
+ const result = await runGit(
471
+ ["log", "-n", "50", "--numstat", "--pretty=format:%x1e%H%x00%h%x00%s%x00%an%x00%ar%x00%D%x00%P"],
472
+ { cwd: gitCwd }
473
+ );
474
+ const commits = parseLogOutput(result.stdout);
475
+ ctx.host.http.writeJson(res, 200, { commits, ...result.truncated ? { truncated: true } : {} });
476
+ } catch (error) {
477
+ if (error instanceof GitExecutorError) {
478
+ if (error.code === "no_git_repo") {
479
+ ctx.host.http.writeJson(res, 200, { commits: [] });
480
+ return;
481
+ }
482
+ if (error.code === "git_unavailable") {
483
+ ctx.host.http.writeJson(res, 422, { error: error.code });
484
+ return;
485
+ }
486
+ if (isNoHeadError2(error)) {
487
+ ctx.host.http.writeJson(res, 200, { commits: [] });
488
+ return;
489
+ }
490
+ ctx.host.http.writeJson(res, 500, { error: "git_failed" });
491
+ return;
492
+ }
493
+ throw error;
494
+ }
495
+ }
331
496
  var REPOS_CAP = 200;
332
497
  var HARD_CAP_DEPTH = 8;
333
498
  var DEFAULT_DEPTH = 3;
334
- function isPlainObject2(value) {
499
+ function isPlainObject4(value) {
335
500
  return typeof value === "object" && value !== null && !Array.isArray(value);
336
501
  }
337
502
  async function resolveRepoBranch(repoDir) {
@@ -351,13 +516,13 @@ async function detectWorktreeParent(dir, gitFileContent) {
351
516
  const match = gitFileContent.trim().match(/^gitdir:\s*(.+)$/m);
352
517
  if (!match) return null;
353
518
  const rawPointer = match[1].trim();
354
- const resolvedGitdir = path2.normalize(
355
- path2.isAbsolute(rawPointer) ? rawPointer : path2.resolve(dir, rawPointer)
519
+ const resolvedGitdir = path3.normalize(
520
+ path3.isAbsolute(rawPointer) ? rawPointer : path3.resolve(dir, rawPointer)
356
521
  );
357
- if (resolvedGitdir.includes(`${path2.sep}modules${path2.sep}`)) {
522
+ if (resolvedGitdir.includes(`${path3.sep}modules${path3.sep}`)) {
358
523
  return null;
359
524
  }
360
- const worktreesSegment = `${path2.sep}.git${path2.sep}worktrees${path2.sep}`;
525
+ const worktreesSegment = `${path3.sep}.git${path3.sep}worktrees${path3.sep}`;
361
526
  const wtIdx = resolvedGitdir.indexOf(worktreesSegment);
362
527
  if (wtIdx === -1) {
363
528
  return null;
@@ -367,17 +532,17 @@ async function detectWorktreeParent(dir, gitFileContent) {
367
532
  try {
368
533
  parentAbs = await fs.realpath(parentAbsRaw);
369
534
  } catch {
370
- parentAbs = path2.normalize(parentAbsRaw);
535
+ parentAbs = path3.normalize(parentAbsRaw);
371
536
  }
372
537
  return { isWorktree: true, parentAbs };
373
538
  }
374
539
  async function scanRepos(theaterPath, realTheaterPath, dir, currentDepth, maxDepth, repos, cap = REPOS_CAP) {
375
540
  if (repos.length >= cap) return true;
376
- const gitPath = path2.join(dir, ".git");
541
+ const gitPath = path3.join(dir, ".git");
377
542
  try {
378
543
  const gitStat = await fs.stat(gitPath);
379
- const relPath = path2.relative(theaterPath, dir);
380
- const name = relPath === "" ? path2.basename(theaterPath) : path2.basename(dir);
544
+ const relPath = path3.relative(theaterPath, dir);
545
+ const name = relPath === "" ? path3.basename(theaterPath) : path3.basename(dir);
381
546
  const branch = await resolveRepoBranch(dir);
382
547
  if (gitStat.isFile()) {
383
548
  const content = await fs.readFile(gitPath, "utf8");
@@ -407,7 +572,7 @@ async function scanRepos(theaterPath, realTheaterPath, dir, currentDepth, maxDep
407
572
  dirent = await dirHandle.read();
408
573
  continue;
409
574
  }
410
- const childPath = path2.join(dir, childName);
575
+ const childPath = path3.join(dir, childName);
411
576
  let realChildPath;
412
577
  try {
413
578
  realChildPath = await fs.realpath(childPath);
@@ -415,7 +580,7 @@ async function scanRepos(theaterPath, realTheaterPath, dir, currentDepth, maxDep
415
580
  dirent = await dirHandle.read();
416
581
  continue;
417
582
  }
418
- const normalizedReal = realTheaterPath.endsWith(path2.sep) ? realTheaterPath : realTheaterPath + path2.sep;
583
+ const normalizedReal = realTheaterPath.endsWith(path3.sep) ? realTheaterPath : realTheaterPath + path3.sep;
419
584
  if (realChildPath !== realTheaterPath && !realChildPath.startsWith(normalizedReal)) {
420
585
  dirent = await dirHandle.read();
421
586
  continue;
@@ -442,15 +607,15 @@ async function scanRepos(theaterPath, realTheaterPath, dir, currentDepth, maxDep
442
607
  function resolveWorktreeParents(raw, realTheaterPath) {
443
608
  const absToRelPath = /* @__PURE__ */ new Map();
444
609
  for (const entry of raw) {
445
- const absDir = path2.normalize(
446
- entry.relPath === "" ? realTheaterPath : path2.join(realTheaterPath, entry.relPath)
610
+ const absDir = path3.normalize(
611
+ entry.relPath === "" ? realTheaterPath : path3.join(realTheaterPath, entry.relPath)
447
612
  );
448
613
  absToRelPath.set(absDir, entry.relPath);
449
614
  }
450
615
  return raw.map((entry) => {
451
616
  const { _wtParentAbs, ...rest } = entry;
452
617
  if (_wtParentAbs && entry.isWorktree) {
453
- const normalizedParent = path2.normalize(_wtParentAbs);
618
+ const normalizedParent = path3.normalize(_wtParentAbs);
454
619
  const parentRelPath = absToRelPath.get(normalizedParent);
455
620
  if (parentRelPath !== void 0) {
456
621
  return { ...rest, worktreeOf: parentRelPath };
@@ -469,7 +634,7 @@ async function handleDiffRepos(req, res, ctx) {
469
634
  return;
470
635
  }
471
636
  const body = await ctx.host.http.readJsonBody(req);
472
- if (!isPlainObject2(body)) {
637
+ if (!isPlainObject4(body)) {
473
638
  ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
474
639
  return;
475
640
  }
@@ -520,6 +685,14 @@ var routes_default = definePlugin({
520
685
  await handleDiffFile(req, res, ctx);
521
686
  return true;
522
687
  });
688
+ registerRouter(ctx, "log", async ({ req, res }) => {
689
+ await handleDiffLog(req, res, ctx);
690
+ return true;
691
+ });
692
+ registerRouter(ctx, "commit", async ({ req, res }) => {
693
+ await handleDiffCommit(req, res, ctx);
694
+ return true;
695
+ });
523
696
  }
524
697
  });
525
698
 
@@ -243,7 +243,7 @@ var ImageServeError = class extends Error {
243
243
  this.code = code;
244
244
  }
245
245
  };
246
- var IMAGE_SIZE_CAP = 4 * 1024 * 1024;
246
+ var IMAGE_SIZE_CAP = 16 * 1024 * 1024;
247
247
  var MIME_ALLOWLIST = {
248
248
  ".png": "image/png",
249
249
  ".jpg": "image/jpeg",
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import path2 from 'path';
2
+ import path from 'path';
3
3
  import { execFile } from 'child_process';
4
4
  import fs3 from 'fs/promises';
5
5
  import os2 from 'os';
6
6
  import crypto4 from 'crypto';
7
7
  import 'http';
8
8
  import 'stream';
9
- import { existsSync } from 'fs';
9
+ import { existsSync, accessSync, constants } from 'fs';
10
10
 
11
11
  var __defProp = Object.defineProperty;
12
12
  var __export = (target, all) => {
@@ -15932,6 +15932,93 @@ external_exports.union([
15932
15932
  id: zRequestId
15933
15933
  })
15934
15934
  ]);
15935
+ var DEFAULT_WINDOWS_PATHEXT = ".COM;.EXE;.BAT;.CMD";
15936
+ var WINDOWS_PATH_SEPARATOR = ";";
15937
+ var WINDOWS_SHIM_EXTENSIONS = /* @__PURE__ */ new Set([".cmd", ".bat"]);
15938
+ var CMD_EXPANSION_SENSITIVE_PATTERN = /[%^]/;
15939
+ function resolvePathBinary(command, env, options = {}) {
15940
+ const resolved = findBinaryPath(command, env, options);
15941
+ return resolved ? wrapWindowsShim(resolved, env, options.platform ?? process.platform) : void 0;
15942
+ }
15943
+ function findBinaryPath(command, env, options = {}) {
15944
+ const platform = options.platform ?? process.platform;
15945
+ const isWindows2 = platform === "win32";
15946
+ const pathValue = isWindows2 ? env.Path ?? env.PATH ?? "" : env.PATH ?? "";
15947
+ const pathExts = isWindows2 ? parsePathExt(env.PATHEXT) : [""];
15948
+ return findOnPath(command, pathValue, pathExts, platform);
15949
+ }
15950
+ function wrapWindowsShim(resolved, env, platform) {
15951
+ if (platform !== "win32" || !WINDOWS_SHIM_EXTENSIONS.has(path.extname(resolved).toLowerCase())) {
15952
+ return { bin: resolved, prefixArgs: [] };
15953
+ }
15954
+ rejectCmdExpansionSensitiveShim(resolved);
15955
+ return {
15956
+ bin: env.ComSpec ?? "cmd.exe",
15957
+ prefixArgs: ["/d", "/s", "/c", "call", forceWindowsArgQuoting(resolved)]
15958
+ };
15959
+ }
15960
+ function rejectCmdExpansionSensitiveShim(resolved) {
15961
+ if (CMD_EXPANSION_SENSITIVE_PATTERN.test(resolved)) {
15962
+ throw new Error(`Refusing to run Windows shim path with cmd.exe expansion-sensitive characters (% or ^): ${resolved}`);
15963
+ }
15964
+ }
15965
+ function forceWindowsArgQuoting(value) {
15966
+ return `${value} `;
15967
+ }
15968
+ function findOnPath(bin, pathValue, pathExts, platform) {
15969
+ const pathSeparator = platform === "win32" ? WINDOWS_PATH_SEPARATOR : path.delimiter;
15970
+ if (hasPathSeparator(bin, platform) || path.isAbsolute(bin)) {
15971
+ return resolveWithExtensions(bin, pathExts, platform);
15972
+ }
15973
+ for (const entry of pathValue.split(pathSeparator)) {
15974
+ const searchDir = entry.length === 0 ? "." : entry;
15975
+ const candidate = resolveWithExtensions(path.join(searchDir, bin), pathExts, platform);
15976
+ if (candidate) {
15977
+ return candidate;
15978
+ }
15979
+ }
15980
+ return void 0;
15981
+ }
15982
+ function resolveWithExtensions(candidate, pathExts, platform) {
15983
+ if (platform !== "win32" || path.extname(candidate).length > 0) {
15984
+ return isAccessibleExecutable(candidate, platform) ? candidate : void 0;
15985
+ }
15986
+ for (const ext of pathExts) {
15987
+ if (ext.length === 0) {
15988
+ continue;
15989
+ }
15990
+ const withExt = `${candidate}${ext}`;
15991
+ if (existsSync(withExt)) {
15992
+ return withExt;
15993
+ }
15994
+ }
15995
+ return isAccessibleExecutable(candidate, platform) ? candidate : void 0;
15996
+ }
15997
+ function isAccessibleExecutable(candidate, platform) {
15998
+ if (!existsSync(candidate)) return false;
15999
+ if (platform === "win32") return true;
16000
+ try {
16001
+ accessSync(candidate, constants.X_OK);
16002
+ return true;
16003
+ } catch {
16004
+ return false;
16005
+ }
16006
+ }
16007
+ function hasPathSeparator(value, platform) {
16008
+ if (value.includes("/")) {
16009
+ return true;
16010
+ }
16011
+ return platform === "win32" && value.includes("\\");
16012
+ }
16013
+ function parsePathExt(pathExt) {
16014
+ const raw = pathExt && pathExt.trim().length > 0 ? pathExt : DEFAULT_WINDOWS_PATHEXT;
16015
+ return raw.split(WINDOWS_PATH_SEPARATOR).map((entry) => entry.trim()).filter((entry) => entry.length > 0);
16016
+ }
16017
+
16018
+ // ../../packages/core-process/src/hidden.ts
16019
+ function withHidden(options) {
16020
+ return { ...options ?? {}, windowsHide: true };
16021
+ }
15935
16022
 
15936
16023
  // ../../packages/core-unified-agent/models.json
15937
16024
  var models_default = {
@@ -15939,7 +16026,7 @@ var models_default = {
15939
16026
  updatedAt: "2026-07-04T00:00:00Z",
15940
16027
  providers: {
15941
16028
  claude: {
15942
- name: "Claude Code with Anthropic",
16029
+ name: "Claude Code",
15943
16030
  defaultModel: "opus[1m]",
15944
16031
  models: [
15945
16032
  { modelId: "haiku", name: "Claude Haiku", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "low" } },
@@ -15952,7 +16039,7 @@ var models_default = {
15952
16039
  ]
15953
16040
  },
15954
16041
  codex: {
15955
- name: "OpenAI Codex CLI",
16042
+ name: "Codex",
15956
16043
  defaultModel: "gpt-5.4",
15957
16044
  models: [
15958
16045
  { modelId: "gpt-5.4", name: "GPT-5.4", effort: { supported: true, levels: ["low", "medium", "high", "xhigh"], default: "high" } },
@@ -16160,75 +16247,6 @@ Object.entries(CLI_BACKENDS).map(([id, backend]) => ({
16160
16247
 
16161
16248
  // ../../packages/core-unified-agent/src/client/UnifiedCodexAgentClient.ts
16162
16249
  process.platform === "win32";
16163
- var DEFAULT_WINDOWS_PATHEXT = ".COM;.EXE;.BAT;.CMD";
16164
- var WINDOWS_PATH_SEPARATOR = ";";
16165
- var WINDOWS_SHIM_EXTENSIONS = /* @__PURE__ */ new Set([".cmd", ".bat"]);
16166
- var CMD_EXPANSION_SENSITIVE_PATTERN = /[%^]/;
16167
- function resolvePathBinary(command, env, options = {}) {
16168
- const platform = options.platform ?? process.platform;
16169
- const isWindows2 = platform === "win32";
16170
- const pathValue = isWindows2 ? env.Path ?? env.PATH ?? "" : env.PATH ?? "";
16171
- const pathExts = isWindows2 ? parsePathExt(env.PATHEXT) : [""];
16172
- const resolved = findOnPath(command, pathValue, pathExts, platform);
16173
- return resolved ? wrapWindowsShim(resolved, env, platform) : void 0;
16174
- }
16175
- function wrapWindowsShim(resolved, env, platform) {
16176
- if (platform !== "win32" || !WINDOWS_SHIM_EXTENSIONS.has(path2.extname(resolved).toLowerCase())) {
16177
- return { bin: resolved, prefixArgs: [] };
16178
- }
16179
- rejectCmdExpansionSensitiveShim(resolved);
16180
- return {
16181
- bin: env.ComSpec ?? "cmd.exe",
16182
- prefixArgs: ["/d", "/s", "/c", "call", forceWindowsArgQuoting(resolved)]
16183
- };
16184
- }
16185
- function rejectCmdExpansionSensitiveShim(resolved) {
16186
- if (CMD_EXPANSION_SENSITIVE_PATTERN.test(resolved)) {
16187
- throw new Error(`Refusing to run Windows shim path with cmd.exe expansion-sensitive characters (% or ^): ${resolved}`);
16188
- }
16189
- }
16190
- function forceWindowsArgQuoting(value) {
16191
- return `${value} `;
16192
- }
16193
- function findOnPath(bin, pathValue, pathExts, platform) {
16194
- const pathSeparator = platform === "win32" ? WINDOWS_PATH_SEPARATOR : path2.delimiter;
16195
- if (hasPathSeparator(bin, platform) || path2.isAbsolute(bin)) {
16196
- return resolveWithExtensions(bin, pathExts, platform);
16197
- }
16198
- for (const entry of pathValue.split(pathSeparator)) {
16199
- const searchDir = entry.length === 0 ? "." : entry;
16200
- const candidate = resolveWithExtensions(path2.join(searchDir, bin), pathExts, platform);
16201
- if (candidate) {
16202
- return candidate;
16203
- }
16204
- }
16205
- return void 0;
16206
- }
16207
- function resolveWithExtensions(candidate, pathExts, platform) {
16208
- if (platform !== "win32" || path2.extname(candidate).length > 0) {
16209
- return existsSync(candidate) ? candidate : void 0;
16210
- }
16211
- for (const ext of pathExts) {
16212
- if (ext.length === 0) {
16213
- continue;
16214
- }
16215
- const withExt = `${candidate}${ext}`;
16216
- if (existsSync(withExt)) {
16217
- return withExt;
16218
- }
16219
- }
16220
- return existsSync(candidate) ? candidate : void 0;
16221
- }
16222
- function hasPathSeparator(value, platform) {
16223
- if (value.includes("/")) {
16224
- return true;
16225
- }
16226
- return platform === "win32" && value.includes("\\");
16227
- }
16228
- function parsePathExt(pathExt) {
16229
- const raw = pathExt && pathExt.trim().length > 0 ? pathExt : DEFAULT_WINDOWS_PATHEXT;
16230
- return raw.split(WINDOWS_PATH_SEPARATOR).map((entry) => entry.trim()).filter((entry) => entry.length > 0);
16231
- }
16232
16250
 
16233
16251
  // ../fleet-plugins/skills/server/cli.ts
16234
16252
  var SKILLS_VERSION = "1.5.14";
@@ -16267,7 +16285,7 @@ async function runNpmInstall(cliHome) {
16267
16285
  file2,
16268
16286
  args,
16269
16287
  // windowsHide: GUI 콘솔에서 하위 프로세스(cmd.exe 심 래퍼) 콘솔 창이 순간 표시되는 것을 막는다.
16270
- { shell: false, windowsHide: true, timeout: BOOTSTRAP_TIMEOUT_MS }
16288
+ withHidden({ shell: false, timeout: BOOTSTRAP_TIMEOUT_MS })
16271
16289
  );
16272
16290
  child.on("close", (code) => {
16273
16291
  if (code === 0) resolve();
@@ -16280,8 +16298,8 @@ async function ensureCliMjs(cliHome, onBootstrap) {
16280
16298
  if (_cliMjsPath) return _cliMjsPath;
16281
16299
  if (_bootstrapPromise) return _bootstrapPromise;
16282
16300
  _bootstrapPromise = (async () => {
16283
- const mjsPath = path2.join(cliHome, "node_modules", SKILLS_PACKAGE, "bin", "cli.mjs");
16284
- const pkgPath = path2.join(cliHome, "node_modules", SKILLS_PACKAGE, "package.json");
16301
+ const mjsPath = path.join(cliHome, "node_modules", SKILLS_PACKAGE, "bin", "cli.mjs");
16302
+ const pkgPath = path.join(cliHome, "node_modules", SKILLS_PACKAGE, "package.json");
16285
16303
  let needsInstall = true;
16286
16304
  try {
16287
16305
  const raw = await fs3.readFile(pkgPath, "utf-8");
@@ -16310,7 +16328,7 @@ function createDefaultExecutor(cliHome) {
16310
16328
  process.execPath,
16311
16329
  [mjsPath, ...args],
16312
16330
  // windowsHide: GUI 콘솔에서 하위 node.exe 콘솔 창이 순간 표시되는 것을 막는다.
16313
- { shell: false, windowsHide: true, cwd, timeout, maxBuffer: 10 * 1024 * 1024 }
16331
+ withHidden({ shell: false, cwd, timeout, maxBuffer: 10 * 1024 * 1024 })
16314
16332
  );
16315
16333
  const stdoutParts = [];
16316
16334
  const stderrParts = [];
@@ -16493,7 +16511,7 @@ var CLI_TIMEOUT_MS = 12e4;
16493
16511
  async function readSkillSources(cwd) {
16494
16512
  const sources = /* @__PURE__ */ new Map();
16495
16513
  try {
16496
- const raw = await fs3.readFile(path2.join(cwd, "skills-lock.json"), "utf-8");
16514
+ const raw = await fs3.readFile(path.join(cwd, "skills-lock.json"), "utf-8");
16497
16515
  const parsed = JSON.parse(raw);
16498
16516
  if (typeof parsed === "object" && parsed !== null) {
16499
16517
  for (const [name, entry] of Object.entries(parsed)) {
@@ -16504,7 +16522,7 @@ async function readSkillSources(cwd) {
16504
16522
  } catch {
16505
16523
  }
16506
16524
  try {
16507
- const raw = await fs3.readFile(path2.join(cwd, ".agents", ".skill-lock.json"), "utf-8");
16525
+ const raw = await fs3.readFile(path.join(cwd, ".agents", ".skill-lock.json"), "utf-8");
16508
16526
  const parsed = JSON.parse(raw);
16509
16527
  if (typeof parsed === "object" && parsed !== null) {
16510
16528
  for (const [name, entry] of Object.entries(parsed)) {
@@ -16869,7 +16887,7 @@ async function handleInstalledFile(req, res, ctx, executor) {
16869
16887
  return;
16870
16888
  }
16871
16889
  const skillRoot = entry.path;
16872
- const skillMdPath = path2.join(skillRoot, "SKILL.md");
16890
+ const skillMdPath = path.join(skillRoot, "SKILL.md");
16873
16891
  const [realAllowedRoot, realRoot, realMd] = await Promise.all([
16874
16892
  // CLI가 보고한 skillRoot 자체도 신뢰하지 않는다 — scope의 정당한 상위 경계
16875
16893
  // (project=theater 루트, global=홈)를 벗어나면 읽지 않는다. `.agents/skills`로
@@ -16882,11 +16900,11 @@ async function handleInstalledFile(req, res, ctx, executor) {
16882
16900
  ctx.host.http.writeJson(res, 404, { error: "skill_not_found" });
16883
16901
  return;
16884
16902
  }
16885
- if (realRoot !== realAllowedRoot && !realRoot.startsWith(realAllowedRoot + path2.sep)) {
16903
+ if (realRoot !== realAllowedRoot && !realRoot.startsWith(realAllowedRoot + path.sep)) {
16886
16904
  ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
16887
16905
  return;
16888
16906
  }
16889
- if (realMd !== realRoot && !realMd.startsWith(realRoot + path2.sep)) {
16907
+ if (realMd !== realRoot && !realMd.startsWith(realRoot + path.sep)) {
16890
16908
  ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
16891
16909
  return;
16892
16910
  }
@@ -16901,7 +16919,7 @@ async function handleInstalledFile(req, res, ctx, executor) {
16901
16919
  var routes_default = definePlugin({
16902
16920
  id: "skills",
16903
16921
  register(ctx) {
16904
- const cliHome = path2.join(ctx.host.paths.pluginDataDir("skills"), "cli");
16922
+ const cliHome = path.join(ctx.host.paths.pluginDataDir("skills"), "cli");
16905
16923
  const executor = createDefaultExecutor(cliHome);
16906
16924
  registerRouter(ctx, "list", async ({ req, res }) => {
16907
16925
  await handleList(req, res, ctx, executor);