@jvittechs/jai1-cli 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -33,7 +33,7 @@ var NetworkError = class extends Jai1Error {
33
33
  // package.json
34
34
  var package_default = {
35
35
  name: "@jvittechs/jai1-cli",
36
- version: "1.0.1",
36
+ version: "1.0.3",
37
37
  description: "A unified CLI tool for JV-IT TECHS developers to manage Jai1 Framework. Please contact TeamAI for usage instructions.",
38
38
  type: "module",
39
39
  bin: {
@@ -969,24 +969,24 @@ trigger: ${trigger}
969
969
  name: "OpenCode",
970
970
  icon: "\u{1F4BB}",
971
971
  basePath: ".opencode",
972
- rulesPath: "rules",
973
- workflowsPath: "workflows",
974
- commandsPath: null,
972
+ rulesPath: null,
973
+ // OpenCode uses AGENTS.md for rules
974
+ workflowsPath: null,
975
+ commandsPath: "command",
976
+ // Note: singular "command" not "commands"
975
977
  fileExtension: ".md",
976
978
  generateFrontmatter: (opts) => {
977
- let trigger;
978
- if (opts.trigger) {
979
- trigger = opts.trigger === "always" ? "always_on" : opts.trigger;
980
- } else if (opts.alwaysApply) {
981
- trigger = "always_on";
982
- } else if (opts.globs && opts.globs.length > 0) {
983
- trigger = opts.globs[0];
984
- } else {
985
- trigger = "always_on";
979
+ const lines = ["---"];
980
+ if (opts.description) {
981
+ lines.push(`description: ${opts.description}`);
986
982
  }
987
- return `---
988
- trigger: ${trigger}
989
- ---`;
983
+ const agent = opts.agent ?? "code";
984
+ lines.push(`agent: ${agent}`);
985
+ if (opts.model) {
986
+ lines.push(`model: ${opts.model}`);
987
+ }
988
+ lines.push("---");
989
+ return lines.join("\n");
990
990
  }
991
991
  }
992
992
  };
@@ -1031,7 +1031,8 @@ var MigrateIdeService = class {
1031
1031
  }
1032
1032
  const files = await fs4.readdir(presetDir);
1033
1033
  for (const file of files) {
1034
- if (!file.endsWith(".mdc")) continue;
1034
+ if (!file.endsWith(".md") && !file.endsWith(".mdc")) continue;
1035
+ if (file === "preset.json") continue;
1035
1036
  const filepath = path.join(presetDir, file);
1036
1037
  const stat = await fs4.stat(filepath);
1037
1038
  if (!stat.isFile()) continue;
@@ -1042,7 +1043,7 @@ var MigrateIdeService = class {
1042
1043
  frontmatter = data;
1043
1044
  } catch {
1044
1045
  }
1045
- const name = path.basename(file, ".mdc");
1046
+ const name = file.endsWith(".mdc") ? path.basename(file, ".mdc") : path.basename(file, ".md");
1046
1047
  const trigger = this.extractTrigger(frontmatter);
1047
1048
  const alwaysApply = this.isAlwaysTrigger(trigger);
1048
1049
  items.push({
@@ -1404,7 +1405,7 @@ var UnifiedApplyApp = ({
1404
1405
  }, [components, searchQuery, activePackageFilter]);
1405
1406
  useInput((input5, key) => {
1406
1407
  if (viewState === "done") {
1407
- if (key.return || input5 === "q" || key.escape) {
1408
+ if (key.return || input5 === "q" && key.ctrl || key.escape) {
1408
1409
  onExit();
1409
1410
  }
1410
1411
  return;
@@ -1412,7 +1413,7 @@ var UnifiedApplyApp = ({
1412
1413
  if (viewState === "summary") {
1413
1414
  if (key.return) {
1414
1415
  setViewState("ide-sync");
1415
- } else if (input5 === "s" || input5 === "q" || key.escape) {
1416
+ } else if (input5 === "s" || input5 === "q" && key.ctrl || key.escape) {
1416
1417
  onExit();
1417
1418
  }
1418
1419
  return;
@@ -1443,7 +1444,7 @@ var UnifiedApplyApp = ({
1443
1444
  if (selectedIdes.size > 0) {
1444
1445
  handleIdeSync();
1445
1446
  }
1446
- } else if (input5 === "s" || input5 === "q" || key.escape) {
1447
+ } else if (input5 === "s" || input5 === "q" && key.ctrl || key.escape) {
1447
1448
  onExit();
1448
1449
  }
1449
1450
  return;
@@ -1467,7 +1468,7 @@ var UnifiedApplyApp = ({
1467
1468
  }
1468
1469
  return;
1469
1470
  }
1470
- if (key.escape || input5 === "q") {
1471
+ if (key.escape || input5 === "q" && key.ctrl) {
1471
1472
  onExit();
1472
1473
  return;
1473
1474
  }
@@ -1629,7 +1630,7 @@ var UnifiedApplyApp = ({
1629
1630
  return /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React3.createElement(Box2, { marginBottom: 1 }, /* @__PURE__ */ React3.createElement(Text3, { bold: true, color: "cyan" }, "\u{1F4E6} Installing Components")), /* @__PURE__ */ React3.createElement(Box2, { marginBottom: 1 }, /* @__PURE__ */ React3.createElement(ProgressBar, { current: installStats.completed, total: installStats.total, width: 50 })), /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 1, height: 10 }, installProgress.slice(-8).map((item) => /* @__PURE__ */ React3.createElement(Box2, { key: item.filepath }, /* @__PURE__ */ React3.createElement(StatusIcon, { status: item.status === "success" ? "success" : item.status === "error" ? "error" : item.status === "downloading" ? "loading" : "pending" }), /* @__PURE__ */ React3.createElement(Text3, null, " ", item.filepath), item.error && /* @__PURE__ */ React3.createElement(Text3, { color: "red", dimColor: true }, " (", item.error, ")")))), /* @__PURE__ */ React3.createElement(Box2, { marginTop: 1 }, /* @__PURE__ */ React3.createElement(Text3, null, "\u{1F4CA} ", /* @__PURE__ */ React3.createElement(Text3, { color: "green" }, installStats.added, " added"), " \xB7 ", /* @__PURE__ */ React3.createElement(Text3, { color: "cyan" }, installStats.updated, " updated"), " \xB7 ", /* @__PURE__ */ React3.createElement(Text3, { color: "red" }, installStats.failed, " failed"))));
1630
1631
  }
1631
1632
  if (viewState === "summary") {
1632
- return /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React3.createElement(Box2, { marginBottom: 1 }, /* @__PURE__ */ React3.createElement(Text3, { bold: true, color: "green" }, "\u2705 Installation Complete!")), /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 1 }, /* @__PURE__ */ React3.createElement(Text3, null, installStats.total, " components processed:"), /* @__PURE__ */ React3.createElement(Text3, null, " \u2514\u2500 ", /* @__PURE__ */ React3.createElement(Text3, { color: "green" }, installStats.added), " newly added"), /* @__PURE__ */ React3.createElement(Text3, null, " \u2514\u2500 ", /* @__PURE__ */ React3.createElement(Text3, { color: "cyan" }, installStats.updated), " updated"), installStats.failed > 0 && /* @__PURE__ */ React3.createElement(Text3, null, " \u2514\u2500 ", /* @__PURE__ */ React3.createElement(Text3, { color: "red" }, installStats.failed), " failed")), /* @__PURE__ */ React3.createElement(Box2, { marginTop: 1 }, /* @__PURE__ */ React3.createElement(Text3, null, "\u{1F4C1} Location: ", /* @__PURE__ */ React3.createElement(Text3, { color: "cyan" }, process.cwd(), "/.jai1"))), /* @__PURE__ */ React3.createElement(Box2, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true, color: "yellow" }, "\u{1F4E6} Next Step: Sync to IDE(s)?"), /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, "Sync .jai1/ content to your IDE directories (rules, workflows)")), /* @__PURE__ */ React3.createElement(Box2, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, "[Enter] Select IDE(s) to sync \xB7 [S/Q] Skip and exit")));
1633
+ return /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React3.createElement(Box2, { marginBottom: 1 }, /* @__PURE__ */ React3.createElement(Text3, { bold: true, color: "green" }, "\u2705 Installation Complete!")), /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 1 }, /* @__PURE__ */ React3.createElement(Text3, null, installStats.total, " components processed:"), /* @__PURE__ */ React3.createElement(Text3, null, " \u2514\u2500 ", /* @__PURE__ */ React3.createElement(Text3, { color: "green" }, installStats.added), " newly added"), /* @__PURE__ */ React3.createElement(Text3, null, " \u2514\u2500 ", /* @__PURE__ */ React3.createElement(Text3, { color: "cyan" }, installStats.updated), " updated"), installStats.failed > 0 && /* @__PURE__ */ React3.createElement(Text3, null, " \u2514\u2500 ", /* @__PURE__ */ React3.createElement(Text3, { color: "red" }, installStats.failed), " failed")), /* @__PURE__ */ React3.createElement(Box2, { marginTop: 1 }, /* @__PURE__ */ React3.createElement(Text3, null, "\u{1F4C1} Location: ", /* @__PURE__ */ React3.createElement(Text3, { color: "cyan" }, process.cwd(), "/.jai1"))), /* @__PURE__ */ React3.createElement(Box2, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true, color: "yellow" }, "\u{1F4E6} Next Step: Sync to IDE(s)?"), /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, "Sync .jai1/ content to your IDE directories (rules, workflows)")), /* @__PURE__ */ React3.createElement(Box2, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, "[Enter] Select IDE(s) to sync \xB7 [S/Ctrl+Q] Skip and exit")));
1633
1634
  }
