@jvittechs/jai1-cli 1.0.7 → 1.0.9
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 +340 -304
- package/dist/cli.js.map +1 -1
- package/package.json +4 -2
- package/scripts/postinstall.js +74 -0
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
// src/utils/node-version-check.ts
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
var MIN_NODE_VERSION = "20.12.0";
|
|
6
|
+
function parseVersion(version) {
|
|
7
|
+
return version.replace(/^v/, "").split(".").map(Number);
|
|
8
|
+
}
|
|
9
|
+
function compareVersions(a, b) {
|
|
10
|
+
const partsA = parseVersion(a);
|
|
11
|
+
const partsB = parseVersion(b);
|
|
12
|
+
for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {
|
|
13
|
+
const numA = partsA[i] || 0;
|
|
14
|
+
const numB = partsB[i] || 0;
|
|
15
|
+
if (numA < numB) return -1;
|
|
16
|
+
if (numA > numB) return 1;
|
|
17
|
+
}
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
function checkNodeVersion() {
|
|
21
|
+
const currentVersion = process.version;
|
|
22
|
+
if (compareVersions(currentVersion, MIN_NODE_VERSION) < 0) {
|
|
23
|
+
console.error(chalk.red("\u274C Node.js version too old!"));
|
|
24
|
+
console.error(chalk.yellow(` Current version: ${currentVersion}`));
|
|
25
|
+
console.error(chalk.yellow(` Required version: >=${MIN_NODE_VERSION}`));
|
|
26
|
+
console.error();
|
|
27
|
+
console.error(chalk.cyan("\u{1F4A1} Please upgrade Node.js:"));
|
|
28
|
+
console.error(chalk.gray(" - Using nvm: nvm install 20 && nvm use 20"));
|
|
29
|
+
console.error(chalk.gray(" - Using fnm: fnm install 20 && fnm use 20"));
|
|
30
|
+
console.error(chalk.gray(" - Download: https://nodejs.org/"));
|
|
31
|
+
console.error();
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
3
36
|
// src/cli.ts
|
|
4
37
|
import { Command as Command62 } from "commander";
|
|
5
38
|
|
|
@@ -33,7 +66,7 @@ var NetworkError = class extends Jai1Error {
|
|
|
33
66
|
// package.json
|
|
34
67
|
var package_default = {
|
|
35
68
|
name: "@jvittechs/jai1-cli",
|
|
36
|
-
version: "1.0.
|
|
69
|
+
version: "1.0.9",
|
|
37
70
|
description: "A unified CLI tool for JV-IT TECHS developers to manage Jai1 Framework. Please contact TeamAI for usage instructions.",
|
|
38
71
|
type: "module",
|
|
39
72
|
bin: {
|
|
@@ -45,7 +78,8 @@ var package_default = {
|
|
|
45
78
|
files: [
|
|
46
79
|
"dist",
|
|
47
80
|
"redmine.config.example.yaml",
|
|
48
|
-
"scripts/redmine-sync-issue.sh"
|
|
81
|
+
"scripts/redmine-sync-issue.sh",
|
|
82
|
+
"scripts/postinstall.js"
|
|
49
83
|
],
|
|
50
84
|
engines: {
|
|
51
85
|
node: ">=20"
|
|
@@ -70,6 +104,7 @@ var package_default = {
|
|
|
70
104
|
"coding"
|
|
71
105
|
],
|
|
72
106
|
scripts: {
|
|
107
|
+
postinstall: "node scripts/postinstall.js",
|
|
73
108
|
"bundle:guide": "node scripts/bundle-guide-content.js",
|
|
74
109
|
build: "npm run bundle:guide && tsup src/cli.ts --dts --format esm --target node22 --out-dir dist --sourcemap && npm run copy-web-chat",
|
|
75
110
|
"copy-web-chat": "mkdir -p dist/web-chat && cp -r src/web-chat/* dist/web-chat/",
|
|
@@ -270,7 +305,7 @@ function showUpdateNotification(latestVersion) {
|
|
|
270
305
|
|
|
271
306
|
// src/commands/framework/auth.ts
|
|
272
307
|
import { Command } from "commander";
|
|
273
|
-
import
|
|
308
|
+
import chalk2 from "chalk";
|
|
274
309
|
import boxen from "boxen";
|
|
275
310
|
|
|
276
311
|
// src/services/tracking.service.ts
|
|
@@ -384,11 +419,11 @@ async function handleAuth(options) {
|
|
|
384
419
|
const existingConfig = await configService.load();
|
|
385
420
|
if (existingConfig) {
|
|
386
421
|
console.log(
|
|
387
|
-
|
|
388
|
-
|
|
422
|
+
chalk2.yellow("\u26A0\uFE0F C\u1EA5u h\xECnh \u0111\xE3 t\u1ED3n t\u1EA1i t\u1EA1i:"),
|
|
423
|
+
chalk2.dim(configService.getConfigPath())
|
|
389
424
|
);
|
|
390
425
|
console.log(
|
|
391
|
-
|
|
426
|
+
chalk2.dim(" Ch\u1EA1y l\u1EA1i l\u1EC7nh n\xE0y v\u1EDBi gi\xE1 tr\u1ECB m\u1EDBi \u0111\u1EC3 ghi \u0111\xE8.\n")
|
|
392
427
|
);
|
|
393
428
|
}
|
|
394
429
|
if (options.apiUrl && options.accessKey) {
|
|
@@ -401,7 +436,7 @@ async function handleAuth(options) {
|
|
|
401
436
|
} else {
|
|
402
437
|
isInteractive = true;
|
|
403
438
|
console.log(
|
|
404
|
-
boxen(
|
|
439
|
+
boxen(chalk2.cyan.bold("\u{1F680} Jai1 Client Setup"), {
|
|
405
440
|
padding: { left: 1, right: 1, top: 0, bottom: 0 },
|
|
406
441
|
borderStyle: "round",
|
|
407
442
|
borderColor: "cyan"
|
|
@@ -421,12 +456,12 @@ async function handleAuth(options) {
|
|
|
421
456
|
});
|
|
422
457
|
};
|
|
423
458
|
apiUrl = await question(
|
|
424
|
-
|
|
459
|
+
chalk2.dim("API URL") + chalk2.gray(" (https://store.jai1.io): ")
|
|
425
460
|
);
|
|
426
461
|
if (!apiUrl) {
|
|
427
462
|
apiUrl = "https://store.jai1.io";
|
|
428
463
|
}
|
|
429
|
-
accessKey = await question(
|
|
464
|
+
accessKey = await question(chalk2.dim("Access Key: "));
|
|
430
465
|
if (!accessKey) {
|
|
431
466
|
rl.close();
|
|
432
467
|
throw new ValidationError("Access key l\xE0 b\u1EAFt bu\u1ED9c");
|
|
@@ -438,7 +473,7 @@ async function handleAuth(options) {
|
|
|
438
473
|
} catch {
|
|
439
474
|
throw new ValidationError("\u0110\u1ECBnh d\u1EA1ng API URL kh\xF4ng h\u1EE3p l\u1EC7");
|
|
440
475
|
}
|
|
441
|
-
console.log(
|
|
476
|
+
console.log(chalk2.dim("\n\u0110ang x\xE1c th\u1EF1c access key..."));
|
|
442
477
|
await configService.save({
|
|
443
478
|
apiUrl,
|
|
444
479
|
accessKey,
|
|
@@ -451,20 +486,20 @@ async function handleAuth(options) {
|
|
|
451
486
|
isReconfig: !!existingConfig
|
|
452
487
|
});
|
|
453
488
|
console.log(
|
|
454
|
-
|
|
455
|
-
|
|
489
|
+
chalk2.green("\u2713 C\u1EA5u h\xECnh \u0111\xE3 l\u01B0u t\u1EA1i"),
|
|
490
|
+
chalk2.dim(configService.getConfigPath())
|
|
456
491
|
);
|
|
457
492
|
console.log();
|
|
458
493
|
console.log(
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
494
|
+
chalk2.dim("B\u1EA1n \u0111\xE3 s\u1EB5n s\xE0ng! Ch\u1EA1y"),
|
|
495
|
+
chalk2.cyan("'jai1 check'"),
|
|
496
|
+
chalk2.dim("\u0111\u1EC3 ki\u1EC3m tra c\u1EADp nh\u1EADt.")
|
|
462
497
|
);
|
|
463
498
|
}
|
|
464
499
|
|
|
465
500
|
// src/commands/status.ts
|
|
466
501
|
import { Command as Command2 } from "commander";
|
|
467
|
-
import
|
|
502
|
+
import chalk3 from "chalk";
|
|
468
503
|
import boxen2 from "boxen";
|
|
469
504
|
|
|
470
505
|
// src/services/components.service.ts
|
|
@@ -787,36 +822,36 @@ async function handleStatus(options) {
|
|
|
787
822
|
return;
|
|
788
823
|
}
|
|
789
824
|
console.log(
|
|
790
|
-
boxen2(
|
|
825
|
+
boxen2(chalk3.cyan.bold("\u{1F4CA} Jai1 Client Status"), {
|
|
791
826
|
padding: { left: 1, right: 1, top: 0, bottom: 0 },
|
|
792
827
|
borderStyle: "round",
|
|
793
828
|
borderColor: "cyan"
|
|
794
829
|
})
|
|
795
830
|
);
|
|
796
|
-
console.log(
|
|
797
|
-
console.log(` ${
|
|
798
|
-
console.log(` ${
|
|
799
|
-
console.log(` ${
|
|
800
|
-
console.log(
|
|
801
|
-
console.log(` ${
|
|
802
|
-
console.log(` ${
|
|
803
|
-
console.log(` ${
|
|
804
|
-
console.log(
|
|
805
|
-
const existsIcon = info.projectStatus.exists ?
|
|
806
|
-
console.log(` ${
|
|
831
|
+
console.log(chalk3.bold("\n\u{1F527} C\u1EA5u h\xECnh"));
|
|
832
|
+
console.log(` ${chalk3.dim("Config:")} ${info.configPath}`);
|
|
833
|
+
console.log(` ${chalk3.dim("API URL:")} ${info.apiUrl}`);
|
|
834
|
+
console.log(` ${chalk3.dim("Access Key:")} ${chalk3.yellow(info.accessKey)}`);
|
|
835
|
+
console.log(chalk3.bold("\n\u{1F4E6} Framework"));
|
|
836
|
+
console.log(` ${chalk3.dim("Version:")} ${chalk3.green(info.version)}`);
|
|
837
|
+
console.log(` ${chalk3.dim("Updated:")} ${info.lastUpdated}`);
|
|
838
|
+
console.log(` ${chalk3.dim("Location:")} ${info.frameworkPath}`);
|
|
839
|
+
console.log(chalk3.bold("\n\u{1F4C1} Project"));
|
|
840
|
+
const existsIcon = info.projectStatus.exists ? chalk3.green("\u2713") : chalk3.red("\u2717");
|
|
841
|
+
console.log(` ${chalk3.dim(".jai1/ exists:")} ${existsIcon}`);
|
|
807
842
|
if (info.projectStatus.exists) {
|
|
808
843
|
console.log(
|
|
809
|
-
` ${
|
|
844
|
+
` ${chalk3.dim("Components:")} ${chalk3.cyan(componentCount)} installed`
|
|
810
845
|
);
|
|
811
846
|
}
|
|
812
847
|
console.log();
|
|
813
848
|
if (!info.projectStatus.exists) {
|
|
814
849
|
console.log(
|
|
815
|
-
|
|
850
|
+
chalk3.dim('\u{1F4A1} Ch\u1EA1y "jai1 apply" \u0111\u1EC3 c\xE0i components cho project n\xE0y.')
|
|
816
851
|
);
|
|
817
852
|
} else if (componentCount > 0) {
|
|
818
853
|
console.log(
|
|
819
|
-
|
|
854
|
+
chalk3.dim('\u{1F4A1} Ch\u1EA1y "jai1 check" \u0111\u1EC3 ki\u1EC3m tra c\u1EADp nh\u1EADt components.')
|
|
820
855
|
);
|
|
821
856
|
}
|
|
822
857
|
}
|
|
@@ -2205,7 +2240,7 @@ function createApplyNewCommand() {
|
|
|
2205
2240
|
// src/commands/update.ts
|
|
2206
2241
|
import { Command as Command5 } from "commander";
|
|
2207
2242
|
import { confirm } from "@inquirer/prompts";
|
|
2208
|
-
import
|
|
2243
|
+
import chalk4 from "chalk";
|
|
2209
2244
|
function createUpdateCommand() {
|
|
2210
2245
|
return new Command5("update").description("Update installed components to latest versions").option("--force", "Force update even if files are modified locally").action(async (options) => {
|
|
2211
2246
|
await handleUpdate(options);
|
|
@@ -2221,11 +2256,11 @@ async function handleUpdate(options) {
|
|
|
2221
2256
|
const installed = await componentsService.getInstalled();
|
|
2222
2257
|
const filepaths = Object.keys(installed);
|
|
2223
2258
|
if (filepaths.length === 0) {
|
|
2224
|
-
console.log(
|
|
2225
|
-
console.log(
|
|
2259
|
+
console.log(chalk4.yellow("\u{1F4E6} Ch\u01B0a c\xF3 components n\xE0o \u0111\u01B0\u1EE3c c\xE0i \u0111\u1EB7t."));
|
|
2260
|
+
console.log(chalk4.dim(' Ch\u1EA1y "jai1 apply" \u0111\u1EC3 th\xEAm components.'));
|
|
2226
2261
|
return;
|
|
2227
2262
|
}
|
|
2228
|
-
console.log(
|
|
2263
|
+
console.log(chalk4.cyan("\u{1F50D} \u0110ang ki\u1EC3m tra c\u1EADp nh\u1EADt..."));
|
|
2229
2264
|
try {
|
|
2230
2265
|
const checksums = await componentsService.getChecksums(config, filepaths);
|
|
2231
2266
|
const updates = [];
|
|
@@ -2245,32 +2280,32 @@ async function handleUpdate(options) {
|
|
|
2245
2280
|
}
|
|
2246
2281
|
}
|
|
2247
2282
|
if (deprecated.length > 0) {
|
|
2248
|
-
console.log(
|
|
2283
|
+
console.log(chalk4.yellow("\n\u26A0\uFE0F Components kh\xF4ng c\xF2n tr\xEAn server (deprecated):"));
|
|
2249
2284
|
for (const fp of deprecated) {
|
|
2250
|
-
console.log(
|
|
2285
|
+
console.log(chalk4.dim(` - ${fp}`));
|
|
2251
2286
|
}
|
|
2252
2287
|
}
|
|
2253
2288
|
if (updates.length === 0) {
|
|
2254
|
-
console.log(
|
|
2289
|
+
console.log(chalk4.green("\n\u2705 T\u1EA5t c\u1EA3 components \u0111\xE3 l\xE0 phi\xEAn b\u1EA3n m\u1EDBi nh\u1EA5t."));
|
|
2255
2290
|
if (upToDate.length > 0) {
|
|
2256
|
-
console.log(
|
|
2291
|
+
console.log(chalk4.dim(` ${upToDate.length} component(s) \u0111\xE3 c\u1EADp nh\u1EADt.`));
|
|
2257
2292
|
}
|
|
2258
2293
|
return;
|
|
2259
2294
|
}
|
|
2260
|
-
console.log(
|
|
2261
|
-
\u{1F4E6} T\xECm th\u1EA5y ${
|
|
2295
|
+
console.log(chalk4.cyan(`
|
|
2296
|
+
\u{1F4E6} T\xECm th\u1EA5y ${chalk4.bold(updates.length)} c\u1EADp nh\u1EADt:`));
|
|
2262
2297
|
for (const fp of updates) {
|
|
2263
2298
|
const current = installed[fp];
|
|
2264
2299
|
const latest = checksums[fp];
|
|
2265
2300
|
console.log(
|
|
2266
|
-
` ${
|
|
2301
|
+
` ${chalk4.white(fp)} ` + chalk4.dim(`v${current.version}`) + chalk4.cyan(" \u2192 ") + chalk4.green(`v${latest.version}`)
|
|
2267
2302
|
);
|
|
2268
2303
|
}
|
|
2269
2304
|
console.log();
|
|
2270
2305
|
if (!options.force) {
|
|
2271
2306
|
const shouldUpdate = await confirm({ message: "C\u1EADp nh\u1EADt ngay?", default: true });
|
|
2272
2307
|
if (!shouldUpdate) {
|
|
2273
|
-
console.log(
|
|
2308
|
+
console.log(chalk4.dim("\u0110\xE3 h\u1EE7y c\u1EADp nh\u1EADt."));
|
|
2274
2309
|
return;
|
|
2275
2310
|
}
|
|
2276
2311
|
}
|
|
@@ -2280,34 +2315,34 @@ async function handleUpdate(options) {
|
|
|
2280
2315
|
console.log();
|
|
2281
2316
|
for (const fp of updates) {
|
|
2282
2317
|
try {
|
|
2283
|
-
process.stdout.write(
|
|
2318
|
+
process.stdout.write(chalk4.cyan(`\u{1F4E5} \u0110ang c\u1EADp nh\u1EADt ${chalk4.white(fp)}...`));
|
|
2284
2319
|
const backupPath = await componentsService.backupFile(fp, targetDir);
|
|
2285
2320
|
if (backupPath) {
|
|
2286
2321
|
backupPaths.push(backupPath);
|
|
2287
2322
|
}
|
|
2288
2323
|
await componentsService.install(config, fp, targetDir);
|
|
2289
|
-
console.log(
|
|
2324
|
+
console.log(chalk4.green(" \u2713"));
|
|
2290
2325
|
updatedCount++;
|
|
2291
2326
|
} catch (error) {
|
|
2292
|
-
console.log(
|
|
2293
|
-
console.log(
|
|
2327
|
+
console.log(chalk4.red(" \u2717"));
|
|
2328
|
+
console.log(chalk4.red(` L\u1ED7i: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
2294
2329
|
}
|
|
2295
2330
|
}
|
|
2296
2331
|
console.log();
|
|
2297
2332
|
if (updatedCount === updates.length) {
|
|
2298
|
-
console.log(
|
|
2333
|
+
console.log(chalk4.green(`\u2705 Ho\xE0n t\u1EA5t: ${updatedCount}/${updates.length} \u0111\xE3 c\u1EADp nh\u1EADt.`));
|
|
2299
2334
|
} else {
|
|
2300
|
-
console.log(
|
|
2335
|
+
console.log(chalk4.yellow(`\u26A0\uFE0F Ho\xE0n t\u1EA5t: ${updatedCount}/${updates.length} \u0111\xE3 c\u1EADp nh\u1EADt.`));
|
|
2301
2336
|
}
|
|
2302
2337
|
if (backupPaths.length > 0) {
|
|
2303
|
-
console.log(
|
|
2338
|
+
console.log(chalk4.dim(`
|
|
2304
2339
|
\u{1F4C1} \u0110\xE3 t\u1EA1o backup t\u1EA1i .jai1_backup/`));
|
|
2305
2340
|
const cleanBackups = await confirm({ message: "X\xF3a c\xE1c backup n\xE0y?", default: false });
|
|
2306
2341
|
if (cleanBackups) {
|
|
2307
2342
|
await componentsService.clearBackups(process.cwd());
|
|
2308
|
-
console.log(
|
|
2343
|
+
console.log(chalk4.green("\u{1F5D1}\uFE0F \u0110\xE3 x\xF3a backups."));
|
|
2309
2344
|
} else {
|
|
2310
|
-
console.log(
|
|
2345
|
+
console.log(chalk4.dim('\u{1F4A1} Ch\u1EA1y "jai1 clean" \u0111\u1EC3 x\xF3a sau.'));
|
|
2311
2346
|
}
|
|
2312
2347
|
}
|
|
2313
2348
|
trackAction("components_update", { count: updatedCount });
|
|
@@ -2318,7 +2353,7 @@ async function handleUpdate(options) {
|
|
|
2318
2353
|
|
|
2319
2354
|
// src/commands/framework/check.ts
|
|
2320
2355
|
import { Command as Command6 } from "commander";
|
|
2321
|
-
import
|
|
2356
|
+
import chalk5 from "chalk";
|
|
2322
2357
|
import Table from "cli-table3";
|
|
2323
2358
|
function createCheckCommand() {
|
|
2324
2359
|
const cmd = new Command6("check").description("Ki\u1EC3m tra c\u1EADp nh\u1EADt framework").option("--json", "Output as JSON").action(async (options) => {
|
|
@@ -2337,11 +2372,11 @@ async function handleCheck(options) {
|
|
|
2337
2372
|
const filepaths = Object.keys(installed);
|
|
2338
2373
|
if (filepaths.length === 0) {
|
|
2339
2374
|
console.log(
|
|
2340
|
-
|
|
2375
|
+
chalk5.yellow('Ch\u01B0a c\xF3 components n\xE0o. Ch\u1EA1y "jai1 apply" \u0111\u1EC3 b\u1EAFt \u0111\u1EA7u.')
|
|
2341
2376
|
);
|
|
2342
2377
|
return;
|
|
2343
2378
|
}
|
|
2344
|
-
console.log(
|
|
2379
|
+
console.log(chalk5.dim("\u0110ang ki\u1EC3m tra c\u1EADp nh\u1EADt...\n"));
|
|
2345
2380
|
try {
|
|
2346
2381
|
const checksums = await componentsService.getChecksums(config, filepaths);
|
|
2347
2382
|
const updates = [];
|
|
@@ -2376,14 +2411,14 @@ async function handleCheck(options) {
|
|
|
2376
2411
|
);
|
|
2377
2412
|
return;
|
|
2378
2413
|
}
|
|
2379
|
-
console.log(
|
|
2414
|
+
console.log(chalk5.bold("\u{1F4CC} Tr\u1EA1ng th\xE1i Components:\n"));
|
|
2380
2415
|
if (updates.length > 0) {
|
|
2381
2416
|
const table = new Table({
|
|
2382
2417
|
head: [
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2418
|
+
chalk5.bold("Component"),
|
|
2419
|
+
chalk5.bold("Hi\u1EC7n t\u1EA1i"),
|
|
2420
|
+
chalk5.bold("M\u1EDBi nh\u1EA5t"),
|
|
2421
|
+
chalk5.bold("Tr\u1EA1ng th\xE1i")
|
|
2387
2422
|
],
|
|
2388
2423
|
style: {
|
|
2389
2424
|
head: ["cyan"],
|
|
@@ -2396,8 +2431,8 @@ async function handleCheck(options) {
|
|
|
2396
2431
|
table.push([
|
|
2397
2432
|
fp,
|
|
2398
2433
|
`v${current.version}`,
|
|
2399
|
-
|
|
2400
|
-
|
|
2434
|
+
chalk5.green(`v${latest.version}`),
|
|
2435
|
+
chalk5.yellow("\u26A0\uFE0F C\u1EA6N C\u1EACP NH\u1EACT")
|
|
2401
2436
|
]);
|
|
2402
2437
|
}
|
|
2403
2438
|
console.log(table.toString());
|
|
@@ -2405,27 +2440,27 @@ async function handleCheck(options) {
|
|
|
2405
2440
|
console.log();
|
|
2406
2441
|
if (updates.length === 0 && upToDate.length > 0) {
|
|
2407
2442
|
console.log(
|
|
2408
|
-
|
|
2443
|
+
chalk5.green(`\u2713 T\u1EA5t c\u1EA3 ${upToDate.length} components \u0111\xE3 c\u1EADp nh\u1EADt.`)
|
|
2409
2444
|
);
|
|
2410
2445
|
} else if (upToDate.length > 0) {
|
|
2411
|
-
console.log(
|
|
2446
|
+
console.log(chalk5.dim(`\u2713 ${upToDate.length} components \u0111\xE3 c\u1EADp nh\u1EADt.`));
|
|
2412
2447
|
}
|
|
2413
2448
|
if (updates.length > 0) {
|
|
2414
2449
|
console.log(
|
|
2415
|
-
|
|
2450
|
+
chalk5.yellow(`
|
|
2416
2451
|
\u26A0\uFE0F ${updates.length} component(s) c\xF3 b\u1EA3n c\u1EADp nh\u1EADt!`)
|
|
2417
2452
|
);
|
|
2418
2453
|
console.log(
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2454
|
+
chalk5.dim("Ch\u1EA1y"),
|
|
2455
|
+
chalk5.cyan("'jai1 update'"),
|
|
2456
|
+
chalk5.dim("\u0111\u1EC3 c\u1EADp nh\u1EADt.")
|
|
2422
2457
|
);
|
|
2423
2458
|
} else {
|
|
2424
|
-
console.log(
|
|
2459
|
+
console.log(chalk5.green("\n\u2705 M\u1ECDi th\u1EE9 \u0111\xE3 \u0111\u01B0\u1EE3c c\u1EADp nh\u1EADt!"));
|
|
2425
2460
|
}
|
|
2426
2461
|
} catch (error) {
|
|
2427
2462
|
console.error(
|
|
2428
|
-
|
|
2463
|
+
chalk5.red("L\u1ED7i ki\u1EC3m tra c\u1EADp nh\u1EADt:"),
|
|
2429
2464
|
error instanceof Error ? error.message : error
|
|
2430
2465
|
);
|
|
2431
2466
|
}
|
|
@@ -2433,7 +2468,7 @@ async function handleCheck(options) {
|
|
|
2433
2468
|
|
|
2434
2469
|
// src/commands/ide/index.ts
|
|
2435
2470
|
import { Command as Command11 } from "commander";
|
|
2436
|
-
import
|
|
2471
|
+
import chalk6 from "chalk";
|
|
2437
2472
|
|
|
2438
2473
|
// src/commands/ide/context.ts
|
|
2439
2474
|
import React12 from "react";
|
|
@@ -4167,24 +4202,24 @@ function getConfidenceEmoji(confidence) {
|
|
|
4167
4202
|
|
|
4168
4203
|
// src/commands/ide/index.ts
|
|
4169
4204
|
function showIdeHelp() {
|
|
4170
|
-
console.log(
|
|
4205
|
+
console.log(chalk6.bold.cyan("\u{1F5A5}\uFE0F jai1 ide") + chalk6.dim(" - IDE integration v\xE0 c\u1EA5u h\xECnh"));
|
|
4171
4206
|
console.log();
|
|
4172
|
-
console.log(
|
|
4173
|
-
console.log(` ${
|
|
4174
|
-
console.log(` ${
|
|
4175
|
-
console.log(` ${
|
|
4176
|
-
console.log(` ${
|
|
4207
|
+
console.log(chalk6.bold("C\xE1c l\u1EC7nh:"));
|
|
4208
|
+
console.log(` ${chalk6.cyan("context")} Duy\u1EC7t v\xE0 kh\xE1m ph\xE1 IDE context`);
|
|
4209
|
+
console.log(` ${chalk6.cyan("setup")} C\u1EA5u h\xECnh IDE settings (VSCode optimizations)`);
|
|
4210
|
+
console.log(` ${chalk6.cyan("sync")} \u0110\u1ED3ng b\u1ED9 .jai1 content \u0111\u1EBFn IDE directories`);
|
|
4211
|
+
console.log(` ${chalk6.cyan("status")} Hi\u1EC3n th\u1ECB c\xE1c IDE \u0111\u01B0\u1EE3c ph\xE1t hi\u1EC7n v\xE0 tr\u1EA1ng th\xE1i`);
|
|
4177
4212
|
console.log();
|
|
4178
|
-
console.log(
|
|
4179
|
-
console.log(
|
|
4213
|
+
console.log(chalk6.bold("IDEs \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3:"));
|
|
4214
|
+
console.log(chalk6.dim(" Cursor, Windsurf, VSCode, Trae, Claude"));
|
|
4180
4215
|
console.log();
|
|
4181
|
-
console.log(
|
|
4182
|
-
console.log(
|
|
4183
|
-
console.log(
|
|
4184
|
-
console.log(
|
|
4185
|
-
console.log(
|
|
4216
|
+
console.log(chalk6.bold("V\xED d\u1EE5:"));
|
|
4217
|
+
console.log(chalk6.dim(" $ jai1 ide status"));
|
|
4218
|
+
console.log(chalk6.dim(" $ jai1 ide setup --optimize"));
|
|
4219
|
+
console.log(chalk6.dim(" $ jai1 ide sync"));
|
|
4220
|
+
console.log(chalk6.dim(" $ jai1 ide context"));
|
|
4186
4221
|
console.log();
|
|
4187
|
-
console.log(
|
|
4222
|
+
console.log(chalk6.dim('Ch\u1EA1y "jai1 ide <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
|
|
4188
4223
|
}
|
|
4189
4224
|
function createIdeCommand() {
|
|
4190
4225
|
const ideCommand = new Command11("ide").description("IDE integration and configuration commands").action(() => {
|
|
@@ -4705,35 +4740,35 @@ import { useState as useState8, useEffect as useEffect4, useMemo as useMemo3 } f
|
|
|
4705
4740
|
import matter3 from "gray-matter";
|
|
4706
4741
|
|
|
4707
4742
|
// src/ui/guide/utils/markdown.ts
|
|
4708
|
-
import
|
|
4743
|
+
import chalk7 from "chalk";
|
|
4709
4744
|
import { marked } from "marked";
|
|
4710
4745
|
import TerminalRenderer from "marked-terminal";
|
|
4711
4746
|
var renderer = new TerminalRenderer({
|
|
4712
4747
|
// Code styling
|
|
4713
|
-
code:
|
|
4714
|
-
codespan:
|
|
4748
|
+
code: chalk7.yellow,
|
|
4749
|
+
codespan: chalk7.yellow.dim,
|
|
4715
4750
|
// Block elements
|
|
4716
|
-
blockquote:
|
|
4717
|
-
html:
|
|
4718
|
-
heading:
|
|
4719
|
-
firstHeading:
|
|
4720
|
-
hr:
|
|
4751
|
+
blockquote: chalk7.green.italic,
|
|
4752
|
+
html: chalk7.gray,
|
|
4753
|
+
heading: chalk7.magenta.bold,
|
|
4754
|
+
firstHeading: chalk7.magenta.bold,
|
|
4755
|
+
hr: chalk7.gray,
|
|
4721
4756
|
// Lists
|
|
4722
|
-
listitem:
|
|
4757
|
+
listitem: chalk7.white,
|
|
4723
4758
|
list: (body) => body,
|
|
4724
4759
|
// Tables
|
|
4725
|
-
table:
|
|
4726
|
-
tablerow:
|
|
4727
|
-
tablecell:
|
|
4760
|
+
table: chalk7.white,
|
|
4761
|
+
tablerow: chalk7.white,
|
|
4762
|
+
tablecell: chalk7.white,
|
|
4728
4763
|
// Inline elements
|
|
4729
|
-
strong:
|
|
4730
|
-
em:
|
|
4731
|
-
del:
|
|
4732
|
-
link:
|
|
4733
|
-
href:
|
|
4764
|
+
strong: chalk7.bold,
|
|
4765
|
+
em: chalk7.italic,
|
|
4766
|
+
del: chalk7.strikethrough,
|
|
4767
|
+
link: chalk7.cyan.underline,
|
|
4768
|
+
href: chalk7.cyan,
|
|
4734
4769
|
// Other
|
|
4735
|
-
paragraph:
|
|
4736
|
-
image:
|
|
4770
|
+
paragraph: chalk7.white,
|
|
4771
|
+
image: chalk7.gray,
|
|
4737
4772
|
// Custom options
|
|
4738
4773
|
showSectionPrefix: false,
|
|
4739
4774
|
reflowText: true,
|
|
@@ -7427,7 +7462,7 @@ function createChatCommand() {
|
|
|
7427
7462
|
|
|
7428
7463
|
// src/commands/openai-keys.ts
|
|
7429
7464
|
import { Command as Command14 } from "commander";
|
|
7430
|
-
import
|
|
7465
|
+
import chalk8 from "chalk";
|
|
7431
7466
|
import boxen3 from "boxen";
|
|
7432
7467
|
function maskKey2(key) {
|
|
7433
7468
|
if (key.length <= 8) return "****";
|
|
@@ -7441,17 +7476,17 @@ async function handleOpenAiKeysCommand(options) {
|
|
|
7441
7476
|
}
|
|
7442
7477
|
const service = new LlmProxyService(config);
|
|
7443
7478
|
console.log(
|
|
7444
|
-
boxen3(
|
|
7479
|
+
boxen3(chalk8.cyan.bold("\u{1F4E1} Jai1 LLM Proxy - OpenAI Compatible API"), {
|
|
7445
7480
|
padding: { top: 0, bottom: 0, left: 1, right: 1 },
|
|
7446
7481
|
borderStyle: "round",
|
|
7447
7482
|
borderColor: "cyan"
|
|
7448
7483
|
})
|
|
7449
7484
|
);
|
|
7450
7485
|
console.log();
|
|
7451
|
-
console.log(
|
|
7452
|
-
console.log(` ${
|
|
7486
|
+
console.log(chalk8.bold("\u{1F511} API Credentials"));
|
|
7487
|
+
console.log(` ${chalk8.dim("BASE_URL:")} ${chalk8.white(service.getBaseUrl())}`);
|
|
7453
7488
|
console.log(
|
|
7454
|
-
` ${
|
|
7489
|
+
` ${chalk8.dim("API_KEY:")} ${options.full ? chalk8.green(service.getApiKey()) : chalk8.yellow(maskKey2(service.getApiKey()))}`
|
|
7455
7490
|
);
|
|
7456
7491
|
console.log();
|
|
7457
7492
|
try {
|
|
@@ -7460,39 +7495,39 @@ async function handleOpenAiKeysCommand(options) {
|
|
|
7460
7495
|
service.getLimits()
|
|
7461
7496
|
]);
|
|
7462
7497
|
const allowedModels = models.filter((m) => m.allowed);
|
|
7463
|
-
console.log(
|
|
7498
|
+
console.log(chalk8.bold("\u{1F4E6} Available Models"));
|
|
7464
7499
|
if (allowedModels.length === 0) {
|
|
7465
|
-
console.log(
|
|
7500
|
+
console.log(chalk8.dim(" Kh\xF4ng c\xF3 models kh\u1EA3 d\u1EE5ng"));
|
|
7466
7501
|
} else {
|
|
7467
7502
|
for (const model of allowedModels) {
|
|
7468
|
-
const usageText = model.dailyLimit !== void 0 && model.usedToday !== void 0 ?
|
|
7469
|
-
console.log(` ${
|
|
7503
|
+
const usageText = model.dailyLimit !== void 0 && model.usedToday !== void 0 ? chalk8.dim(` (${model.usedToday}/${model.dailyLimit} h\xF4m nay)`) : "";
|
|
7504
|
+
console.log(` ${chalk8.green("\u2713")} ${chalk8.white(model.id)}${usageText}`);
|
|
7470
7505
|
}
|
|
7471
7506
|
}
|
|
7472
7507
|
console.log();
|
|
7473
7508
|
const defaultModel = allowedModels[0]?.id || "gpt-4o";
|
|
7474
|
-
console.log(
|
|
7509
|
+
console.log(chalk8.bold("\u{1F4DD} Sample cURL"));
|
|
7475
7510
|
console.log();
|
|
7476
7511
|
const curlSample = options.full ? service.generateFullCurlSample(defaultModel) : service.generateCurlSample(defaultModel);
|
|
7477
7512
|
const curlLines = curlSample.split("\n");
|
|
7478
7513
|
for (const line of curlLines) {
|
|
7479
|
-
console.log(
|
|
7514
|
+
console.log(chalk8.dim(` ${line}`));
|
|
7480
7515
|
}
|
|
7481
7516
|
console.log();
|
|
7482
|
-
console.log(
|
|
7483
|
-
console.log(
|
|
7484
|
-
console.log(
|
|
7485
|
-
console.log(
|
|
7517
|
+
console.log(chalk8.bold("\u{1F4A1} C\xE1ch s\u1EED d\u1EE5ng"));
|
|
7518
|
+
console.log(chalk8.dim(" - Thay th\u1EBF OpenAI API URL v\xE0 API Key"));
|
|
7519
|
+
console.log(chalk8.dim(" - T\u01B0\u01A1ng th\xEDch: OpenAI SDK, LangChain, LlamaIndex, v.v."));
|
|
7520
|
+
console.log(chalk8.dim(' - Ch\u1EA1y "jai1 chat" \u0111\u1EC3 chat tr\u1EF1c ti\u1EBFp'));
|
|
7486
7521
|
if (!options.full) {
|
|
7487
|
-
console.log(
|
|
7522
|
+
console.log(chalk8.dim(' - Ch\u1EA1y "jai1 openai-keys --full" \u0111\u1EC3 hi\u1EC3n th\u1ECB API key \u0111\u1EA7y \u0111\u1EE7'));
|
|
7488
7523
|
}
|
|
7489
7524
|
} catch (error) {
|
|
7490
7525
|
console.log();
|
|
7491
7526
|
console.log(
|
|
7492
|
-
|
|
7493
|
-
|
|
7527
|
+
chalk8.red("\u274C L\u1ED7i khi l\u1EA5y th\xF4ng tin API:"),
|
|
7528
|
+
chalk8.dim(error instanceof Error ? error.message : String(error))
|
|
7494
7529
|
);
|
|
7495
|
-
console.log(
|
|
7530
|
+
console.log(chalk8.dim('\n\u{1F4A1} Ki\u1EC3m tra API URL v\xE0 access key v\u1EDBi "jai1 status"'));
|
|
7496
7531
|
}
|
|
7497
7532
|
}
|
|
7498
7533
|
function createOpenAiKeysCommand() {
|
|
@@ -7505,7 +7540,7 @@ function createOpenAiKeysCommand() {
|
|
|
7505
7540
|
// src/commands/stats.ts
|
|
7506
7541
|
import { Command as Command15 } from "commander";
|
|
7507
7542
|
import Table2 from "cli-table3";
|
|
7508
|
-
import
|
|
7543
|
+
import chalk9 from "chalk";
|
|
7509
7544
|
async function handleStatsCommand() {
|
|
7510
7545
|
const configService = new ConfigService();
|
|
7511
7546
|
const config = await configService.load();
|
|
@@ -7515,8 +7550,8 @@ async function handleStatsCommand() {
|
|
|
7515
7550
|
);
|
|
7516
7551
|
}
|
|
7517
7552
|
const service = new LlmProxyService(config);
|
|
7518
|
-
console.log(
|
|
7519
|
-
console.log(
|
|
7553
|
+
console.log(chalk9.bold("\n\u{1F4CA} Th\u1ED1ng K\xEA S\u1EED D\u1EE5ng LLM"));
|
|
7554
|
+
console.log(chalk9.dim("\u2500".repeat(45)));
|
|
7520
7555
|
try {
|
|
7521
7556
|
const [limits, usage7Days, usageToday] = await Promise.all([
|
|
7522
7557
|
service.getLimits(),
|
|
@@ -7526,7 +7561,7 @@ async function handleStatsCommand() {
|
|
|
7526
7561
|
const today = (/* @__PURE__ */ new Date()).toLocaleDateString("en-CA", {
|
|
7527
7562
|
timeZone: "Asia/Ho_Chi_Minh"
|
|
7528
7563
|
});
|
|
7529
|
-
console.log(
|
|
7564
|
+
console.log(chalk9.cyan("\n\u{1F4C5} Kho\u1EA3ng th\u1EDDi gian: 7 ng\xE0y qua\n"));
|
|
7530
7565
|
const usageByModel = /* @__PURE__ */ new Map();
|
|
7531
7566
|
let total7DaysRequests = 0;
|
|
7532
7567
|
usage7Days.data?.forEach((record) => {
|
|
@@ -7546,16 +7581,16 @@ async function handleStatsCommand() {
|
|
|
7546
7581
|
modelData.today = record.count;
|
|
7547
7582
|
}
|
|
7548
7583
|
});
|
|
7549
|
-
console.log(
|
|
7550
|
-
console.log(` T\u1ED5ng s\u1ED1 y\xEAu c\u1EA7u (7 ng\xE0y): ${
|
|
7584
|
+
console.log(chalk9.bold("\u{1F4C8} T\u1ED5ng quan s\u1EED d\u1EE5ng"));
|
|
7585
|
+
console.log(` T\u1ED5ng s\u1ED1 y\xEAu c\u1EA7u (7 ng\xE0y): ${chalk9.green(total7DaysRequests)}
|
|
7551
7586
|
`);
|
|
7552
|
-
console.log(
|
|
7587
|
+
console.log(chalk9.bold("\u{1F4E6} Th\u1ED1ng k\xEA theo model\n"));
|
|
7553
7588
|
const table = new Table2({
|
|
7554
7589
|
head: [
|
|
7555
|
-
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
7590
|
+
chalk9.bold("Model"),
|
|
7591
|
+
chalk9.bold("H\xF4m nay"),
|
|
7592
|
+
chalk9.bold("Gi\u1EDBi h\u1EA1n"),
|
|
7593
|
+
chalk9.bold("T\u1ED5ng 7 ng\xE0y")
|
|
7559
7594
|
],
|
|
7560
7595
|
style: {
|
|
7561
7596
|
head: ["cyan"],
|
|
@@ -7567,7 +7602,7 @@ async function handleStatsCommand() {
|
|
|
7567
7602
|
const rateLimits = limits.effectiveRateLimits || {};
|
|
7568
7603
|
if (allowedModels.length === 0) {
|
|
7569
7604
|
table.push([
|
|
7570
|
-
{ colSpan: 4, content:
|
|
7605
|
+
{ colSpan: 4, content: chalk9.yellow("Kh\xF4ng c\xF3 model n\xE0o kh\u1EA3 d\u1EE5ng") }
|
|
7571
7606
|
]);
|
|
7572
7607
|
} else {
|
|
7573
7608
|
allowedModels.forEach((modelId) => {
|
|
@@ -7576,25 +7611,25 @@ async function handleStatsCommand() {
|
|
|
7576
7611
|
const usagePercent = limit > 0 ? usage.today / limit : 0;
|
|
7577
7612
|
let todayDisplay = `${usage.today}/${limit}`;
|
|
7578
7613
|
if (usagePercent >= 0.9) {
|
|
7579
|
-
todayDisplay =
|
|
7614
|
+
todayDisplay = chalk9.red(todayDisplay);
|
|
7580
7615
|
} else if (usagePercent >= 0.7) {
|
|
7581
|
-
todayDisplay =
|
|
7616
|
+
todayDisplay = chalk9.yellow(todayDisplay);
|
|
7582
7617
|
} else {
|
|
7583
|
-
todayDisplay =
|
|
7618
|
+
todayDisplay = chalk9.green(todayDisplay);
|
|
7584
7619
|
}
|
|
7585
7620
|
table.push([modelId, todayDisplay, `${limit}/ng\xE0y`, String(usage.total7Days)]);
|
|
7586
7621
|
});
|
|
7587
7622
|
}
|
|
7588
7623
|
console.log(table.toString());
|
|
7589
7624
|
console.log(
|
|
7590
|
-
|
|
7625
|
+
chalk9.dim('\n\u{1F4A1} M\u1EB9o: Ch\u1EA1y "jai1 openai-keys" \u0111\u1EC3 xem danh s\xE1ch model kh\u1EA3 d\u1EE5ng')
|
|
7591
7626
|
);
|
|
7592
7627
|
} catch (error) {
|
|
7593
7628
|
console.error(
|
|
7594
|
-
|
|
7629
|
+
chalk9.red("\n\u274C Kh\xF4ng th\u1EC3 l\u1EA5y th\u1ED1ng k\xEA:"),
|
|
7595
7630
|
error instanceof Error ? error.message : String(error)
|
|
7596
7631
|
);
|
|
7597
|
-
console.log(
|
|
7632
|
+
console.log(chalk9.dim('\n\u{1F4A1} Ki\u1EC3m tra k\u1EBFt n\u1ED1i API v\u1EDBi "jai1 status"'));
|
|
7598
7633
|
}
|
|
7599
7634
|
}
|
|
7600
7635
|
function createStatsCommand() {
|
|
@@ -7961,7 +7996,7 @@ function createTranslateCommand() {
|
|
|
7961
7996
|
|
|
7962
7997
|
// src/commands/image/index.ts
|
|
7963
7998
|
import { Command as Command21 } from "commander";
|
|
7964
|
-
import
|
|
7999
|
+
import chalk10 from "chalk";
|
|
7965
8000
|
|
|
7966
8001
|
// src/commands/image/gen.ts
|
|
7967
8002
|
import { Command as Command17 } from "commander";
|
|
@@ -8236,22 +8271,22 @@ function createImageDeleteCommand() {
|
|
|
8236
8271
|
|
|
8237
8272
|
// src/commands/image/index.ts
|
|
8238
8273
|
function showImageHelp() {
|
|
8239
|
-
console.log(
|
|
8274
|
+
console.log(chalk10.bold.cyan("\u{1F3A8} jai1 image") + chalk10.dim(" - Image generation commands"));
|
|
8240
8275
|
console.log();
|
|
8241
|
-
console.log(
|
|
8276
|
+
console.log(chalk10.yellow("\u26A0\uFE0F Coming Soon - T\xEDnh n\u0103ng \u0111ang ph\xE1t tri\u1EC3n"));
|
|
8242
8277
|
console.log();
|
|
8243
|
-
console.log(
|
|
8244
|
-
console.log(` ${
|
|
8245
|
-
console.log(` ${
|
|
8246
|
-
console.log(` ${
|
|
8247
|
-
console.log(` ${
|
|
8278
|
+
console.log(chalk10.bold("C\xE1c l\u1EC7nh:"));
|
|
8279
|
+
console.log(` ${chalk10.cyan("gen")} T\u1EA1o \u1EA3nh t\u1EEB prompt`);
|
|
8280
|
+
console.log(` ${chalk10.cyan("list")} Li\u1EC7t k\xEA c\xE1c \u1EA3nh \u0111\xE3 t\u1EA1o`);
|
|
8281
|
+
console.log(` ${chalk10.cyan("info")} Xem th\xF4ng tin \u1EA3nh`);
|
|
8282
|
+
console.log(` ${chalk10.cyan("delete")} X\xF3a \u1EA3nh`);
|
|
8248
8283
|
console.log();
|
|
8249
|
-
console.log(
|
|
8250
|
-
console.log(
|
|
8251
|
-
console.log(
|
|
8252
|
-
console.log(
|
|
8284
|
+
console.log(chalk10.bold("V\xED d\u1EE5:"));
|
|
8285
|
+
console.log(chalk10.dim(' $ jai1 image gen "a cute cat"'));
|
|
8286
|
+
console.log(chalk10.dim(" $ jai1 image list"));
|
|
8287
|
+
console.log(chalk10.dim(" $ jai1 image info <image-id>"));
|
|
8253
8288
|
console.log();
|
|
8254
|
-
console.log(
|
|
8289
|
+
console.log(chalk10.dim('Ch\u1EA1y "jai1 image <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
|
|
8255
8290
|
}
|
|
8256
8291
|
function createImageCommand() {
|
|
8257
8292
|
const cmd = new Command21("image").description("Image generation commands (Coming Soon)").action(() => {
|
|
@@ -8482,7 +8517,7 @@ function createFeedbackCommand() {
|
|
|
8482
8517
|
|
|
8483
8518
|
// src/commands/utils/index.ts
|
|
8484
8519
|
import { Command as Command36 } from "commander";
|
|
8485
|
-
import
|
|
8520
|
+
import chalk11 from "chalk";
|
|
8486
8521
|
|
|
8487
8522
|
// src/commands/utils/password.ts
|
|
8488
8523
|
import { Command as Command23 } from "commander";
|
|
@@ -10800,40 +10835,40 @@ async function runInteractiveMode() {
|
|
|
10800
10835
|
|
|
10801
10836
|
// src/commands/utils/index.ts
|
|
10802
10837
|
function showUtilsHelp() {
|
|
10803
|
-
console.log(
|
|
10838
|
+
console.log(chalk11.bold.cyan("\u{1F6E0}\uFE0F jai1 utils") + chalk11.dim(" - Developer utilities"));
|
|
10804
10839
|
console.log();
|
|
10805
|
-
console.log(
|
|
10806
|
-
console.log(` ${
|
|
10807
|
-
console.log(` ${
|
|
10808
|
-
console.log(` ${
|
|
10809
|
-
console.log(` ${
|
|
10840
|
+
console.log(chalk11.bold("M\xE3 h\xF3a & B\u1EA3o m\u1EADt:"));
|
|
10841
|
+
console.log(` ${chalk11.cyan("password")} T\u1EA1o m\u1EADt kh\u1EA9u ng\u1EABu nhi\xEAn`);
|
|
10842
|
+
console.log(` ${chalk11.cyan("uuid")} T\u1EA1o UUID v4`);
|
|
10843
|
+
console.log(` ${chalk11.cyan("hash")} Hash text (MD5/SHA/bcrypt)`);
|
|
10844
|
+
console.log(` ${chalk11.cyan("jwt")} Decode/encode JWT tokens`);
|
|
10810
10845
|
console.log();
|
|
10811
|
-
console.log(
|
|
10812
|
-
console.log(` ${
|
|
10813
|
-
console.log(` ${
|
|
10814
|
-
console.log(` ${
|
|
10815
|
-
console.log(` ${
|
|
10846
|
+
console.log(chalk11.bold("Encoding:"));
|
|
10847
|
+
console.log(` ${chalk11.cyan("base64-encode")} Encode sang Base64`);
|
|
10848
|
+
console.log(` ${chalk11.cyan("base64-decode")} Decode t\u1EEB Base64`);
|
|
10849
|
+
console.log(` ${chalk11.cyan("url-encode")} Encode URL components`);
|
|
10850
|
+
console.log(` ${chalk11.cyan("url-decode")} Decode URL components`);
|
|
10816
10851
|
console.log();
|
|
10817
|
-
console.log(
|
|
10818
|
-
console.log(` ${
|
|
10819
|
-
console.log(` ${
|
|
10820
|
-
console.log(` ${
|
|
10852
|
+
console.log(chalk11.bold("Th\u1EDDi gian:"));
|
|
10853
|
+
console.log(` ${chalk11.cyan("unix-time")} Chuy\u1EC3n \u0111\u1ED5i unix timestamp`);
|
|
10854
|
+
console.log(` ${chalk11.cyan("timezone")} Chuy\u1EC3n \u0111\u1ED5i m\xFAi gi\u1EDD`);
|
|
10855
|
+
console.log(` ${chalk11.cyan("cron")} Parse cron expressions`);
|
|
10821
10856
|
console.log();
|
|
10822
|
-
console.log(
|
|
10823
|
-
console.log(` ${
|
|
10824
|
-
console.log(` ${
|
|
10857
|
+
console.log(chalk11.bold("Kh\xE1c:"));
|
|
10858
|
+
console.log(` ${chalk11.cyan("http")} G\u1EEDi HTTP requests`);
|
|
10859
|
+
console.log(` ${chalk11.cyan("markdown-preview")} Xem tr\u01B0\u1EDBc file markdown`);
|
|
10825
10860
|
console.log();
|
|
10826
|
-
console.log(
|
|
10827
|
-
console.log(
|
|
10828
|
-
console.log(
|
|
10861
|
+
console.log(chalk11.bold("Ch\u1EBF \u0111\u1ED9 Interactive:"));
|
|
10862
|
+
console.log(chalk11.dim(" $ jai1 utils -i"));
|
|
10863
|
+
console.log(chalk11.dim(" $ jai1 utils --interactive"));
|
|
10829
10864
|
console.log();
|
|
10830
|
-
console.log(
|
|
10831
|
-
console.log(
|
|
10832
|
-
console.log(
|
|
10833
|
-
console.log(
|
|
10834
|
-
console.log(
|
|
10865
|
+
console.log(chalk11.bold("V\xED d\u1EE5:"));
|
|
10866
|
+
console.log(chalk11.dim(" $ jai1 utils password --length 24"));
|
|
10867
|
+
console.log(chalk11.dim(" $ jai1 utils uuid --count 5"));
|
|
10868
|
+
console.log(chalk11.dim(' $ jai1 utils hash "text" --algorithm sha256'));
|
|
10869
|
+
console.log(chalk11.dim(" $ jai1 utils http https://api.example.com"));
|
|
10835
10870
|
console.log();
|
|
10836
|
-
console.log(
|
|
10871
|
+
console.log(chalk11.dim('Ch\u1EA1y "jai1 utils <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
|
|
10837
10872
|
}
|
|
10838
10873
|
function createUtilsCommand() {
|
|
10839
10874
|
const utilsCommand = new Command36("utils").description("Developer utilities for common tasks").option("-i, --interactive", "Run in interactive mode");
|
|
@@ -10862,11 +10897,11 @@ function createUtilsCommand() {
|
|
|
10862
10897
|
|
|
10863
10898
|
// src/commands/deps/index.ts
|
|
10864
10899
|
import { Command as Command39 } from "commander";
|
|
10865
|
-
import
|
|
10900
|
+
import chalk14 from "chalk";
|
|
10866
10901
|
|
|
10867
10902
|
// src/commands/deps/check.ts
|
|
10868
10903
|
import { Command as Command37 } from "commander";
|
|
10869
|
-
import
|
|
10904
|
+
import chalk12 from "chalk";
|
|
10870
10905
|
import Table3 from "cli-table3";
|
|
10871
10906
|
import ora from "ora";
|
|
10872
10907
|
|
|
@@ -11469,7 +11504,7 @@ function createDepsCheckCommand() {
|
|
|
11469
11504
|
if (projects.length === 0) {
|
|
11470
11505
|
spinner.fail("Kh\xF4ng t\xECm th\u1EA5y project n\xE0o \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3");
|
|
11471
11506
|
console.log();
|
|
11472
|
-
console.log(
|
|
11507
|
+
console.log(chalk12.dim("H\u1ED7 tr\u1EE3: Node.js (package.json), PHP (composer.json), Python (requirements.txt/Pipfile)"));
|
|
11473
11508
|
process.exit(1);
|
|
11474
11509
|
}
|
|
11475
11510
|
spinner.succeed(`Ph\xE1t hi\u1EC7n ${projects.length} project:`);
|
|
@@ -11483,7 +11518,7 @@ function createDepsCheckCommand() {
|
|
|
11483
11518
|
await checkEcosystem(project.ecosystem, project.manager, cwd);
|
|
11484
11519
|
}
|
|
11485
11520
|
console.log();
|
|
11486
|
-
console.log(
|
|
11521
|
+
console.log(chalk12.dim('\u{1F4A1} Ch\u1EA1y "jai1 deps upgrade" \u0111\u1EC3 n\xE2ng c\u1EA5p packages.'));
|
|
11487
11522
|
});
|
|
11488
11523
|
return checkCommand;
|
|
11489
11524
|
}
|
|
@@ -11516,7 +11551,7 @@ async function checkEcosystem(ecosystem, manager, cwd) {
|
|
|
11516
11551
|
});
|
|
11517
11552
|
} catch (error) {
|
|
11518
11553
|
spinner.fail(`L\u1ED7i ki\u1EC3m tra ${label}`);
|
|
11519
|
-
console.log(
|
|
11554
|
+
console.log(chalk12.red(error.message));
|
|
11520
11555
|
console.log();
|
|
11521
11556
|
return;
|
|
11522
11557
|
}
|
|
@@ -11529,10 +11564,10 @@ async function checkEcosystem(ecosystem, manager, cwd) {
|
|
|
11529
11564
|
console.log();
|
|
11530
11565
|
const table = new Table3({
|
|
11531
11566
|
head: [
|
|
11532
|
-
|
|
11533
|
-
|
|
11534
|
-
|
|
11535
|
-
|
|
11567
|
+
chalk12.cyan("Package"),
|
|
11568
|
+
chalk12.cyan("Hi\u1EC7n t\u1EA1i"),
|
|
11569
|
+
chalk12.cyan("M\u1EDBi nh\u1EA5t"),
|
|
11570
|
+
chalk12.cyan("Lo\u1EA1i")
|
|
11536
11571
|
],
|
|
11537
11572
|
style: {
|
|
11538
11573
|
head: [],
|
|
@@ -11543,9 +11578,9 @@ async function checkEcosystem(ecosystem, manager, cwd) {
|
|
|
11543
11578
|
const upgradeIcon = pkg.upgradeType === "major" ? "\u{1F534}" : pkg.upgradeType === "minor" ? "\u{1F7E1}" : "\u{1F7E2}";
|
|
11544
11579
|
table.push([
|
|
11545
11580
|
`${upgradeIcon} ${pkg.name}`,
|
|
11546
|
-
|
|
11547
|
-
|
|
11548
|
-
pkg.type === "dev" ?
|
|
11581
|
+
chalk12.dim(pkg.current),
|
|
11582
|
+
chalk12.green(pkg.latest),
|
|
11583
|
+
pkg.type === "dev" ? chalk12.dim("dev") : "dep"
|
|
11549
11584
|
]);
|
|
11550
11585
|
}
|
|
11551
11586
|
console.log(table.toString());
|
|
@@ -11553,13 +11588,13 @@ async function checkEcosystem(ecosystem, manager, cwd) {
|
|
|
11553
11588
|
if (result.isLaravel) {
|
|
11554
11589
|
const blockedPackages = result.packages.filter((p) => p.blockedReason);
|
|
11555
11590
|
if (blockedPackages.length > 0) {
|
|
11556
|
-
console.log(
|
|
11591
|
+
console.log(chalk12.yellow("\u26A0\uFE0F Laravel major version upgrades blocked (nguy hi\u1EC3m):"));
|
|
11557
11592
|
for (const pkg of blockedPackages) {
|
|
11558
|
-
console.log(
|
|
11593
|
+
console.log(chalk12.dim(` - ${pkg.name}: ${pkg.current} \u2192 ${pkg.latest}`));
|
|
11559
11594
|
}
|
|
11560
11595
|
console.log();
|
|
11561
|
-
console.log(
|
|
11562
|
-
console.log(
|
|
11596
|
+
console.log(chalk12.dim("\u{1F4A1} \u0110\u1EC3 n\xE2ng c\u1EA5p Laravel major version, ch\u1EA1y th\u1EE7 c\xF4ng:"));
|
|
11597
|
+
console.log(chalk12.dim(` composer require ${blockedPackages[0].name}:^${blockedPackages[0].latest}`));
|
|
11563
11598
|
console.log();
|
|
11564
11599
|
}
|
|
11565
11600
|
}
|
|
@@ -11568,7 +11603,7 @@ async function checkEcosystem(ecosystem, manager, cwd) {
|
|
|
11568
11603
|
// src/commands/deps/upgrade.ts
|
|
11569
11604
|
import { Command as Command38 } from "commander";
|
|
11570
11605
|
import { checkbox as checkbox3, confirm as confirm6 } from "@inquirer/prompts";
|
|
11571
|
-
import
|
|
11606
|
+
import chalk13 from "chalk";
|
|
11572
11607
|
import ora2 from "ora";
|
|
11573
11608
|
import Table4 from "cli-table3";
|
|
11574
11609
|
function createDepsUpgradeCommand() {
|
|
@@ -11585,7 +11620,7 @@ async function handleDepsUpgrade(options) {
|
|
|
11585
11620
|
if (projects.length === 0) {
|
|
11586
11621
|
spinner.fail("Kh\xF4ng t\xECm th\u1EA5y project n\xE0o \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3");
|
|
11587
11622
|
console.log();
|
|
11588
|
-
console.log(
|
|
11623
|
+
console.log(chalk13.dim("H\u1ED7 tr\u1EE3: Node.js (package.json), PHP (composer.json), Python (requirements.txt/Pipfile)"));
|
|
11589
11624
|
process.exit(1);
|
|
11590
11625
|
}
|
|
11591
11626
|
spinner.succeed(`Ph\xE1t hi\u1EC7n ${projects.length} project:`);
|
|
@@ -11599,9 +11634,9 @@ async function handleDepsUpgrade(options) {
|
|
|
11599
11634
|
await upgradeEcosystem(project, cwd, options);
|
|
11600
11635
|
}
|
|
11601
11636
|
console.log();
|
|
11602
|
-
console.log(
|
|
11637
|
+
console.log(chalk13.green("\u2705 Ho\xE0n th\xE0nh!"));
|
|
11603
11638
|
} catch (error) {
|
|
11604
|
-
console.error(
|
|
11639
|
+
console.error(chalk13.red(`
|
|
11605
11640
|
\u274C ${error.message}
|
|
11606
11641
|
`));
|
|
11607
11642
|
process.exit(1);
|
|
@@ -11610,10 +11645,10 @@ async function handleDepsUpgrade(options) {
|
|
|
11610
11645
|
async function upgradeEcosystem(project, cwd, options) {
|
|
11611
11646
|
const service = getService(project.ecosystem);
|
|
11612
11647
|
const label = `${getEcosystemIcon(project.ecosystem)} ${getEcosystemLabel(project.ecosystem)}`;
|
|
11613
|
-
console.log(
|
|
11648
|
+
console.log(chalk13.bold.cyan(`
|
|
11614
11649
|
${"\u2501".repeat(80)}`));
|
|
11615
|
-
console.log(
|
|
11616
|
-
console.log(
|
|
11650
|
+
console.log(chalk13.bold.cyan(`${label}`));
|
|
11651
|
+
console.log(chalk13.bold.cyan("\u2501".repeat(80)));
|
|
11617
11652
|
console.log();
|
|
11618
11653
|
const spinner = ora2("\u0110ang ki\u1EC3m tra packages...").start();
|
|
11619
11654
|
let packages;
|
|
@@ -11624,7 +11659,7 @@ ${"\u2501".repeat(80)}`));
|
|
|
11624
11659
|
packages = result.packages;
|
|
11625
11660
|
} catch (error) {
|
|
11626
11661
|
spinner.fail("L\u1ED7i ki\u1EC3m tra packages");
|
|
11627
|
-
console.log(
|
|
11662
|
+
console.log(chalk13.red(error.message));
|
|
11628
11663
|
return;
|
|
11629
11664
|
}
|
|
11630
11665
|
if (packages.length === 0) {
|
|
@@ -11637,7 +11672,7 @@ ${"\u2501".repeat(80)}`));
|
|
|
11637
11672
|
let selectedPackages;
|
|
11638
11673
|
if (options.all) {
|
|
11639
11674
|
selectedPackages = packages;
|
|
11640
|
-
console.log(
|
|
11675
|
+
console.log(chalk13.cyan(`\u{1F4CB} \u0110\xE3 ch\u1ECDn t\u1EA5t c\u1EA3 ${selectedPackages.length} packages
|
|
11641
11676
|
`));
|
|
11642
11677
|
} else {
|
|
11643
11678
|
try {
|
|
@@ -11655,12 +11690,12 @@ ${"\u2501".repeat(80)}`));
|
|
|
11655
11690
|
theme: checkboxTheme
|
|
11656
11691
|
});
|
|
11657
11692
|
if (selected.length === 0) {
|
|
11658
|
-
console.log(
|
|
11693
|
+
console.log(chalk13.yellow("\u23F8\uFE0F Kh\xF4ng c\xF3 packages n\xE0o \u0111\u01B0\u1EE3c ch\u1ECDn\n"));
|
|
11659
11694
|
return;
|
|
11660
11695
|
}
|
|
11661
11696
|
selectedPackages = packages.filter((p) => selected.includes(p.name));
|
|
11662
11697
|
} catch {
|
|
11663
|
-
console.log(
|
|
11698
|
+
console.log(chalk13.yellow("\n\u23F8\uFE0F \u0110\xE3 h\u1EE7y\n"));
|
|
11664
11699
|
return;
|
|
11665
11700
|
}
|
|
11666
11701
|
}
|
|
@@ -11671,35 +11706,35 @@ ${"\u2501".repeat(80)}`));
|
|
|
11671
11706
|
default: true
|
|
11672
11707
|
});
|
|
11673
11708
|
} catch {
|
|
11674
|
-
console.log(
|
|
11709
|
+
console.log(chalk13.yellow("\n\u23F8\uFE0F \u0110\xE3 h\u1EE7y\n"));
|
|
11675
11710
|
return;
|
|
11676
11711
|
}
|
|
11677
11712
|
if (!shouldProceed) {
|
|
11678
|
-
console.log(
|
|
11713
|
+
console.log(chalk13.yellow("\u23F8\uFE0F Upgrade \u0111\xE3 h\u1EE7y\n"));
|
|
11679
11714
|
return;
|
|
11680
11715
|
}
|
|
11681
11716
|
console.log();
|
|
11682
|
-
console.log(
|
|
11683
|
-
console.log(
|
|
11717
|
+
console.log(chalk13.cyan(`\u{1F527} Package manager: ${project.manager}`));
|
|
11718
|
+
console.log(chalk13.cyan("\u{1F4E5} \u0110ang upgrade...\n"));
|
|
11684
11719
|
const commands = service.getUpgradeCommands(selectedPackages);
|
|
11685
11720
|
try {
|
|
11686
11721
|
if (commands.deps) {
|
|
11687
|
-
console.log(
|
|
11722
|
+
console.log(chalk13.dim(`$ ${commands.deps}
|
|
11688
11723
|
`));
|
|
11689
11724
|
}
|
|
11690
11725
|
if (commands.devDeps) {
|
|
11691
|
-
console.log(
|
|
11726
|
+
console.log(chalk13.dim(`$ ${commands.devDeps}
|
|
11692
11727
|
`));
|
|
11693
11728
|
}
|
|
11694
11729
|
await service.upgrade(cwd, { packages: selectedPackages });
|
|
11695
|
-
console.log(
|
|
11730
|
+
console.log(chalk13.green(`
|
|
11696
11731
|
\u2705 \u0110\xE3 upgrade ${selectedPackages.length} packages th\xE0nh c\xF4ng!`));
|
|
11697
11732
|
} catch (error) {
|
|
11698
|
-
console.error(
|
|
11699
|
-
console.error(
|
|
11700
|
-
console.log(
|
|
11701
|
-
if (commands.deps) console.log(
|
|
11702
|
-
if (commands.devDeps) console.log(
|
|
11733
|
+
console.error(chalk13.red("\n\u274C L\u1ED7i khi upgrade:"));
|
|
11734
|
+
console.error(chalk13.red(error.message));
|
|
11735
|
+
console.log(chalk13.yellow("\n\u{1F4A1} B\u1EA1n c\xF3 th\u1EC3 th\u1EED upgrade th\u1EE7 c\xF4ng:"));
|
|
11736
|
+
if (commands.deps) console.log(chalk13.cyan(` ${commands.deps}`));
|
|
11737
|
+
if (commands.devDeps) console.log(chalk13.cyan(` ${commands.devDeps}`));
|
|
11703
11738
|
console.log();
|
|
11704
11739
|
throw error;
|
|
11705
11740
|
}
|
|
@@ -11707,10 +11742,10 @@ ${"\u2501".repeat(80)}`));
|
|
|
11707
11742
|
function displayUpgradeTable(packages) {
|
|
11708
11743
|
const table = new Table4({
|
|
11709
11744
|
head: [
|
|
11710
|
-
|
|
11711
|
-
|
|
11712
|
-
|
|
11713
|
-
|
|
11745
|
+
chalk13.cyan("Package"),
|
|
11746
|
+
chalk13.cyan("Hi\u1EC7n t\u1EA1i"),
|
|
11747
|
+
chalk13.cyan("M\u1EDBi nh\u1EA5t"),
|
|
11748
|
+
chalk13.cyan("Lo\u1EA1i")
|
|
11714
11749
|
],
|
|
11715
11750
|
style: {
|
|
11716
11751
|
head: [],
|
|
@@ -11721,9 +11756,9 @@ function displayUpgradeTable(packages) {
|
|
|
11721
11756
|
const upgradeIcon = pkg.upgradeType === "major" ? "\u{1F534}" : pkg.upgradeType === "minor" ? "\u{1F7E1}" : "\u{1F7E2}";
|
|
11722
11757
|
table.push([
|
|
11723
11758
|
`${upgradeIcon} ${pkg.name}`,
|
|
11724
|
-
|
|
11725
|
-
|
|
11726
|
-
pkg.type === "dev" ?
|
|
11759
|
+
chalk13.dim(pkg.current),
|
|
11760
|
+
chalk13.green(pkg.latest),
|
|
11761
|
+
pkg.type === "dev" ? chalk13.dim("dev") : "dep"
|
|
11727
11762
|
]);
|
|
11728
11763
|
}
|
|
11729
11764
|
console.log(table.toString());
|
|
@@ -11766,23 +11801,23 @@ function getEcosystemLabel(ecosystem) {
|
|
|
11766
11801
|
|
|
11767
11802
|
// src/commands/deps/index.ts
|
|
11768
11803
|
function showDepsHelp() {
|
|
11769
|
-
console.log(
|
|
11804
|
+
console.log(chalk14.bold.cyan("\u{1F4E6} jai1 deps") + chalk14.dim(" - Qu\u1EA3n l\xFD dependencies trong project"));
|
|
11770
11805
|
console.log();
|
|
11771
|
-
console.log(
|
|
11772
|
-
console.log(` ${
|
|
11773
|
-
console.log(` ${
|
|
11806
|
+
console.log(chalk14.bold("C\xE1c l\u1EC7nh:"));
|
|
11807
|
+
console.log(` ${chalk14.cyan("check")} Ki\u1EC3m tra c\xE1c packages c\u1EA7n upgrade`);
|
|
11808
|
+
console.log(` ${chalk14.cyan("upgrade")} N\xE2ng c\u1EA5p dependencies l\xEAn phi\xEAn b\u1EA3n m\u1EDBi nh\u1EA5t`);
|
|
11774
11809
|
console.log();
|
|
11775
|
-
console.log(
|
|
11776
|
-
console.log(
|
|
11777
|
-
console.log(
|
|
11778
|
-
console.log(
|
|
11810
|
+
console.log(chalk14.bold("H\u1ED7 tr\u1EE3:"));
|
|
11811
|
+
console.log(chalk14.dim(" \u2022 Node.js (npm, pnpm, yarn, bun)"));
|
|
11812
|
+
console.log(chalk14.dim(" \u2022 PHP/Composer (v\u1EDBi b\u1EA3o v\u1EC7 Laravel major version)"));
|
|
11813
|
+
console.log(chalk14.dim(" \u2022 Python (pip, pipenv)"));
|
|
11779
11814
|
console.log();
|
|
11780
|
-
console.log(
|
|
11781
|
-
console.log(
|
|
11782
|
-
console.log(
|
|
11783
|
-
console.log(
|
|
11815
|
+
console.log(chalk14.bold("V\xED d\u1EE5:"));
|
|
11816
|
+
console.log(chalk14.dim(" $ jai1 deps check"));
|
|
11817
|
+
console.log(chalk14.dim(" $ jai1 deps upgrade"));
|
|
11818
|
+
console.log(chalk14.dim(" $ jai1 deps upgrade --all"));
|
|
11784
11819
|
console.log();
|
|
11785
|
-
console.log(
|
|
11820
|
+
console.log(chalk14.dim('Ch\u1EA1y "jai1 deps <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
|
|
11786
11821
|
}
|
|
11787
11822
|
function createDepsCommand() {
|
|
11788
11823
|
const depsCommand = new Command39("deps").description("Qu\u1EA3n l\xFD dependencies trong project").action(() => {
|
|
@@ -11795,11 +11830,11 @@ function createDepsCommand() {
|
|
|
11795
11830
|
|
|
11796
11831
|
// src/commands/kit/index.ts
|
|
11797
11832
|
import { Command as Command43 } from "commander";
|
|
11798
|
-
import
|
|
11833
|
+
import chalk16 from "chalk";
|
|
11799
11834
|
|
|
11800
11835
|
// src/commands/kit/list.ts
|
|
11801
11836
|
import { Command as Command40 } from "commander";
|
|
11802
|
-
import
|
|
11837
|
+
import chalk15 from "chalk";
|
|
11803
11838
|
import Table5 from "cli-table3";
|
|
11804
11839
|
|
|
11805
11840
|
// src/services/starter-kit.service.ts
|
|
@@ -11873,7 +11908,7 @@ function createKitListCommand() {
|
|
|
11873
11908
|
if (!config) {
|
|
11874
11909
|
throw new ValidationError('Not initialized. Run "jai1 auth" first.');
|
|
11875
11910
|
}
|
|
11876
|
-
console.log(
|
|
11911
|
+
console.log(chalk15.cyan("\u{1F4E6} \u0110ang t\u1EA3i danh s\xE1ch starter kits..."));
|
|
11877
11912
|
console.log();
|
|
11878
11913
|
const kitService = new StarterKitService();
|
|
11879
11914
|
const kits = await kitService.list(config, {
|
|
@@ -11881,9 +11916,9 @@ function createKitListCommand() {
|
|
|
11881
11916
|
search: options.search
|
|
11882
11917
|
});
|
|
11883
11918
|
if (kits.length === 0) {
|
|
11884
|
-
console.log(
|
|
11919
|
+
console.log(chalk15.yellow("Kh\xF4ng t\xECm th\u1EA5y starter kits n\xE0o."));
|
|
11885
11920
|
if (options.category || options.search) {
|
|
11886
|
-
console.log(
|
|
11921
|
+
console.log(chalk15.dim("Th\u1EED b\u1ECF filter \u0111\u1EC3 xem t\u1EA5t c\u1EA3."));
|
|
11887
11922
|
}
|
|
11888
11923
|
return;
|
|
11889
11924
|
}
|
|
@@ -11907,28 +11942,28 @@ function createKitListCommand() {
|
|
|
11907
11942
|
const categoryKits = byCategory[category];
|
|
11908
11943
|
const categoryIcon = category === "frontend" ? "\u{1F3A8}" : category === "backend" ? "\u2699\uFE0F" : category === "fullstack" ? "\u{1F680}" : "\u{1F4E6}";
|
|
11909
11944
|
console.log(
|
|
11910
|
-
|
|
11945
|
+
chalk15.bold(`${categoryIcon} ${category.charAt(0).toUpperCase() + category.slice(1)}`)
|
|
11911
11946
|
);
|
|
11912
11947
|
const table = new Table5({
|
|
11913
11948
|
head: [
|
|
11914
|
-
|
|
11915
|
-
|
|
11916
|
-
|
|
11949
|
+
chalk15.cyan("Slug"),
|
|
11950
|
+
chalk15.cyan("M\xF4 t\u1EA3"),
|
|
11951
|
+
chalk15.cyan("Version")
|
|
11917
11952
|
],
|
|
11918
11953
|
style: { head: [], border: ["gray"] }
|
|
11919
11954
|
});
|
|
11920
11955
|
for (const kit of categoryKits) {
|
|
11921
11956
|
table.push([
|
|
11922
|
-
|
|
11923
|
-
|
|
11924
|
-
|
|
11957
|
+
chalk15.white(kit.slug),
|
|
11958
|
+
chalk15.dim(kit.description.slice(0, 50)),
|
|
11959
|
+
chalk15.green(`v${kit.version}`)
|
|
11925
11960
|
]);
|
|
11926
11961
|
}
|
|
11927
11962
|
console.log(table.toString());
|
|
11928
11963
|
console.log();
|
|
11929
11964
|
}
|
|
11930
|
-
console.log(
|
|
11931
|
-
console.log(
|
|
11965
|
+
console.log(chalk15.dim(`T\u1ED5ng c\u1ED9ng: ${kits.length} starter kit(s)`));
|
|
11966
|
+
console.log(chalk15.dim('\n\u{1F4A1} Ch\u1EA1y "jai1 kit create <slug>" \u0111\u1EC3 t\u1EA1o project m\u1EDBi'));
|
|
11932
11967
|
});
|
|
11933
11968
|
}
|
|
11934
11969
|
|
|
@@ -12208,20 +12243,20 @@ async function getAllFiles(dir) {
|
|
|
12208
12243
|
|
|
12209
12244
|
// src/commands/kit/index.ts
|
|
12210
12245
|
function showKitHelp() {
|
|
12211
|
-
console.log(
|
|
12246
|
+
console.log(chalk16.bold.cyan("\u{1F4E6} jai1 kit") + chalk16.dim(" - Qu\u1EA3n l\xFD starter kits"));
|
|
12212
12247
|
console.log();
|
|
12213
|
-
console.log(
|
|
12214
|
-
console.log(` ${
|
|
12215
|
-
console.log(` ${
|
|
12216
|
-
console.log(` ${
|
|
12248
|
+
console.log(chalk16.bold("C\xE1c l\u1EC7nh:"));
|
|
12249
|
+
console.log(` ${chalk16.cyan("list")} Li\u1EC7t k\xEA c\xE1c starter kits c\xF3 s\u1EB5n`);
|
|
12250
|
+
console.log(` ${chalk16.cyan("info")} Xem chi ti\u1EBFt m\u1ED9t starter kit`);
|
|
12251
|
+
console.log(` ${chalk16.cyan("create")} T\u1EA1o project m\u1EDBi t\u1EEB starter kit`);
|
|
12217
12252
|
console.log();
|
|
12218
|
-
console.log(
|
|
12219
|
-
console.log(
|
|
12220
|
-
console.log(
|
|
12221
|
-
console.log(
|
|
12222
|
-
console.log(
|
|
12253
|
+
console.log(chalk16.bold("V\xED d\u1EE5:"));
|
|
12254
|
+
console.log(chalk16.dim(" $ jai1 kit list"));
|
|
12255
|
+
console.log(chalk16.dim(" $ jai1 kit list --category frontend"));
|
|
12256
|
+
console.log(chalk16.dim(" $ jai1 kit info next-tw4-shadcn"));
|
|
12257
|
+
console.log(chalk16.dim(" $ jai1 kit create next-tw4-shadcn my-project"));
|
|
12223
12258
|
console.log();
|
|
12224
|
-
console.log(
|
|
12259
|
+
console.log(chalk16.dim('Ch\u1EA1y "jai1 kit <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
|
|
12225
12260
|
}
|
|
12226
12261
|
function createKitCommand() {
|
|
12227
12262
|
const cmd = new Command43("kit").description("Manage starter kits for new projects").action(() => {
|
|
@@ -12235,11 +12270,11 @@ function createKitCommand() {
|
|
|
12235
12270
|
|
|
12236
12271
|
// src/commands/rules/index.ts
|
|
12237
12272
|
import { Command as Command50 } from "commander";
|
|
12238
|
-
import
|
|
12273
|
+
import chalk18 from "chalk";
|
|
12239
12274
|
|
|
12240
12275
|
// src/commands/rules/list.ts
|
|
12241
12276
|
import { Command as Command44 } from "commander";
|
|
12242
|
-
import
|
|
12277
|
+
import chalk17 from "chalk";
|
|
12243
12278
|
import Table6 from "cli-table3";
|
|
12244
12279
|
function createRulesListCommand() {
|
|
12245
12280
|
return new Command44("list").description("List available rule presets").option("--json", "Output as JSON").action(async (options) => {
|
|
@@ -12248,7 +12283,7 @@ function createRulesListCommand() {
|
|
|
12248
12283
|
if (!config) {
|
|
12249
12284
|
throw new ValidationError('Not initialized. Run "jai1 auth" first.');
|
|
12250
12285
|
}
|
|
12251
|
-
console.log(
|
|
12286
|
+
console.log(chalk17.cyan("\u{1F4CB} \u0110ang t\u1EA3i danh s\xE1ch rule presets..."));
|
|
12252
12287
|
console.log();
|
|
12253
12288
|
try {
|
|
12254
12289
|
const response = await fetch(`${config.apiUrl}/api/rules/presets`, {
|
|
@@ -12265,23 +12300,23 @@ function createRulesListCommand() {
|
|
|
12265
12300
|
return;
|
|
12266
12301
|
}
|
|
12267
12302
|
if (data.total === 0) {
|
|
12268
|
-
console.log(
|
|
12303
|
+
console.log(chalk17.yellow("Kh\xF4ng c\xF3 presets n\xE0o."));
|
|
12269
12304
|
return;
|
|
12270
12305
|
}
|
|
12271
12306
|
console.log(
|
|
12272
|
-
|
|
12307
|
+
chalk17.green(`\u2713 T\xECm th\u1EA5y ${chalk17.bold(data.total)} preset${data.total > 1 ? "s" : ""}`)
|
|
12273
12308
|
);
|
|
12274
12309
|
console.log();
|
|
12275
12310
|
for (const preset of data.presets) {
|
|
12276
|
-
console.log(
|
|
12311
|
+
console.log(chalk17.bold.cyan(`\u{1F4E6} ${preset.slug}`));
|
|
12277
12312
|
const table = new Table6({
|
|
12278
12313
|
style: { head: [], border: ["gray"], compact: true },
|
|
12279
12314
|
colWidths: [15, 55]
|
|
12280
12315
|
});
|
|
12281
12316
|
table.push(
|
|
12282
|
-
[
|
|
12283
|
-
[
|
|
12284
|
-
[
|
|
12317
|
+
[chalk17.dim("T\xEAn"), chalk17.white(preset.name)],
|
|
12318
|
+
[chalk17.dim("M\xF4 t\u1EA3"), chalk17.white(preset.description)],
|
|
12319
|
+
[chalk17.dim("Version"), chalk17.green(`v${preset.version}`)]
|
|
12285
12320
|
);
|
|
12286
12321
|
const stackParts = [];
|
|
12287
12322
|
if (preset.stack.frontend) stackParts.push(preset.stack.frontend);
|
|
@@ -12289,16 +12324,16 @@ function createRulesListCommand() {
|
|
|
12289
12324
|
if (preset.stack.css) stackParts.push(preset.stack.css);
|
|
12290
12325
|
if (preset.stack.database) stackParts.push(preset.stack.database);
|
|
12291
12326
|
if (stackParts.length > 0) {
|
|
12292
|
-
table.push([
|
|
12327
|
+
table.push([chalk17.dim("Stack"), chalk17.yellow(stackParts.join(" + "))]);
|
|
12293
12328
|
}
|
|
12294
12329
|
table.push(
|
|
12295
|
-
[
|
|
12296
|
-
[
|
|
12330
|
+
[chalk17.dim("Tags"), chalk17.dim(preset.tags.join(", ") || "-")],
|
|
12331
|
+
[chalk17.dim("Downloads"), chalk17.white(preset.downloads.toString())]
|
|
12297
12332
|
);
|
|
12298
12333
|
console.log(table.toString());
|
|
12299
12334
|
console.log();
|
|
12300
12335
|
}
|
|
12301
|
-
console.log(
|
|
12336
|
+
console.log(chalk17.dim('\u{1F4A1} Ch\u1EA1y "jai1 rules apply <name>" \u0111\u1EC3 \xE1p d\u1EE5ng preset'));
|
|
12302
12337
|
} catch (error) {
|
|
12303
12338
|
throw new Error(
|
|
12304
12339
|
`L\u1ED7i khi t\u1EA3i presets: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -13726,23 +13761,23 @@ async function checkIdeFilesExist(ideId, format) {
|
|
|
13726
13761
|
|
|
13727
13762
|
// src/commands/rules/index.ts
|
|
13728
13763
|
function showRulesHelp() {
|
|
13729
|
-
console.log(
|
|
13764
|
+
console.log(chalk18.bold.cyan("\u{1F4CB} jai1 rules") + chalk18.dim(" - Qu\u1EA3n l\xFD rule presets cho AI agents"));
|
|
13730
13765
|
console.log();
|
|
13731
|
-
console.log(
|
|
13732
|
-
console.log(` ${
|
|
13733
|
-
console.log(` ${
|
|
13734
|
-
console.log(` ${
|
|
13735
|
-
console.log(` ${
|
|
13736
|
-
console.log(` ${
|
|
13737
|
-
console.log(` ${
|
|
13766
|
+
console.log(chalk18.bold("C\xE1c l\u1EC7nh:"));
|
|
13767
|
+
console.log(` ${chalk18.cyan("list")} Li\u1EC7t k\xEA c\xE1c presets c\xF3 s\u1EB5n`);
|
|
13768
|
+
console.log(` ${chalk18.cyan("info")} Xem chi ti\u1EBFt m\u1ED9t preset`);
|
|
13769
|
+
console.log(` ${chalk18.cyan("init")} Kh\u1EDFi t\u1EA1o rules t\u1EEB preset`);
|
|
13770
|
+
console.log(` ${chalk18.cyan("apply")} \xC1p d\u1EE5ng preset v\xE0o project`);
|
|
13771
|
+
console.log(` ${chalk18.cyan("sync")} \u0110\u1ED3ng b\u1ED9 rules sang c\xE1c \u0111\u1ECBnh d\u1EA1ng IDE`);
|
|
13772
|
+
console.log(` ${chalk18.cyan("restore")} Kh\xF4i ph\u1EE5c rules t\u1EEB backup`);
|
|
13738
13773
|
console.log();
|
|
13739
|
-
console.log(
|
|
13740
|
-
console.log(
|
|
13741
|
-
console.log(
|
|
13742
|
-
console.log(
|
|
13743
|
-
console.log(
|
|
13774
|
+
console.log(chalk18.bold("V\xED d\u1EE5:"));
|
|
13775
|
+
console.log(chalk18.dim(" $ jai1 rules list"));
|
|
13776
|
+
console.log(chalk18.dim(" $ jai1 rules info react-typescript"));
|
|
13777
|
+
console.log(chalk18.dim(" $ jai1 rules init --preset=react-typescript"));
|
|
13778
|
+
console.log(chalk18.dim(" $ jai1 rules apply react-typescript"));
|
|
13744
13779
|
console.log();
|
|
13745
|
-
console.log(
|
|
13780
|
+
console.log(chalk18.dim('Ch\u1EA1y "jai1 rules <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
|
|
13746
13781
|
}
|
|
13747
13782
|
function createRulesCommand() {
|
|
13748
13783
|
const rulesCommand = new Command50("rules").description("Manage rule presets for AI agents").action(() => {
|
|
@@ -15669,53 +15704,54 @@ async function runMigrateIde(options) {
|
|
|
15669
15704
|
|
|
15670
15705
|
// src/utils/help-formatter.ts
|
|
15671
15706
|
import boxen4 from "boxen";
|
|
15672
|
-
import
|
|
15707
|
+
import chalk19 from "chalk";
|
|
15673
15708
|
import gradient from "gradient-string";
|
|
15674
15709
|
import figlet from "figlet";
|
|
15675
15710
|
function showCustomHelp(version) {
|
|
15676
15711
|
const title = figlet.textSync("JAI1", { font: "Small" });
|
|
15677
15712
|
console.log(gradient.pastel(title));
|
|
15678
15713
|
console.log(
|
|
15679
|
-
boxen4(
|
|
15714
|
+
boxen4(chalk19.cyan(`Agentic Coding CLI v${version}`), {
|
|
15680
15715
|
padding: { left: 1, right: 1, top: 0, bottom: 0 },
|
|
15681
15716
|
borderStyle: "round",
|
|
15682
15717
|
borderColor: "cyan"
|
|
15683
15718
|
})
|
|
15684
15719
|
);
|
|
15685
|
-
console.log(
|
|
15720
|
+
console.log(chalk19.bold("\n\u{1F527} Thi\u1EBFt l\u1EADp & Th\xF4ng tin"));
|
|
15686
15721
|
console.log(" auth X\xE1c th\u1EF1c v\xE0 c\u1EA5u h\xECnh jai1-client");
|
|
15687
15722
|
console.log(" status Hi\u1EC3n th\u1ECB tr\u1EA1ng th\xE1i c\u1EA5u h\xECnh");
|
|
15688
15723
|
console.log(" guide Trung t\xE2m h\u1ECDc Agentic Coding");
|
|
15689
|
-
console.log(
|
|
15724
|
+
console.log(chalk19.bold("\n\u{1F4E6} Qu\u1EA3n l\xFD Components"));
|
|
15690
15725
|
console.log(" apply C\xE0i \u0111\u1EB7t components (interactive)");
|
|
15691
15726
|
console.log(" update C\u1EADp nh\u1EADt components \u0111\xE3 c\xE0i");
|
|
15692
15727
|
console.log(" check Ki\u1EC3m tra c\u1EADp nh\u1EADt t\u1EEB server");
|
|
15693
|
-
console.log(
|
|
15728
|
+
console.log(chalk19.bold("\n\u{1F5A5}\uFE0F IDE & T\xEDch h\u1EE3p"));
|
|
15694
15729
|
console.log(" ide L\u1EC7nh c\u1EA5u h\xECnh IDE");
|
|
15695
15730
|
console.log(" chat Chat AI v\u1EDBi Jai1 LLM Proxy");
|
|
15696
15731
|
console.log(" openai-keys Th\xF4ng tin API credentials");
|
|
15697
|
-
console.log(
|
|
15732
|
+
console.log(chalk19.bold("\n\u{1F916} AI Tools"));
|
|
15698
15733
|
console.log(" translate D\u1ECBch v\u0103n b\u1EA3n/file b\u1EB1ng AI");
|
|
15699
15734
|
console.log(" image T\u1EA1o \u1EA3nh (Coming Soon)");
|
|
15700
15735
|
console.log(" stats Th\u1ED1ng k\xEA s\u1EED d\u1EE5ng LLM");
|
|
15701
15736
|
console.log(" feedback G\u1EEDi b\xE1o c\xE1o/\u0111\u1EC1 xu\u1EA5t");
|
|
15702
|
-
console.log(
|
|
15737
|
+
console.log(chalk19.bold("\n\u{1F4C1} Project"));
|
|
15703
15738
|
console.log(" kit Qu\u1EA3n l\xFD starter kits");
|
|
15704
15739
|
console.log(" rules Qu\u1EA3n l\xFD rule presets");
|
|
15705
15740
|
console.log(" deps Qu\u1EA3n l\xFD dependencies");
|
|
15706
15741
|
console.log(" redmine Redmine context sync");
|
|
15707
|
-
console.log(
|
|
15742
|
+
console.log(chalk19.bold("\n\u2699\uFE0F B\u1EA3o tr\xEC"));
|
|
15708
15743
|
console.log(" upgrade C\u1EADp nh\u1EADt jai1-client");
|
|
15709
15744
|
console.log(" clean D\u1ECDn d\u1EB9p cache/backup");
|
|
15710
15745
|
console.log(" utils Developer utilities");
|
|
15711
|
-
console.log(
|
|
15746
|
+
console.log(chalk19.dim("\nS\u1EED d\u1EE5ng: jai1 [l\u1EC7nh] --help \u0111\u1EC3 xem chi ti\u1EBFt"));
|
|
15712
15747
|
}
|
|
15713
15748
|
function showUnknownCommand(commandName) {
|
|
15714
|
-
console.error(
|
|
15715
|
-
console.error(
|
|
15749
|
+
console.error(chalk19.red(`\u274C L\u1EC7nh kh\xF4ng t\u1ED3n t\u1EA1i: ${commandName}`));
|
|
15750
|
+
console.error(chalk19.dim("\nG\u1EE3i \xFD: Ch\u1EA1y jai1 --help \u0111\u1EC3 xem danh s\xE1ch l\u1EC7nh"));
|
|
15716
15751
|
}
|
|
15717
15752
|
|
|
15718
15753
|
// src/cli.ts
|
|
15754
|
+
checkNodeVersion();
|
|
15719
15755
|
var program = new Command62();
|
|
15720
15756
|
if (process.argv.includes("-v") || process.argv.includes("--version")) {
|
|
15721
15757
|
console.log(package_default.version);
|