@dotobokuri/fleet-console 1.28.0 → 1.30.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 (65) hide show
  1. package/dist/cli.mjs +209 -387
  2. package/dist/client/assets/{_baseUniq-0TpVlb56.js → _baseUniq-Dvbxpxj-.js} +1 -1
  3. package/dist/client/assets/{arc-BIRhKPNZ.js → arc-Cqerxs8I.js} +1 -1
  4. package/dist/client/assets/{architectureDiagram-Q4EWVU46-CJzkivmk.js → architectureDiagram-Q4EWVU46-gNhmCKnU.js} +1 -1
  5. package/dist/client/assets/{blockDiagram-DXYQGD6D-PkVBy6UB.js → blockDiagram-DXYQGD6D-CM5HRpKC.js} +1 -1
  6. package/dist/client/assets/{c4Diagram-AHTNJAMY-TOO0Zc07.js → c4Diagram-AHTNJAMY-DxLhQuvg.js} +1 -1
  7. package/dist/client/assets/channel-DKkQpLWI.js +1 -0
  8. package/dist/client/assets/{chunk-4BX2VUAB-Ugm2Ht26.js → chunk-4BX2VUAB-HX6C_GAC.js} +1 -1
  9. package/dist/client/assets/{chunk-4TB4RGXK-Byfwafb_.js → chunk-4TB4RGXK-CoBQUhS4.js} +1 -1
  10. package/dist/client/assets/{chunk-55IACEB6-2I_nwtuS.js → chunk-55IACEB6-DWsWxGBm.js} +1 -1
  11. package/dist/client/assets/{chunk-EDXVE4YY-JYP41aJo.js → chunk-EDXVE4YY-BXNRu1M4.js} +1 -1
  12. package/dist/client/assets/{chunk-FMBD7UC4-Duh-U1jY.js → chunk-FMBD7UC4-DzKgP1_A.js} +1 -1
  13. package/dist/client/assets/{chunk-OYMX7WX6-64cqkTOO.js → chunk-OYMX7WX6-aqXdvKUD.js} +1 -1
  14. package/dist/client/assets/{chunk-QZHKN3VN-engflZJB.js → chunk-QZHKN3VN-BbMqaUb0.js} +1 -1
  15. package/dist/client/assets/{chunk-YZCP3GAM-BwnK_1vX.js → chunk-YZCP3GAM-D8Mo0nv8.js} +1 -1
  16. package/dist/client/assets/classDiagram-6PBFFD2Q-CQurO5ix.js +1 -0
  17. package/dist/client/assets/classDiagram-v2-HSJHXN6E-CQurO5ix.js +1 -0
  18. package/dist/client/assets/clone-IodjsAGU.js +1 -0
  19. package/dist/client/assets/{cose-bilkent-S5V4N54A-D43_BnnE.js → cose-bilkent-S5V4N54A-BOuVjjXz.js} +1 -1
  20. package/dist/client/assets/{dagre-KV5264BT-Wh_p74YO.js → dagre-KV5264BT-BdUFzAj_.js} +1 -1
  21. package/dist/client/assets/{diagram-5BDNPKRD-BNcxA6wC.js → diagram-5BDNPKRD-C0iFrsGo.js} +1 -1
  22. package/dist/client/assets/{diagram-G4DWMVQ6-HQdA06kX.js → diagram-G4DWMVQ6-CGxGeQZt.js} +1 -1
  23. package/dist/client/assets/{diagram-MMDJMWI5-DlMdX_ng.js → diagram-MMDJMWI5-Dex5uqlA.js} +1 -1
  24. package/dist/client/assets/{diagram-TYMM5635-C1hKAjZD.js → diagram-TYMM5635-O48PEpaS.js} +1 -1
  25. package/dist/client/assets/{erDiagram-SMLLAGMA-CsSiuv9G.js → erDiagram-SMLLAGMA-B7PGw3YA.js} +1 -1
  26. package/dist/client/assets/{flowDiagram-DWJPFMVM-DfjQ3Ug9.js → flowDiagram-DWJPFMVM-CCXWJIMw.js} +1 -1
  27. package/dist/client/assets/{ganttDiagram-T4ZO3ILL-B0QHKePg.js → ganttDiagram-T4ZO3ILL-B26RghpR.js} +1 -1
  28. package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-_zejoqTH.js → gitGraphDiagram-UUTBAWPF-BJsjMn6A.js} +1 -1
  29. package/dist/client/assets/{graph-Dr6IPcji.js → graph-DuEL0RWH.js} +1 -1
  30. package/dist/client/assets/index-Dj775lUe.css +1 -0
  31. package/dist/client/assets/index-r6rDZQCs.js +451 -0
  32. package/dist/client/assets/{infoDiagram-42DDH7IO-dhruAwPt.js → infoDiagram-42DDH7IO-D32dz1SM.js} +1 -1
  33. package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-DPoZZiH0.js → ishikawaDiagram-UXIWVN3A-4YPQjln0.js} +1 -1
  34. package/dist/client/assets/{journeyDiagram-VCZTEJTY-DQk8gmrd.js → journeyDiagram-VCZTEJTY-BSvi22HM.js} +1 -1
  35. package/dist/client/assets/{kanban-definition-6JOO6SKY-B9rOgVFq.js → kanban-definition-6JOO6SKY-SozOXS7m.js} +1 -1
  36. package/dist/client/assets/{layout-D54BXsv2.js → layout-CNXntIRV.js} +1 -1
  37. package/dist/client/assets/{linear-DJxG7kFF.js → linear-9RZPFtO4.js} +1 -1
  38. package/dist/client/assets/{mermaid.core-BBFWA-zA.js → mermaid.core-kwH-UxKY.js} +4 -4
  39. package/dist/client/assets/{min-Dv_aLAYb.js → min-BdN2p8Q_.js} +1 -1
  40. package/dist/client/assets/{mindmap-definition-QFDTVHPH-Dv5woCon.js → mindmap-definition-QFDTVHPH-H-3dJmH9.js} +1 -1
  41. package/dist/client/assets/{pieDiagram-DEJITSTG-B_V_vCG8.js → pieDiagram-DEJITSTG-CspzYvcs.js} +1 -1
  42. package/dist/client/assets/{quadrantDiagram-34T5L4WZ-QHqq3tFD.js → quadrantDiagram-34T5L4WZ-D1C7e3-s.js} +1 -1
  43. package/dist/client/assets/{requirementDiagram-MS252O5E-BhPhfMzK.js → requirementDiagram-MS252O5E-BJwKRtMi.js} +1 -1
  44. package/dist/client/assets/{sankeyDiagram-XADWPNL6-D2-ZsaS_.js → sankeyDiagram-XADWPNL6-7oc42Z3P.js} +1 -1
  45. package/dist/client/assets/{sequenceDiagram-FGHM5R23-Di0qgM3v.js → sequenceDiagram-FGHM5R23-TP5H_DnF.js} +1 -1
  46. package/dist/client/assets/{stateDiagram-FHFEXIEX-BAuqrwY8.js → stateDiagram-FHFEXIEX-BWnrNgJY.js} +1 -1
  47. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-Cmp8tobq.js +1 -0
  48. package/dist/client/assets/{timeline-definition-GMOUNBTQ-BcMGkC6T.js → timeline-definition-GMOUNBTQ-xXFvCsrr.js} +1 -1
  49. package/dist/client/assets/{vennDiagram-DHZGUBPP-C9dkwyKX.js → vennDiagram-DHZGUBPP-D5unm_iH.js} +1 -1
  50. package/dist/client/assets/{wardley-RL74JXVD-BLLCncPa.js → wardley-RL74JXVD-B-eT02rs.js} +1 -1
  51. package/dist/client/assets/{wardleyDiagram-NUSXRM2D-Yb9mlL0_.js → wardleyDiagram-NUSXRM2D-BTQ1Yqmb.js} +1 -1
  52. package/dist/client/assets/{xychartDiagram-5P7HB3ND-BAHLdje7.js → xychartDiagram-5P7HB3ND-Bialvg0l.js} +1 -1
  53. package/dist/client/index.html +2 -2
  54. package/dist/fleet-plugins/file-explorer/routes.mjs +199 -38
  55. package/dist/fleet-plugins/repository/routes.mjs +407 -108
  56. package/dist/fleet-plugins/skills/routes.mjs +60 -79
  57. package/dist/fleet-plugins/terminal/routes.mjs +577 -102
  58. package/package.json +1 -1
  59. package/dist/client/assets/channel-CqmujVSi.js +0 -1
  60. package/dist/client/assets/classDiagram-6PBFFD2Q-DLXkYur6.js +0 -1
  61. package/dist/client/assets/classDiagram-v2-HSJHXN6E-DLXkYur6.js +0 -1
  62. package/dist/client/assets/clone-KonJWRw9.js +0 -1
  63. package/dist/client/assets/index-CsmxZ8UQ.js +0 -453
  64. package/dist/client/assets/index-DC8tBAf_.css +0 -1
  65. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-DhNebJyd.js +0 -1
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import path5 from 'path';
2
+ import path from 'path';
3
3
  import { execFile } from 'child_process';