1634
1635
  if (viewState === "ide-sync") {
1635
1636
  return /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React3.createElement(Box2, { marginBottom: 1 }, /* @__PURE__ */ React3.createElement(Text3, { bold: true, color: "cyan" }, "\u{1F504} Select IDE(s) to Sync")), /* @__PURE__ */ React3.createElement(Box2, { marginBottom: 1 }, /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, "Sync .jai1/ content (rules, workflows) to IDE-specific directories")), /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", padding: 1 }, availableIdes.map((ide, i) => {
@@ -1637,7 +1638,7 @@ var UnifiedApplyApp = ({
1637
1638
  const isCursor = i === ideCursorIndex;
1638
1639
  const isChecked = selectedIdes.has(ide);
1639
1640
  return /* @__PURE__ */ React3.createElement(Box2, { key: ide }, /* @__PURE__ */ React3.createElement(Text3, { color: isCursor ? "cyan" : "white" }, isCursor ? "\u276F " : " ", isChecked ? "[\u2713]" : "[ ]", " ", ideConfig.icon, " ", ideConfig.name));
1640
- })), selectedIdes.size > 0 && /* @__PURE__ */ React3.createElement(Box2, { marginTop: 1 }, /* @__PURE__ */ React3.createElement(Text3, null, "Selected: ", /* @__PURE__ */ React3.createElement(Text3, { color: "green" }, selectedIdes.size), " IDE(s)")), /* @__PURE__ */ React3.createElement(Box2, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, "[\u2191\u2193] Navigate \xB7 [\u2423] Toggle \xB7 [A] Select all \xB7 [C] Clear \xB7 [Enter] Sync \xB7 [S/Q] Skip")));
1641
+ })), selectedIdes.size > 0 && /* @__PURE__ */ React3.createElement(Box2, { marginTop: 1 }, /* @__PURE__ */ React3.createElement(Text3, null, "Selected: ", /* @__PURE__ */ React3.createElement(Text3, { color: "green" }, selectedIdes.size), " IDE(s)")), /* @__PURE__ */ React3.createElement(Box2, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, "[\u2191\u2193] Navigate \xB7 [\u2423] Toggle \xB7 [A] Select all \xB7 [C] Clear \xB7 [Enter] Sync \xB7 [S/Ctrl+Q] Skip")));
1641
1642
  }
