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