@jvittechs/j 1.0.17 → 1.0.19
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 +98 -34
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -169,7 +169,7 @@ import { basename as basename4 } from "path";
|
|
|
169
169
|
// package.json
|
|
170
170
|
var package_default = {
|
|
171
171
|
name: "@jvittechs/j",
|
|
172
|
-
version: "1.0.
|
|
172
|
+
version: "1.0.19",
|
|
173
173
|
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.",
|
|
174
174
|
type: "module",
|
|
175
175
|
bin: {
|
|
@@ -1322,8 +1322,6 @@ ${bodyContent}
|
|
|
1322
1322
|
}
|
|
1323
1323
|
const lines = [
|
|
1324
1324
|
"# AGENTS.md",
|
|
1325
|
-
"",
|
|
1326
|
-
"> Auto-generated by jai1 ide sync for OpenCode",
|
|
1327
1325
|
""
|
|
1328
1326
|
];
|
|
1329
1327
|
for (const rule of rules) {
|
|
@@ -3068,17 +3066,19 @@ function renderIDEContext(ideContext) {
|
|
|
3068
3066
|
function createContextCommand() {
|
|
3069
3067
|
const cmd = new Command7("context").description("Visualize IDE context window token budget").argument("[ide]", "Show specific IDE only (cursor, windsurf, antigravity)").action(async (ideArg) => {
|
|
3070
3068
|
const name = getCliName();
|
|
3071
|
-
const
|
|
3069
|
+
const allIDEs = ["cursor", "windsurf", "antigravity"];
|
|
3072
3070
|
if (ideArg) {
|
|
3073
|
-
if (!
|
|
3071
|
+
if (!allIDEs.includes(ideArg)) {
|
|
3074
3072
|
console.error(chalk6.red(`\u274C Invalid IDE: ${ideArg}`));
|
|
3075
|
-
console.error(chalk6.dim(` Valid IDEs: ${
|
|
3073
|
+
console.error(chalk6.dim(` Valid IDEs: ${allIDEs.join(", ")}`));
|
|
3076
3074
|
console.error(chalk6.dim(` Usage: ${name} context [ide]`));
|
|
3077
3075
|
process.exit(1);
|
|
3078
3076
|
}
|
|
3079
3077
|
}
|
|
3080
3078
|
const scanner = new ContextScannerService();
|
|
3081
|
-
const
|
|
3079
|
+
const detectedIDEs = await scanner.detectIDEs();
|
|
3080
|
+
const installedIDEs = detectedIDEs.filter((ide) => allIDEs.includes(ide));
|
|
3081
|
+
const targetIDEs = ideArg ? [ideArg] : installedIDEs;
|
|
3082
3082
|
console.log("");
|
|
3083
3083
|
console.log(` ${chalk6.bgGray.white.bold(" /context ")}`);
|
|
3084
3084
|
let found = false;
|
|
@@ -3441,13 +3441,14 @@ async function resetSettings(groupKeys) {
|
|
|
3441
3441
|
import { Command as Command9 } from "commander";
|
|
3442
3442
|
import { checkbox as checkbox2, confirm as confirm3 } from "@inquirer/prompts";
|
|
3443
3443
|
function createSyncSubcommand() {
|
|
3444
|
-
const cmd = new Command9("sync").description("Sync .jai1 content to IDE directories (Cursor, Windsurf, Claude Code, etc.)").option("--
|
|
3444
|
+
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) => {
|
|
3445
3445
|
await runSync(options);
|
|
3446
3446
|
});
|
|
3447
3447
|
return cmd;
|
|
3448
3448
|
}
|
|
3449
3449
|
async function runSync(options) {
|
|
3450
3450
|
const service = new MigrateIdeService();
|
|
3451
|
+
const headless = options.yes === true;
|
|
3451
3452
|
console.log("\n\u{1F504} Sync rules and workflows to IDE(s)\n");
|
|
3452
3453
|
console.log("\u{1F4C1} Scanning .jai1/ directory...");
|
|
3453
3454
|
console.log(" \u2022 .jai1/rule-preset/ (active rule preset)");
|
|
@@ -3463,8 +3464,14 @@ async function runSync(options) {
|
|
|
3463
3464
|
console.log(`\u2713 Found: ${content.rules.length} rules, ${content.workflows.length} workflows
|
|
3464
3465
|
`);
|
|
3465
3466
|
let selectedIdes;
|
|
3466
|
-
if (options.
|
|
3467
|
-
selectedIdes =
|
|
3467
|
+
if (options.all) {
|
|
3468
|
+
selectedIdes = getMigrationIDEs();
|
|
3469
|
+
} else if (options.ides && options.ides.length > 0) {
|
|
3470
|
+
selectedIdes = options.ides;
|
|
3471
|
+
} else if (headless) {
|
|
3472
|
+
throw new Error(
|
|
3473
|
+
"Headless mode (-y) requires --ides or --all flag.\nExamples:\n j ide sync --ides cursor windsurf -y\n j ide sync --all -y"
|
|
3474
|
+
);
|
|
3468
3475
|
} else {
|
|
3469
3476
|
const ideChoices = getMigrationIDEs().map((ide) => {
|
|
3470
3477
|
const config = IDE_MIGRATION_CONFIGS[ide];
|
|
@@ -3487,6 +3494,8 @@ async function runSync(options) {
|
|
|
3487
3494
|
let selectedTypes;
|
|
3488
3495
|
if (options.type && options.type.length > 0) {
|
|
3489
3496
|
selectedTypes = options.type;
|
|
3497
|
+
} else if (headless) {
|
|
3498
|
+
selectedTypes = ["rules", "workflows", "commands"];
|
|
3490
3499
|
} else {
|
|
3491
3500
|
const typeChoices = [
|
|
3492
3501
|
{ name: `Rules (${content.rules.length} files)`, value: "rules" },
|
|
@@ -3516,13 +3525,15 @@ async function runSync(options) {
|
|
|
3516
3525
|
if (options.dryRun) {
|
|
3517
3526
|
console.log("\u{1F50D} DRY RUN - No files will be written\n");
|
|
3518
3527
|
}
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3528
|
+
if (!headless) {
|
|
3529
|
+
const confirmed = await confirm3({
|
|
3530
|
+
message: "Proceed with sync?",
|
|
3531
|
+
default: true
|
|
3532
|
+
});
|
|
3533
|
+
if (!confirmed) {
|
|
3534
|
+
console.log("\n\u274C Sync cancelled.\n");
|
|
3535
|
+
process.exit(0);
|
|
3536
|
+
}
|
|
3526
3537
|
}
|
|
3527
3538
|
console.log("\n\u{1F504} Syncing...\n");
|
|
3528
3539
|
let completed = 0;
|
|
@@ -11984,7 +11995,7 @@ async function applyAgentsMdFormat(bundle) {
|
|
|
11984
11995
|
import { Command as Command63 } from "commander";
|
|
11985
11996
|
import { promises as fs25 } from "fs";
|
|
11986
11997
|
import { join as join15 } from "path";
|
|
11987
|
-
import {
|
|
11998
|
+
import { search, confirm as confirm11, checkbox as checkbox5 } from "@inquirer/prompts";
|
|
11988
11999
|
|
|
11989
12000
|
// src/services/rules-generator.service.ts
|
|
11990
12001
|
var RulesGeneratorService = class {
|
|
@@ -12495,7 +12506,7 @@ Restoring backup from ${metadata.timestamp}...`);
|
|
|
12495
12506
|
|
|
12496
12507
|
// src/commands/rules/apply.ts
|
|
12497
12508
|
function createRulesApplyCommand() {
|
|
12498
|
-
return new Command63("apply").description("Apply rule preset to project with multi-IDE support").argument("[preset]", "Preset slug to apply (optional)").option("--ides <ides>",
|
|
12509
|
+
return new Command63("apply").description("Apply rule preset to project with multi-IDE support").argument("[preset]", "Preset slug to apply (optional)").option("--ides <ides>", 'Comma-separated list of IDE formats (cursor,windsurf,antigravity,claude,agentsmd,gemini) or "all"').option("--skip-backup", "Skip backup creation").option("-y, --yes", "Skip all confirmations (auto mode)").action(async (presetSlug, options) => {
|
|
12499
12510
|
const configService = new ConfigService();
|
|
12500
12511
|
const config = await configService.load();
|
|
12501
12512
|
if (!config) {
|
|
@@ -12507,7 +12518,12 @@ function createRulesApplyCommand() {
|
|
|
12507
12518
|
const skipBackup = options.skipBackup === true;
|
|
12508
12519
|
let selectedIdes = [];
|
|
12509
12520
|
if (options.ides) {
|
|
12510
|
-
|
|
12521
|
+
const idesValue = options.ides;
|
|
12522
|
+
if (idesValue.toLowerCase() === "all") {
|
|
12523
|
+
selectedIdes = generatorService.getAvailableIdes();
|
|
12524
|
+
} else {
|
|
12525
|
+
selectedIdes = idesValue.split(",").map((ide) => ide.trim()).filter((ide) => generatorService.isValidIde(ide));
|
|
12526
|
+
}
|
|
12511
12527
|
if (selectedIdes.length === 0) {
|
|
12512
12528
|
throw new ValidationError("No valid IDE formats specified");
|
|
12513
12529
|
}
|
|
@@ -12527,13 +12543,20 @@ function createRulesApplyCommand() {
|
|
|
12527
12543
|
console.log("No presets available.");
|
|
12528
12544
|
return;
|
|
12529
12545
|
}
|
|
12530
|
-
presetSlug = await
|
|
12531
|
-
message: "
|
|
12532
|
-
|
|
12533
|
-
|
|
12534
|
-
|
|
12535
|
-
|
|
12536
|
-
|
|
12546
|
+
presetSlug = await search({
|
|
12547
|
+
message: "Search and select a preset (type keywords to filter):",
|
|
12548
|
+
source: async (input5) => {
|
|
12549
|
+
const keywords = (input5 || "").toLowerCase().split(/\s+/).filter(Boolean);
|
|
12550
|
+
const filtered = keywords.length === 0 ? data.presets : data.presets.filter((p) => {
|
|
12551
|
+
const searchable = [p.name, p.description, p.slug, ...p.tags].join(" ").toLowerCase();
|
|
12552
|
+
return keywords.every((kw) => searchable.includes(kw));
|
|
12553
|
+
});
|
|
12554
|
+
return filtered.map((p) => ({
|
|
12555
|
+
name: `${p.name} - ${p.description}`,
|
|
12556
|
+
value: p.slug,
|
|
12557
|
+
description: `v${p.version} | ${p.tags.join(", ")}`
|
|
12558
|
+
}));
|
|
12559
|
+
},
|
|
12537
12560
|
theme: selectTheme
|
|
12538
12561
|
});
|
|
12539
12562
|
}
|
|
@@ -12556,7 +12579,9 @@ function createRulesApplyCommand() {
|
|
|
12556
12579
|
console.log(` Files: ${Object.keys(bundle.files).length}`);
|
|
12557
12580
|
if (selectedIdes.length === 0) {
|
|
12558
12581
|
if (autoMode) {
|
|
12559
|
-
|
|
12582
|
+
throw new ValidationError(
|
|
12583
|
+
"Headless mode (-y) requires --ides flag.\nExamples:\n j rules apply <preset> --ides cursor,antigravity -y\n j rules apply <preset> --ides all -y"
|
|
12584
|
+
);
|
|
12560
12585
|
} else {
|
|
12561
12586
|
const detectionService = new IdeDetectionService();
|
|
12562
12587
|
const suggestions = await detectionService.suggestIdes();
|
|
@@ -12733,13 +12758,52 @@ function createRulesApplyCommand() {
|
|
|
12733
12758
|
console.log(' 3. Run "jai1 rules sync" to regenerate IDE outputs');
|
|
12734
12759
|
console.log(" 4. Commit the rules to git");
|
|
12735
12760
|
console.log(' 5. Use "jai1 ide status" to check IDE configuration\n');
|
|
12761
|
+
const migrationIdeIds = getMigrationIDEs();
|
|
12762
|
+
const ideSyncMap = {
|
|
12763
|
+
"cursor": "cursor",
|
|
12764
|
+
"windsurf": "windsurf",
|
|
12765
|
+
"antigravity": "antigravity",
|
|
12766
|
+
"claude": "claudecode",
|
|
12767
|
+
"agentsmd": "opencode",
|
|
12768
|
+
"opencode": "opencode"
|
|
12769
|
+
};
|
|
12770
|
+
const migrationIdes = resolvedIdes.map((ide) => ideSyncMap[ide]).filter((ide) => !!ide && migrationIdeIds.includes(ide)).filter((ide, index, self) => self.indexOf(ide) === index);
|
|
12771
|
+
if (migrationIdes.length > 0) {
|
|
12772
|
+
console.log("\u{1F504} Auto-syncing .jai1/ content to IDE(s)...\n");
|
|
12773
|
+
try {
|
|
12774
|
+
const migrateService = new MigrateIdeService();
|
|
12775
|
+
const content = await migrateService.scanJai1Content();
|
|
12776
|
+
if (content.totalCount > 0) {
|
|
12777
|
+
const contentTypes = ["rules", "workflows", "commands"];
|
|
12778
|
+
const results = await migrateService.migrate(
|
|
12779
|
+
migrationIdes,
|
|
12780
|
+
contentTypes,
|
|
12781
|
+
content,
|
|
12782
|
+
(result) => {
|
|
12783
|
+
const icon = result.status === "created" ? "\u2713" : result.status === "updated" ? "\u21BB" : result.status === "error" ? "\u2717" : "\u25CB";
|
|
12784
|
+
console.log(` ${icon} ${result.targetPath}`);
|
|
12785
|
+
}
|
|
12786
|
+
);
|
|
12787
|
+
const created = results.filter((r) => r.status === "created").length;
|
|
12788
|
+
const updated = results.filter((r) => r.status === "updated").length;
|
|
12789
|
+
console.log(`
|
|
12790
|
+
\u2705 IDE sync complete! (${created} created, ${updated} updated)
|
|
12791
|
+
`);
|
|
12792
|
+
} else {
|
|
12793
|
+
console.log(" No .jai1/ content found to sync.\n");
|
|
12794
|
+
}
|
|
12795
|
+
} catch (error) {
|
|
12796
|
+
console.warn("\u26A0\uFE0F IDE sync failed:", error instanceof Error ? error.message : error);
|
|
12797
|
+
console.log(' You can manually run "j ide sync" to retry.\n');
|
|
12798
|
+
}
|
|
12799
|
+
}
|
|
12736
12800
|
});
|
|
12737
12801
|
}
|
|
12738
12802
|
|
|
12739
12803
|
// src/commands/rules/restore.ts
|
|
12740
12804
|
import { Command as Command64 } from "commander";
|
|
12741
12805
|
import { join as join16 } from "path";
|
|
12742
|
-
import { select as
|
|
12806
|
+
import { select as select5, confirm as confirm12 } from "@inquirer/prompts";
|
|
12743
12807
|
function createRulesRestoreCommand() {
|
|
12744
12808
|
return new Command64("restore").description("Restore rules from a backup").option("--latest", "Restore the most recent backup").option("-y, --yes", "Skip confirmation").action(async (options) => {
|
|
12745
12809
|
const backupService = new BackupService();
|
|
@@ -12754,7 +12818,7 @@ function createRulesRestoreCommand() {
|
|
|
12754
12818
|
console.log(`\u{1F4E6} Selected latest backup: ${selectedBackup.timestamp}`);
|
|
12755
12819
|
} else {
|
|
12756
12820
|
console.log("\u{1F4CB} Available backups:\n");
|
|
12757
|
-
const backupTimestamp = await
|
|
12821
|
+
const backupTimestamp = await select5({
|
|
12758
12822
|
message: "Select a backup to restore:",
|
|
12759
12823
|
choices: backups.map((backup) => ({
|
|
12760
12824
|
name: formatBackupInfo(backup),
|
|
@@ -13333,7 +13397,7 @@ function getInstallCommand(packageManager2) {
|
|
|
13333
13397
|
|
|
13334
13398
|
// src/commands/clean.ts
|
|
13335
13399
|
import { Command as Command69 } from "commander";
|
|
13336
|
-
import { confirm as confirm15, select as
|
|
13400
|
+
import { confirm as confirm15, select as select6 } from "@inquirer/prompts";
|
|
13337
13401
|
import { join as join19 } from "path";
|
|
13338
13402
|
function createCleanCommand() {
|
|
13339
13403
|
return new Command69("clean").description("Clean up backups, cache, and temporary files").option("-y, --yes", "Skip confirmation").option("--backups", "Clean only backup files").option("--all", "Clean all (backups + cache)").action(async (options) => {
|
|
@@ -13397,7 +13461,7 @@ async function handleClean(options) {
|
|
|
13397
13461
|
console.log(` Path: ${target.path}
|
|
13398
13462
|
`);
|
|
13399
13463
|
}
|
|
13400
|
-
const action = await
|
|
13464
|
+
const action = await select6({
|
|
13401
13465
|
message: "What do you want to clean?",
|
|
13402
13466
|
choices: [
|
|
13403
13467
|
...availableTargets.map(({ target, info }) => ({
|
|
@@ -14580,7 +14644,7 @@ function createClearBackupsCommand() {
|
|
|
14580
14644
|
|
|
14581
14645
|
// src/commands/vscode/index.ts
|
|
14582
14646
|
import { Command as Command76 } from "commander";
|
|
14583
|
-
import { checkbox as checkbox7, confirm as confirm18, select as
|
|
14647
|
+
import { checkbox as checkbox7, confirm as confirm18, select as select7 } from "@inquirer/prompts";
|
|
14584
14648
|
import fs29 from "fs/promises";
|
|
14585
14649
|
import path12 from "path";
|
|
14586
14650
|
import { existsSync as existsSync3 } from "fs";
|
|
@@ -14763,7 +14827,7 @@ async function interactiveMode2() {
|
|
|
14763
14827
|
console.log("\u2502 \u2022 Nh\u1EA5n ENTER \u0111\u1EC3 x\xE1c nh\u1EADn v\xE0 \xE1p d\u1EE5ng \u2502");
|
|
14764
14828
|
console.log("\u2502 \u2022 Nh\u1EA5n Ctrl+C \u0111\u1EC3 h\u1EE7y \u2502");
|
|
14765
14829
|
console.log("\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F\n");
|
|
14766
|
-
const action = await
|
|
14830
|
+
const action = await select7({
|
|
14767
14831
|
message: "B\u1EA1n mu\u1ED1n l\xE0m g\xEC?",
|
|
14768
14832
|
choices: [
|
|
14769
14833
|
{ name: "\u2705 Enable c\xE1c nh\xF3m t\u1ED1i \u01B0u", value: "enable" },
|