1642
1643
  if (viewState === "syncing") {
1643
1644
  return /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React3.createElement(Box2, { marginBottom: 1 }, /* @__PURE__ */ React3.createElement(Text3, { bold: true, color: "cyan" }, "\u{1F504} Syncing to IDE(s)")), /* @__PURE__ */ React3.createElement(Box2, { marginBottom: 1 }, /* @__PURE__ */ React3.createElement(ProgressBar, { current: syncStats.completed, total: syncStats.total, width: 50 })), /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 1, height: 10 }, syncProgress.slice(-8).map((item, idx) => /* @__PURE__ */ React3.createElement(Box2, { key: `${item.targetPath}-${idx}` }, /* @__PURE__ */ React3.createElement(StatusIcon, { status: item.status === "success" ? "success" : item.status === "error" ? "error" : item.status === "syncing" ? "loading" : "pending" }), /* @__PURE__ */ React3.createElement(Text3, null, " ", item.targetPath), item.error && /* @__PURE__ */ React3.createElement(Text3, { color: "red", dimColor: true }, " (", item.error, ")")))), /* @__PURE__ */ React3.createElement(Box2, { marginTop: 1 }, /* @__PURE__ */ React3.createElement(Text3, null, "\u{1F4CA} ", /* @__PURE__ */ React3.createElement(Text3, { color: "green" }, syncStats.created, " created"), " \xB7 ", /* @__PURE__ */ React3.createElement(Text3, { color: "cyan" }, syncStats.updated, " updated"), syncStats.skipped > 0 && /* @__PURE__ */ React3.createElement(React3.Fragment, null, " \xB7 ", /* @__PURE__ */ React3.createElement(Text3, { color: "yellow" }, syncStats.skipped, " skipped")), syncStats.errors > 0 && /* @__PURE__ */ React3.createElement(React3.Fragment, null, " \xB7 ", /* @__PURE__ */ React3.createElement(Text3, { color: "red" }, syncStats.errors, " errors")))));