4
4
  import fs4 from 'fs/promises';
5
5
  import os2 from 'os';
@@ -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(path5.extname(resolved).toLowerCase())) {
16315
+ if (platform !== "win32" || !WINDOWS_SHIM_EXTENSIONS.has(path.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 : path5.delimiter;
16334
- if (hasPathSeparator(bin, platform) || path5.isAbsolute(bin)) {
16333
+ const pathSeparator = platform === "win32" ? WINDOWS_PATH_SEPARATOR : path.delimiter;
16334
+ if (hasPathSeparator(bin, platform) || path.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(path5.join(searchDir, bin), pathExts, platform);
16339
+ const candidate = resolveWithExtensions(path.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" || path5.extname(candidate).length > 0) {
16347
+ if (platform !== "win32" || path.extname(candidate).length > 0) {
16348
16348
  return isAccessibleExecutable(candidate, platform) ? candidate : void 0;
16349
16349
  }
16350
16350
  for (const ext of pathExts) {
@@ -16387,7 +16387,7 @@ function withHidden(options) {
16387
16387
  // ../../packages/core-unified-agent/models.json
16388
16388
  var models_default = {
16389
16389
  version: 1,
16390
- updatedAt: "2026-07-10T00:00:00Z",
16390
+ updatedAt: "2026-07-20T00:00:00Z",
16391
16391
  providers: {
16392
16392
  claude: {
16393
16393
  name: "Claude Code",
@@ -16406,15 +16406,16 @@ var models_default = {
16406
16406
  name: "Kimi via Claude Code",
16407
16407
  defaultModel: "kimi-for-coding",
16408
16408
  models: [
16409
- { modelId: "kimi-for-coding", name: "Kimi for Coding", description: "Available on every Kimi Code membership tier (262K context)", effort: { supported: false } },
16410
- { modelId: "k3", name: "Kimi K3", description: "Available on Moderato and higher tiers (262K context)", effort: { supported: true, levels: ["max"], default: "max" } },
16411
- { modelId: "k3[1m]", name: "Kimi K3 [1M]", description: "Available on Allegretto and higher tiers (1M context)", effort: { supported: true, levels: ["max"], default: "max" } },
16412
- { modelId: "kimi-for-coding-highspeed", name: "Kimi for Coding Highspeed", description: "Available on Allegretto and higher tiers (262K context)", effort: { supported: false } }
16409
+ { modelId: "kimi-for-coding", name: "Kimi for Coding", description: "Available on every Kimi Code membership tier (262K context)", effort: { supported: false }, contextWindow: 262144 },
16410
+ { modelId: "k3", name: "Kimi K3", description: "Available on Moderato and higher tiers (262K context)", effort: { supported: true, levels: ["low", "high", "max"], default: "high" }, contextWindow: 262144 },
16411
+ { modelId: "k3[1m]", name: "Kimi K3 [1M]", description: "Available on Allegretto and higher tiers (1M context)", effort: { supported: true, levels: ["low", "high", "max"], default: "high" }, contextWindow: 1048576 },
16412
+ { modelId: "kimi-for-coding-highspeed", name: "Kimi for Coding Highspeed", description: "Available on Allegretto and higher tiers (262K context)", effort: { supported: false }, contextWindow: 262144 }
16413
16413
  ],
16414
16414
  modelsMapping: {
16415
16415
  haiku: "kimi-for-coding",
16416
16416
  sonnet: "kimi-for-coding",
16417
- opus: "kimi-for-coding"
16417
+ opus: "kimi-for-coding",
16418
+ fable: "kimi-for-coding"
16418
16419
  }
16419
16420
  },
16420
16421
  codex: {
@@ -16488,6 +16489,8 @@ var ModelEntrySchema = external_exports.object({
16488
16489
  description: external_exports.string().optional(),
16489
16490
  /** spawn 시 실제 CLI 모델 ID를 조립해야 하는 경우의 템플릿 */
16490
16491
  spawnModelTemplate: external_exports.string().optional(),
16492
+ /** 모델의 컨텍스트 윈도우 크기 (토큰) */
16493
+ contextWindow: external_exports.number().int().positive().optional(),
16491
16494
  /** 모델별 effort 설정 */
16492
16495
  effort: EffortSchema
16493
16496
  }).check((ctx) => {
@@ -16704,8 +16707,8 @@ async function ensureCliMjs(cliHome, onBootstrap) {
16704
16707
  if (_cliMjsPath) return _cliMjsPath;
16705
16708
  if (_bootstrapPromise) return _bootstrapPromise;
16706
16709
  _bootstrapPromise = (async () => {
16707
- const mjsPath = path5.join(cliHome, "node_modules", SKILLS_PACKAGE, "bin", "cli.mjs");
16708
- const pkgPath = path5.join(cliHome, "node_modules", SKILLS_PACKAGE, "package.json");
16710
+ const mjsPath = path.join(cliHome, "node_modules", SKILLS_PACKAGE, "bin", "cli.mjs");
16711
+ const pkgPath = path.join(cliHome, "node_modules", SKILLS_PACKAGE, "package.json");
16709
16712
  let needsInstall = true;
16710
16713
  try {
16711
16714
  const raw = await fs4.readFile(pkgPath, "utf-8");
@@ -16848,52 +16851,29 @@ var ProjectPathError = class extends Error {
16848
16851
  this.code = code;
16849
16852
  }
16850
16853
  };
16851
- async function resolveProjectCwd(theaterRoot, relPath) {
16852
- if (relPath !== null && !isSafeRelativePath(relPath)) {
16853
- throw new ProjectPathError("invalid_rel_path");
16854
- }
16855
- const lexicalRoot = path5.resolve(theaterRoot);
16856
- const lexicalTarget = path5.resolve(lexicalRoot, relPath ?? ".");
16857
- if (!isContainedBy(lexicalRoot, lexicalTarget)) {
16858
- throw new ProjectPathError("path_outside_theater");
16859
- }
16854
+ async function resolveProjectCwd(theaterRoot) {
16855
+ const lexicalRoot = path.resolve(theaterRoot);
16860
16856
  let realRoot;
16861
- let realTarget;
16862
16857
  try {
16863
- [realRoot, realTarget] = await Promise.all([
16864
- fs4.realpath(lexicalRoot),
16865
- fs4.realpath(lexicalTarget)
16866
- ]);
16858
+ realRoot = await fs4.realpath(lexicalRoot);
16867
16859
  } catch (error51) {
16868
16860
  throw mapFilesystemError(error51);
16869
16861
  }
16870
- if (!isContainedBy(realRoot, realTarget)) {
16871
- throw new ProjectPathError("path_outside_theater");
16872
- }
16873
16862
  try {
16874
- if (!(await fs4.stat(realTarget)).isDirectory()) {
16875
- throw new ProjectPathError("invalid_rel_path");
16863
+ if (!(await fs4.stat(realRoot)).isDirectory()) {
16864
+ throw new ProjectPathError("invalid_path");
16876
16865
  }
16877
16866
  } catch (error51) {
16878
16867
  if (error51 instanceof ProjectPathError) throw error51;
16879
16868
  throw mapFilesystemError(error51);
16880
16869
  }
16881
- return realTarget;
16882
- }
16883
- function isSafeRelativePath(value) {
16884
- if (!value || value.includes("\0") || path5.isAbsolute(value) || path5.posix.isAbsolute(value) || path5.win32.isAbsolute(value)) {
16885
- return false;
16886
- }
16887
- return value.split(/[\\/]/).every((segment) => segment !== "" && segment !== "." && segment !== "..");
16888
- }
16889
- function isContainedBy(root, target) {
16890
- return target === root || target.startsWith(root.endsWith(path5.sep) ? root : root + path5.sep);
16870
+ return realRoot;
16891
16871
  }
16892
16872
  function mapFilesystemError(error51) {
16893
16873
  const code = error51.code;
16894
16874
  if (code === "EACCES" || code === "EPERM") return new ProjectPathError("path_outside_theater");
16895
16875
  if (code === "ENOENT" || code === "ENOTDIR") return new ProjectPathError("not_found");
16896
- return new ProjectPathError("invalid_rel_path");
16876
+ return new ProjectPathError("invalid_path");
16897
16877
  }
16898
16878
 
16899
16879
  // ../fleet-plugins/skills/server/registry-search.ts
@@ -16974,7 +16954,7 @@ var TOKEN_URL_PARAM_RE = /([?&](?:access_?token|token|api_?key|apikey|auth(?:ori
16974
16954
  async function readSkillSources(cwd) {
16975
16955
  const sources = /* @__PURE__ */ new Map();
16976
16956
  try {
16977
- const raw = await fs4.readFile(path5.join(cwd, "skills-lock.json"), "utf-8");
16957
+ const raw = await fs4.readFile(path.join(cwd, "skills-lock.json"), "utf-8");
16978
16958
  const parsed = JSON.parse(raw);
16979
16959
  if (typeof parsed === "object" && parsed !== null) {
16980
16960
  for (const [name, entry] of Object.entries(parsed)) {
@@ -16985,7 +16965,7 @@ async function readSkillSources(cwd) {
16985
16965
  } catch {
16986
16966
  }
16987
16967
  try {
16988
- const raw = await fs4.readFile(path5.join(cwd, ".agents", ".skill-lock.json"), "utf-8");
16968
+ const raw = await fs4.readFile(path.join(cwd, ".agents", ".skill-lock.json"), "utf-8");
16989
16969
  const parsed = JSON.parse(raw);
16990
16970
  if (typeof parsed === "object" && parsed !== null) {
16991
16971
  for (const [name, entry] of Object.entries(parsed)) {
@@ -17011,15 +16991,10 @@ async function runListCommand(args, cwd, executor) {
17011
16991
  function buildDisplayPath(scope, name) {
17012
16992
  return scope === "global" ? `~/.agents/skills/${name}` : `.agents/skills/${name}`;
17013
16993
  }
17014
- function parseOptionalRelPath(value) {
17015
- if (value === void 0 || value === null) return null;
17016
- return typeof value === "string" ? value : void 0;
17017
- }
17018
- async function resolveProjectScopeCwd(ctx, theaterId, relPath) {
16994
+ async function resolveProjectScopeCwd(ctx, theaterId) {
17019
16995
  if (!theaterId) return null;
17020
- if (relPath === void 0) throw new ProjectPathError("invalid_rel_path");
17021
16996
  const theaterRoot = ctx.host.paths.resolveTheaterPath(theaterId);
17022
- return theaterRoot ? resolveProjectCwd(theaterRoot, relPath) : null;
16997
+ return theaterRoot ? resolveProjectCwd(theaterRoot) : null;
17023
16998
  }
17024
16999
  function writeProjectPathError(res, ctx, error51) {
17025
17000
  if (!(error51 instanceof ProjectPathError)) throw error51;
@@ -17072,12 +17047,15 @@ async function handleList(req, res, ctx, executor) {
17072
17047
  return;
17073
17048
  }
17074
17049
  const url2 = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
17050
+ if (url2.searchParams.has("relPath")) {
17051
+ ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
17052
+ return;
17053
+ }
17075
17054
  const theaterId = url2.searchParams.get("theaterId") ?? void 0;
17076
- const relPath = url2.searchParams.has("relPath") ? url2.searchParams.get("relPath") || null : null;
17077
17055
  let projectCwd = null;
17078
17056
  if (theaterId) {
17079
17057
  try {
17080
- projectCwd = await resolveProjectScopeCwd(ctx, theaterId, relPath);
17058
+ projectCwd = await resolveProjectScopeCwd(ctx, theaterId);
17081
17059
  } catch (error51) {
17082
17060
  writeProjectPathError(res, ctx, error51);
17083
17061
  return;
@@ -17138,6 +17116,10 @@ async function handleSearch(req, res, ctx) {
17138
17116
  return;
17139
17117
  }
17140
17118
  const url2 = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
17119
+ if (url2.searchParams.has("relPath")) {
17120
+ ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
17121
+ return;
17122
+ }
17141
17123
  const q = url2.searchParams.get("q") ?? "";
17142
17124
  const rawLimit = parseInt(url2.searchParams.get("limit") ?? "10", 10);
17143
17125
  const limit = isNaN(rawLimit) ? 10 : rawLimit;
@@ -17162,13 +17144,12 @@ async function handleInstall(req, res, ctx, executor) {
17162
17144
  return;
17163
17145
  }
17164
17146
  const body = await ctx.host.http.readJsonBody(req);
17165
- if (!isPlainObject2(body)) {
17147
+ if (!isPlainObject2(body) || "relPath" in body) {
17166
17148
  ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
17167
17149
  return;
17168
17150
  }
17169
- const { source, skill, scope, agents, theaterId: rawTheaterId, relPath: rawRelPath } = body;
17151
+ const { source, skill, scope, agents, theaterId: rawTheaterId } = body;
17170
17152
  const theaterId = typeof rawTheaterId === "string" ? rawTheaterId : void 0;
17171
- const relPath = parseOptionalRelPath(rawRelPath);
17172
17153
  if (!validateSource(source)) {
17173
17154
  ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
17174
17155
  return;
@@ -17194,7 +17175,7 @@ async function handleInstall(req, res, ctx, executor) {
17194
17175
  let projectCwd = null;
17195
17176
  if (scope === "project") {
17196
17177
  try {
17197
- projectCwd = await resolveProjectScopeCwd(ctx, theaterId, relPath);
17178
+ projectCwd = await resolveProjectScopeCwd(ctx, theaterId);
17198
17179
  } catch (error51) {
17199
17180
  writeProjectPathError(res, ctx, error51);
17200
17181
  return;
@@ -17226,13 +17207,12 @@ async function handleUpdate(req, res, ctx, executor) {
17226
17207
  return;
17227
17208
  }
17228
17209
  const body = await ctx.host.http.readJsonBody(req);
17229
- if (!isPlainObject2(body)) {
17210
+ if (!isPlainObject2(body) || "relPath" in body) {
17230
17211
  ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
17231
17212
  return;
17232
17213
  }
17233
- const { scope, theaterId: rawTheaterId, relPath: rawRelPath } = body;
17214
+ const { scope, theaterId: rawTheaterId } = body;
17234
17215
  const theaterId = typeof rawTheaterId === "string" ? rawTheaterId : void 0;
17235
- const relPath = parseOptionalRelPath(rawRelPath);
17236
17216
  if (!validateScope(scope)) {
17237
17217
  ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
17238
17218
  return;
@@ -17240,7 +17220,7 @@ async function handleUpdate(req, res, ctx, executor) {
17240
17220
  let projectCwd = null;
17241
17221
  if (scope === "project") {
17242
17222
  try {
17243
- projectCwd = await resolveProjectScopeCwd(ctx, theaterId, relPath);
17223
+ projectCwd = await resolveProjectScopeCwd(ctx, theaterId);
17244
17224
  } catch (error51) {
17245
17225
  writeProjectPathError(res, ctx, error51);
17246
17226
  return;
@@ -17271,6 +17251,10 @@ async function handleGetJob(req, res, ctx) {
17271
17251
  return;
17272
17252
  }
17273
17253
  const url2 = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
17254
+ if (url2.searchParams.has("relPath")) {
17255
+ ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
17256
+ return;
17257
+ }
17274
17258
  const jobId = url2.searchParams.get("jobId");
17275
17259
  const rawCursor = parseInt(url2.searchParams.get("cursor") ?? "0", 10);
17276
17260
  const cursor = isNaN(rawCursor) || rawCursor < 0 ? 0 : rawCursor;
@@ -17295,13 +17279,12 @@ async function handleRemove(req, res, ctx, executor) {
17295
17279
  return;
17296
17280
  }
17297
17281
  const body = await ctx.host.http.readJsonBody(req);
17298
- if (!isPlainObject2(body)) {
17282
+ if (!isPlainObject2(body) || "relPath" in body) {
17299
17283
  ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
17300
17284
  return;
17301
17285
  }
17302
- const { scope, skill, theaterId: rawTheaterId, relPath: rawRelPath } = body;
17286
+ const { scope, skill, theaterId: rawTheaterId } = body;
17303
17287
  const theaterId = typeof rawTheaterId === "string" ? rawTheaterId : void 0;
17304
- const relPath = parseOptionalRelPath(rawRelPath);
17305
17288
  if (!validateScope(scope)) {
17306
17289
  ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
17307
17290
  return;
@@ -17313,7 +17296,7 @@ async function handleRemove(req, res, ctx, executor) {
17313
17296
  let projectCwd = null;
17314
17297
  if (scope === "project") {
17315
17298
  try {
17316
- projectCwd = await resolveProjectScopeCwd(ctx, theaterId, relPath);
17299
+ projectCwd = await resolveProjectScopeCwd(ctx, theaterId);
17317
17300
  } catch (error51) {
17318
17301
  writeProjectPathError(res, ctx, error51);
17319
17302
  return;
@@ -17345,13 +17328,12 @@ async function handlePreview(req, res, ctx, executor) {
17345
17328
  return;
17346
17329
  }
17347
17330
  const body = await ctx.host.http.readJsonBody(req);
17348
- if (!isPlainObject2(body)) {
17331
+ if (!isPlainObject2(body) || "relPath" in body) {
17349
17332
  ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
17350
17333
  return;
17351
17334
  }
17352
- const { source, skill, theaterId: rawTheaterId, relPath: rawRelPath } = body;
17335
+ const { source, skill, theaterId: rawTheaterId } = body;
17353
17336
  const theaterId = typeof rawTheaterId === "string" ? rawTheaterId : void 0;
17354
- const relPath = parseOptionalRelPath(rawRelPath);
17355
17337
  if (!validateSource(source)) {
17356
17338
  ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
17357
17339
  return;
@@ -17363,7 +17345,7 @@ async function handlePreview(req, res, ctx, executor) {
17363
17345
  let cwd = defaultCwd();
17364
17346
  if (theaterId) {
17365
17347
  try {
17366
- const projectCwd = await resolveProjectScopeCwd(ctx, theaterId, relPath);
17348
+ const projectCwd = await resolveProjectScopeCwd(ctx, theaterId);
17367
17349
  if (!projectCwd) {
17368
17350
  ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
17369
17351
  return;
@@ -17391,13 +17373,12 @@ async function handleInstalledFile(req, res, ctx, executor) {
17391
17373
  return;
17392
17374
  }
17393
17375
  const body = await ctx.host.http.readJsonBody(req);
17394
- if (!isPlainObject2(body)) {
17376
+ if (!isPlainObject2(body) || "relPath" in body) {
17395
17377
  ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
17396
17378
  return;
17397
17379
  }
17398
- const { scope, skill, theaterId: rawTheaterId, relPath: rawRelPath } = body;
17380
+ const { scope, skill, theaterId: rawTheaterId } = body;
17399
17381
  const theaterId = typeof rawTheaterId === "string" ? rawTheaterId : void 0;
17400
- const relPath = parseOptionalRelPath(rawRelPath);
17401
17382
  if (!validateScope(scope)) {
17402
17383
  ctx.host.http.writeJson(res, 400, { error: "invalid_argument" });
17403
17384
  return;
@@ -17409,7 +17390,7 @@ async function handleInstalledFile(req, res, ctx, executor) {
17409
17390
  let projectCwd = null;
17410
17391
  if (scope === "project") {
17411
17392
  try {
17412
- projectCwd = await resolveProjectScopeCwd(ctx, theaterId, relPath);
17393
+ projectCwd = await resolveProjectScopeCwd(ctx, theaterId);
17413
17394
  } catch (error51) {
17414
17395
  writeProjectPathError(res, ctx, error51);
17415
17396
  return;
@@ -17429,7 +17410,7 @@ async function handleInstalledFile(req, res, ctx, executor) {
17429
17410
  return;
17430
17411
  }
17431
17412
  const skillRoot = entry.path;
17432
- const skillMdPath = path5.join(skillRoot, "SKILL.md");
17413
+ const skillMdPath = path.join(skillRoot, "SKILL.md");
17433
17414
  const [realAllowedRoot, realRoot, realMd] = await Promise.all([
17434
17415
  // CLI가 보고한 skillRoot 자체도 신뢰하지 않는다 — scope의 정당한 상위 경계
17435
17416
  // (project=theater 루트, global=홈)를 벗어나면 읽지 않는다. `.agents/skills`로
@@ -17442,11 +17423,11 @@ async function handleInstalledFile(req, res, ctx, executor) {
17442
17423
  ctx.host.http.writeJson(res, 404, { error: "skill_not_found" });
17443
17424
  return;
17444
17425
  }
17445
- if (realRoot !== realAllowedRoot && !realRoot.startsWith(realAllowedRoot + path5.sep)) {
17426
+ if (realRoot !== realAllowedRoot && !realRoot.startsWith(realAllowedRoot + path.sep)) {
17446
17427
  ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
17447
17428
  return;
17448
17429
  }
17449
- if (realMd !== realRoot && !realMd.startsWith(realRoot + path5.sep)) {
17430
+ if (realMd !== realRoot && !realMd.startsWith(realRoot + path.sep)) {
17450
17431
  ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
17451
17432
  return;
17452
17433
  }
@@ -17461,7 +17442,7 @@ async function handleInstalledFile(req, res, ctx, executor) {
17461
17442
  var routes_default = definePlugin({
17462
17443
  id: "skills",
17463
17444
  register(ctx) {
17464
- const cliHome = path5.join(ctx.host.paths.pluginDataDir("skills"), "cli");
17445
+ const cliHome = path.join(ctx.host.paths.pluginDataDir("skills"), "cli");
17465
17446
  const executor = createDefaultExecutor(cliHome);
17466
17447
  registerRouter(ctx, "list", async ({ req, res }) => {
17467
17448
  await handleList(req, res, ctx, executor);