@jvittechs/j 1.0.65 → 1.0.67

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
@@ -13,7 +13,7 @@ import {
13
13
  CloudTaskProvider,
14
14
  TaskService,
15
15
  createTaskSummaryCommand
16
- } from "./chunk-QA66JGRJ.js";
16
+ } from "./chunk-H3YFFEME.js";
17
17
  import {
18
18
  BLOCKED_ICON,
19
19
  PRIORITY_ICONS,
@@ -160,7 +160,7 @@ import { basename as basename5 } from "path";
160
160
  // package.json
161
161
  var package_default = {
162
162
  name: "@jvittechs/j",
163
- version: "1.0.65",
163
+ version: "1.0.67",
164
164
  description: "A unified CLI tool for JV-IT TECHS developers to manage Jai1 Framework. Supports both `j` and `jai1` commands. Please contact TeamAI for usage instructions.",
165
165
  type: "module",
166
166
  bin: {
@@ -618,7 +618,7 @@ async function getProjectStatus() {
618
618
  // src/commands/apply.ts
619
619
  import React4 from "react";
620
620
  import { render } from "ink";
621
- import { Command as Command3 } from "commander";
621
+ import { Command as Command4 } from "commander";
622
622
 
623
623
  // src/ui/apply/UnifiedApplyApp.tsx
624
624
  import React3, { useState, useEffect, useMemo } from "react";
@@ -1581,9 +1581,162 @@ var UnifiedApplyApp = ({
1581
1581
  }), filteredComponents.length === 0 && /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, "No components match your filter")), 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, 3).map((fp) => /* @__PURE__ */ React3.createElement(Text3, { key: fp, dimColor: true }, "\u{1F4CC} ", fp)), selectedPaths.size > 3 && /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, " ... +", selectedPaths.size - 3, " more"))), /* @__PURE__ */ React3.createElement(Box2, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, focusArea === "packages" && "[\u2190\u2192] Package \xB7 [\u2193] List \xB7 [\u2423] Select all", focusArea === "search" && "Type to filter \xB7 [\u2193] List", focusArea === "components" && "[\u2191\u2193] Navigate \xB7 [\u2423] Toggle", " \xB7 [Tab] Switch \xB7 [A] All \xB7 [C] Clear \xB7 [Enter] Apply")));
1582
1582
  };
1583
1583
 