@@ -1673,7 +1674,7 @@ var UnifiedApplyApp = ({
1673
1674
  const isChecked = selectedPaths.has(comp.filepath);
1674
1675
  const isInstalled = installedPaths.has(comp.filepath);
1675
1676
  return /* @__PURE__ */ React3.createElement(Box2, { key: comp.filepath }, /* @__PURE__ */ React3.createElement(Text3, { color: isCursor ? "cyan" : "white" }, isCursor ? "\u276F " : " ", isChecked ? "[\u2713]" : "[ ]", " ", comp.filepath), /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, " ", isInstalled ? "\u2713 installed" : "\u25CB new"));
1676
- }), filteredComponents.length === 0 && /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, "No components match your search")), selectedPaths.size > 0 && /* @__PURE__ */ React3.createElement(Box2, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Selected: ", selectedPaths.size, " components"), /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "column", marginLeft: 2 }, Array.from(selectedPaths).slice(0, 4).map((fp) => /* @__PURE__ */ React3.createElement(Text3, { key: fp, dimColor: true }, "\u{1F4CC} ", fp)), selectedPaths.size > 4 && /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, " ... and ", selectedPaths.size - 4, " more"))), /* @__PURE__ */ React3.createElement(Box2, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, focusArea === "packages" && "[\u2190\u2192] Browse packages \xB7 [\u2423/Enter] Select package", focusArea === "components" && "[\u2191\u2193] Navigate \xB7 [\u2423] Toggle", focusArea === "search" && "Type to search...", " \xB7 [Tab] Switch area \xB7 [A] All \xB7 [C] Clear \xB7 [Enter] Apply \xB7 [Q] Quit")));
1677
+ }), filteredComponents.length === 0 && /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, "No components match your search")), selectedPaths.size > 0 && /* @__PURE__ */ React3.createElement(Box2, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Selected: ", selectedPaths.size, " components"), /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "column", marginLeft: 2 }, Array.from(selectedPaths).slice(0, 4).map((fp) => /* @__PURE__ */ React3.createElement(Text3, { key: fp, dimColor: true }, "\u{1F4CC} ", fp)), selectedPaths.size > 4 && /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, " ... and ", selectedPaths.size - 4, " more"))), /* @__PURE__ */ React3.createElement(Box2, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, focusArea === "packages" && "[\u2190\u2192] Browse packages \xB7 [\u2423/Enter] Select package", focusArea === "components" && "[\u2191\u2193] Navigate \xB7 [\u2423] Toggle", focusArea === "search" && "Type to search...", " \xB7 [Tab] Switch area \xB7 [A] All \xB7 [C] Clear \xB7 [Enter] Apply \xB7 [Ctrl+Q] Quit")));
1677
1678
  };
