@dotobokuri/fleet-console 1.32.0 → 1.34.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 +578 -451
  2. package/dist/client/assets/{_baseUniq-BcB5wmG1.js → _baseUniq-kpxXKqaz.js} +1 -1
  3. package/dist/client/assets/{arc-DdDM-o2K.js → arc-Cf0soLes.js} +1 -1
  4. package/dist/client/assets/{architectureDiagram-Q4EWVU46-CIF7NLBh.js → architectureDiagram-Q4EWVU46-DiRqbCQ7.js} +1 -1
  5. package/dist/client/assets/{blockDiagram-DXYQGD6D-uTDIsi9C.js → blockDiagram-DXYQGD6D-DC25h3LU.js} +1 -1
  6. package/dist/client/assets/{c4Diagram-AHTNJAMY-B-L5_peH.js → c4Diagram-AHTNJAMY-BJLnKoD4.js} +1 -1
  7. package/dist/client/assets/channel-Deg6stWj.js +1 -0
  8. package/dist/client/assets/{chunk-4BX2VUAB-R3NuBeMM.js → chunk-4BX2VUAB-DWUk4gCy.js} +1 -1
  9. package/dist/client/assets/{chunk-4TB4RGXK-GqEsM9Hl.js → chunk-4TB4RGXK-DW4Ee9nw.js} +1 -1
  10. package/dist/client/assets/{chunk-55IACEB6-D4a7-QMt.js → chunk-55IACEB6-8z_Na955.js} +1 -1
  11. package/dist/client/assets/{chunk-EDXVE4YY-CFnwIApt.js → chunk-EDXVE4YY-C3Z4nalr.js} +1 -1
  12. package/dist/client/assets/{chunk-FMBD7UC4-Bx6k_N10.js → chunk-FMBD7UC4-UIVDEAE7.js} +1 -1
  13. package/dist/client/assets/{chunk-OYMX7WX6-2QjCvEfI.js → chunk-OYMX7WX6-DpFWa4G9.js} +1 -1
  14. package/dist/client/assets/{chunk-QZHKN3VN-SRIQm3h2.js → chunk-QZHKN3VN-BJndYOsb.js} +1 -1
  15. package/dist/client/assets/{chunk-YZCP3GAM-D3j-Ehhn.js → chunk-YZCP3GAM-DJcSuWBd.js} +1 -1
  16. package/dist/client/assets/classDiagram-6PBFFD2Q-CpidLq53.js +1 -0
  17. package/dist/client/assets/classDiagram-v2-HSJHXN6E-CpidLq53.js +1 -0
  18. package/dist/client/assets/clone-CPyCexwP.js +1 -0
  19. package/dist/client/assets/{cose-bilkent-S5V4N54A-BDRpmFTS.js → cose-bilkent-S5V4N54A-C3m_quy1.js} +1 -1
  20. package/dist/client/assets/{dagre-KV5264BT-CNnBa0oO.js → dagre-KV5264BT-DzDFWezD.js} +1 -1
  21. package/dist/client/assets/{diagram-5BDNPKRD-DmLR5VLJ.js → diagram-5BDNPKRD-D3OFrOF_.js} +1 -1
  22. package/dist/client/assets/{diagram-G4DWMVQ6-D9-S4gAC.js → diagram-G4DWMVQ6-CgCqSaI7.js} +1 -1
  23. package/dist/client/assets/{diagram-MMDJMWI5-BgkkFSRH.js → diagram-MMDJMWI5-CnJzOV_w.js} +1 -1
  24. package/dist/client/assets/{diagram-TYMM5635-CRwM_tDY.js → diagram-TYMM5635-BrUz8pH4.js} +1 -1
  25. package/dist/client/assets/{erDiagram-SMLLAGMA-DU-pow1m.js → erDiagram-SMLLAGMA-C1IvCMgN.js} +1 -1
  26. package/dist/client/assets/{flowDiagram-DWJPFMVM-B91EFbjc.js → flowDiagram-DWJPFMVM-DCrfhs19.js} +1 -1
  27. package/dist/client/assets/{ganttDiagram-T4ZO3ILL-B-gUVWSs.js → ganttDiagram-T4ZO3ILL-ChQcD1Li.js} +1 -1
  28. package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-TBkviHit.js → gitGraphDiagram-UUTBAWPF-C5aEYdTT.js} +1 -1
  29. package/dist/client/assets/{graph-Da2r3MMt.js → graph-CpGaCv1x.js} +1 -1
  30. package/dist/client/assets/index-DKrNZlfG.css +1 -0
  31. package/dist/client/assets/index-aW5PuGmI.js +452 -0
  32. package/dist/client/assets/{infoDiagram-42DDH7IO-CAdIgU9C.js → infoDiagram-42DDH7IO-BMhiz3U-.js} +1 -1
  33. package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-DKMRplux.js → ishikawaDiagram-UXIWVN3A-5_f4rhFk.js} +1 -1
  34. package/dist/client/assets/{journeyDiagram-VCZTEJTY-CPR33z10.js → journeyDiagram-VCZTEJTY-BHP2UyTZ.js} +1 -1
  35. package/dist/client/assets/{kanban-definition-6JOO6SKY-CDsviLfH.js → kanban-definition-6JOO6SKY-edTTflKa.js} +1 -1
  36. package/dist/client/assets/{layout-CkN1-8C9.js → layout-B7z9q0n7.js} +1 -1
  37. package/dist/client/assets/{linear-BxLFCpuS.js → linear-BDNnEnhj.js} +1 -1
  38. package/dist/client/assets/{mermaid.core-DA-WJY50.js → mermaid.core-DDcMYg9W.js} +4 -4
  39. package/dist/client/assets/{min-BsISxNaF.js → min-D6WC647e.js} +1 -1
  40. package/dist/client/assets/{mindmap-definition-QFDTVHPH-B-IUTdhh.js → mindmap-definition-QFDTVHPH-lvrJFtla.js} +1 -1
  41. package/dist/client/assets/{pieDiagram-DEJITSTG-hwSroJDA.js → pieDiagram-DEJITSTG-D1h_ZTUL.js} +1 -1
  42. package/dist/client/assets/{quadrantDiagram-34T5L4WZ-DDt9AzF7.js → quadrantDiagram-34T5L4WZ-DSAYqOT0.js} +1 -1
  43. package/dist/client/assets/{requirementDiagram-MS252O5E-C5Xj9gqW.js → requirementDiagram-MS252O5E-BtNZUJPU.js} +1 -1
  44. package/dist/client/assets/{sankeyDiagram-XADWPNL6-ZwBDrthi.js → sankeyDiagram-XADWPNL6-Ci2wj876.js} +1 -1
  45. package/dist/client/assets/{sequenceDiagram-FGHM5R23-DmyMDdrv.js → sequenceDiagram-FGHM5R23-ES3fQi8m.js} +1 -1
  46. package/dist/client/assets/{stateDiagram-FHFEXIEX-VD5zvoai.js → stateDiagram-FHFEXIEX-BAJV8Z8I.js} +1 -1
  47. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-CiX1nm_r.js +1 -0
  48. package/dist/client/assets/{timeline-definition-GMOUNBTQ-DP8udMAZ.js → timeline-definition-GMOUNBTQ-Bl7xwJpF.js} +1 -1
  49. package/dist/client/assets/{vennDiagram-DHZGUBPP-CiBN7TbR.js → vennDiagram-DHZGUBPP-Csv3w_qu.js} +1 -1
  50. package/dist/client/assets/{wardley-RL74JXVD-BtqeTzop.js → wardley-RL74JXVD-CaXvusTS.js} +1 -1
  51. package/dist/client/assets/{wardleyDiagram-NUSXRM2D-DaRdj2RP.js → wardleyDiagram-NUSXRM2D-DfKsNCHq.js} +1 -1
  52. package/dist/client/assets/{xychartDiagram-5P7HB3ND-jlgNCyFB.js → xychartDiagram-5P7HB3ND-BmDHSI31.js} +1 -1
  53. package/dist/client/index.html +2 -2
  54. package/dist/fleet-plugins/file-explorer/routes.mjs +102 -5
  55. package/dist/fleet-plugins/repository/routes.mjs +106 -4
  56. package/dist/fleet-plugins/skills/routes.mjs +93 -42
  57. package/dist/fleet-plugins/terminal/routes.mjs +1003 -917
  58. package/package.json +1 -1
  59. package/dist/client/assets/channel-BamKwHPs.js +0 -1
  60. package/dist/client/assets/classDiagram-6PBFFD2Q-sEh9Glhk.js +0 -1
  61. package/dist/client/assets/classDiagram-v2-HSJHXN6E-sEh9Glhk.js +0 -1
  62. package/dist/client/assets/clone-iMU-qXwc.js +0 -1
  63. package/dist/client/assets/index-5-y-ZMI6.js +0 -451
  64. package/dist/client/assets/index-BBOlVlPk.css +0 -1
  65. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-CFTLlJ0p.js +0 -1
