@jvittechs/j 1.0.53 → 1.0.55
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 +94 -49
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -149,7 +149,7 @@ import { basename as basename5 } from "path";
|
|
|
149
149
|
// package.json
|
|
150
150
|
var package_default = {
|
|
151
151
|
name: "@jvittechs/j",
|
|
152
|
-
version: "1.0.
|
|
152
|
+
version: "1.0.55",
|
|
153
153
|
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.",
|
|
154
154
|
type: "module",
|
|
155
155
|
bin: {
|
|
@@ -10972,7 +10972,12 @@ async function handleWatch(address, options) {
|
|
|
10972
10972
|
process.exit(1);
|
|
10973
10973
|
}
|
|
10974
10974
|
const intervalSec = Math.max(5, parseInt(options.interval, 10) || 15);
|
|
10975
|
-
const
|
|
10975
|
+
const DEFAULT_TIMEOUT = 300;
|
|
10976
|
+
const MAX_TIMEOUT = 1800;
|
|
10977
|
+
const timeoutSec = Math.min(
|
|
10978
|
+
options.timeout ? parseInt(options.timeout, 10) || DEFAULT_TIMEOUT : DEFAULT_TIMEOUT,
|
|
10979
|
+
MAX_TIMEOUT
|
|
10980
|
+
);
|
|
10976
10981
|
const api = new TempMailApiService(config);
|
|
10977
10982
|
const seenIds = /* @__PURE__ */ new Set();
|
|
10978
10983
|
let pollCount = 0;
|
|
@@ -10980,7 +10985,7 @@ async function handleWatch(address, options) {
|
|
|
10980
10985
|
if (!options.json) {
|
|
10981
10986
|
console.log(chalk25.bold.cyan(`\u{1F440} Watching inbox: ${address}`));
|
|
10982
10987
|
console.log(chalk25.dim(
|
|
10983
|
-
` Polling every ${intervalSec}s
|
|
10988
|
+
` Polling every ${intervalSec}s \xB7 timeout ${timeoutSec}s` + (options.keep ? " \xB7 keep watching" : " \xB7 stops after first email") + ` \xB7 Ctrl+C to stop
|
|
10984
10989
|
`
|
|
10985
10990
|
));
|
|
10986
10991
|
}
|
|
@@ -11048,12 +11053,12 @@ async function handleWatch(address, options) {
|
|
|
11048
11053
|
});
|
|
11049
11054
|
}
|
|
11050
11055
|
function createMailWatchCommand() {
|
|
11051
|
-
return new Command52("watch").description("L\u1EAFng nghe email m\u1EDBi (polling)").argument("<address>", "\u0110\u1ECBa ch\u1EC9 email c\u1EA7n theo d\xF5i").option("-i, --interval <seconds>", "Kho\u1EA3ng th\u1EDDi gian poll (gi\xE2y, m\u1EB7c \u0111\u1ECBnh: 15)", "15").option("-t, --timeout <seconds>", "D\u1EEBng sau N gi\xE2y (m\u1EB7c \u0111\u1ECBnh:
|
|
11056
|
+
return new Command52("watch").description("L\u1EAFng nghe email m\u1EDBi (polling)").argument("<address>", "\u0110\u1ECBa ch\u1EC9 email c\u1EA7n theo d\xF5i").option("-i, --interval <seconds>", "Kho\u1EA3ng th\u1EDDi gian poll (gi\xE2y, m\u1EB7c \u0111\u1ECBnh: 15)", "15").option("-t, --timeout <seconds>", "D\u1EEBng sau N gi\xE2y (m\u1EB7c \u0111\u1ECBnh: 300s / 5 ph\xFAt, t\u1ED1i \u0111a: 1800s / 30 ph\xFAt)").option("-k, --keep", "Ti\u1EBFp t\u1EE5c watch sau khi nh\u1EADn \u0111\u01B0\u1EE3c email (m\u1EB7c \u0111\u1ECBnh: d\u1EEBng sau email \u0111\u1EA7u ti\xEAn)").option("-j, --json", "Output s\u1EF1 ki\u1EC7n email m\u1EDBi d\u1EA1ng JSON (m\u1ED7i d\xF2ng 1 event)").addHelpText("after", `
|
|
11052
11057
|
Examples:
|
|
11053
|
-
$ j dev mail watch user@dollicons.com # D\u1EEBng khi nh\u1EADn \u0111\u01B0\u1EE3c email \u0111\u1EA7u ti\xEAn
|
|
11058
|
+
$ j dev mail watch user@dollicons.com # D\u1EEBng khi nh\u1EADn \u0111\u01B0\u1EE3c email \u0111\u1EA7u ti\xEAn (timeout 5 ph\xFAt)
|
|
11054
11059
|
$ j dev mail watch user@dollicons.com -k # Ti\u1EBFp t\u1EE5c watch
|
|
11055
11060
|
$ j dev mail watch user@dollicons.com -i 30 -k
|
|
11056
|
-
$ j dev mail watch user@dollicons.com -t
|
|
11061
|
+
$ j dev mail watch user@dollicons.com -t 600 # Timeout 10 ph\xFAt (t\u1ED1i \u0111a 30 ph\xFAt)
|
|
11057
11062
|
$ j dev mail watch user@dollicons.com -j | jq .
|
|
11058
11063
|
`).action(async (address, options) => {
|
|
11059
11064
|
await handleWatch(address, options);
|
|
@@ -11420,7 +11425,7 @@ import { Command as Command71 } from "commander";
|
|
|
11420
11425
|
import { Command as Command58 } from "commander";
|
|
11421
11426
|
import chalk31 from "chalk";
|
|
11422
11427
|
function createTaskAddCommand() {
|
|
11423
|
-
return new Command58("add").description("Add a new task").argument("<title>", "Task title").option("-p, --priority <n>", "Priority: 0=critical, 1=high, 2=medium, 3=low", "2").option("-P, --parent <parent>", "Parent: feature/xxx, plan/xxx,
|
|
11428
|
+
return new Command58("add").description("Add a new task").argument("<title>", "Task title").option("-p, --priority <n>", "Priority: 0=critical, 1=high, 2=medium, 3=low", "2").option("-P, --parent <parent>", "Parent: feature/xxx, bug/xxx, plan/xxx, task/xxx, prd/xxx").option("-t, --tags <tags>", "Comma-separated tags").option("-j, --json", "Output JSON").action(async (title, options) => {
|
|
11424
11429
|
const service = new TaskService();
|
|
11425
11430
|
const priority = Number(options.priority ?? 2);
|
|
11426
11431
|
if (priority < 0 || priority > 3) {
|
|
@@ -14129,7 +14134,6 @@ import chalk53 from "chalk";
|
|
|
14129
14134
|
// src/commands/skills/find.ts
|
|
14130
14135
|
import { Command as Command83 } from "commander";
|
|
14131
14136
|
import chalk48 from "chalk";
|
|
14132
|
-
import Table8 from "cli-table3";
|
|
14133
14137
|
|
|
14134
14138
|
// src/services/skills.service.ts
|
|
14135
14139
|
import { promises as fs27 } from "fs";
|
|
@@ -14438,28 +14442,21 @@ function createSkillsFindCommand() {
|
|
|
14438
14442
|
if (results.length === 0) {
|
|
14439
14443
|
console.log(chalk48.yellow("Kh\xF4ng t\xECm th\u1EA5y skills n\xE0o tr\xEAn server."));
|
|
14440
14444
|
} else {
|
|
14441
|
-
|
|
14442
|
-
|
|
14443
|
-
chalk48.cyan("T\xEAn"),
|
|
14444
|
-
chalk48.cyan("M\xF4 t\u1EA3"),
|
|
14445
|
-
chalk48.cyan("Version"),
|
|
14446
|
-
chalk48.cyan("Downloads")
|
|
14447
|
-
],
|
|
14448
|
-
style: { head: [], border: ["gray"] },
|
|
14449
|
-
colWidths: [25, 40, 10, 12]
|
|
14450
|
-
});
|
|
14445
|
+
console.log(chalk48.bold(`\u{1F4E6} Jai1 Server (${results.length} k\u1EBFt qu\u1EA3)
|
|
14446
|
+
`));
|
|
14451
14447
|
for (const skill of results) {
|
|
14452
14448
|
const name = skill.filepath.replace("skills/", "");
|
|
14453
|
-
|
|
14454
|
-
|
|
14455
|
-
|
|
14456
|
-
|
|
14457
|
-
|
|
14458
|
-
|
|
14449
|
+
const version = skill.version ? chalk48.green(`v${skill.version}`) : chalk48.dim("-");
|
|
14450
|
+
const downloads = chalk48.dim(`${skill.downloads || 0} downloads`);
|
|
14451
|
+
const desc = skill.description || "";
|
|
14452
|
+
const maxDesc = 120;
|
|
14453
|
+
const truncatedDesc = desc.length > maxDesc ? desc.slice(0, maxDesc) + "\u2026" : desc;
|
|
14454
|
+
console.log(` ${chalk48.bold.white(name)} ${version} \xB7 ${downloads}`);
|
|
14455
|
+
if (truncatedDesc) {
|
|
14456
|
+
console.log(` ${chalk48.dim(truncatedDesc)}`);
|
|
14457
|
+
}
|
|
14458
|
+
console.log();
|
|
14459
14459
|
}
|
|
14460
|
-
console.log(chalk48.bold(`\u{1F4E6} Jai1 Server (${results.length} k\u1EBFt qu\u1EA3)`));
|
|
14461
|
-
console.log(table.toString());
|
|
14462
|
-
console.log();
|
|
14463
14460
|
}
|
|
14464
14461
|
}
|
|
14465
14462
|
if (searchNpm) {
|
|
@@ -14567,7 +14564,7 @@ function createSkillsAddCommand() {
|
|
|
14567
14564
|
// src/commands/skills/list.ts
|
|
14568
14565
|
import { Command as Command85 } from "commander";
|
|
14569
14566
|
import chalk50 from "chalk";
|
|
14570
|
-
import
|
|
14567
|
+
import Table8 from "cli-table3";
|
|
14571
14568
|
function createSkillsListCommand() {
|
|
14572
14569
|
return new Command85("list").description("List installed skills or available skills on server").option("--available", "List all skills available on Jai1 server").option("-s, --search <term>", "Search skills by name or description").action(async (options) => {
|
|
14573
14570
|
const skillsService = new SkillsService();
|
|
@@ -14584,7 +14581,7 @@ function createSkillsListCommand() {
|
|
|
14584
14581
|
console.log(chalk50.yellow("Kh\xF4ng t\xECm th\u1EA5y skills n\xE0o."));
|
|
14585
14582
|
return;
|
|
14586
14583
|
}
|
|
14587
|
-
const table = new
|
|
14584
|
+
const table = new Table8({
|
|
14588
14585
|
head: [
|
|
14589
14586
|
chalk50.cyan("T\xEAn"),
|
|
14590
14587
|
chalk50.cyan("M\xF4 t\u1EA3"),
|
|
@@ -14619,7 +14616,7 @@ function createSkillsListCommand() {
|
|
|
14619
14616
|
}
|
|
14620
14617
|
console.log(chalk50.bold.cyan("\u{1F6E0} Skills \u0111\xE3 c\xE0i \u0111\u1EB7t"));
|
|
14621
14618
|
console.log();
|
|
14622
|
-
const table = new
|
|
14619
|
+
const table = new Table8({
|
|
14623
14620
|
head: [
|
|
14624
14621
|
chalk50.cyan("T\xEAn"),
|
|
14625
14622
|
chalk50.cyan("M\xF4 t\u1EA3"),
|
|
@@ -15001,9 +14998,11 @@ function getInstallCommand(packageManager2) {
|
|
|
15001
14998
|
// src/commands/clean.ts
|
|
15002
14999
|
import { Command as Command90 } from "commander";
|
|
15003
15000
|
import { confirm as confirm21, select as select6 } from "@inquirer/prompts";
|
|
15001
|
+
import { promises as fs28 } from "fs";
|
|
15004
15002
|
import { join as join21 } from "path";
|
|
15003
|
+
import { existsSync as existsSync4 } from "fs";
|
|
15005
15004
|
function createCleanCommand() {
|
|
15006
|
-
return new Command90("clean").description("Clean up backups, cache, and
|
|
15005
|
+
return new Command90("clean").description("Clean up backups, cache, IDE configs, and .jai1 directory").option("-y, --yes", "Skip confirmation").option("--backups", "Clean only backup files").option("--jai1", "Clean only .jai1/ directory").option("--ide", "Clean only IDE directories (.cursor, .windsurf, .agent, .claude, .opencode)").option("--all", "Clean all (backups + .jai1 + IDE dirs)").action(async (options) => {
|
|
15007
15006
|
await handleClean(options);
|
|
15008
15007
|
});
|
|
15009
15008
|
}
|
|
@@ -15022,15 +15021,41 @@ async function handleClean(options) {
|
|
|
15022
15021
|
clean: async () => {
|
|
15023
15022
|
await service.clearBackups(cwd);
|
|
15024
15023
|
}
|
|
15024
|
+
},
|
|
15025
|
+
{
|
|
15026
|
+
name: "Jai1 Config",
|
|
15027
|
+
description: "Jai1 framework config (.jai1/)",
|
|
15028
|
+
path: join21(cwd, ".jai1"),
|
|
15029
|
+
check: async () => {
|
|
15030
|
+
const exists = existsSync4(join21(cwd, ".jai1"));
|
|
15031
|
+
return { exists };
|
|
15032
|
+
},
|
|
15033
|
+
clean: async () => {
|
|
15034
|
+
await fs28.rm(join21(cwd, ".jai1"), { recursive: true, force: true });
|
|
15035
|
+
}
|
|
15025
15036
|
}
|
|
15026
|
-
// Future targets can be added here:
|
|
15027
|
-
// {
|
|
15028
|
-
// name: 'Cache',
|
|
15029
|
-
// description: 'Downloaded component cache',
|
|
15030
|
-
// path: join(homedir(), '.jai1', 'cache'),
|
|
15031
|
-
// ...
|
|
15032
|
-
// }
|
|
15033
15037
|
];
|
|
15038
|
+
const ideDirectories = [
|
|
15039
|
+
{ name: "Cursor", dir: ".cursor" },
|
|
15040
|
+
{ name: "Windsurf", dir: ".windsurf" },
|
|
15041
|
+
{ name: "Antigravity", dir: ".agent" },
|
|
15042
|
+
{ name: "Claude Code", dir: ".claude" },
|
|
15043
|
+
{ name: "OpenCode", dir: ".opencode" }
|
|
15044
|
+
];
|
|
15045
|
+
for (const ide of ideDirectories) {
|
|
15046
|
+
const idePath = join21(cwd, ide.dir);
|
|
15047
|
+
if (existsSync4(idePath)) {
|
|
15048
|
+
targets.push({
|
|
15049
|
+
name: `IDE: ${ide.name}`,
|
|
15050
|
+
description: `${ide.name} IDE config (${ide.dir}/)`,
|
|
15051
|
+
path: idePath,
|
|
15052
|
+
check: async () => ({ exists: true }),
|
|
15053
|
+
clean: async () => {
|
|
15054
|
+
await fs28.rm(idePath, { recursive: true, force: true });
|
|
15055
|
+
}
|
|
15056
|
+
});
|
|
15057
|
+
}
|
|
15058
|
+
}
|
|
15034
15059
|
console.log("\u{1F9F9} Clean up CLI client files\n");
|
|
15035
15060
|
const availableTargets = [];
|
|
15036
15061
|
for (const target of targets) {
|
|
@@ -15050,6 +15075,26 @@ async function handleClean(options) {
|
|
|
15050
15075
|
}
|
|
15051
15076
|
return;
|
|
15052
15077
|
}
|
|
15078
|
+
if (options.jai1) {
|
|
15079
|
+
const jai1Target = availableTargets.find(({ target }) => target.name === "Jai1 Config");
|
|
15080
|
+
if (jai1Target) {
|
|
15081
|
+
await cleanTarget(jai1Target.target, options.yes);
|
|
15082
|
+
} else {
|
|
15083
|
+
console.log("\u2728 No .jai1/ directory found.");
|
|
15084
|
+
}
|
|
15085
|
+
return;
|
|
15086
|
+
}
|
|
15087
|
+
if (options.ide) {
|
|
15088
|
+
const ideTargets = availableTargets.filter(({ target }) => target.name.startsWith("IDE:"));
|
|
15089
|
+
if (ideTargets.length === 0) {
|
|
15090
|
+
console.log("\u2728 No IDE directories found.");
|
|
15091
|
+
return;
|
|
15092
|
+
}
|
|
15093
|
+
for (const { target } of ideTargets) {
|
|
15094
|
+
await cleanTarget(target, options.yes);
|
|
15095
|
+
}
|
|
15096
|
+
return;
|
|
15097
|
+
}
|
|
15053
15098
|
if (options.all) {
|
|
15054
15099
|
for (const { target } of availableTargets) {
|
|
15055
15100
|
await cleanTarget(target, options.yes);
|
|
@@ -16006,7 +16051,7 @@ async function handleSyncProject(options) {
|
|
|
16006
16051
|
|
|
16007
16052
|
// src/commands/framework/info.ts
|
|
16008
16053
|
import { Command as Command94 } from "commander";
|
|
16009
|
-
import { promises as
|
|
16054
|
+
import { promises as fs29 } from "fs";
|
|
16010
16055
|
import { join as join22 } from "path";
|
|
16011
16056
|
import { homedir as homedir5 } from "os";
|
|
16012
16057
|
function createInfoCommand() {
|
|
@@ -16058,7 +16103,7 @@ function maskKey4(key) {
|
|
|
16058
16103
|
async function getProjectStatus2() {
|
|
16059
16104
|
const projectJai1 = join22(process.cwd(), ".jai1");
|
|
16060
16105
|
try {
|
|
16061
|
-
await
|
|
16106
|
+
await fs29.access(projectJai1);
|
|
16062
16107
|
return { exists: true, version: "Synced" };
|
|
16063
16108
|
} catch {
|
|
16064
16109
|
return { exists: false };
|
|
@@ -16248,9 +16293,9 @@ function createClearBackupsCommand() {
|
|
|
16248
16293
|
// src/commands/vscode/index.ts
|
|
16249
16294
|
import { Command as Command97 } from "commander";
|
|
16250
16295
|
import { checkbox as checkbox9, confirm as confirm24, select as select7 } from "@inquirer/prompts";
|
|
16251
|
-
import
|
|
16296
|
+
import fs30 from "fs/promises";
|
|
16252
16297
|
import path12 from "path";
|
|
16253
|
-
import { existsSync as
|
|
16298
|
+
import { existsSync as existsSync5 } from "fs";
|
|
16254
16299
|
var PERFORMANCE_GROUPS2 = {
|
|
16255
16300
|
telemetry: {
|
|
16256
16301
|
name: "Telemetry",
|
|
@@ -16480,14 +16525,14 @@ async function applyGroups2(groupKeys, action) {
|
|
|
16480
16525
|
console.log(' \u{1F4A1} Ch\u1EA1y "jai1 vscode list" \u0111\u1EC3 xem danh s\xE1ch nh\xF3m c\xF3 s\u1EB5n.');
|
|
16481
16526
|
return;
|
|
16482
16527
|
}
|
|
16483
|
-
if (!
|
|
16484
|
-
await
|
|
16528
|
+
if (!existsSync5(vscodeDir)) {
|
|
16529
|
+
await fs30.mkdir(vscodeDir, { recursive: true });
|
|
16485
16530
|
console.log("\u{1F4C1} \u0110\xE3 t\u1EA1o th\u01B0 m\u1EE5c .vscode/");
|
|
16486
16531
|
}
|
|
16487
16532
|
let currentSettings = {};
|
|
16488
|
-
if (
|
|
16533
|
+
if (existsSync5(settingsPath)) {
|
|
16489
16534
|
try {
|
|
16490
|
-
const content = await
|
|
16535
|
+
const content = await fs30.readFile(settingsPath, "utf-8");
|
|
16491
16536
|
currentSettings = JSON.parse(content);
|
|
16492
16537
|
console.log("\u{1F4C4} \u0110\xE3 \u0111\u1ECDc c\xE0i \u0111\u1EB7t hi\u1EC7n t\u1EA1i t\u1EEB settings.json");
|
|
16493
16538
|
} catch {
|
|
@@ -16527,7 +16572,7 @@ async function applyGroups2(groupKeys, action) {
|
|
|
16527
16572
|
}
|
|
16528
16573
|
}
|
|
16529
16574
|
}
|
|
16530
|
-
await
|
|
16575
|
+
await fs30.writeFile(settingsPath, JSON.stringify(newSettings, null, 2));
|
|
16531
16576
|
console.log(`
|
|
16532
16577
|
\u2705 \u0110\xE3 c\u1EADp nh\u1EADt c\xE0i \u0111\u1EB7t VSCode t\u1EA1i: ${settingsPath}`);
|
|
16533
16578
|
console.log("\u{1F4A1} M\u1EB9o: Kh\u1EDFi \u0111\u1ED9ng l\u1EA1i VSCode \u0111\u1EC3 \xE1p d\u1EE5ng c\xE1c thay \u0111\u1ED5i.");
|
|
@@ -16535,7 +16580,7 @@ async function applyGroups2(groupKeys, action) {
|
|
|
16535
16580
|
async function resetSettings2(groupKeys) {
|
|
16536
16581
|
const vscodeDir = path12.join(process.cwd(), ".vscode");
|
|
16537
16582
|
const settingsPath = path12.join(vscodeDir, "settings.json");
|
|
16538
|
-
if (!
|
|
16583
|
+
if (!existsSync5(settingsPath)) {
|
|
16539
16584
|
console.log("\n\u26A0\uFE0F Kh\xF4ng t\xECm th\u1EA5y file settings.json");
|
|
16540
16585
|
return;
|
|
16541
16586
|
}
|
|
@@ -16548,7 +16593,7 @@ async function resetSettings2(groupKeys) {
|
|
|
16548
16593
|
return;
|
|
16549
16594
|
}
|
|
16550
16595
|
if (groupKeys.length === 0) {
|
|
16551
|
-
await
|
|
16596
|
+
await fs30.unlink(settingsPath);
|
|
16552
16597
|
console.log("\n\u2705 \u0110\xE3 x\xF3a file settings.json");
|
|
16553
16598
|
} else {
|
|
16554
16599
|
await applyGroups2(groupKeys, "disable");
|