1678
1679
 
1679
1680
  // src/commands/apply.ts
@@ -3355,6 +3356,19 @@ var IDE_FORMATS = {
3355
3356
  supportsReference: false,
3356
3357
  dependencies: ["agentsmd"]
3357
3358
  // Gemini requires AGENTS.md
3359
+ },
3360
+ opencode: {
3361
+ id: "opencode",
3362
+ name: "OpenCode",
3363
+ description: "OpenCode (AGENTS.md + .opencode/command/)",
3364
+ rulesPath: ".",
3365
+ // Uses AGENTS.md
3366
+ workflowsPath: ".opencode/command",
3367
+ fileExtension: ".md",
3368
+ metadataFormat: "yaml-frontmatter",
3369
+ supportsReference: true,
3370
+ dependencies: ["agentsmd"]
3371
+ // OpenCode requires AGENTS.md for rules
3358
3372
  }
3359
3373
  };
3360
3374
 
@@ -3405,6 +3419,20 @@ var IdeDetectionService = class {
3405
3419
  detection.confidence = exists ? "high" : "low";
3406
3420
  return detection;
3407
3421
  }
3422
+ if (ideId === "opencode") {
3423
+ const hasAgents = await this.pathExists("AGENTS.md");
3424
+ const commandPath = join4(this.projectPath, ".opencode/command");
3425
+ const hasCommands = await this.pathExists(commandPath);
3426
+ detection.hasRules = hasAgents;
3427
+ detection.ruleCount = hasAgents ? 1 : 0;
3428
+ if (hasCommands) {
3429
+ detection.hasWorkflows = true;
3430
+ detection.workflowCount = await this.countFiles(commandPath, ".md");
3431
+ }
3432
+ detection.detected = hasAgents || hasCommands && detection.workflowCount > 0;
3433
+ detection.confidence = detection.detected ? hasAgents && hasCommands ? "high" : "medium" : "low";
3434
+ return detection;
3435
+ }
3408
3436
  const rulesPath = join4(this.projectPath, format.rulesPath);
3409
3437
  const rulesExist = await this.pathExists(rulesPath);