1584
+ // src/commands/ide/sync.ts
1585
+ import { Command as Command3 } from "commander";
1586
+ import { checkbox, confirm } from "@inquirer/prompts";
1587
+
1588
+ // src/utils/prompt-theme.ts
1589
+ var keysHelpTipWithQuit = (keys) => {
1590
+ const keyStrings = keys.map(([key, action]) => `${key} ${action}`);
1591
+ keyStrings.push("Ctrl+C quit");
1592
+ return keyStrings.join(" \u2022 ");
1593
+ };
1594
+ var checkboxTheme = {
1595
+ style: {
1596
+ keysHelpTip: keysHelpTipWithQuit
1597
+ }
1598
+ };
1599
+ var selectTheme = {
1600
+ style: {
1601
+ keysHelpTip: keysHelpTipWithQuit
1602
+ }
1603
+ };
1604
+
1605
+ // src/commands/ide/sync.ts
1606
+ function createSyncSubcommand() {
1607
+ const cmd = new Command3("sync").description("Sync .jai1 content to IDE directories (Cursor, Windsurf, Claude Code, etc.)").option("--ides <ides...>", "Target IDEs (cursor, windsurf, antigravity, claudecode, opencode)").option("--type <types...>", "Content types (rules, workflows, commands)").option("--dry-run", "Preview changes without writing files").option("-y, --yes", "Headless mode (skip all prompts)").option("--all", "Select all available IDEs").action(async (options) => {
1608
+ await runSync(options);
1609
+ });
1610
+ return cmd;
1611
+ }
1612
+ async function runSync(options) {
1613
+ const service = new MigrateIdeService();
1614
+ const headless = options.yes === true;
1615
+ console.log("\n\u{1F504} Sync rules and workflows to IDE(s)\n");
1616
+ console.log("\u{1F4C1} Scanning .jai1/ directory...");
1617
+ console.log(" \u2022 .jai1/rule-preset/ (active rule preset)");
1618
+ console.log(" \u2022 .jai1/rules/ (manual rules)");
1619
+ console.log(" \u2022 .jai1/workflows/\n");
1620
+ const content = await service.scanJai1Content();
1621
+ if (content.totalCount === 0) {
1622
+ console.log("\u26A0\uFE0F No content found in .jai1/");
1623
+ console.log(' \u{1F4A1} Run "jai1 rules apply" to apply a rule preset, or');
1624
+ console.log(" \u{1F4A1} Create files in .jai1/rules/ or .jai1/workflows/\n");
1625
+ process.exit(1);
1626
+ }
1627
+ console.log(`\u2713 Found: ${content.rules.length} rules, ${content.workflows.length} workflows
1628
+ `);
1629
+ let selectedIdes;
1630
+ if (options.all) {
1631
+ selectedIdes = getMigrationIDEs();
1632
+ } else if (options.ides && options.ides.length > 0) {
1633
+ selectedIdes = options.ides;
1634
+ } else if (headless) {
1635
+ throw new Error(
1636
+ "Headless mode (-y) requires --ides or --all flag.\nExamples:\n j ide sync --ides cursor windsurf -y\n j ide sync --all -y"
1637
+ );
1638
+ } else {
1639
+ const ideChoices = getMigrationIDEs().map((ide) => {
1640
+ const config = IDE_MIGRATION_CONFIGS[ide];
1641
+ return {
1642
+ name: `${config.icon} ${config.name}`,
1643
+ value: ide
1644
+ };
1645
+ });
1646
+ selectedIdes = await checkbox({
1647
+ message: "Select target IDE(s) (SPACE to select, ENTER to confirm):",
1648
+ choices: ideChoices,
1649
+ theme: checkboxTheme
1650
+ });
1651
+ if (selectedIdes.length === 0) {
1652
+ console.log("\n\u26A0\uFE0F No IDE selected!");
1653
+ console.log(" \u{1F4A1} Select at least 1 IDE.\n");
1654
+ process.exit(0);
1655
+ }
1656
+ }
1657
+ let selectedTypes;
1658
+ if (options.type && options.type.length > 0) {
1659
+ selectedTypes = options.type;
1660
+ } else if (headless) {
1661
+ selectedTypes = ["rules", "workflows", "commands"];
1662
+ } else {
1663
+ const typeChoices = [
1664
+ { name: `Rules (${content.rules.length} files)`, value: "rules" },
1665
+ { name: `Workflows (${content.workflows.length} files)`, value: "workflows" },
1666
+ { name: `Commands (${content.commands.length} files)`, value: "commands" }
1667
+ ];
1668
+ selectedTypes = await checkbox({
1669
+ message: "Select content types to sync:",
1670
+ choices: typeChoices,
1671
+ theme: checkboxTheme
1672
+ });
1673
+ if (selectedTypes.length === 0) {
1674
+ console.log("\n\u26A0\uFE0F No content type selected!");
1675
+ console.log(" \u{1F4A1} Select at least 1 content type.\n");
1676
+ process.exit(0);
1677
+ }
1678
+ }
1679
+ const totalItems = selectedTypes.reduce((sum, type) => {
1680
+ return sum + (type === "rules" ? content.rules.length : type === "workflows" ? content.workflows.length : content.commands.length);
1681
+ }, 0);
1682
+ const totalFiles = totalItems * selectedIdes.length;
1683
+ console.log("\n\u{1F4CA} Preview:\n");
1684
+ console.log(` IDEs: ${selectedIdes.map((ide) => IDE_MIGRATION_CONFIGS[ide].name).join(", ")}`);
1685
+ console.log(` Content types: ${selectedTypes.join(", ")}`);
1686
+ console.log(` Will create/update: ${totalFiles} stub files
1687
+ `);
1688
+ if (options.dryRun) {
1689
+ console.log("\u{1F50D} DRY RUN - No files will be written\n");
1690
+ }
1691
+ if (!headless) {
1692
+ const confirmed = await confirm({
1693
+ message: "Proceed with sync?",
1694
+ default: true
1695
+ });
1696
+ if (!confirmed) {
1697
+ console.log("\n\u274C Sync cancelled.\n");
1698
+ process.exit(0);
1699
+ }
1700
+ }
1701
+ console.log("\n\u{1F504} Syncing...\n");
1702
+ let completed = 0;
1703
+ const results = await service.migrate(
1704
+ selectedIdes,
1705
+ selectedTypes,
1706
+ content,
1707
+ (result) => {
1708
+ completed++;
1709
+ const icon = result.status === "created" ? "\u2713" : result.status === "updated" ? "\u21BB" : result.status === "error" ? "\u2717" : "\u25CB";
1710
+ const percentage = Math.round(completed / totalFiles * 100);
1711
+ console.log(` ${icon} [${percentage}%] ${result.targetPath}`);
1712
+ if (result.status === "error" && result.error) {
1713
+ console.log(` Error: ${result.error}`);
1714
+ }
1715
+ }
1716
+ );
1717
+ const created = results.filter((r) => r.status === "created").length;
1718
+ const updated = results.filter((r) => r.status === "updated").length;
1719
+ const skipped = results.filter((r) => r.status === "skipped").length;
1720
+ const errors = results.filter((r) => r.status === "error").length;
1721
+ console.log("\n\u2705 Sync complete!\n");
1722
+ console.log(` Created: ${created}`);
1723
+ console.log(` Updated: ${updated}`);
1724
+ if (skipped > 0) console.log(` Skipped: ${skipped}`);
1725
+ if (errors > 0) console.log(` Errors: ${errors}`);
1726
+ console.log("");
1727
+ }
1728
+
1584
1729
  // src/commands/apply.ts
