@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 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.53",
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 timeoutSec = options.timeout ? parseInt(options.timeout, 10) : void 0;
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` + (timeoutSec ? ` \xB7 timeout ${timeoutSec}s` : "") + (options.keep ? " \xB7 keep watching" : " \xB7 stops after first email") + ` \xB7 Ctrl+C to stop
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: ch\u1EA1y m\xE3i)").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", `
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 300
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, bug/xxx").option("-t, --tags <tags>", "Comma-separated tags").option("-j, --json", "Output JSON").action(async (title, options) => {
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
- const table = new Table8({
14442
- head: [
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
- table.push([
14454
- chalk48.white(name),
14455
- chalk48.dim((skill.description || "").slice(0, 38)),
14456
- chalk48.green(skill.version || "-"),
14457
- chalk48.dim(String(skill.downloads || 0))
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 Table9 from "cli-table3";
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 Table9({
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 Table9({
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 temporary files").option("-y, --yes", "Skip confirmation").option("--backups", "Clean only backup files").option("--all", "Clean all (backups + cache)").action(async (options) => {
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 fs28 } from "fs";
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 fs28.access(projectJai1);
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 fs29 from "fs/promises";
16296
+ import fs30 from "fs/promises";
16252
16297
  import path12 from "path";
16253
- import { existsSync as existsSync4 } from "fs";
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 (!existsSync4(vscodeDir)) {
16484
- await fs29.mkdir(vscodeDir, { recursive: true });
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 (existsSync4(settingsPath)) {
16533
+ if (existsSync5(settingsPath)) {
16489
16534
  try {
16490
- const content = await fs29.readFile(settingsPath, "utf-8");
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 fs29.writeFile(settingsPath, JSON.stringify(newSettings, null, 2));
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 (!existsSync4(settingsPath)) {
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 fs29.unlink(settingsPath);
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");