3410
3438
  if (rulesExist) {
@@ -3480,6 +3508,13 @@ var IdeDetectionService = class {
3480
3508
  if (await this.pathExists("GEMINI.md")) {
3481
3509
  detected.push(ideId);
3482
3510
  }
3511
+ } else if (ideId === "opencode") {
3512
+ const hasAgents = await this.pathExists("AGENTS.md");
3513
+ const commandPath = join4(this.projectPath, ".opencode/command");
3514
+ const hasCommands = await this.pathExists(commandPath);
3515
+ if (hasAgents || hasCommands) {
3516
+ detected.push(ideId);
3517
+ }
3483
3518
  } else {
3484
3519
  const rulesPath = join4(this.projectPath, format.rulesPath);
3485
3520
  if (await this.pathExists(rulesPath)) {
@@ -3573,6 +3608,15 @@ var IdeDetectionService = class {
3573
3608
  priority: "high"
3574
3609
  });
3575
3610
  }
3611
+ const hasOpenCodeConfig = await this.pathExists(join4(this.projectPath, ".opencode"));
3612
+ if (hasOpenCodeConfig) {
3613
+ suggestions.push({
3614
+ ideId: "opencode",
3615
+ name: "OpenCode",
3616
+ reason: ".opencode directory detected",
3617
+ priority: "high"
3618
+ });
3619
+ }
3576
3620
  return suggestions;
3577
3621
  }
3578
3622
  };
@@ -3624,6 +3668,8 @@ async function runStatus(options) {
3624
3668
  console.log(` Location: AGENTS.md`);
3625
3669
  } else if (ide.id === "gemini") {
3626
3670
  console.log(` Location: GEMINI.md`);
3671
+ } else if (ide.id === "opencode") {
3672
+ console.log(` Location: AGENTS.md + .opencode/command/`);
3627
3673
  } else {
3628
3674
  console.log(` Location: ${format.rulesPath}/`);
3629
3675
  }
@@ -3851,7 +3897,7 @@ var Footer = ({ focusArea, isSearchOpen = false }) => {
3851
3897
  { key: "Enter", action: "Select" },
3852
3898
  { key: "\u2192/Tab", action: "Content" },
3853
3899
  { key: "/", action: "Search" },
3854
- { key: "q", action: "Quit" }
3900
+ { key: "Ctrl+q", action: "Quit" }
3855
3901
  ];
3856
3902
  }
