@jvittechs/j 1.0.60 → 1.0.62
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/{chunk-22FXNN76.js → chunk-TEVFTK65.js} +11 -44
- package/dist/chunk-TEVFTK65.js.map +1 -0
- package/dist/chunk-WOAXYUZ6.js +62 -0
- package/dist/chunk-WOAXYUZ6.js.map +1 -0
- package/dist/cli.js +205 -101
- package/dist/cli.js.map +1 -1
- package/dist/{summary-4ZVFN4XV.js → summary-7EHQYYJU.js} +3 -2
- package/dist/task.types-M4GWGDMH.js +21 -0
- package/dist/task.types-M4GWGDMH.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-22FXNN76.js.map +0 -1
- /package/dist/{summary-4ZVFN4XV.js.map → summary-7EHQYYJU.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -9,14 +9,18 @@ import {
|
|
|
9
9
|
import {
|
|
10
10
|
createSettingsShowCommand
|
|
11
11
|
} from "./chunk-5RDBJYO2.js";
|
|
12
|
+
import {
|
|
13
|
+
CloudTaskProvider,
|
|
14
|
+
TaskService,
|
|
15
|
+
createTaskSummaryCommand
|
|
16
|
+
} from "./chunk-TEVFTK65.js";
|
|
12
17
|
import {
|
|
13
18
|
BLOCKED_ICON,
|
|
14
19
|
PRIORITY_ICONS,
|
|
15
20
|
PRIORITY_LABELS,
|
|
16
21
|
STATUS_ICONS,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
} from "./chunk-22FXNN76.js";
|
|
22
|
+
TaskSchema
|
|
23
|
+
} from "./chunk-WOAXYUZ6.js";
|
|
20
24
|
import {
|
|
21
25
|
ConfigService,
|
|
22
26
|
SettingsService
|
|
@@ -156,7 +160,7 @@ import { basename as basename5 } from "path";
|
|
|
156
160
|
// package.json
|
|
157
161
|
var package_default = {
|
|
158
162
|
name: "@jvittechs/j",
|
|
159
|
-
version: "1.0.
|
|
163
|
+
version: "1.0.62",
|
|
160
164
|
description: "A unified CLI tool for JV-IT TECHS developers to manage Jai1 Framework. Supports both `j` and `jai1` commands. Please contact TeamAI for usage instructions.",
|
|
161
165
|
type: "module",
|
|
162
166
|
bin: {
|
|
@@ -11366,13 +11370,54 @@ async function checkAuthStatus() {
|
|
|
11366
11370
|
try {
|
|
11367
11371
|
const config = await new ConfigService().load();
|
|
11368
11372
|
if (config?.apiUrl && config?.accessKey) {
|
|
11369
|
-
return { ok: true,
|
|
11373
|
+
return { ok: true, config };
|
|
11370
11374
|
}
|
|
11371
11375
|
return { ok: false };
|
|
11372
11376
|
} catch {
|
|
11373
11377
|
return { ok: false };
|
|
11374
11378
|
}
|
|
11375
11379
|
}
|
|
11380
|
+
async function registerProject(config, projectId, repoUrl, silent) {
|
|
11381
|
+
try {
|
|
11382
|
+
const provider = new CloudTaskProvider(config, projectId);
|
|
11383
|
+
const registeredId = await provider.ensureProjectRegistered(repoUrl);
|
|
11384
|
+
if (!silent) {
|
|
11385
|
+
console.log(chalk31.green(" \u2713 Project registered on server"));
|
|
11386
|
+
}
|
|
11387
|
+
return registeredId;
|
|
11388
|
+
} catch (error) {
|
|
11389
|
+
if (!silent) {
|
|
11390
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
11391
|
+
console.log(chalk31.yellow(` \u26A0\uFE0F Register failed: ${msg}`));
|
|
11392
|
+
console.log(chalk31.dim(" Project s\u1EBD \u0111\u01B0\u1EE3c \u0111\u0103ng k\xFD l\u1EA1i khi ch\u1EA1y l\u1EC7nh task \u0111\u1EA7u ti\xEAn."));
|
|
11393
|
+
}
|
|
11394
|
+
return null;
|
|
11395
|
+
}
|
|
11396
|
+
}
|
|
11397
|
+
async function syncLocalTasksToCloud(config, projectId, tasksPath, silent) {
|
|
11398
|
+
try {
|
|
11399
|
+
const { existsSync: existsSync7, readFileSync: readFileSync4 } = await import("fs");
|
|
11400
|
+
if (!existsSync7(tasksPath)) return;
|
|
11401
|
+
const content = readFileSync4(tasksPath, "utf-8").trim();
|
|
11402
|
+
if (!content) return;
|
|
11403
|
+
const { TaskSchema: TaskSchema2 } = await import("./task.types-M4GWGDMH.js");
|
|
11404
|
+
const lines = content.split("\n").filter(Boolean);
|
|
11405
|
+
const tasks = lines.map((line) => TaskSchema2.parse(JSON.parse(line)));
|
|
11406
|
+
if (tasks.length === 0) return;
|
|
11407
|
+
if (!silent) {
|
|
11408
|
+
console.log(chalk31.dim(` \u2191 Syncing ${tasks.length} local tasks to cloud...`));
|
|
11409
|
+
}
|
|
11410
|
+
const provider = new CloudTaskProvider(config, projectId);
|
|
11411
|
+
await provider.push(tasks);
|
|
11412
|
+
if (!silent) {
|
|
11413
|
+
console.log(chalk31.green(` \u2713 ${tasks.length} tasks synced to cloud`));
|
|
11414
|
+
}
|
|
11415
|
+
} catch {
|
|
11416
|
+
if (!silent) {
|
|
11417
|
+
console.log(chalk31.dim(" \u26A0\uFE0F Could not sync local tasks. Use j t sync --push later."));
|
|
11418
|
+
}
|
|
11419
|
+
}
|
|
11420
|
+
}
|
|
11376
11421
|
function createSettingsInitCommand() {
|
|
11377
11422
|
return new Command58("init").description("Kh\u1EDFi t\u1EA1o .jai1/settings.yaml").option("-f, --force", "Ghi \u0111\xE8 file c\u0169 n\u1EBFu \u0111\xE3 t\u1ED3n t\u1EA1i").option("--cloud", "Enable cloud task sync (non-interactive)").option("--no-interactive", "Kh\xF4ng h\u1ECFi, d\xF9ng flags/defaults").option("-j, --json", "Output JSON").action(async (options) => {
|
|
11378
11423
|
try {
|
|
@@ -11381,6 +11426,7 @@ function createSettingsInitCommand() {
|
|
|
11381
11426
|
throw new Error("Settings file \u0111\xE3 t\u1ED3n t\u1EA1i. D\xF9ng --force \u0111\u1EC3 ghi \u0111\xE8.");
|
|
11382
11427
|
}
|
|
11383
11428
|
let enableCloud = options.cloud || false;
|
|
11429
|
+
let authResult = { ok: false };
|
|
11384
11430
|
if (options.interactive !== false && !options.json) {
|
|
11385
11431
|
const repoUrl = service.resolveGitRepoUrl();
|
|
11386
11432
|
console.log(chalk31.bold("\u{1F4CB} Kh\u1EDFi t\u1EA1o Project Settings"));
|
|
@@ -11394,8 +11440,8 @@ function createSettingsInitCommand() {
|
|
|
11394
11440
|
default: false
|
|
11395
11441
|
});
|
|
11396
11442
|
if (enableCloud) {
|
|
11397
|
-
|
|
11398
|
-
if (!
|
|
11443
|
+
authResult = await checkAuthStatus();
|
|
11444
|
+
if (!authResult.ok) {
|
|
11399
11445
|
console.log("");
|
|
11400
11446
|
console.log(chalk31.yellow("\u26A0\uFE0F Ch\u01B0a \u0111\u0103ng nh\u1EADp Jai1."));
|
|
11401
11447
|
console.log(chalk31.dim(" Ch\u1EA1y: j auth"));
|
|
@@ -11409,22 +11455,48 @@ function createSettingsInitCommand() {
|
|
|
11409
11455
|
console.log(chalk31.green(" \u2713 Auth OK"));
|
|
11410
11456
|
}
|
|
11411
11457
|
}
|
|
11412
|
-
} else if (enableCloud
|
|
11413
|
-
|
|
11414
|
-
if (!
|
|
11458
|
+
} else if (enableCloud) {
|
|
11459
|
+
authResult = await checkAuthStatus();
|
|
11460
|
+
if (!authResult.ok && !options.json) {
|
|
11415
11461
|
console.log(chalk31.yellow("\u26A0\uFE0F Ch\u01B0a \u0111\u0103ng nh\u1EADp. Ch\u1EA1y j auth tr\u01B0\u1EDBc khi d\xF9ng cloud tasks."));
|
|
11416
11462
|
}
|
|
11417
11463
|
}
|
|
11418
|
-
|
|
11464
|
+
await service.init(true);
|
|
11419
11465
|
if (enableCloud) {
|
|
11420
11466
|
await service.set("tasks.cloud", true);
|
|
11421
11467
|
}
|
|
11468
|
+
let registeredProjectId = null;
|
|
11469
|
+
if (enableCloud && authResult.ok && authResult.config) {
|
|
11470
|
+
const repoUrl = service.resolveGitRepoUrl();
|
|
11471
|
+
const projectId = service.getProjectId();
|
|
11472
|
+
if (repoUrl && projectId) {
|
|
11473
|
+
registeredProjectId = await registerProject(
|
|
11474
|
+
authResult.config,
|
|
11475
|
+
projectId,
|
|
11476
|
+
repoUrl,
|
|
11477
|
+
!!options.json
|
|
11478
|
+
);
|
|
11479
|
+
const finalProjectId = registeredProjectId && registeredProjectId !== projectId ? registeredProjectId : projectId;
|
|
11480
|
+
if (registeredProjectId && registeredProjectId !== projectId) {
|
|
11481
|
+
await service.set("tasks.projectId", registeredProjectId);
|
|
11482
|
+
}
|
|
11483
|
+
if (registeredProjectId) {
|
|
11484
|
+
await syncLocalTasksToCloud(
|
|
11485
|
+
authResult.config,
|
|
11486
|
+
finalProjectId,
|
|
11487
|
+
service.getSettingsPath().replace(/settings\.yaml$/, "tasks.jsonl"),
|
|
11488
|
+
!!options.json
|
|
11489
|
+
);
|
|
11490
|
+
}
|
|
11491
|
+
}
|
|
11492
|
+
}
|
|
11422
11493
|
const finalSettings = service.load();
|
|
11423
11494
|
if (options.json) {
|
|
11424
11495
|
console.log(JSON.stringify({
|
|
11425
11496
|
success: true,
|
|
11426
11497
|
path: service.getSettingsPath(),
|
|
11427
|
-
settings: finalSettings
|
|
11498
|
+
settings: finalSettings,
|
|
11499
|
+
registered: !!registeredProjectId
|
|
11428
11500
|
}, null, 2));
|
|
11429
11501
|
return;
|
|
11430
11502
|
}
|
|
@@ -11437,8 +11509,6 @@ function createSettingsInitCommand() {
|
|
|
11437
11509
|
if (projectId) {
|
|
11438
11510
|
console.log(` ${chalk31.dim("Project ID:")} ${projectId}`);
|
|
11439
11511
|
}
|
|
11440
|
-
console.log("");
|
|
11441
|
-
console.log(chalk31.dim(" Cloud tasks s\u1EBD t\u1EF1 \u0111\u0103ng k\xFD project khi ch\u1EA1y l\u1EC7nh task \u0111\u1EA7u ti\xEAn."));
|
|
11442
11512
|
}
|
|
11443
11513
|
} catch (error) {
|
|
11444
11514
|
if (options.json) {
|
|
@@ -11454,6 +11524,8 @@ function createSettingsInitCommand() {
|
|
|
11454
11524
|
// src/commands/settings/set.ts
|
|
11455
11525
|
import { Command as Command59 } from "commander";
|
|
11456
11526
|
import chalk32 from "chalk";
|
|
11527
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
|
|
11528
|
+
import { join as join9 } from "path";
|
|
11457
11529
|
function createSettingsSetCommand() {
|
|
11458
11530
|
return new Command59("set").description("Set a setting value (dot-notation)").argument("<key>", "Setting key (e.g., tasks.cloud)").argument("<value>", "Setting value").option("-j, --json", "Output JSON").action(async (key, value, options) => {
|
|
11459
11531
|
try {
|
|
@@ -11476,9 +11548,38 @@ function createSettingsSetCommand() {
|
|
|
11476
11548
|
console.log(chalk32.yellow("\u26A0\uFE0F Ch\u01B0a \u0111\u0103ng nh\u1EADp. Ch\u1EA1y j auth tr\u01B0\u1EDBc khi d\xF9ng cloud tasks."));
|
|
11477
11549
|
} else {
|
|
11478
11550
|
console.log(chalk32.dim(" Auth: \u2713 OK"));
|
|
11551
|
+
const repoUrl = service.resolveGitRepoUrl();
|
|
11479
11552
|
const projectId = service.getProjectId();
|
|
11480
|
-
if (projectId) {
|
|
11481
|
-
|
|
11553
|
+
if (repoUrl && projectId) {
|
|
11554
|
+
let finalProjectId = projectId;
|
|
11555
|
+
try {
|
|
11556
|
+
const provider = new CloudTaskProvider(config, projectId);
|
|
11557
|
+
const registeredId = await provider.ensureProjectRegistered(repoUrl);
|
|
11558
|
+
console.log(chalk32.green(" \u2713 Project registered on server"));
|
|
11559
|
+
if (registeredId && registeredId !== projectId) {
|
|
11560
|
+
await service.set("tasks.projectId", registeredId);
|
|
11561
|
+
finalProjectId = registeredId;
|
|
11562
|
+
}
|
|
11563
|
+
console.log(chalk32.dim(` Project: ${finalProjectId}`));
|
|
11564
|
+
const tasksPath = join9(process.cwd(), ".jai1", "tasks.jsonl");
|
|
11565
|
+
if (existsSync4(tasksPath)) {
|
|
11566
|
+
const content = readFileSync3(tasksPath, "utf-8").trim();
|
|
11567
|
+
if (content) {
|
|
11568
|
+
const lines = content.split("\n").filter(Boolean);
|
|
11569
|
+
const tasks = lines.map((l) => TaskSchema.parse(JSON.parse(l)));
|
|
11570
|
+
if (tasks.length > 0) {
|
|
11571
|
+
console.log(chalk32.dim(` \u2191 Syncing ${tasks.length} local tasks to cloud...`));
|
|
11572
|
+
const p = new CloudTaskProvider(config, finalProjectId);
|
|
11573
|
+
await p.push(tasks);
|
|
11574
|
+
console.log(chalk32.green(` \u2713 ${tasks.length} tasks synced to cloud`));
|
|
11575
|
+
}
|
|
11576
|
+
}
|
|
11577
|
+
}
|
|
11578
|
+
} catch (error) {
|
|
11579
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
11580
|
+
console.log(chalk32.yellow(` \u26A0\uFE0F Register failed: ${msg}`));
|
|
11581
|
+
console.log(chalk32.dim(" Project s\u1EBD \u0111\u01B0\u1EE3c \u0111\u0103ng k\xFD l\u1EA1i khi ch\u1EA1y l\u1EC7nh task \u0111\u1EA7u ti\xEAn."));
|
|
11582
|
+
}
|
|
11482
11583
|
}
|
|
11483
11584
|
}
|
|
11484
11585
|
}
|
|
@@ -11624,6 +11725,9 @@ function printTaskLine(task, resolvedIds) {
|
|
|
11624
11725
|
const blockedBy = task.depends_on.filter((id) => !resolvedIds.has(id));
|
|
11625
11726
|
line += chalk35.red(` (blocked: ${blockedBy.join(", ")})`);
|
|
11626
11727
|
}
|
|
11728
|
+
if (task.type && task.type !== "task") {
|
|
11729
|
+
line += chalk35.magenta(` {${task.type}}`);
|
|
11730
|
+
}
|
|
11627
11731
|
if (task.parent) {
|
|
11628
11732
|
line += chalk35.dim(` [${task.parent}]`);
|
|
11629
11733
|
}
|
|
@@ -12347,7 +12451,7 @@ function createTasksCommand() {
|
|
|
12347
12451
|
cmd.addCommand(createTaskDeleteCommand());
|
|
12348
12452
|
cmd.addCommand(createTaskGuideCommand());
|
|
12349
12453
|
cmd.action(async () => {
|
|
12350
|
-
const { handleTaskSummary } = await import("./summary-
|
|
12454
|
+
const { handleTaskSummary } = await import("./summary-7EHQYYJU.js");
|
|
12351
12455
|
await handleTaskSummary({ json: false });
|
|
12352
12456
|
});
|
|
12353
12457
|
return cmd;
|
|
@@ -12364,7 +12468,7 @@ import Table6 from "cli-table3";
|
|
|
12364
12468
|
|
|
12365
12469
|
// src/services/starter-kit.service.ts
|
|
12366
12470
|
import { promises as fs18 } from "fs";
|
|
12367
|
-
import { join as
|
|
12471
|
+
import { join as join10 } from "path";
|
|
12368
12472
|
import AdmZip from "adm-zip";
|
|
12369
12473
|
var StarterKitService = class {
|
|
12370
12474
|
/**
|
|
@@ -12411,9 +12515,9 @@ var StarterKitService = class {
|
|
|
12411
12515
|
throw new NetworkError(`Failed to download kit: HTTP ${response.status}`);
|
|
12412
12516
|
}
|
|
12413
12517
|
if (onProgress) onProgress(30);
|
|
12414
|
-
const tmpDir =
|
|
12518
|
+
const tmpDir = join10(process.env.TMPDIR || "/tmp", "jai1-kits");
|
|
12415
12519
|
await fs18.mkdir(tmpDir, { recursive: true });
|
|
12416
|
-
const tmpFile =
|
|
12520
|
+
const tmpFile = join10(tmpDir, `${slug}.zip`);
|
|
12417
12521
|
const buffer = await response.arrayBuffer();
|
|
12418
12522
|
await fs18.writeFile(tmpFile, Buffer.from(buffer));
|
|
12419
12523
|
if (onProgress) onProgress(60);
|
|
@@ -12546,7 +12650,7 @@ Post-Init Commands:`);
|
|
|
12546
12650
|
// src/commands/kit/create.ts
|
|
12547
12651
|
import { Command as Command78 } from "commander";
|
|
12548
12652
|
import { promises as fs19 } from "fs";
|
|
12549
|
-
import { join as
|
|
12653
|
+
import { join as join11 } from "path";
|
|
12550
12654
|
import { select as select3, input as input2, checkbox as checkbox4 } from "@inquirer/prompts";
|
|
12551
12655
|
import { execa as execa2 } from "execa";
|
|
12552
12656
|
|
|
@@ -12609,7 +12713,7 @@ function createKitCreateCommand() {
|
|
|
12609
12713
|
}
|
|
12610
12714
|
}
|
|
12611
12715
|
}
|
|
12612
|
-
const targetDir = directory ||
|
|
12716
|
+
const targetDir = directory || join11(process.cwd(), options.name || slug);
|
|
12613
12717
|
try {
|
|
12614
12718
|
await fs19.access(targetDir);
|
|
12615
12719
|
throw new Error(`Directory already exists: ${targetDir}`);
|
|
@@ -12674,7 +12778,7 @@ function createKitCreateCommand() {
|
|
|
12674
12778
|
);
|
|
12675
12779
|
for (const filepath of expandedPaths) {
|
|
12676
12780
|
console.log(` \u{1F4E5} Installing ${filepath}...`);
|
|
12677
|
-
await componentsService.install(config, filepath,
|
|
12781
|
+
await componentsService.install(config, filepath, join11(targetDir, ".jai1"));
|
|
12678
12782
|
}
|
|
12679
12783
|
console.log(" \u2713 Framework components applied");
|
|
12680
12784
|
}
|
|
@@ -12754,7 +12858,7 @@ async function getAllFiles(dir) {
|
|
|
12754
12858
|
const files = [];
|
|
12755
12859
|
const entries = await fs19.readdir(dir, { withFileTypes: true });
|
|
12756
12860
|
for (const entry of entries) {
|
|
12757
|
-
const fullPath =
|
|
12861
|
+
const fullPath = join11(dir, entry.name);
|
|
12758
12862
|
if (entry.isDirectory()) {
|
|
12759
12863
|
if (!entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
12760
12864
|
files.push(...await getAllFiles(fullPath));
|
|
@@ -12870,20 +12974,20 @@ function createRulesListCommand() {
|
|
|
12870
12974
|
// src/commands/rules/init.ts
|
|
12871
12975
|
import { Command as Command81 } from "commander";
|
|
12872
12976
|
import { promises as fs21 } from "fs";
|
|
12873
|
-
import { join as
|
|
12977
|
+
import { join as join13 } from "path";
|
|
12874
12978
|
import { select as select4, confirm as confirm15 } from "@inquirer/prompts";
|
|
12875
12979
|
|
|
12876
12980
|
// src/services/project-config.service.ts
|
|
12877
12981
|
import { promises as fs20 } from "fs";
|
|
12878
|
-
import { join as
|
|
12982
|
+
import { join as join12 } from "path";
|
|
12879
12983
|
var ProjectConfigService = class {
|
|
12880
12984
|
projectRoot;
|
|
12881
12985
|
configDir;
|
|
12882
12986
|
configPath;
|
|
12883
12987
|
constructor(projectRoot = process.cwd()) {
|
|
12884
12988
|
this.projectRoot = projectRoot;
|
|
12885
|
-
this.configDir =
|
|
12886
|
-
this.configPath =
|
|
12989
|
+
this.configDir = join12(this.projectRoot, ".jai1");
|
|
12990
|
+
this.configPath = join12(this.configDir, "project.json");
|
|
12887
12991
|
}
|
|
12888
12992
|
/**
|
|
12889
12993
|
* Check if config file exists
|
|
@@ -13089,10 +13193,10 @@ function createRulesInitCommand() {
|
|
|
13089
13193
|
});
|
|
13090
13194
|
}
|
|
13091
13195
|
async function applyCursorFormat(bundle) {
|
|
13092
|
-
const rulesDir =
|
|
13196
|
+
const rulesDir = join13(process.cwd(), ".cursor", "rules");
|
|
13093
13197
|
await fs21.mkdir(rulesDir, { recursive: true });
|
|
13094
13198
|
for (const [filename, content] of Object.entries(bundle.files)) {
|
|
13095
|
-
const filePath =
|
|
13199
|
+
const filePath = join13(rulesDir, filename);
|
|
13096
13200
|
await fs21.writeFile(filePath, content, "utf-8");
|
|
13097
13201
|
console.log(`\u2713 Created .cursor/rules/${filename}`);
|
|
13098
13202
|
}
|
|
@@ -13127,7 +13231,7 @@ async function applyAgentsMdFormat(bundle) {
|
|
|
13127
13231
|
// src/commands/rules/apply.ts
|
|
13128
13232
|
import { Command as Command82 } from "commander";
|
|
13129
13233
|
import { promises as fs23 } from "fs";
|
|
13130
|
-
import { join as
|
|
13234
|
+
import { join as join15 } from "path";
|
|
13131
13235
|
import { search, confirm as confirm16, checkbox as checkbox5 } from "@inquirer/prompts";
|
|
13132
13236
|
|
|
13133
13237
|
// src/services/rules-generator.service.ts
|
|
@@ -13419,7 +13523,7 @@ Follow all instructions and patterns defined in AGENTS.md above.
|
|
|
13419
13523
|
|
|
13420
13524
|
// src/services/backup.service.ts
|
|
13421
13525
|
import { promises as fs22 } from "fs";
|
|
13422
|
-
import { join as
|
|
13526
|
+
import { join as join14, dirname } from "path";
|
|
13423
13527
|
var BackupService = class {
|
|
13424
13528
|
backupDir = ".jai1/backups";
|
|
13425
13529
|
/**
|
|
@@ -13427,7 +13531,7 @@ var BackupService = class {
|
|
|
13427
13531
|
*/
|
|
13428
13532
|
async createBackup(ides, presetSlug) {
|
|
13429
13533
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
13430
|
-
const backupPath =
|
|
13534
|
+
const backupPath = join14(this.backupDir, timestamp);
|
|
13431
13535
|
const backedUpFiles = [];
|
|
13432
13536
|
let hasContent = false;
|
|
13433
13537
|
for (const ideId of ides) {
|
|
@@ -13436,7 +13540,7 @@ var BackupService = class {
|
|
|
13436
13540
|
console.warn(`Unknown IDE format: ${ideId}, skipping backup`);
|
|
13437
13541
|
continue;
|
|
13438
13542
|
}
|
|
13439
|
-
const rulesPath = format.rulesPath === "." ? process.cwd() :
|
|
13543
|
+
const rulesPath = format.rulesPath === "." ? process.cwd() : join14(process.cwd(), format.rulesPath);
|
|
13440
13544
|
try {
|
|
13441
13545
|
const exists = await this.pathExists(rulesPath);
|
|
13442
13546
|
if (!exists) {
|
|
@@ -13454,14 +13558,14 @@ var BackupService = class {
|
|
|
13454
13558
|
const files = await fs22.readdir(rulesPath);
|
|
13455
13559
|
for (const file of files) {
|
|
13456
13560
|
if (file.endsWith(format.fileExtension)) {
|
|
13457
|
-
const originalPath =
|
|
13458
|
-
const relativePath =
|
|
13459
|
-
const destPath =
|
|
13561
|
+
const originalPath = join14(rulesPath, file);
|
|
13562
|
+
const relativePath = join14(format.rulesPath, file);
|
|
13563
|
+
const destPath = join14(backupPath, ideId, file);
|
|
13460
13564
|
await fs22.mkdir(dirname(destPath), { recursive: true });
|
|
13461
13565
|
await fs22.copyFile(originalPath, destPath);
|
|
13462
13566
|
backedUpFiles.push({
|
|
13463
13567
|
originalPath: relativePath,
|
|
13464
|
-
backupPath:
|
|
13568
|
+
backupPath: join14(ideId, file),
|
|
13465
13569
|
ide: ideId
|
|
13466
13570
|
});
|
|
13467
13571
|
hasContent = true;
|
|
@@ -13484,7 +13588,7 @@ var BackupService = class {
|
|
|
13484
13588
|
};
|
|
13485
13589
|
await fs22.mkdir(backupPath, { recursive: true });
|
|
13486
13590
|
await fs22.writeFile(
|
|
13487
|
-
|
|
13591
|
+
join14(backupPath, "metadata.json"),
|
|
13488
13592
|
JSON.stringify(metadata, null, 2),
|
|
13489
13593
|
"utf-8"
|
|
13490
13594
|
);
|
|
@@ -13494,18 +13598,18 @@ var BackupService = class {
|
|
|
13494
13598
|
* Backup a single file (for AGENTS.md, GEMINI.md)
|
|
13495
13599
|
*/
|
|
13496
13600
|
async backupSingleFile(filename, backupPath, ideId, backedUpFiles) {
|
|
13497
|
-
const originalPath =
|
|
13601
|
+
const originalPath = join14(process.cwd(), filename);
|
|
13498
13602
|
try {
|
|
13499
13603
|
const exists = await this.pathExists(originalPath);
|
|
13500
13604
|
if (!exists) {
|
|
13501
13605
|
return;
|
|
13502
13606
|
}
|
|
13503
|
-
const destPath =
|
|
13607
|
+
const destPath = join14(backupPath, ideId, filename);
|
|
13504
13608
|
await fs22.mkdir(dirname(destPath), { recursive: true });
|
|
13505
13609
|
await fs22.copyFile(originalPath, destPath);
|
|
13506
13610
|
backedUpFiles.push({
|
|
13507
13611
|
originalPath: filename,
|
|
13508
|
-
backupPath:
|
|
13612
|
+
backupPath: join14(ideId, filename),
|
|
13509
13613
|
ide: ideId
|
|
13510
13614
|
});
|
|
13511
13615
|
} catch (error) {
|
|
@@ -13515,14 +13619,14 @@ var BackupService = class {
|
|
|
13515
13619
|
* Restore files from a backup
|
|
13516
13620
|
*/
|
|
13517
13621
|
async restoreBackup(backupPath) {
|
|
13518
|
-
const metadataPath =
|
|
13622
|
+
const metadataPath = join14(backupPath, "metadata.json");
|
|
13519
13623
|
const metadataContent = await fs22.readFile(metadataPath, "utf-8");
|
|
13520
13624
|
const metadata = JSON.parse(metadataContent);
|
|
13521
13625
|
console.log(`
|
|
13522
13626
|
Restoring backup from ${metadata.timestamp}...`);
|
|
13523
13627
|
for (const file of metadata.files) {
|
|
13524
|
-
const sourcePath =
|
|
13525
|
-
const destPath =
|
|
13628
|
+
const sourcePath = join14(backupPath, file.backupPath);
|
|
13629
|
+
const destPath = join14(process.cwd(), file.originalPath);
|
|
13526
13630
|
await fs22.mkdir(dirname(destPath), { recursive: true });
|
|
13527
13631
|
await fs22.copyFile(sourcePath, destPath);
|
|
13528
13632
|
console.log(`\u2713 Restored ${file.originalPath}`);
|
|
@@ -13534,7 +13638,7 @@ Restoring backup from ${metadata.timestamp}...`);
|
|
|
13534
13638
|
*/
|
|
13535
13639
|
async listBackups() {
|
|
13536
13640
|
try {
|
|
13537
|
-
const backupDirPath =
|
|
13641
|
+
const backupDirPath = join14(process.cwd(), this.backupDir);
|
|
13538
13642
|
const exists = await this.pathExists(backupDirPath);
|
|
13539
13643
|
if (!exists) {
|
|
13540
13644
|
return [];
|
|
@@ -13543,7 +13647,7 @@ Restoring backup from ${metadata.timestamp}...`);
|
|
|
13543
13647
|
const backups = [];
|
|
13544
13648
|
for (const entry of entries) {
|
|
13545
13649
|
if (entry.isDirectory()) {
|
|
13546
|
-
const metadataPath =
|
|
13650
|
+
const metadataPath = join14(backupDirPath, entry.name, "metadata.json");
|
|
13547
13651
|
try {
|
|
13548
13652
|
const metadataContent = await fs22.readFile(metadataPath, "utf-8");
|
|
13549
13653
|
const metadata = JSON.parse(metadataContent);
|
|
@@ -13562,7 +13666,7 @@ Restoring backup from ${metadata.timestamp}...`);
|
|
|
13562
13666
|
* Delete a specific backup
|
|
13563
13667
|
*/
|
|
13564
13668
|
async deleteBackup(timestamp) {
|
|
13565
|
-
const backupPath =
|
|
13669
|
+
const backupPath = join14(process.cwd(), this.backupDir, timestamp);
|
|
13566
13670
|
await this.deleteDirectory(backupPath);
|
|
13567
13671
|
}
|
|
13568
13672
|
/**
|
|
@@ -13611,7 +13715,7 @@ Restoring backup from ${metadata.timestamp}...`);
|
|
|
13611
13715
|
}
|
|
13612
13716
|
const entries = await fs22.readdir(path13, { withFileTypes: true });
|
|
13613
13717
|
for (const entry of entries) {
|
|
13614
|
-
const fullPath =
|
|
13718
|
+
const fullPath = join14(path13, entry.name);
|
|
13615
13719
|
if (entry.isDirectory()) {
|
|
13616
13720
|
await this.deleteDirectory(fullPath);
|
|
13617
13721
|
} else {
|
|
@@ -13626,13 +13730,13 @@ Restoring backup from ${metadata.timestamp}...`);
|
|
|
13626
13730
|
* Get backup directory path
|
|
13627
13731
|
*/
|
|
13628
13732
|
getBackupDir() {
|
|
13629
|
-
return
|
|
13733
|
+
return join14(process.cwd(), this.backupDir);
|
|
13630
13734
|
}
|
|
13631
13735
|
/**
|
|
13632
13736
|
* Ensure backup directory exists
|
|
13633
13737
|
*/
|
|
13634
13738
|
async ensureBackupDir() {
|
|
13635
|
-
const backupDirPath =
|
|
13739
|
+
const backupDirPath = join14(process.cwd(), this.backupDir);
|
|
13636
13740
|
await fs22.mkdir(backupDirPath, { recursive: true });
|
|
13637
13741
|
}
|
|
13638
13742
|
};
|
|
@@ -13805,20 +13909,20 @@ function createRulesApplyCommand() {
|
|
|
13805
13909
|
}
|
|
13806
13910
|
}
|
|
13807
13911
|
console.log("\n\u{1F4DD} Applying preset...\n");
|
|
13808
|
-
const rulePresetDir =
|
|
13912
|
+
const rulePresetDir = join15(process.cwd(), ".jai1", "rule-preset");
|
|
13809
13913
|
try {
|
|
13810
13914
|
await fs23.rm(rulePresetDir, { recursive: true, force: true });
|
|
13811
13915
|
} catch {
|
|
13812
13916
|
}
|
|
13813
13917
|
await fs23.mkdir(rulePresetDir, { recursive: true });
|
|
13814
13918
|
await fs23.writeFile(
|
|
13815
|
-
|
|
13919
|
+
join15(rulePresetDir, "preset.json"),
|
|
13816
13920
|
JSON.stringify(bundle.preset, null, 2),
|
|
13817
13921
|
"utf-8"
|
|
13818
13922
|
);
|
|
13819
13923
|
for (const [filename, content] of Object.entries(bundle.files)) {
|
|
13820
|
-
const filePath =
|
|
13821
|
-
await fs23.mkdir(
|
|
13924
|
+
const filePath = join15(rulePresetDir, filename);
|
|
13925
|
+
await fs23.mkdir(join15(filePath, ".."), { recursive: true });
|
|
13822
13926
|
await fs23.writeFile(filePath, content, "utf-8");
|
|
13823
13927
|
}
|
|
13824
13928
|
console.log(`\u2713 Saved preset to .jai1/rule-preset/`);
|
|
@@ -13827,8 +13931,8 @@ function createRulesApplyCommand() {
|
|
|
13827
13931
|
try {
|
|
13828
13932
|
const files = generatorService.generateForIde(bundle, ideId);
|
|
13829
13933
|
for (const file of files) {
|
|
13830
|
-
const fullPath =
|
|
13831
|
-
await fs23.mkdir(
|
|
13934
|
+
const fullPath = join15(process.cwd(), file.path);
|
|
13935
|
+
await fs23.mkdir(join15(fullPath, ".."), { recursive: true });
|
|
13832
13936
|
await fs23.writeFile(fullPath, file.content, "utf-8");
|
|
13833
13937
|
console.log(`\u2713 [${ideId}] ${file.path}`);
|
|
13834
13938
|
allGeneratedFiles.push({
|
|
@@ -13935,7 +14039,7 @@ function createRulesApplyCommand() {
|
|
|
13935
14039
|
|
|
13936
14040
|
// src/commands/rules/restore.ts
|
|
13937
14041
|
import { Command as Command83 } from "commander";
|
|
13938
|
-
import { join as
|
|
14042
|
+
import { join as join16 } from "path";
|
|
13939
14043
|
import { select as select5, confirm as confirm17 } from "@inquirer/prompts";
|
|
13940
14044
|
function createRulesRestoreCommand() {
|
|
13941
14045
|
return new Command83("restore").description("Restore rules from a backup").option("--latest", "Restore the most recent backup").option("-y, --yes", "Skip confirmation").action(async (options) => {
|
|
@@ -13982,7 +14086,7 @@ function createRulesRestoreCommand() {
|
|
|
13982
14086
|
}
|
|
13983
14087
|
console.log("\n\u{1F504} Restoring backup...\n");
|
|
13984
14088
|
try {
|
|
13985
|
-
const backupPath =
|
|
14089
|
+
const backupPath = join16(backupService.getBackupDir(), selectedBackup.timestamp);
|
|
13986
14090
|
await backupService.restoreBackup(backupPath);
|
|
13987
14091
|
console.log("\n\u2705 Backup restored successfully!\n");
|
|
13988
14092
|
console.log("\u{1F4A1} Tip: Your IDE may need to be restarted to pick up the changes.");
|
|
@@ -14009,12 +14113,12 @@ function formatTimestamp(timestamp) {
|
|
|
14009
14113
|
// src/commands/rules/sync.ts
|
|
14010
14114
|
import { Command as Command84 } from "commander";
|
|
14011
14115
|
import { promises as fs24 } from "fs";
|
|
14012
|
-
import { join as
|
|
14116
|
+
import { join as join17 } from "path";
|
|
14013
14117
|
import { checkbox as checkbox6, confirm as confirm18, Separator } from "@inquirer/prompts";
|
|
14014
14118
|
function createRulesSyncCommand() {
|
|
14015
14119
|
return new Command84("sync").description("Regenerate rule outputs for all configured IDEs").option("--ides <ides>", "Comma-separated list of IDEs to sync (default: all configured)").option("--detect", "Auto-detect active IDEs instead of using config").option("-y, --yes", "Skip confirmations").action(async (options) => {
|
|
14016
|
-
const rulePresetDir =
|
|
14017
|
-
const presetJsonPath =
|
|
14120
|
+
const rulePresetDir = join17(process.cwd(), ".jai1", "rule-preset");
|
|
14121
|
+
const presetJsonPath = join17(rulePresetDir, "preset.json");
|
|
14018
14122
|
let presetExists = false;
|
|
14019
14123
|
let presetData = null;
|
|
14020
14124
|
try {
|
|
@@ -14151,7 +14255,7 @@ Current IDE(s): ${currentIdes.join(", ") || "none"}`);
|
|
|
14151
14255
|
const files = await fs24.readdir(rulePresetDir);
|
|
14152
14256
|
for (const file of files) {
|
|
14153
14257
|
if (file.endsWith(".mdc") || file.endsWith(".md")) {
|
|
14154
|
-
const filePath =
|
|
14258
|
+
const filePath = join17(rulePresetDir, file);
|
|
14155
14259
|
const content = await fs24.readFile(filePath, "utf-8");
|
|
14156
14260
|
bundle.files[file] = content;
|
|
14157
14261
|
}
|
|
@@ -14166,8 +14270,8 @@ Current IDE(s): ${currentIdes.join(", ") || "none"}`);
|
|
|
14166
14270
|
}
|
|
14167
14271
|
const files2 = generatorService.generateForIde(bundle, ideId);
|
|
14168
14272
|
for (const file of files2) {
|
|
14169
|
-
const fullPath =
|
|
14170
|
-
await fs24.mkdir(
|
|
14273
|
+
const fullPath = join17(process.cwd(), file.path);
|
|
14274
|
+
await fs24.mkdir(join17(fullPath, ".."), { recursive: true });
|
|
14171
14275
|
await fs24.writeFile(fullPath, file.content, "utf-8");
|
|
14172
14276
|
}
|
|
14173
14277
|
console.log(`\u2713 ${format.name} - ${files2.length} files regenerated`);
|
|
@@ -14232,7 +14336,7 @@ function buildIdeChoices(currentIdes, detected, suggestions) {
|
|
|
14232
14336
|
// src/commands/rules/info.ts
|
|
14233
14337
|
import { Command as Command85 } from "commander";
|
|
14234
14338
|
import { promises as fs25 } from "fs";
|
|
14235
|
-
import { join as
|
|
14339
|
+
import { join as join18 } from "path";
|
|
14236
14340
|
function createRulesInfoCommand() {
|
|
14237
14341
|
return new Command85("info").description("Show current preset information").option("--json", "Output as JSON").action(async (options) => {
|
|
14238
14342
|
const projectConfigService = new ProjectConfigService();
|
|
@@ -14247,8 +14351,8 @@ function createRulesInfoCommand() {
|
|
|
14247
14351
|
return;
|
|
14248
14352
|
}
|
|
14249
14353
|
console.log("\u{1F4CB} Current Preset Information\n");
|
|
14250
|
-
const rulePresetDir =
|
|
14251
|
-
const presetJsonPath =
|
|
14354
|
+
const rulePresetDir = join18(process.cwd(), ".jai1", "rule-preset");
|
|
14355
|
+
const presetJsonPath = join18(rulePresetDir, "preset.json");
|
|
14252
14356
|
let presetMetadata = null;
|
|
14253
14357
|
let presetFiles = [];
|
|
14254
14358
|
try {
|
|
@@ -14315,7 +14419,7 @@ Available Backups (${rulesConfig.backups.length}):`);
|
|
|
14315
14419
|
}
|
|
14316
14420
|
async function checkPathExists(path13) {
|
|
14317
14421
|
try {
|
|
14318
|
-
await fs25.access(
|
|
14422
|
+
await fs25.access(join18(process.cwd(), path13));
|
|
14319
14423
|
return true;
|
|
14320
14424
|
} catch {
|
|
14321
14425
|
return false;
|
|
@@ -14378,7 +14482,7 @@ import chalk51 from "chalk";
|
|
|
14378
14482
|
|
|
14379
14483
|
// src/services/skills.service.ts
|
|
14380
14484
|
import { promises as fs26 } from "fs";
|
|
14381
|
-
import { join as
|
|
14485
|
+
import { join as join19 } from "path";
|
|
14382
14486
|
import { execFile } from "child_process";
|
|
14383
14487
|
import { promisify } from "util";
|
|
14384
14488
|
var execFileAsync = promisify(execFile);
|
|
@@ -14414,14 +14518,14 @@ var SkillsService = class {
|
|
|
14414
14518
|
* List locally installed skills from .jai1/skills/
|
|
14415
14519
|
*/
|
|
14416
14520
|
async listLocal(projectRoot) {
|
|
14417
|
-
const skillsDir =
|
|
14521
|
+
const skillsDir = join19(projectRoot, ".jai1", "skills");
|
|
14418
14522
|
const skills = [];
|
|
14419
14523
|
try {
|
|
14420
14524
|
const entries = await fs26.readdir(skillsDir, { withFileTypes: true });
|
|
14421
14525
|
for (const entry of entries) {
|
|
14422
14526
|
if (!entry.isDirectory()) continue;
|
|
14423
|
-
const skillPath =
|
|
14424
|
-
const skillMd =
|
|
14527
|
+
const skillPath = join19(skillsDir, entry.name);
|
|
14528
|
+
const skillMd = join19(skillPath, "SKILL.md");
|
|
14425
14529
|
try {
|
|
14426
14530
|
await fs26.access(skillMd);
|
|
14427
14531
|
} catch {
|
|
@@ -14446,8 +14550,8 @@ var SkillsService = class {
|
|
|
14446
14550
|
* Get detailed info for a single skill
|
|
14447
14551
|
*/
|
|
14448
14552
|
async getSkillInfo(projectRoot, skillName) {
|
|
14449
|
-
const skillPath =
|
|
14450
|
-
const skillMd =
|
|
14553
|
+
const skillPath = join19(projectRoot, ".jai1", "skills", skillName);
|
|
14554
|
+
const skillMd = join19(skillPath, "SKILL.md");
|
|
14451
14555
|
try {
|
|
14452
14556
|
await fs26.access(skillMd);
|
|
14453
14557
|
} catch {
|
|
@@ -14522,22 +14626,22 @@ var SkillsService = class {
|
|
|
14522
14626
|
* After npx skills add, copy newly installed skills from .agents/skills/ into .jai1/skills/
|
|
14523
14627
|
*/
|
|
14524
14628
|
async copySkillshResultsToJai1(projectRoot, specificSkill) {
|
|
14525
|
-
const jai1SkillsDir =
|
|
14629
|
+
const jai1SkillsDir = join19(projectRoot, ".jai1", "skills");
|
|
14526
14630
|
await fs26.mkdir(jai1SkillsDir, { recursive: true });
|
|
14527
|
-
const universalDir =
|
|
14631
|
+
const universalDir = join19(projectRoot, ".agents", "skills");
|
|
14528
14632
|
try {
|
|
14529
14633
|
const entries = await fs26.readdir(universalDir, { withFileTypes: true });
|
|
14530
14634
|
for (const entry of entries) {
|
|
14531
14635
|
if (!entry.isDirectory()) continue;
|
|
14532
14636
|
if (specificSkill && entry.name !== specificSkill) continue;
|
|
14533
|
-
const srcSkill =
|
|
14534
|
-
const skillMd =
|
|
14637
|
+
const srcSkill = join19(universalDir, entry.name);
|
|
14638
|
+
const skillMd = join19(srcSkill, "SKILL.md");
|
|
14535
14639
|
try {
|
|
14536
14640
|
await fs26.access(skillMd);
|
|
14537
14641
|
} catch {
|
|
14538
14642
|
continue;
|
|
14539
14643
|
}
|
|
14540
|
-
const targetSkill =
|
|
14644
|
+
const targetSkill = join19(jai1SkillsDir, entry.name);
|
|
14541
14645
|
try {
|
|
14542
14646
|
await fs26.access(targetSkill);
|
|
14543
14647
|
} catch {
|
|
@@ -14576,7 +14680,7 @@ var SkillsService = class {
|
|
|
14576
14680
|
const target = this.getIDETarget(ide);
|
|
14577
14681
|
if (!target) continue;
|
|
14578
14682
|
for (const skill of skillsToSync) {
|
|
14579
|
-
const targetPath =
|
|
14683
|
+
const targetPath = join19(projectRoot, target.skillsPath, skill.slug);
|
|
14580
14684
|
try {
|
|
14581
14685
|
let status = "created";
|
|
14582
14686
|
try {
|
|
@@ -14640,7 +14744,7 @@ var SkillsService = class {
|
|
|
14640
14744
|
const entries = await fs26.readdir(dirPath, { withFileTypes: true });
|
|
14641
14745
|
for (const entry of entries) {
|
|
14642
14746
|
if (entry.isDirectory()) {
|
|
14643
|
-
count += await this.countFiles(
|
|
14747
|
+
count += await this.countFiles(join19(dirPath, entry.name));
|
|
14644
14748
|
} else {
|
|
14645
14749
|
count++;
|
|
14646
14750
|
}
|
|
@@ -14653,8 +14757,8 @@ var SkillsService = class {
|
|
|
14653
14757
|
async copyDir(source, target) {
|
|
14654
14758
|
const entries = await fs26.readdir(source, { withFileTypes: true });
|
|
14655
14759
|
for (const entry of entries) {
|
|
14656
|
-
const srcPath =
|
|
14657
|
-
const tgtPath =
|
|
14760
|
+
const srcPath = join19(source, entry.name);
|
|
14761
|
+
const tgtPath = join19(target, entry.name);
|
|
14658
14762
|
if (entry.isDirectory()) {
|
|
14659
14763
|
await fs26.mkdir(tgtPath, { recursive: true });
|
|
14660
14764
|
await this.copyDir(srcPath, tgtPath);
|
|
@@ -14728,7 +14832,7 @@ function createSkillsFindCommand() {
|
|
|
14728
14832
|
|
|
14729
14833
|
// src/commands/skills/add.ts
|
|
14730
14834
|
import { Command as Command88 } from "commander";
|
|
14731
|
-
import { join as
|
|
14835
|
+
import { join as join20 } from "path";
|
|
14732
14836
|
import chalk52 from "chalk";
|
|
14733
14837
|
import { checkbox as checkbox7 } from "@inquirer/prompts";
|
|
14734
14838
|
function createSkillsAddCommand() {
|
|
@@ -14750,7 +14854,7 @@ function createSkillsAddCommand() {
|
|
|
14750
14854
|
}
|
|
14751
14855
|
console.log(chalk52.cyan(`\u{1F4E6} \u0110ang c\xE0i \u0111\u1EB7t skill: ${name}...`));
|
|
14752
14856
|
console.log();
|
|
14753
|
-
const targetDir =
|
|
14857
|
+
const targetDir = join20(projectRoot, ".jai1");
|
|
14754
14858
|
await skillsService.installFromServer(config, name, targetDir);
|
|
14755
14859
|
console.log(chalk52.green(`\u2705 \u0110\xE3 c\xE0i \u0111\u1EB7t skill "${name}" v\xE0o .jai1/skills/${name}/`));
|
|
14756
14860
|
}
|
|
@@ -15240,8 +15344,8 @@ function getInstallCommand(packageManager2) {
|
|
|
15240
15344
|
import { Command as Command94 } from "commander";
|
|
15241
15345
|
import { confirm as confirm22, select as select6 } from "@inquirer/prompts";
|
|
15242
15346
|
import { promises as fs27 } from "fs";
|
|
15243
|
-
import { join as
|
|
15244
|
-
import { existsSync as
|
|
15347
|
+
import { join as join21 } from "path";
|
|
15348
|
+
import { existsSync as existsSync5 } from "fs";
|
|
15245
15349
|
function createCleanCommand() {
|
|
15246
15350
|
return new Command94("clean").description("Clean up backups, cache, IDE configs, and .jai1 directory").option("-y, --yes", "Skip confirmation").option("--backups", "Clean only backup files").option("--jai1", "Clean only .jai1/ directory").option("--ide", "Clean only IDE directories (.cursor, .windsurf, .agent, .claude, .opencode)").option("--all", "Clean all (backups + .jai1 + IDE dirs)").action(async (options) => {
|
|
15247
15351
|
await handleClean(options);
|
|
@@ -15254,7 +15358,7 @@ async function handleClean(options) {
|
|
|
15254
15358
|
{
|
|
15255
15359
|
name: "Backups",
|
|
15256
15360
|
description: "Component backup files (.jai1_backup/)",
|
|
15257
|
-
path:
|
|
15361
|
+
path: join21(cwd, ".jai1_backup"),
|
|
15258
15362
|
check: async () => {
|
|
15259
15363
|
const backups = await service.listBackups(cwd);
|
|
15260
15364
|
return { exists: backups.length > 0, count: backups.length };
|
|
@@ -15266,13 +15370,13 @@ async function handleClean(options) {
|
|
|
15266
15370
|
{
|
|
15267
15371
|
name: "Jai1 Config",
|
|
15268
15372
|
description: "Jai1 framework config (.jai1/)",
|
|
15269
|
-
path:
|
|
15373
|
+
path: join21(cwd, ".jai1"),
|
|
15270
15374
|
check: async () => {
|
|
15271
|
-
const exists =
|
|
15375
|
+
const exists = existsSync5(join21(cwd, ".jai1"));
|
|
15272
15376
|
return { exists };
|
|
15273
15377
|
},
|
|
15274
15378
|
clean: async () => {
|
|
15275
|
-
await fs27.rm(
|
|
15379
|
+
await fs27.rm(join21(cwd, ".jai1"), { recursive: true, force: true });
|
|
15276
15380
|
}
|
|
15277
15381
|
}
|
|
15278
15382
|
];
|
|
@@ -15284,8 +15388,8 @@ async function handleClean(options) {
|
|
|
15284
15388
|
{ name: "OpenCode", dir: ".opencode" }
|
|
15285
15389
|
];
|
|
15286
15390
|
for (const ide of ideDirectories) {
|
|
15287
|
-
const idePath =
|
|
15288
|
-
if (
|
|
15391
|
+
const idePath = join21(cwd, ide.dir);
|
|
15392
|
+
if (existsSync5(idePath)) {
|
|
15289
15393
|
targets.push({
|
|
15290
15394
|
name: `IDE: ${ide.name}`,
|
|
15291
15395
|
description: `${ide.name} IDE config (${ide.dir}/)`,
|
|
@@ -16293,7 +16397,7 @@ async function handleSyncProject(options) {
|
|
|
16293
16397
|
// src/commands/framework/info.ts
|
|
16294
16398
|
import { Command as Command98 } from "commander";
|
|
16295
16399
|
import { promises as fs28 } from "fs";
|
|
16296
|
-
import { join as
|
|
16400
|
+
import { join as join22 } from "path";
|
|
16297
16401
|
import { homedir as homedir4 } from "os";
|
|
16298
16402
|
function createInfoCommand() {
|
|
16299
16403
|
const cmd = new Command98("info").description("Show client configuration and status").option("--json", "Output as JSON").option("--verbose", "Show detailed information").action(async (options) => {
|
|
@@ -16307,7 +16411,7 @@ async function handleInfo(options) {
|
|
|
16307
16411
|
if (!config) {
|
|
16308
16412
|
throw new ValidationError(`Not initialized. Run "${getCliName()} auth" first.`);
|
|
16309
16413
|
}
|
|
16310
|
-
const frameworkPath =
|
|
16414
|
+
const frameworkPath = join22(homedir4(), ".jai1", "framework");
|
|
16311
16415
|
const projectStatus = await getProjectStatus2();
|
|
16312
16416
|
const info = {
|
|
16313
16417
|
configPath: configService.getConfigPath(),
|
|
@@ -16342,7 +16446,7 @@ function maskKey4(key) {
|
|
|
16342
16446
|
return "****" + key.slice(-4);
|
|
16343
16447
|
}
|
|
16344
16448
|
async function getProjectStatus2() {
|
|
16345
|
-
const projectJai1 =
|
|
16449
|
+
const projectJai1 = join22(process.cwd(), ".jai1");
|
|
16346
16450
|
try {
|
|
16347
16451
|
await fs28.access(projectJai1);
|
|
16348
16452
|
return { exists: true, version: "Synced" };
|
|
@@ -16536,7 +16640,7 @@ import { Command as Command101 } from "commander";
|
|
|
16536
16640
|
import { checkbox as checkbox9, confirm as confirm25, select as select7 } from "@inquirer/prompts";
|
|
16537
16641
|
import fs29 from "fs/promises";
|
|
16538
16642
|
import path12 from "path";
|
|
16539
|
-
import { existsSync as
|
|
16643
|
+
import { existsSync as existsSync6 } from "fs";
|
|
16540
16644
|
var PERFORMANCE_GROUPS2 = {
|
|
16541
16645
|
telemetry: {
|
|
16542
16646
|
name: "Telemetry",
|
|
@@ -16766,12 +16870,12 @@ async function applyGroups2(groupKeys, action) {
|
|
|
16766
16870
|
console.log(' \u{1F4A1} Ch\u1EA1y "jai1 vscode list" \u0111\u1EC3 xem danh s\xE1ch nh\xF3m c\xF3 s\u1EB5n.');
|
|
16767
16871
|
return;
|
|
16768
16872
|
}
|
|
16769
|
-
if (!
|
|
16873
|
+
if (!existsSync6(vscodeDir)) {
|
|
16770
16874
|
await fs29.mkdir(vscodeDir, { recursive: true });
|
|
16771
16875
|
console.log("\u{1F4C1} \u0110\xE3 t\u1EA1o th\u01B0 m\u1EE5c .vscode/");
|
|
16772
16876
|
}
|
|
16773
16877
|
let currentSettings = {};
|
|
16774
|
-
if (
|
|
16878
|
+
if (existsSync6(settingsPath)) {
|
|
16775
16879
|
try {
|
|
16776
16880
|
const content = await fs29.readFile(settingsPath, "utf-8");
|
|
16777
16881
|
currentSettings = JSON.parse(content);
|
|
@@ -16821,7 +16925,7 @@ async function applyGroups2(groupKeys, action) {
|
|
|
16821
16925
|
async function resetSettings2(groupKeys) {
|
|
16822
16926
|
const vscodeDir = path12.join(process.cwd(), ".vscode");
|
|
16823
16927
|
const settingsPath = path12.join(vscodeDir, "settings.json");
|
|
16824
|
-
if (!
|
|
16928
|
+
if (!existsSync6(settingsPath)) {
|
|
16825
16929
|
console.log("\n\u26A0\uFE0F Kh\xF4ng t\xECm th\u1EA5y file settings.json");
|
|
16826
16930
|
return;
|
|
16827
16931
|
}
|