@@ -40,6 +40,10 @@ function runGit(args, opts) {
40
40
  const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
41
41
  const maxBuffer = opts.maxBuffer ?? DEFAULT_MAX_BUFFER;
42
42
  return new Promise((resolve, reject) => {
43
+ if (opts.signal?.aborted) {
44
+ reject(new GitExecutorError("timeout"));
45
+ return;
46
+ }
43
47
  let child;
44
48
  try {
45
49
  child = spawn("git", args, withHidden({ cwd: opts.cwd, shell: false }));
@@ -53,11 +57,19 @@ function runGit(args, opts) {
53
57
  let stdoutLen = 0;
54
58
  let truncated = false;
55
59
  let timedOut = false;
56
- const timer = setTimeout(() => {
60
+ const abort = () => {
57
61
  timedOut = true;
58
62
  child.kill("SIGTERM");
59
63
  reject(new GitExecutorError("timeout"));
64
+ };
65
+ opts.signal?.addEventListener("abort", abort, { once: true });
66
+ const timer = setTimeout(() => {
67
+ abort();
60
68
  }, timeoutMs);
69
+ const cleanup = () => {
70
+ clearTimeout(timer);
71
+ opts.signal?.removeEventListener("abort", abort);
72
+ };
61
73
  child.stdout.on("data", (chunk) => {
62
74
  if (truncated) return;
63
75
  const remaining = maxBuffer - stdoutLen;
@@ -74,12 +86,12 @@ function runGit(args, opts) {
74
86
  stderrChunks.push(chunk);
75
87
  });
76
88
  child.on("error", (error) => {
77
- clearTimeout(timer);
89
+ cleanup();
78
90
  const code = error.code === "ENOENT" ? "git_unavailable" : "spawn_failed";
79
91
  reject(new GitExecutorError(code, error.message));
80
92
  });
81
93
  child.on("close", (code) => {
82
- clearTimeout(timer);
94
+ cleanup();
83
95
  if (timedOut) return;
84
96
  const stderr = Buffer.concat(stderrChunks).toString("utf8");
85
97
  if (code !== 0) {
@@ -1208,9 +1220,95 @@ async function handleRepositoryRepos(req, res, ctx) {
1208
1220
  const result = { repos, ...truncated ? { truncated: true } : {} };
1209
1221
  ctx.host.http.writeJson(res, 200, result);
1210
1222
  }
1223
+
1224
+ // ../fleet-plugins/repository/server/search.ts
1225
+ var SEARCH_COMMIT_CAP = 200;
1226
+ function parseRepositorySearchOutput(stdout, query, limit) {
1227
+ const tokens = query.trim().toLocaleLowerCase().split(/\s+/).filter(Boolean);
1228
+ const results = [];
1229
+ for (const line of stdout.split("\n")) {
1230
+ const [fullHash = "", shortHash = "", ...subjectParts] = line.split("\0");
1231
+ const subject = subjectParts.join("\0");
1232
+ if (!/^[0-9a-f]{40}$/i.test(fullHash) || !/^[0-9a-f]{7,40}$/i.test(shortHash)) continue;
1233
+ const text = `${subject}
1234
+ ${shortHash}
1235
+ ${fullHash}`.toLocaleLowerCase();
1236
+ if (!tokens.every((token) => text.includes(token))) continue;
1237
+ results.push({ fullHash, shortHash, subject });
1238
+ if (results.length >= limit) break;
1239
+ }
1240
+ return results;
1241
+ }
1242
+ async function handleRepositorySearch(req, res, ctx) {
1243
+ if (req.method !== "POST") {
1244
+ ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
1245
+ return;
1246
+ }
1247
+ if (!ctx.host.security.isTerminalAuthorized(req)) {
1248
+ ctx.host.http.writeJson(res, 401, { error: "unauthorized" });
1249
+ return;
1250
+ }
1251
+ const body = await ctx.host.http.readJsonBody(req);
1252
+ if (!isPlainObject8(body) || typeof body.theaterId !== "string" || typeof body.query !== "string" || body.query.trim() === "" || !Number.isInteger(body.limit) || body.limit < 1 || body.limit > 8 || "subPath" in body || "ref" in body) {
1253
+ ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
1254
+ return;
1255
+ }
1256
+ const theaterPath = ctx.host.paths.resolveTheaterPath(body.theaterId);
1257
+ if (!theaterPath) {
1258
+ ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
1259
+ return;
1260
+ }
1261
+ let gitCwd;
1262
+ try {
1263
+ gitCwd = (await resolveGitCwd(theaterPath, body.repoRel)).gitCwd;
1264
+ } catch (error) {
1265
+ if (error instanceof InvalidRepoError) {
1266
+ ctx.host.http.writeJson(res, 400, { error: error.code });
1267
+ return;
1268
+ }
1269
+ throw error;
1270
+ }
1271
+ try {
1272
+ const result = await runGit([
1273
+ "log",
1274
+ "--branches",
1275
+ "--tags",
1276
+ "--remotes",
1277
+ "--date-order",
1278
+ "-n",
1279
+ String(SEARCH_COMMIT_CAP),
1280
+ "--pretty=format:%H%x00%h%x00%s"
1281
+ ], { cwd: gitCwd });
1282
+ ctx.host.http.writeJson(res, 200, {
1283
+ repoRel: typeof body.repoRel === "string" ? body.repoRel : "",
1284
+ commits: parseRepositorySearchOutput(result.stdout, body.query, body.limit)
1285
+ });
1286
+ } catch (error) {
1287
+ if (error instanceof GitExecutorError) {
1288
+ if (error.code === "no_git_repo") {
1289
+ ctx.host.http.writeJson(res, 200, { repoRel: typeof body.repoRel === "string" ? body.repoRel : "", commits: [] });
1290
+ return;
1291
+ }
1292
+ if (error.code === "non_zero_exit" && error.stderr.includes("does not have any commits")) {
1293
+ ctx.host.http.writeJson(res, 200, { repoRel: typeof body.repoRel === "string" ? body.repoRel : "", commits: [] });
1294
+ return;
1295
+ }
1296
+ if (error.code === "git_unavailable") {
1297
+ ctx.host.http.writeJson(res, 422, { error: error.code });
1298
+ return;
1299
+ }
1300
+ ctx.host.http.writeJson(res, 500, { error: "git_failed" });
1301
+ return;
1302
+ }
1303
+ throw error;
1304
+ }
1305
+ }
1211
1306
  function isPlainObject8(value) {
1212
1307
  return typeof value === "object" && value !== null && !Array.isArray(value);
1213
1308
  }
1309
+ function isPlainObject9(value) {
1310
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1311
+ }
1214
1312
  async function handleRepositoryWorktrees(req, res, ctx) {
1215
1313
  if (req.method !== "POST") {
1216
1314
  ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
@@ -1221,7 +1319,7 @@ async function handleRepositoryWorktrees(req, res, ctx) {
1221
1319
  return;
1222
1320
  }
1223
1321
  const body = await ctx.host.http.readJsonBody(req);
1224
- if (!isPlainObject8(body) || "subPath" in body || typeof body.theaterId !== "string") {
1322
+ if (!isPlainObject9(body) || "subPath" in body || typeof body.theaterId !== "string") {
1225
1323
  ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
1226
1324
  return;
1227
1325
  }
@@ -1310,6 +1408,10 @@ var routes_default = definePlugin({
1310
1408
  await handleRepositoryLog(req, res, ctx);
1311
1409
  return true;
1312
1410
  });
1411
+ registerRouter(ctx, "palette-search", async ({ req, res }) => {
1412
+ await handleRepositorySearch(req, res, ctx);
1413
+ return true;
1414
+ });
1313
1415
  registerRouter(ctx, "refs", async ({ req, res }) => {
1314
1416
  await handleRepositoryRefs(req, res, ctx);
1315
1417
  return true;
@@ -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-21T00:00:00Z",
16390
+ updatedAt: "2026-07-25T00:00:00Z",
16391
16391
  providers: {
16392
16392
  claude: {
16393
16393
  name: "Claude Code",
@@ -16423,11 +16423,13 @@ var models_default = {
16423
16423
  defaultModel: "gpt-5.6-sol",
16424
16424
  models: [
16425
16425
  { modelId: "gpt-5.6-sol", name: "GPT-5.6-Sol", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max", "ultra"], default: "low" } },
16426
+ { modelId: "gpt-5.6-sol-fast", name: "GPT-5.6-Sol Fast", providerModelId: "gpt-5.6-sol", serviceTier: "priority", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max", "ultra"], default: "low" } },
16426
16427
  { modelId: "gpt-5.6-terra", name: "GPT-5.6-Terra", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max", "ultra"], default: "medium" } },
16428
+ { modelId: "gpt-5.6-terra-fast", name: "GPT-5.6-Terra Fast", providerModelId: "gpt-5.6-terra", serviceTier: "priority", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max", "ultra"], default: "medium" } },
16427
16429
  { modelId: "gpt-5.6-luna", name: "GPT-5.6-Luna", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "medium" } },
16430
+ { modelId: "gpt-5.6-luna-fast", name: "GPT-5.6-Luna Fast", providerModelId: "gpt-5.6-luna", serviceTier: "priority", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "medium" } },
16428
16431
  { modelId: "gpt-5.5", name: "GPT-5.5", effort: { supported: true, levels: ["low", "medium", "high", "xhigh"], default: "high" } },
16429
- { modelId: "gpt-5.4", name: "GPT-5.4", effort: { supported: true, levels: ["low", "medium", "high", "xhigh"], default: "high" } },
16430
- { modelId: "gpt-5.4-mini", name: "GPT-5.4 Mini", effort: { supported: true, levels: ["low", "medium", "high", "xhigh"], default: "high" } }
16432
+ { modelId: "gpt-5.5-fast", name: "GPT-5.5 Fast", providerModelId: "gpt-5.5", serviceTier: "priority", effort: { supported: true, levels: ["low", "medium", "high", "xhigh"], default: "high" } }
16431
16433
  ]
16432
16434
  },
16433
16435
  "opencode-go": {
@@ -16513,6 +16515,10 @@ var ModelEntrySchema = external_exports.object({
16513
16515
  description: external_exports.string().optional(),
16514
16516
  /** spawn 시 실제 CLI 모델 ID를 조립해야 하는 경우의 템플릿 */
16515
16517
  spawnModelTemplate: external_exports.string().optional(),
16518
+ /** 카탈로그 ID와 실제 provider 모델 ID가 다른 경우의 원본 모델 ID */
16519
+ providerModelId: external_exports.string().optional(),
16520
+ /** provider가 모델과 별도로 받는 서비스 티어 */
16521
+ serviceTier: external_exports.string().optional(),
16516
16522
  /** 모델의 컨텍스트 윈도우 크기 (토큰) */
16517
16523
  contextWindow: external_exports.number().int().positive().optional(),
16518
16524
  /** 모델별 effort 설정 */
@@ -16535,6 +16541,14 @@ var ModelEntrySchema = external_exports.object({
16535
16541
  path: ["spawnModelTemplate"]
16536
16542
  });
16537
16543
  }
16544
+ if (ctx.value.serviceTier && !ctx.value.providerModelId) {
16545
+ ctx.issues.push({
16546
+ code: "custom",
16547
+ input: ctx.value.serviceTier,
16548
+ message: "serviceTier\uB97C \uC9C0\uC815\uD55C \uBAA8\uB378\uC740 providerModelId\uB3C4 \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4",
16549
+ path: ["serviceTier"]
16550
+ });
16551
+ }
16538
16552
  });
16539
16553
  var ModelsMappingSchema = external_exports.record(external_exports.string(), external_exports.string());
16540
16554
  var ProviderSchema = external_exports.object({
@@ -16627,8 +16641,6 @@ var CLI_BACKENDS = {
16627
16641
  cliCommand: "codex",
16628
16642
  protocol: "codex-app-server",
16629
16643
  authRequired: true,
16630
- npxPackage: "@agentclientprotocol/codex-acp@1.1.2",
16631
- acpArgs: [],
16632
16644
  appServerArgs: ["app-server", "--listen", "stdio://"],
16633
16645
  modes: [
16634
16646
  { id: "default", label: "Plan" },
@@ -16638,7 +16650,7 @@ var CLI_BACKENDS = {
16638
16650
  supportsSessionClose: true,
16639
16651
  supportsSessionLoad: true,
16640
16652
  requiresModelAtSpawn: false,
16641
- usesNpxBridge: true,
16653
+ usesNpxBridge: false,
16642
16654
  defaultMaxTokens: 1e5
16643
16655
  },
16644
16656
  "opencode-go": {
@@ -16975,6 +16987,7 @@ var PREVIEW_TIMEOUT_MS = 3e4;
16975
16987
  var CLI_TIMEOUT_MS = 12e4;
16976
16988
  var USERINFO_URL_RE = /\b[a-z][a-z0-9+.-]*:\/\/[^\s/@]+@[^\s]+/gi;
16977
16989
  var TOKEN_URL_PARAM_RE = /([?&](?:access_?token|token|api_?key|apikey|auth(?:orization)?|password|secret|credential)=)[^&#\s]*/gi;
16990
+ var installedSkillsByTheater = /* @__PURE__ */ new Map();
16978
16991
  async function readSkillSources(cwd) {
16979
16992
  const sources = /* @__PURE__ */ new Map();
16980
16993
  try {
@@ -17061,6 +17074,43 @@ function spawnJobAsync(jobId, args, cwd, redactionPaths, executor) {
17061
17074
  }).then((result) => finishJob(jobId, result.exitCode)).catch(() => finishJob(jobId, 1));
17062
17075
  });
17063
17076
  }
17077
+ async function listInstalledSkills(projectCwd, executor) {
17078
+ if (projectCwd) {
17079
+ const [projectRaw, globalRaw2, projectSources, globalSources2] = await Promise.all([
17080
+ runListCommand(["list", "--json"], projectCwd, executor),
17081
+ runListCommand(["list", "-g", "--json"], os2.homedir(), executor),
17082
+ readSkillSources(projectCwd),
17083
+ readSkillSources(os2.homedir())
17084
+ ]);
17085
+ return [
17086
+ ...projectRaw.map((entry) => ({
17087
+ name: entry.name,
17088
+ scope: "project",
17089
+ agents: entry.agents,
17090
+ source: projectSources.get(entry.name),
17091
+ displayPath: buildDisplayPath("project", entry.name)
17092
+ })),
17093
+ ...globalRaw2.map((entry) => ({
17094
+ name: entry.name,
17095
+ scope: "global",
17096
+ agents: entry.agents,
17097
+ source: globalSources2.get(entry.name),
17098
+ displayPath: buildDisplayPath("global", entry.name)
17099
+ }))
17100
+ ];
17101
+ }
17102
+ const [globalRaw, globalSources] = await Promise.all([
17103
+ runListCommand(["list", "-g", "--json"], os2.homedir(), executor),
17104
+ readSkillSources(os2.homedir())
17105
+ ]);
17106
+ return globalRaw.map((entry) => ({
17107
+ name: entry.name,
17108
+ scope: "global",
17109
+ agents: entry.agents,
17110
+ source: globalSources.get(entry.name),
17111
+ displayPath: buildDisplayPath("global", entry.name)
17112
+ }));
17113
+ }
17064
17114
  async function handleList(req, res, ctx, executor) {
17065
17115
  if (req.method !== "GET") {
17066
17116
  ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
@@ -17090,46 +17140,43 @@ async function handleList(req, res, ctx, executor) {
17090
17140
  }
17091
17141
  }
17092
17142
  try {
17093
- if (projectCwd) {
17094
- const [projectRaw, globalRaw, projectSources, globalSources] = await Promise.all([
17095
- runListCommand(["list", "--json"], projectCwd, executor),
17096
- runListCommand(["list", "-g", "--json"], os2.homedir(), executor),
17097
- readSkillSources(projectCwd),
17098
- readSkillSources(os2.homedir())
17099
- ]);
17100
- const projectSkills = projectRaw.map((entry) => ({
17101
- name: entry.name,
17102
- scope: "project",
17103
- agents: entry.agents,
17104
- source: projectSources.get(entry.name),
17105
- displayPath: buildDisplayPath("project", entry.name)
17106
- }));
17107
- const globalSkills = globalRaw.map((entry) => ({
17108
- name: entry.name,
17109
- scope: "global",
17110
- agents: entry.agents,
17111
- source: globalSources.get(entry.name),
17112
- displayPath: buildDisplayPath("global", entry.name)
17113
- }));
17114
- ctx.host.http.writeJson(res, 200, { skills: [...projectSkills, ...globalSkills] });
17115
- } else {
17116
- const [globalRaw, globalSources] = await Promise.all([
17117
- runListCommand(["list", "-g", "--json"], os2.homedir(), executor),
17118
- readSkillSources(os2.homedir())
17119
- ]);
17120
- const skills = globalRaw.map((entry) => ({
17121
- name: entry.name,
17122
- scope: "global",
17123
- agents: entry.agents,
17124
- source: globalSources.get(entry.name),
17125
- displayPath: buildDisplayPath("global", entry.name)
17126
- }));
17127
- ctx.host.http.writeJson(res, 200, { skills });
17128
- }
17143
+ const skills = await listInstalledSkills(projectCwd, executor);
17144
+ if (theaterId) installedSkillsByTheater.set(theaterId, skills);
17145
+ ctx.host.http.writeJson(res, 200, { skills });
17129
17146
  } catch {
17147
+ if (theaterId) installedSkillsByTheater.set(theaterId, []);
17130
17148
  ctx.host.http.writeJson(res, 200, { skills: [] });
17131
17149
  }
17132
17150
  }
17151
+ async function handlePaletteSearch(req, res, ctx, executor) {
17152
+ if (req.method !== "POST") {
17153
+ ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
17154
+ return;
17155
+ }
17156
+ if (!ctx.host.security.isTerminalAuthorized(req)) {
17157
+ ctx.host.http.writeJson(res, 401, { error: "unauthorized" });
17158
+ return;
17159
+ }
17160
+ const body = await ctx.host.http.readJsonBody(req);
17161
+ if (!isPlainObject2(body) || typeof body.theaterId !== "string" || typeof body.query !== "string" || body.query.trim() === "" || !Number.isInteger(body.limit) || body.limit < 1 || body.limit > 8 || "relPath" in body) {
17162
+ ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
17163
+ return;
17164
+ }
17165
+ let projectCwd;
17166
+ try {
17167
+ projectCwd = await resolveProjectScopeCwd(ctx, body.theaterId);
17168
+ } catch (error51) {
17169
+ writeProjectPathError(res, ctx, error51);
17170
+ return;
17171
+ }
17172
+ if (!projectCwd) {
17173
+ ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
17174
+ return;
17175
+ }
17176
+ const tokens = body.query.trim().toLocaleLowerCase().split(/\s+/).filter(Boolean);
17177
+ const skills = (installedSkillsByTheater.get(body.theaterId) ?? []).filter((skill) => tokens.every((token) => skill.name.toLocaleLowerCase().includes(token))).sort((left, right) => left.name.localeCompare(right.name) || left.scope.localeCompare(right.scope)).slice(0, body.limit).map(({ name, scope }) => ({ name, scope }));
17178
+ ctx.host.http.writeJson(res, 200, { skills });
17179
+ }
17133
17180
  async function handleSearch(req, res, ctx) {
17134
17181
  if (req.method !== "GET") {
17135
17182
  ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
@@ -17472,6 +17519,10 @@ var routes_default = definePlugin({
17472
17519
  await handleList(req, res, ctx, executor);
17473
17520
  return true;
17474
17521
  });
17522
+ registerRouter(ctx, "palette-search", async ({ req, res }) => {
17523
+ await handlePaletteSearch(req, res, ctx);
17524
+ return true;
17525
+ });
17475
17526
  registerRouter(ctx, "search", async ({ req, res }) => {
17476
17527
  await handleSearch(req, res, ctx);
17477
17528
  return true;