3857
3903
  return [
@@ -10178,7 +10224,7 @@ var UtilsApp = ({ onExit }) => {
10178
10224
  setSelectedIndex((prev) => prev < MENU_ITEMS2.length - 1 ? prev + 1 : 0);
10179
10225
  } else if (key.return) {
10180
10226
  setActiveView(MENU_ITEMS2[selectedIndex].id);
10181
- } else if (input5 === "q" || key.escape) {
10227
+ } else if (input5 === "q" && key.ctrl || key.escape) {
10182
10228
  onExit();
10183
10229
  exit();
10184
10230
  }
@@ -10193,7 +10239,7 @@ var UtilsApp = ({ onExit }) => {
10193
10239
  marginBottom: 1
10194
10240
  },
10195
10241
  /* @__PURE__ */ React41.createElement(Text36, { bold: true, color: "cyan" }, "\u{1F6E0}\uFE0F Developer Utilities - Interactive Mode"),
10196
- /* @__PURE__ */ React41.createElement(Box36, { marginLeft: "auto" }, /* @__PURE__ */ React41.createElement(Text36, { dimColor: true }, "Press 'q' to quit"))
10242
+ /* @__PURE__ */ React41.createElement(Box36, { marginLeft: "auto" }, /* @__PURE__ */ React41.createElement(Text36, { dimColor: true }, "Press Ctrl+Q to quit"))
10197
10243
  ), /* @__PURE__ */ React41.createElement(Box36, { flexGrow: 1 }, /* @__PURE__ */ React41.createElement(
10198
10244
  Box36,
10199
10245
  {
@@ -10252,7 +10298,7 @@ var WelcomeView = ({ selectedItem }) => {
10252
10298
  marginBottom: 2
10253
10299
  },
10254
10300
  /* @__PURE__ */ React41.createElement(Box36, { flexDirection: "column" }, /* @__PURE__ */ React41.createElement(Text36, { bold: true, color: "yellow" }, selectedItem.icon, " ", selectedItem.label), /* @__PURE__ */ React41.createElement(Text36, { dimColor: true }, selectedItem.description))
10255
- ), /* @__PURE__ */ React41.createElement(Box36, { marginBottom: 1 }, /* @__PURE__ */ React41.createElement(Text36, { bold: true }, "Quick Actions:")), /* @__PURE__ */ React41.createElement(Box36, { flexDirection: "column", marginLeft: 2 }, /* @__PURE__ */ React41.createElement(Text36, null, "\u2022 Press ", /* @__PURE__ */ React41.createElement(Text36, { color: "green" }, "Enter"), " to open selected utility"), /* @__PURE__ */ React41.createElement(Text36, null, "\u2022 Use ", /* @__PURE__ */ React41.createElement(Text36, { color: "green" }, "\u2191/\u2193"), " or ", /* @__PURE__ */ React41.createElement(Text36, { color: "green" }, "j/k"), " to navigate"), /* @__PURE__ */ React41.createElement(Text36, null, "\u2022 Press ", /* @__PURE__ */ React41.createElement(Text36, { color: "green" }, "Esc"), " to go back or quit"), /* @__PURE__ */ React41.createElement(Text36, null, "\u2022 Press ", /* @__PURE__ */ React41.createElement(Text36, { color: "green" }, "q"), " to quit anytime")), /* @__PURE__ */ React41.createElement(Box36, { marginTop: 2 }, /* @__PURE__ */ React41.createElement(Text36, { dimColor: true }, "\u{1F4A1} Tip: Each utility provides an interactive interface for easy usage.")));
10301
+ ), /* @__PURE__ */ React41.createElement(Box36, { marginBottom: 1 }, /* @__PURE__ */ React41.createElement(Text36, { bold: true }, "Quick Actions:")), /* @__PURE__ */ React41.createElement(Box36, { flexDirection: "column", marginLeft: 2 }, /* @__PURE__ */ React41.createElement(Text36, null, "\u2022 Press ", /* @__PURE__ */ React41.createElement(Text36, { color: "green" }, "Enter"), " to open selected utility"), /* @__PURE__ */ React41.createElement(Text36, null, "\u2022 Use ", /* @__PURE__ */ React41.createElement(Text36, { color: "green" }, "\u2191/\u2193"), " or ", /* @__PURE__ */ React41.createElement(Text36, { color: "green" }, "j/k"), " to navigate"), /* @__PURE__ */ React41.createElement(Text36, null, "\u2022 Press ", /* @__PURE__ */ React41.createElement(Text36, { color: "green" }, "Esc"), " to go back or quit"), /* @__PURE__ */ React41.createElement(Text36, null, "\u2022 Press ", /* @__PURE__ */ React41.createElement(Text36, { color: "green" }, "Ctrl+Q"), " to quit anytime")), /* @__PURE__ */ React41.createElement(Box36, { marginTop: 2 }, /* @__PURE__ */ React41.createElement(Text36, { dimColor: true }, "\u{1F4A1} Tip: Each utility provides an interactive interface for easy usage.")));
10256
10302
  };
10257
10303
  var ActiveUtilityView = ({ utilityType }) => {
10258
10304
  switch (utilityType) {
@@ -11645,7 +11691,8 @@ function createKitCreateCommand() {
11645
11691
  { name: "Cursor", value: "cursor" },
11646
11692
  { name: "Windsurf", value: "windsurf" },
11647
11693
  { name: "Claude Code", value: "claude-code" },
11648
- { name: "Antigravity", value: "antigravity" }
11694
+ { name: "Antigravity", value: "antigravity" },
11695
+ { name: "OpenCode", value: "opencode" }
11649
11696
  ];
11650
11697
  let selectedIdes = [];
11651
11698
  if (isAutoMode) {