1730
+ var TARGET_IDE_MAP = {
1731
+ "cursor": "cursor",
1732
+ "windsurf": "windsurf",
1733
+ "antigravity": "antigravity",
1734
+ "claude": "claudecode",
1735
+ "claudecode": "claudecode",
1736
+ "opencode": "opencode"
1737
+ };
1585
1738
  function createApplyCommand() {
1586
- const cmd = new Command3("apply").description("Apply components to your project (interactive UI)").argument("[items...]", "Package name or component filepaths (non-interactive mode)").option("--force", "Force overwrite even if modified locally").option("--no-interactive", "Disable interactive UI (for CI/CD)").action(async (items, options) => {
1739
+ const cmd = new Command4("apply").description("Apply components to your project (interactive UI)").argument("[items...]", "Package name or component filepaths (non-interactive mode)").option("--force", "Force overwrite even if modified locally").option("--no-interactive", "Disable interactive UI (for CI/CD)").option("--target <ides...>", "Auto-sync to target IDE(s) after apply (claude, cursor, windsurf, etc.)").action(async (items, options) => {
1587
1740
  const configService = new ConfigService();
1588
1741
  const config = await configService.load();
1589
1742
  if (!config) {
@@ -1667,16 +1820,29 @@ async function nonInteractiveApply(config, items, options) {
1667
1820
  console.log(`
1668
1821
  \u2705 Complete: ${added} added, ${updated} updated, ${skipped} skipped`);
1669
1822
  console.log(`\u{1F4C1} Location: ${targetDir}`);
1670
- console.log(`
1823
+ if (options.target && options.target.length > 0) {
1824
+ const resolvedIdes = options.target.map((ide) => TARGET_IDE_MAP[ide.toLowerCase()]).filter((ide) => !!ide);
1825
+ if (resolvedIdes.length > 0) {
1826
+ console.log(`
1827
+ \u{1F504} Auto-syncing to IDE(s): ${resolvedIdes.join(", ")}...`);
1828
+ await runSync({ ides: resolvedIdes, yes: true });
1829
+ } else {
1830
+ const valid = Object.keys(TARGET_IDE_MAP).join(", ");
1831
+ console.log(`
1832
+ \u26A0\uFE0F Unknown --target IDE(s): ${options.target.join(", ")}. Valid: ${valid}`);
1833
+ }
1834
+ } else {
1835
+ console.log(`
1671
1836
  \u{1F4A1} B\u01B0\u1EDBc ti\u1EBFp theo:`);
1672
- console.log(` \u2022 Ch\u1EA1y "${name} ide sync" \u0111\u1EC3 \u0111\u1ED3ng b\u1ED9 n\u1ED9i dung sang c\xE1c IDE b\u1EA1n \u0111ang d\xF9ng.`);
1673
- console.log(` \u2022 Ch\u1EA1y "${name} doctor" \u0111\u1EC3 ki\u1EC3m tra d\u1EF1 \xE1n \u0111\xE3 setup Jai1 \u0111\u1EA7y \u0111\u1EE7 ch\u01B0a.`);
1837
+ console.log(` \u2022 Ch\u1EA1y "${name} ide sync" \u0111\u1EC3 \u0111\u1ED3ng b\u1ED9 n\u1ED9i dung sang c\xE1c IDE b\u1EA1n \u0111ang d\xF9ng.`);
1838
+ console.log(` \u2022 Ch\u1EA1y "${name} doctor" \u0111\u1EC3 ki\u1EC3m tra d\u1EF1 \xE1n \u0111\xE3 setup Jai1 \u0111\u1EA7y \u0111\u1EE7 ch\u01B0a.`);
1839
+ }
1674
1840
  }
1675
1841
 
1676
1842
  // src/commands/apply-new.ts
1677
1843
  import React6 from "react";
1678
1844
  import { render as render2 } from "ink";
1679
- import { Command as Command4 } from "commander";
1845
+ import { Command as Command5 } from "commander";
1680
1846
 
1681
1847
  // src/ui/apply/TwoPaneApplyApp.tsx
1682
1848
  import React5, { useState as useState2, useEffect as useEffect2, useMemo as useMemo2 } from "react";
@@ -2035,7 +2201,7 @@ var TwoPaneApplyApp = ({
2035
2201
 
2036
2202
  // src/commands/apply-new.ts
2037
2203
  function createApplyNewCommand() {
2038
- const cmd = new Command4("apply-new").description("Apply components (Two-Pane UI - experimental)").option("--force", "Force overwrite even if modified locally").action(async (options) => {
2204
+ const cmd = new Command5("apply-new").description("Apply components (Two-Pane UI - experimental)").option("--force", "Force overwrite even if modified locally").action(async (options) => {
2039
2205
  const configService = new ConfigService();
2040
2206
  const config = await configService.load();
2041
2207
  if (!config) {
@@ -2056,11 +2222,11 @@ function createApplyNewCommand() {
2056
2222
  }
2057
2223
 
2058
2224
  // src/commands/update.ts
2059
- import { Command as Command5 } from "commander";
2060
- import { confirm } from "@inquirer/prompts";
2225
+ import { Command as Command6 } from "commander";
2226
+ import { confirm as confirm2 } from "@inquirer/prompts";
2061
2227
  import chalk4 from "chalk";
2062
2228
  function createUpdateCommand() {
2063
- return new Command5("update").description("Update installed components to latest versions").option("--force", "Force update even if files are modified locally").action(async (options) => {
2229
+ return new Command6("update").description("Update installed components to latest versions").option("--force", "Force update even if files are modified locally").action(async (options) => {
2064
2230
  await handleUpdate(options);
2065
2231
  });
2066
2232
  }
@@ -2121,7 +2287,7 @@ async function handleUpdate(options) {
2121
2287
  }
2122
2288
  console.log();
2123
2289
  if (!options.force) {
2124
- const shouldUpdate = await confirm({ message: "C\u1EADp nh\u1EADt ngay?", default: true });
2290
+ const shouldUpdate = await confirm2({ message: "C\u1EADp nh\u1EADt ngay?", default: true });
2125
2291
  if (!shouldUpdate) {
2126
2292
  console.log(chalk4.dim("\u0110\xE3 h\u1EE7y c\u1EADp nh\u1EADt."));
2127
2293
  return;
@@ -2155,7 +2321,7 @@ async function handleUpdate(options) {
2155
2321
  if (backupPaths.length > 0) {
2156
2322
  console.log(chalk4.dim(`
2157
2323
  \u{1F4C1} \u0110\xE3 t\u1EA1o backup t\u1EA1i .jai1_backup/`));
2158
- const cleanBackups = await confirm({ message: "X\xF3a c\xE1c backup n\xE0y?", default: false });
2324
+ const cleanBackups = await confirm2({ message: "X\xF3a c\xE1c backup n\xE0y?", default: false });
2159
2325
  if (cleanBackups) {
2160
2326
  await componentsService.clearBackups(process.cwd());
2161
2327
  console.log(chalk4.green("\u{1F5D1}\uFE0F \u0110\xE3 x\xF3a backups."));
@@ -2170,11 +2336,11 @@ async function handleUpdate(options) {
2170
2336
  }
2171
2337
 
2172
2338
  // src/commands/framework/check.ts
2173
- import { Command as Command6 } from "commander";
2339
+ import { Command as Command7 } from "commander";
2174
2340
  import chalk5 from "chalk";
2175
2341
  import Table from "cli-table3";
2176
2342
  function createCheckCommand() {
2177
- const cmd = new Command6("check").description("Ki\u1EC3m tra c\u1EADp nh\u1EADt framework").option("--json", "Output as JSON").action(async (options) => {
2343
+ const cmd = new Command7("check").description("Ki\u1EC3m tra c\u1EADp nh\u1EADt framework").option("--json", "Output as JSON").action(async (options) => {
2178
2344
  await handleCheck(options);
2179
2345
  });
2180
2346
  return cmd;
@@ -2289,7 +2455,7 @@ import { Command as Command11 } from "commander";
2289
2455
  import chalk7 from "chalk";
2290
2456
 
2291
2457
  // src/commands/context.ts
2292
- import { Command as Command7 } from "commander";
2458
+ import { Command as Command8 } from "commander";
2293
2459
  import chalk6 from "chalk";
2294
2460
 
2295
2461
  // src/services/context-scanner.service.ts
@@ -2797,7 +2963,7 @@ function renderIDEContext(ideContext) {
2797
2963
  console.log("");
2798
2964
  }
2799
2965
  function createContextCommand() {
2800
- const cmd = new Command7("context").description("Visualize IDE context window token budget").argument("[ide]", "Show specific IDE only (cursor, windsurf, antigravity, claudecode, opencode)").action(async (ideArg) => {
2966
+ const cmd = new Command8("context").description("Visualize IDE context window token budget").argument("[ide]", "Show specific IDE only (cursor, windsurf, antigravity, claudecode, opencode)").action(async (ideArg) => {
2801
2967
  const name = getCliName();
2802
2968
  const allIDEs = ["cursor", "windsurf", "antigravity", "claudecode", "opencode"];
2803
2969
  if (ideArg) {
@@ -2841,30 +3007,11 @@ function createContextSubcommand() {
2841
3007
  }
2842
3008
 
2843
3009
  // src/commands/ide/setup.ts
2844
- import { Command as Command8 } from "commander";
2845
- import { checkbox, confirm as confirm2, select } from "@inquirer/prompts";
3010
+ import { Command as Command9 } from "commander";
3011
+ import { checkbox as checkbox2, confirm as confirm3, select } from "@inquirer/prompts";
2846
3012
  import fs5 from "fs/promises";
2847
3013
  import path3 from "path";
2848
3014
  import { existsSync } from "fs";
2849
-
2850
- // src/utils/prompt-theme.ts
2851
- var keysHelpTipWithQuit = (keys) => {
2852
- const keyStrings = keys.map(([key, action]) => `${key} ${action}`);
2853
- keyStrings.push("Ctrl+C quit");
2854
- return keyStrings.join(" \u2022 ");
2855
- };
2856
- var checkboxTheme = {
2857
- style: {
2858
- keysHelpTip: keysHelpTipWithQuit
2859
- }
2860
- };
2861
- var selectTheme = {
2862
- style: {
2863
- keysHelpTip: keysHelpTipWithQuit
2864
- }
2865
- };
2866
-
2867
- // src/commands/ide/setup.ts
2868
3015
  var PERFORMANCE_GROUPS = {
2869
3016
  telemetry: {
2870
3017
  name: "Telemetry",
@@ -3000,7 +3147,7 @@ var PERFORMANCE_GROUPS = {
3000
3147
  }
3001
3148
  };
3002
3149
  function createSetupSubcommand() {
3003
- const setupCommand = new Command8("setup").description("Configure IDE settings and optimizations");
3150
+ const setupCommand = new Command9("setup").description("Configure IDE settings and optimizations");
3004
3151
  setupCommand.action(async () => {
3005
3152
  await interactiveMode();
3006
3153
  });
@@ -3069,7 +3216,7 @@ async function selectGroupsToApply(action) {
3069
3216
  value: key
3070
3217
  }));
3071
3218
  try {
3072
- const selectedGroups = await checkbox({
3219
+ const selectedGroups = await checkbox2({
3073
3220
  message: `Select groups to ${action} (SPACE to select, ENTER to confirm):`,
3074
3221
  choices,
3075
3222
  theme: checkboxTheme
@@ -3106,7 +3253,7 @@ async function applyGroups(groupKeys, action) {
3106
3253
  console.log("\u{1F4C4} Read current settings from settings.json");
3107
3254
  } catch {
3108
3255
  console.warn("\u26A0\uFE0F Cannot read settings.json (may contain comments).");
3109
- const confirmOverwrite = await confirm2({
3256
+ const confirmOverwrite = await confirm3({
3110
3257
  message: "Overwrite current settings.json file?",
3111
3258
  default: false
3112
3259
  });
@@ -3153,7 +3300,7 @@ async function resetSettings(groupKeys) {
3153
3300
  console.log("\n\u26A0\uFE0F No settings.json file found");
3154
3301
  return;
3155
3302
  }
3156
- const confirmReset = await confirm2({
3303
+ const confirmReset = await confirm3({
3157
3304
  message: groupKeys.length === 0 ? "Reset ALL settings to default (delete entire file)?" : `Reset groups: ${groupKeys.join(", ")}?`,
3158
3305
  default: false
3159
3306
  });
@@ -3170,132 +3317,6 @@ async function resetSettings(groupKeys) {
3170
3317
  console.log("\u{1F4A1} Tip: Restart your IDE to apply changes.");
3171
3318
  }
3172
3319
 
3173
- // src/commands/ide/sync.ts
3174
- import { Command as Command9 } from "commander";
3175
- import { checkbox as checkbox2, confirm as confirm3 } from "@inquirer/prompts";
3176
- function createSyncSubcommand() {
3177
- const cmd = new Command9("sync").description("Sync .jai1 content to IDE directories (Cursor, Windsurf, Claude Code, etc.)").option("--ides <ides...>", "Target IDEs (cursor, windsurf, antigravity, claudecode, opencode)").option("--type <types...>", "Content types (rules, workflows, commands)").option("--dry-run", "Preview changes without writing files").option("-y, --yes", "Headless mode (skip all prompts)").option("--all", "Select all available IDEs").action(async (options) => {
3178
- await runSync(options);
3179
- });
3180
- return cmd;
3181
- }
3182
- async function runSync(options) {
3183
- const service = new MigrateIdeService();
3184
- const headless = options.yes === true;
3185
- console.log("\n\u{1F504} Sync rules and workflows to IDE(s)\n");
3186
- console.log("\u{1F4C1} Scanning .jai1/ directory...");
3187
- console.log(" \u2022 .jai1/rule-preset/ (active rule preset)");
3188
- console.log(" \u2022 .jai1/rules/ (manual rules)");
3189
- console.log(" \u2022 .jai1/workflows/\n");
3190
- const content = await service.scanJai1Content();
3191
- if (content.totalCount === 0) {
3192
- console.log("\u26A0\uFE0F No content found in .jai1/");
3193
- console.log(' \u{1F4A1} Run "jai1 rules apply" to apply a rule preset, or');
3194
- console.log(" \u{1F4A1} Create files in .jai1/rules/ or .jai1/workflows/\n");
3195
- process.exit(1);
3196
- }
3197
- console.log(`\u2713 Found: ${content.rules.length} rules, ${content.workflows.length} workflows
3198
- `);
3199
- let selectedIdes;
3200
- if (options.all) {
3201
- selectedIdes = getMigrationIDEs();
3202
- } else if (options.ides && options.ides.length > 0) {
3203
- selectedIdes = options.ides;
3204
- } else if (headless) {
3205
- throw new Error(
3206
- "Headless mode (-y) requires --ides or --all flag.\nExamples:\n j ide sync --ides cursor windsurf -y\n j ide sync --all -y"
3207
- );
3208
- } else {
3209
- const ideChoices = getMigrationIDEs().map((ide) => {
3210
- const config = IDE_MIGRATION_CONFIGS[ide];
3211
- return {
3212
- name: `${config.icon} ${config.name}`,
3213
- value: ide
3214
- };
3215
- });
3216
- selectedIdes = await checkbox2({
3217
- message: "Select target IDE(s) (SPACE to select, ENTER to confirm):",
3218
- choices: ideChoices,
3219
- theme: checkboxTheme
3220
- });
3221
- if (selectedIdes.length === 0) {
3222
- console.log("\n\u26A0\uFE0F No IDE selected!");
3223
- console.log(" \u{1F4A1} Select at least 1 IDE.\n");
3224
- process.exit(0);
3225
- }
3226
- }
3227
- let selectedTypes;
3228
- if (options.type && options.type.length > 0) {
3229
- selectedTypes = options.type;
3230
- } else if (headless) {
3231
- selectedTypes = ["rules", "workflows", "commands"];
3232
- } else {
3233
- const typeChoices = [
3234
- { name: `Rules (${content.rules.length} files)`, value: "rules" },
3235
- { name: `Workflows (${content.workflows.length} files)`, value: "workflows" },
3236
- { name: `Commands (${content.commands.length} files)`, value: "commands" }
3237
- ];
3238
- selectedTypes = await checkbox2({
3239
- message: "Select content types to sync:",
3240
- choices: typeChoices,
3241
- theme: checkboxTheme
3242
- });
3243
- if (selectedTypes.length === 0) {
3244
- console.log("\n\u26A0\uFE0F No content type selected!");
3245
- console.log(" \u{1F4A1} Select at least 1 content type.\n");
3246
- process.exit(0);
3247
- }
3248
- }
3249
- const totalItems = selectedTypes.reduce((sum, type) => {
3250
- return sum + (type === "rules" ? content.rules.length : type === "workflows" ? content.workflows.length : content.commands.length);
3251
- }, 0);
3252
- const totalFiles = totalItems * selectedIdes.length;
3253
- console.log("\n\u{1F4CA} Preview:\n");
3254
- console.log(` IDEs: ${selectedIdes.map((ide) => IDE_MIGRATION_CONFIGS[ide].name).join(", ")}`);
3255
- console.log(` Content types: ${selectedTypes.join(", ")}`);
3256
- console.log(` Will create/update: ${totalFiles} stub files
3257
- `);
3258
- if (options.dryRun) {
3259
- console.log("\u{1F50D} DRY RUN - No files will be written\n");
3260
- }
3261
- if (!headless) {
3262
- const confirmed = await confirm3({
3263
- message: "Proceed with sync?",
3264
- default: true
3265
- });
3266
- if (!confirmed) {
3267
- console.log("\n\u274C Sync cancelled.\n");
3268
- process.exit(0);
3269
- }
3270
- }
3271
- console.log("\n\u{1F504} Syncing...\n");
3272
- let completed = 0;
3273
- const results = await service.migrate(
3274
- selectedIdes,
3275
- selectedTypes,
3276
- content,
3277
- (result) => {
3278
- completed++;
3279
- const icon = result.status === "created" ? "\u2713" : result.status === "updated" ? "\u21BB" : result.status === "error" ? "\u2717" : "\u25CB";
3280
- const percentage = Math.round(completed / totalFiles * 100);
3281
- console.log(` ${icon} [${percentage}%] ${result.targetPath}`);
3282
- if (result.status === "error" && result.error) {
3283
- console.log(` Error: ${result.error}`);
3284
- }
3285
- }
3286
- );
3287
- const created = results.filter((r) => r.status === "created").length;
3288
- const updated = results.filter((r) => r.status === "updated").length;
3289
- const skipped = results.filter((r) => r.status === "skipped").length;
3290
- const errors = results.filter((r) => r.status === "error").length;
3291
- console.log("\n\u2705 Sync complete!\n");
3292
- console.log(` Created: ${created}`);
3293
- console.log(` Updated: ${updated}`);
3294
- if (skipped > 0) console.log(` Skipped: ${skipped}`);
3295
- if (errors > 0) console.log(` Errors: ${errors}`);
3296
- console.log("");
3297
- }
3298
-
3299
3320
  // src/commands/ide/status.ts
3300
3321
  import { Command as Command10 } from "commander";
3301
3322
 
@@ -12452,7 +12473,7 @@ function createTasksCommand() {
12452
12473
  cmd.addCommand(createTaskDeleteCommand());
12453
12474
  cmd.addCommand(createTaskGuideCommand());
12454
12475
  cmd.action(async () => {
12455
- const { handleTaskSummary } = await import("./summary-ZAWF3OA3.js");
12476
+ const { handleTaskSummary } = await import("./summary-X37LKQYR.js");
12456
12477
  await handleTaskSummary({ json: false });
12457
12478
  });
12458
12479
  return cmd;
@@ -17100,10 +17121,11 @@ function showCustomHelp(version) {
17100
17121
  console.log(" rules Qu\u1EA3n l\xFD rule presets");
17101
17122
  console.log(" deps Qu\u1EA3n l\xFD dependencies");
17102
17123
  console.log(" redmine Redmine context sync");
17124
+ console.log(chalk57.bold("\n\u{1F6E0}\uFE0F Utilities"));
17125
+ console.log(" utils Developer utilities");
17103
17126
  console.log(chalk57.bold("\n\u2699\uFE0F B\u1EA3o tr\xEC"));
17104
17127
  console.log(" upgrade C\u1EADp nh\u1EADt CLI client");
17105
17128
  console.log(" clean D\u1ECDn d\u1EB9p cache/backup");
17106
- console.log(" utils Developer utilities");
17107
17129
  const name = getCliName();
17108
17130
  console.log(chalk57.dim(`
17109
17131
  S\u1EED d\u1EE5ng: ${name} [l\u1EC7nh] --help \u0111\u1EC3 xem chi ti\u1EBFt`));