@jvittechs/j 1.0.61 → 1.0.63
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-F6GY6L6O.js → chunk-LZZF4JQS.js} +27 -44
- package/dist/chunk-LZZF4JQS.js.map +1 -0
- package/dist/chunk-WOAXYUZ6.js +62 -0
- package/dist/chunk-WOAXYUZ6.js.map +1 -0
- package/dist/cli.js +151 -95
- package/dist/cli.js.map +1 -1
- package/dist/{summary-KFXQDFG6.js → summary-EJWKLQF4.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-F6GY6L6O.js.map +0 -1
- /package/dist/{summary-KFXQDFG6.js.map → summary-EJWKLQF4.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -10,14 +10,17 @@ import {
|
|
|
10
10
|
createSettingsShowCommand
|
|
11
11
|
} from "./chunk-5RDBJYO2.js";
|
|
12
12
|
import {
|
|
13
|
-
BLOCKED_ICON,
|
|
14
13
|
CloudTaskProvider,
|
|
14
|
+
TaskService,
|
|
15
|
+
createTaskSummaryCommand
|
|
16
|
+
} from "./chunk-LZZF4JQS.js";
|
|
17
|
+
import {
|
|
18
|
+
BLOCKED_ICON,
|
|
15
19
|
PRIORITY_ICONS,
|
|
16
20
|
PRIORITY_LABELS,
|
|
17
21
|
STATUS_ICONS,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
} from "./chunk-F6GY6L6O.js";
|
|
22
|
+
TaskSchema
|
|
23
|
+
} from "./chunk-WOAXYUZ6.js";
|
|
21
24
|
import {
|
|
22
25
|
ConfigService,
|
|
23
26
|
SettingsService
|
|
@@ -157,7 +160,7 @@ import { basename as basename5 } from "path";
|
|
|
157
160
|
// package.json
|
|
158
161
|
var package_default = {
|
|
159
162
|
name: "@jvittechs/j",
|
|
160
|
-
version: "1.0.
|
|
163
|
+
version: "1.0.63",
|
|
161
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.",
|
|
162
165
|
type: "module",
|
|
163
166
|
bin: {
|
|
@@ -11391,6 +11394,30 @@ async function registerProject(config, projectId, repoUrl, silent) {
|
|
|
11391
11394
|
return null;
|
|
11392
11395
|
}
|
|
11393
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
|
+
}
|
|
11394
11421
|
function createSettingsInitCommand() {
|
|
11395
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) => {
|
|
11396
11423
|
try {
|
|
@@ -11449,9 +11476,18 @@ function createSettingsInitCommand() {
|
|
|
11449
11476
|
repoUrl,
|
|
11450
11477
|
!!options.json
|
|
11451
11478
|
);
|
|
11479
|
+
const finalProjectId = registeredProjectId && registeredProjectId !== projectId ? registeredProjectId : projectId;
|
|
11452
11480
|
if (registeredProjectId && registeredProjectId !== projectId) {
|
|
11453
11481
|
await service.set("tasks.projectId", registeredProjectId);
|
|
11454
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
|
+
}
|
|
11455
11491
|
}
|
|
11456
11492
|
}
|
|
11457
11493
|
const finalSettings = service.load();
|
|
@@ -11488,6 +11524,8 @@ function createSettingsInitCommand() {
|
|
|
11488
11524
|
// src/commands/settings/set.ts
|
|
11489
11525
|
import { Command as Command59 } from "commander";
|
|
11490
11526
|
import chalk32 from "chalk";
|
|
11527
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
|
|
11528
|
+
import { join as join9 } from "path";
|
|
11491
11529
|
function createSettingsSetCommand() {
|
|
11492
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) => {
|
|
11493
11531
|
try {
|
|
@@ -11513,15 +11551,29 @@ function createSettingsSetCommand() {
|
|
|
11513
11551
|
const repoUrl = service.resolveGitRepoUrl();
|
|
11514
11552
|
const projectId = service.getProjectId();
|
|
11515
11553
|
if (repoUrl && projectId) {
|
|
11554
|
+
let finalProjectId = projectId;
|
|
11516
11555
|
try {
|
|
11517
11556
|
const provider = new CloudTaskProvider(config, projectId);
|
|
11518
11557
|
const registeredId = await provider.ensureProjectRegistered(repoUrl);
|
|
11519
11558
|
console.log(chalk32.green(" \u2713 Project registered on server"));
|
|
11520
11559
|
if (registeredId && registeredId !== projectId) {
|
|
11521
11560
|
await service.set("tasks.projectId", registeredId);
|
|
11522
|
-
|
|
11523
|
-
}
|
|
11524
|
-
|
|
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
|
+
}
|
|
11525
11577
|
}
|
|
11526
11578
|
} catch (error) {
|
|
11527
11579
|
const msg = error instanceof Error ? error.message : String(error);
|
|
@@ -11673,6 +11725,9 @@ function printTaskLine(task, resolvedIds) {
|
|
|
11673
11725
|
const blockedBy = task.depends_on.filter((id) => !resolvedIds.has(id));
|
|
11674
11726
|
line += chalk35.red(` (blocked: ${blockedBy.join(", ")})`);
|
|
11675
11727
|
}
|
|
11728
|
+
if (task.type && task.type !== "task") {
|
|
11729
|
+
line += chalk35.magenta(` {${task.type}}`);
|
|
11730
|
+
}
|
|
11676
11731
|
if (task.parent) {
|
|
11677
11732
|
line += chalk35.dim(` [${task.parent}]`);
|
|
11678
11733
|
}
|
|
@@ -11965,7 +12020,8 @@ function createTaskSyncCommand() {
|
|
|
11965
12020
|
const cloudTasks = await service.cloud.pull();
|
|
11966
12021
|
console.log(chalk42.dim(` \u2193 ${cloudTasks.length} tasks fetched from cloud`));
|
|
11967
12022
|
if (isFull) {
|
|
11968
|
-
const localTasks = await service.
|
|
12023
|
+
const localTasks = await service.readLocal();
|
|
12024
|
+
console.log(chalk42.dim(` \u2190 ${localTasks.length} tasks in local file`));
|
|
11969
12025
|
const localMap = new Map(localTasks.map((t) => [t.id, t]));
|
|
11970
12026
|
const cloudMap = new Map(cloudTasks.map((t) => [t.id, t]));
|
|
11971
12027
|
const merged = /* @__PURE__ */ new Map();
|
|
@@ -11987,7 +12043,7 @@ function createTaskSyncCommand() {
|
|
|
11987
12043
|
console.log(chalk42.green(`\u2705 Pull complete: ${cloudTasks.length} tasks written`));
|
|
11988
12044
|
}
|
|
11989
12045
|
} else if (doPush) {
|
|
11990
|
-
const localTasks = await service.
|
|
12046
|
+
const localTasks = await service.readLocal();
|
|
11991
12047
|
await service.cloud.push(localTasks);
|
|
11992
12048
|
console.log(chalk42.green(`\u2705 Push complete: ${localTasks.length} tasks uploaded`));
|
|
11993
12049
|
}
|
|
@@ -12396,7 +12452,7 @@ function createTasksCommand() {
|
|
|
12396
12452
|
cmd.addCommand(createTaskDeleteCommand());
|
|
12397
12453
|
cmd.addCommand(createTaskGuideCommand());
|
|
12398
12454
|
cmd.action(async () => {
|
|
12399
|
-
const { handleTaskSummary } = await import("./summary-
|
|
12455
|
+
const { handleTaskSummary } = await import("./summary-EJWKLQF4.js");
|
|
12400
12456
|
await handleTaskSummary({ json: false });
|
|
12401
12457
|
});
|
|
12402
12458
|
return cmd;
|
|
@@ -12413,7 +12469,7 @@ import Table6 from "cli-table3";
|
|
|
12413
12469
|
|
|
12414
12470
|
// src/services/starter-kit.service.ts
|
|
12415
12471
|
import { promises as fs18 } from "fs";
|
|
12416
|
-
import { join as
|
|
12472
|
+
import { join as join10 } from "path";
|
|
12417
12473
|
import AdmZip from "adm-zip";
|
|
12418
12474
|
var StarterKitService = class {
|
|
12419
12475
|
/**
|
|
@@ -12460,9 +12516,9 @@ var StarterKitService = class {
|
|
|
12460
12516
|
throw new NetworkError(`Failed to download kit: HTTP ${response.status}`);
|
|
12461
12517
|
}
|
|
12462
12518
|
if (onProgress) onProgress(30);
|
|
12463
|
-
const tmpDir =
|
|
12519
|
+
const tmpDir = join10(process.env.TMPDIR || "/tmp", "jai1-kits");
|
|
12464
12520
|
await fs18.mkdir(tmpDir, { recursive: true });
|
|
12465
|
-
const tmpFile =
|
|
12521
|
+
const tmpFile = join10(tmpDir, `${slug}.zip`);
|
|
12466
12522
|
const buffer = await response.arrayBuffer();
|
|
12467
12523
|
await fs18.writeFile(tmpFile, Buffer.from(buffer));
|
|
12468
12524
|
if (onProgress) onProgress(60);
|
|
@@ -12595,7 +12651,7 @@ Post-Init Commands:`);
|
|
|
12595
12651
|
// src/commands/kit/create.ts
|
|
12596
12652
|
import { Command as Command78 } from "commander";
|
|
12597
12653
|
import { promises as fs19 } from "fs";
|
|
12598
|
-
import { join as
|
|
12654
|
+
import { join as join11 } from "path";
|
|
12599
12655
|
import { select as select3, input as input2, checkbox as checkbox4 } from "@inquirer/prompts";
|
|
12600
12656
|
import { execa as execa2 } from "execa";
|
|
12601
12657
|
|
|
@@ -12658,7 +12714,7 @@ function createKitCreateCommand() {
|
|
|
12658
12714
|
}
|
|
12659
12715
|
}
|
|
12660
12716
|
}
|
|
12661
|
-
const targetDir = directory ||
|
|
12717
|
+
const targetDir = directory || join11(process.cwd(), options.name || slug);
|
|
12662
12718
|
try {
|
|
12663
12719
|
await fs19.access(targetDir);
|
|
12664
12720
|
throw new Error(`Directory already exists: ${targetDir}`);
|
|
@@ -12723,7 +12779,7 @@ function createKitCreateCommand() {
|
|
|
12723
12779
|
);
|
|
12724
12780
|
for (const filepath of expandedPaths) {
|
|
12725
12781
|
console.log(` \u{1F4E5} Installing ${filepath}...`);
|
|
12726
|
-
await componentsService.install(config, filepath,
|
|
12782
|
+
await componentsService.install(config, filepath, join11(targetDir, ".jai1"));
|
|
12727
12783
|
}
|
|
12728
12784
|
console.log(" \u2713 Framework components applied");
|
|
12729
12785
|
}
|
|
@@ -12803,7 +12859,7 @@ async function getAllFiles(dir) {
|
|
|
12803
12859
|
const files = [];
|
|
12804
12860
|
const entries = await fs19.readdir(dir, { withFileTypes: true });
|
|
12805
12861
|
for (const entry of entries) {
|
|
12806
|
-
const fullPath =
|
|
12862
|
+
const fullPath = join11(dir, entry.name);
|
|
12807
12863
|
if (entry.isDirectory()) {
|
|
12808
12864
|
if (!entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
12809
12865
|
files.push(...await getAllFiles(fullPath));
|
|
@@ -12919,20 +12975,20 @@ function createRulesListCommand() {
|
|
|
12919
12975
|
// src/commands/rules/init.ts
|
|
12920
12976
|
import { Command as Command81 } from "commander";
|
|
12921
12977
|
import { promises as fs21 } from "fs";
|
|
12922
|
-
import { join as
|
|
12978
|
+
import { join as join13 } from "path";
|
|
12923
12979
|
import { select as select4, confirm as confirm15 } from "@inquirer/prompts";
|
|
12924
12980
|
|
|
12925
12981
|
// src/services/project-config.service.ts
|
|
12926
12982
|
import { promises as fs20 } from "fs";
|
|
12927
|
-
import { join as
|
|
12983
|
+
import { join as join12 } from "path";
|
|
12928
12984
|
var ProjectConfigService = class {
|
|
12929
12985
|
projectRoot;
|
|
12930
12986
|
configDir;
|
|
12931
12987
|
configPath;
|
|
12932
12988
|
constructor(projectRoot = process.cwd()) {
|
|
12933
12989
|
this.projectRoot = projectRoot;
|
|
12934
|
-
this.configDir =
|
|
12935
|
-
this.configPath =
|
|
12990
|
+
this.configDir = join12(this.projectRoot, ".jai1");
|
|
12991
|
+
this.configPath = join12(this.configDir, "project.json");
|
|
12936
12992
|
}
|
|
12937
12993
|
/**
|
|
12938
12994
|
* Check if config file exists
|
|
@@ -13138,10 +13194,10 @@ function createRulesInitCommand() {
|
|
|
13138
13194
|
});
|
|
13139
13195
|
}
|
|
13140
13196
|
async function applyCursorFormat(bundle) {
|
|
13141
|
-
const rulesDir =
|
|
13197
|
+
const rulesDir = join13(process.cwd(), ".cursor", "rules");
|
|
13142
13198
|
await fs21.mkdir(rulesDir, { recursive: true });
|
|
13143
13199
|
for (const [filename, content] of Object.entries(bundle.files)) {
|
|
13144
|
-
const filePath =
|
|
13200
|
+
const filePath = join13(rulesDir, filename);
|
|
13145
13201
|
await fs21.writeFile(filePath, content, "utf-8");
|
|
13146
13202
|
console.log(`\u2713 Created .cursor/rules/${filename}`);
|
|
13147
13203
|
}
|
|
@@ -13176,7 +13232,7 @@ async function applyAgentsMdFormat(bundle) {
|
|
|
13176
13232
|
// src/commands/rules/apply.ts
|
|
13177
13233
|
import { Command as Command82 } from "commander";
|
|
13178
13234
|
import { promises as fs23 } from "fs";
|
|
13179
|
-
import { join as
|
|
13235
|
+
import { join as join15 } from "path";
|
|
13180
13236
|
import { search, confirm as confirm16, checkbox as checkbox5 } from "@inquirer/prompts";
|
|
13181
13237
|
|
|
13182
13238
|
// src/services/rules-generator.service.ts
|
|
@@ -13468,7 +13524,7 @@ Follow all instructions and patterns defined in AGENTS.md above.
|
|
|
13468
13524
|
|
|
13469
13525
|
// src/services/backup.service.ts
|
|
13470
13526
|
import { promises as fs22 } from "fs";
|
|
13471
|
-
import { join as
|
|
13527
|
+
import { join as join14, dirname } from "path";
|
|
13472
13528
|
var BackupService = class {
|
|
13473
13529
|
backupDir = ".jai1/backups";
|
|
13474
13530
|
/**
|
|
@@ -13476,7 +13532,7 @@ var BackupService = class {
|
|
|
13476
13532
|
*/
|
|
13477
13533
|
async createBackup(ides, presetSlug) {
|
|
13478
13534
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
13479
|
-
const backupPath =
|
|
13535
|
+
const backupPath = join14(this.backupDir, timestamp);
|
|
13480
13536
|
const backedUpFiles = [];
|
|
13481
13537
|
let hasContent = false;
|
|
13482
13538
|
for (const ideId of ides) {
|
|
@@ -13485,7 +13541,7 @@ var BackupService = class {
|
|
|
13485
13541
|
console.warn(`Unknown IDE format: ${ideId}, skipping backup`);
|
|
13486
13542
|
continue;
|
|
13487
13543
|
}
|
|
13488
|
-
const rulesPath = format.rulesPath === "." ? process.cwd() :
|
|
13544
|
+
const rulesPath = format.rulesPath === "." ? process.cwd() : join14(process.cwd(), format.rulesPath);
|
|
13489
13545
|
try {
|
|
13490
13546
|
const exists = await this.pathExists(rulesPath);
|
|
13491
13547
|
if (!exists) {
|
|
@@ -13503,14 +13559,14 @@ var BackupService = class {
|
|
|
13503
13559
|
const files = await fs22.readdir(rulesPath);
|
|
13504
13560
|
for (const file of files) {
|
|
13505
13561
|
if (file.endsWith(format.fileExtension)) {
|
|
13506
|
-
const originalPath =
|
|
13507
|
-
const relativePath =
|
|
13508
|
-
const destPath =
|
|
13562
|
+
const originalPath = join14(rulesPath, file);
|
|
13563
|
+
const relativePath = join14(format.rulesPath, file);
|
|
13564
|
+
const destPath = join14(backupPath, ideId, file);
|
|
13509
13565
|
await fs22.mkdir(dirname(destPath), { recursive: true });
|
|
13510
13566
|
await fs22.copyFile(originalPath, destPath);
|
|
13511
13567
|
backedUpFiles.push({
|
|
13512
13568
|
originalPath: relativePath,
|
|
13513
|
-
backupPath:
|
|
13569
|
+
backupPath: join14(ideId, file),
|
|
13514
13570
|
ide: ideId
|
|
13515
13571
|
});
|
|
13516
13572
|
hasContent = true;
|
|
@@ -13533,7 +13589,7 @@ var BackupService = class {
|
|
|
13533
13589
|
};
|
|
13534
13590
|
await fs22.mkdir(backupPath, { recursive: true });
|
|
13535
13591
|
await fs22.writeFile(
|
|
13536
|
-
|
|
13592
|
+
join14(backupPath, "metadata.json"),
|
|
13537
13593
|
JSON.stringify(metadata, null, 2),
|
|
13538
13594
|
"utf-8"
|
|
13539
13595
|
);
|
|
@@ -13543,18 +13599,18 @@ var BackupService = class {
|
|
|
13543
13599
|
* Backup a single file (for AGENTS.md, GEMINI.md)
|
|
13544
13600
|
*/
|
|
13545
13601
|
async backupSingleFile(filename, backupPath, ideId, backedUpFiles) {
|
|
13546
|
-
const originalPath =
|
|
13602
|
+
const originalPath = join14(process.cwd(), filename);
|
|
13547
13603
|
try {
|
|
13548
13604
|
const exists = await this.pathExists(originalPath);
|
|
13549
13605
|
if (!exists) {
|
|
13550
13606
|
return;
|
|
13551
13607
|
}
|
|
13552
|
-
const destPath =
|
|
13608
|
+
const destPath = join14(backupPath, ideId, filename);
|
|
13553
13609
|
await fs22.mkdir(dirname(destPath), { recursive: true });
|
|
13554
13610
|
await fs22.copyFile(originalPath, destPath);
|
|
13555
13611
|
backedUpFiles.push({
|
|
13556
13612
|
originalPath: filename,
|
|
13557
|
-
backupPath:
|
|
13613
|
+
backupPath: join14(ideId, filename),
|
|
13558
13614
|
ide: ideId
|
|
13559
13615
|
});
|
|
13560
13616
|
} catch (error) {
|
|
@@ -13564,14 +13620,14 @@ var BackupService = class {
|
|
|
13564
13620
|
* Restore files from a backup
|
|
13565
13621
|
*/
|
|
13566
13622
|
async restoreBackup(backupPath) {
|
|
13567
|
-
const metadataPath =
|
|
13623
|
+
const metadataPath = join14(backupPath, "metadata.json");
|
|
13568
13624
|
const metadataContent = await fs22.readFile(metadataPath, "utf-8");
|
|
13569
13625
|
const metadata = JSON.parse(metadataContent);
|
|
13570
13626
|
console.log(`
|
|
13571
13627
|
Restoring backup from ${metadata.timestamp}...`);
|
|
13572
13628
|
for (const file of metadata.files) {
|
|
13573
|
-
const sourcePath =
|
|
13574
|
-
const destPath =
|
|
13629
|
+
const sourcePath = join14(backupPath, file.backupPath);
|
|
13630
|
+
const destPath = join14(process.cwd(), file.originalPath);
|
|
13575
13631
|
await fs22.mkdir(dirname(destPath), { recursive: true });
|
|
13576
13632
|
await fs22.copyFile(sourcePath, destPath);
|
|
13577
13633
|
console.log(`\u2713 Restored ${file.originalPath}`);
|
|
@@ -13583,7 +13639,7 @@ Restoring backup from ${metadata.timestamp}...`);
|
|
|
13583
13639
|
*/
|
|
13584
13640
|
async listBackups() {
|
|
13585
13641
|
try {
|
|
13586
|
-
const backupDirPath =
|
|
13642
|
+
const backupDirPath = join14(process.cwd(), this.backupDir);
|
|
13587
13643
|
const exists = await this.pathExists(backupDirPath);
|
|
13588
13644
|
if (!exists) {
|
|
13589
13645
|
return [];
|
|
@@ -13592,7 +13648,7 @@ Restoring backup from ${metadata.timestamp}...`);
|
|
|
13592
13648
|
const backups = [];
|
|
13593
13649
|
for (const entry of entries) {
|
|
13594
13650
|
if (entry.isDirectory()) {
|
|
13595
|
-
const metadataPath =
|
|
13651
|
+
const metadataPath = join14(backupDirPath, entry.name, "metadata.json");
|
|
13596
13652
|
try {
|
|
13597
13653
|
const metadataContent = await fs22.readFile(metadataPath, "utf-8");
|
|
13598
13654
|
const metadata = JSON.parse(metadataContent);
|
|
@@ -13611,7 +13667,7 @@ Restoring backup from ${metadata.timestamp}...`);
|
|
|
13611
13667
|
* Delete a specific backup
|
|
13612
13668
|
*/
|
|
13613
13669
|
async deleteBackup(timestamp) {
|
|
13614
|
-
const backupPath =
|
|
13670
|
+
const backupPath = join14(process.cwd(), this.backupDir, timestamp);
|
|
13615
13671
|
await this.deleteDirectory(backupPath);
|
|
13616
13672
|
}
|
|
13617
13673
|
/**
|
|
@@ -13660,7 +13716,7 @@ Restoring backup from ${metadata.timestamp}...`);
|
|
|
13660
13716
|
}
|
|
13661
13717
|
const entries = await fs22.readdir(path13, { withFileTypes: true });
|
|
13662
13718
|
for (const entry of entries) {
|
|
13663
|
-
const fullPath =
|
|
13719
|
+
const fullPath = join14(path13, entry.name);
|
|
13664
13720
|
if (entry.isDirectory()) {
|
|
13665
13721
|
await this.deleteDirectory(fullPath);
|
|
13666
13722
|
} else {
|
|
@@ -13675,13 +13731,13 @@ Restoring backup from ${metadata.timestamp}...`);
|
|
|
13675
13731
|
* Get backup directory path
|
|
13676
13732
|
*/
|
|
13677
13733
|
getBackupDir() {
|
|
13678
|
-
return
|
|
13734
|
+
return join14(process.cwd(), this.backupDir);
|
|
13679
13735
|
}
|
|
13680
13736
|
/**
|
|
13681
13737
|
* Ensure backup directory exists
|
|
13682
13738
|
*/
|
|
13683
13739
|
async ensureBackupDir() {
|
|
13684
|
-
const backupDirPath =
|
|
13740
|
+
const backupDirPath = join14(process.cwd(), this.backupDir);
|
|
13685
13741
|
await fs22.mkdir(backupDirPath, { recursive: true });
|
|
13686
13742
|
}
|
|
13687
13743
|
};
|
|
@@ -13854,20 +13910,20 @@ function createRulesApplyCommand() {
|
|
|
13854
13910
|
}
|
|
13855
13911
|
}
|
|
13856
13912
|
console.log("\n\u{1F4DD} Applying preset...\n");
|
|
13857
|
-
const rulePresetDir =
|
|
13913
|
+
const rulePresetDir = join15(process.cwd(), ".jai1", "rule-preset");
|
|
13858
13914
|
try {
|
|
13859
13915
|
await fs23.rm(rulePresetDir, { recursive: true, force: true });
|
|
13860
13916
|
} catch {
|
|
13861
13917
|
}
|
|
13862
13918
|
await fs23.mkdir(rulePresetDir, { recursive: true });
|
|
13863
13919
|
await fs23.writeFile(
|
|
13864
|
-
|
|
13920
|
+
join15(rulePresetDir, "preset.json"),
|
|
13865
13921
|
JSON.stringify(bundle.preset, null, 2),
|
|
13866
13922
|
"utf-8"
|
|
13867
13923
|
);
|
|
13868
13924
|
for (const [filename, content] of Object.entries(bundle.files)) {
|
|
13869
|
-
const filePath =
|
|
13870
|
-
await fs23.mkdir(
|
|
13925
|
+
const filePath = join15(rulePresetDir, filename);
|
|
13926
|
+
await fs23.mkdir(join15(filePath, ".."), { recursive: true });
|
|
13871
13927
|
await fs23.writeFile(filePath, content, "utf-8");
|
|
13872
13928
|
}
|
|
13873
13929
|
console.log(`\u2713 Saved preset to .jai1/rule-preset/`);
|
|
@@ -13876,8 +13932,8 @@ function createRulesApplyCommand() {
|
|
|
13876
13932
|
try {
|
|
13877
13933
|
const files = generatorService.generateForIde(bundle, ideId);
|
|
13878
13934
|
for (const file of files) {
|
|
13879
|
-
const fullPath =
|
|
13880
|
-
await fs23.mkdir(
|
|
13935
|
+
const fullPath = join15(process.cwd(), file.path);
|
|
13936
|
+
await fs23.mkdir(join15(fullPath, ".."), { recursive: true });
|
|
13881
13937
|
await fs23.writeFile(fullPath, file.content, "utf-8");
|
|
13882
13938
|
console.log(`\u2713 [${ideId}] ${file.path}`);
|
|
13883
13939
|
allGeneratedFiles.push({
|
|
@@ -13984,7 +14040,7 @@ function createRulesApplyCommand() {
|
|
|
13984
14040
|
|
|
13985
14041
|
// src/commands/rules/restore.ts
|
|
13986
14042
|
import { Command as Command83 } from "commander";
|
|
13987
|
-
import { join as
|
|
14043
|
+
import { join as join16 } from "path";
|
|
13988
14044
|
import { select as select5, confirm as confirm17 } from "@inquirer/prompts";
|
|
13989
14045
|
function createRulesRestoreCommand() {
|
|
13990
14046
|
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) => {
|
|
@@ -14031,7 +14087,7 @@ function createRulesRestoreCommand() {
|
|
|
14031
14087
|
}
|
|
14032
14088
|
console.log("\n\u{1F504} Restoring backup...\n");
|
|
14033
14089
|
try {
|
|
14034
|
-
const backupPath =
|
|
14090
|
+
const backupPath = join16(backupService.getBackupDir(), selectedBackup.timestamp);
|
|
14035
14091
|
await backupService.restoreBackup(backupPath);
|
|
14036
14092
|
console.log("\n\u2705 Backup restored successfully!\n");
|
|
14037
14093
|
console.log("\u{1F4A1} Tip: Your IDE may need to be restarted to pick up the changes.");
|
|
@@ -14058,12 +14114,12 @@ function formatTimestamp(timestamp) {
|
|
|
14058
14114
|
// src/commands/rules/sync.ts
|
|
14059
14115
|
import { Command as Command84 } from "commander";
|
|
14060
14116
|
import { promises as fs24 } from "fs";
|
|
14061
|
-
import { join as
|
|
14117
|
+
import { join as join17 } from "path";
|
|
14062
14118
|
import { checkbox as checkbox6, confirm as confirm18, Separator } from "@inquirer/prompts";
|
|
14063
14119
|
function createRulesSyncCommand() {
|
|
14064
14120
|
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) => {
|
|
14065
|
-
const rulePresetDir =
|
|
14066
|
-
const presetJsonPath =
|
|
14121
|
+
const rulePresetDir = join17(process.cwd(), ".jai1", "rule-preset");
|
|
14122
|
+
const presetJsonPath = join17(rulePresetDir, "preset.json");
|
|
14067
14123
|
let presetExists = false;
|
|
14068
14124
|
let presetData = null;
|
|
14069
14125
|
try {
|
|
@@ -14200,7 +14256,7 @@ Current IDE(s): ${currentIdes.join(", ") || "none"}`);
|
|
|
14200
14256
|
const files = await fs24.readdir(rulePresetDir);
|
|
14201
14257
|
for (const file of files) {
|
|
14202
14258
|
if (file.endsWith(".mdc") || file.endsWith(".md")) {
|
|
14203
|
-
const filePath =
|
|
14259
|
+
const filePath = join17(rulePresetDir, file);
|
|
14204
14260
|
const content = await fs24.readFile(filePath, "utf-8");
|
|
14205
14261
|
bundle.files[file] = content;
|
|
14206
14262
|
}
|
|
@@ -14215,8 +14271,8 @@ Current IDE(s): ${currentIdes.join(", ") || "none"}`);
|
|
|
14215
14271
|
}
|
|
14216
14272
|
const files2 = generatorService.generateForIde(bundle, ideId);
|
|
14217
14273
|
for (const file of files2) {
|
|
14218
|
-
const fullPath =
|
|
14219
|
-
await fs24.mkdir(
|
|
14274
|
+
const fullPath = join17(process.cwd(), file.path);
|
|
14275
|
+
await fs24.mkdir(join17(fullPath, ".."), { recursive: true });
|
|
14220
14276
|
await fs24.writeFile(fullPath, file.content, "utf-8");
|
|
14221
14277
|
}
|
|
14222
14278
|
console.log(`\u2713 ${format.name} - ${files2.length} files regenerated`);
|
|
@@ -14281,7 +14337,7 @@ function buildIdeChoices(currentIdes, detected, suggestions) {
|
|
|
14281
14337
|
// src/commands/rules/info.ts
|
|
14282
14338
|
import { Command as Command85 } from "commander";
|
|
14283
14339
|
import { promises as fs25 } from "fs";
|
|
14284
|
-
import { join as
|
|
14340
|
+
import { join as join18 } from "path";
|
|
14285
14341
|
function createRulesInfoCommand() {
|
|
14286
14342
|
return new Command85("info").description("Show current preset information").option("--json", "Output as JSON").action(async (options) => {
|
|
14287
14343
|
const projectConfigService = new ProjectConfigService();
|
|
@@ -14296,8 +14352,8 @@ function createRulesInfoCommand() {
|
|
|
14296
14352
|
return;
|
|
14297
14353
|
}
|
|
14298
14354
|
console.log("\u{1F4CB} Current Preset Information\n");
|
|
14299
|
-
const rulePresetDir =
|
|
14300
|
-
const presetJsonPath =
|
|
14355
|
+
const rulePresetDir = join18(process.cwd(), ".jai1", "rule-preset");
|
|
14356
|
+
const presetJsonPath = join18(rulePresetDir, "preset.json");
|
|
14301
14357
|
let presetMetadata = null;
|
|
14302
14358
|
let presetFiles = [];
|
|
14303
14359
|
try {
|
|
@@ -14364,7 +14420,7 @@ Available Backups (${rulesConfig.backups.length}):`);
|
|
|
14364
14420
|
}
|
|
14365
14421
|
async function checkPathExists(path13) {
|
|
14366
14422
|
try {
|
|
14367
|
-
await fs25.access(
|
|
14423
|
+
await fs25.access(join18(process.cwd(), path13));
|
|
14368
14424
|
return true;
|
|
14369
14425
|
} catch {
|
|
14370
14426
|
return false;
|
|
@@ -14427,7 +14483,7 @@ import chalk51 from "chalk";
|
|
|
14427
14483
|
|
|
14428
14484
|
// src/services/skills.service.ts
|
|
14429
14485
|
import { promises as fs26 } from "fs";
|
|
14430
|
-
import { join as
|
|
14486
|
+
import { join as join19 } from "path";
|
|
14431
14487
|
import { execFile } from "child_process";
|
|
14432
14488
|
import { promisify } from "util";
|
|
14433
14489
|
var execFileAsync = promisify(execFile);
|
|
@@ -14463,14 +14519,14 @@ var SkillsService = class {
|
|
|
14463
14519
|
* List locally installed skills from .jai1/skills/
|
|
14464
14520
|
*/
|
|
14465
14521
|
async listLocal(projectRoot) {
|
|
14466
|
-
const skillsDir =
|
|
14522
|
+
const skillsDir = join19(projectRoot, ".jai1", "skills");
|
|
14467
14523
|
const skills = [];
|
|
14468
14524
|
try {
|
|
14469
14525
|
const entries = await fs26.readdir(skillsDir, { withFileTypes: true });
|
|
14470
14526
|
for (const entry of entries) {
|
|
14471
14527
|
if (!entry.isDirectory()) continue;
|
|
14472
|
-
const skillPath =
|
|
14473
|
-
const skillMd =
|
|
14528
|
+
const skillPath = join19(skillsDir, entry.name);
|
|
14529
|
+
const skillMd = join19(skillPath, "SKILL.md");
|
|
14474
14530
|
try {
|
|
14475
14531
|
await fs26.access(skillMd);
|
|
14476
14532
|
} catch {
|
|
@@ -14495,8 +14551,8 @@ var SkillsService = class {
|
|
|
14495
14551
|
* Get detailed info for a single skill
|
|
14496
14552
|
*/
|
|
14497
14553
|
async getSkillInfo(projectRoot, skillName) {
|
|
14498
|
-
const skillPath =
|
|
14499
|
-
const skillMd =
|
|
14554
|
+
const skillPath = join19(projectRoot, ".jai1", "skills", skillName);
|
|
14555
|
+
const skillMd = join19(skillPath, "SKILL.md");
|
|
14500
14556
|
try {
|
|
14501
14557
|
await fs26.access(skillMd);
|
|
14502
14558
|
} catch {
|
|
@@ -14571,22 +14627,22 @@ var SkillsService = class {
|
|
|
14571
14627
|
* After npx skills add, copy newly installed skills from .agents/skills/ into .jai1/skills/
|
|
14572
14628
|
*/
|
|
14573
14629
|
async copySkillshResultsToJai1(projectRoot, specificSkill) {
|
|
14574
|
-
const jai1SkillsDir =
|
|
14630
|
+
const jai1SkillsDir = join19(projectRoot, ".jai1", "skills");
|
|
14575
14631
|
await fs26.mkdir(jai1SkillsDir, { recursive: true });
|
|
14576
|
-
const universalDir =
|
|
14632
|
+
const universalDir = join19(projectRoot, ".agents", "skills");
|
|
14577
14633
|
try {
|
|
14578
14634
|
const entries = await fs26.readdir(universalDir, { withFileTypes: true });
|
|
14579
14635
|
for (const entry of entries) {
|
|
14580
14636
|
if (!entry.isDirectory()) continue;
|
|
14581
14637
|
if (specificSkill && entry.name !== specificSkill) continue;
|
|
14582
|
-
const srcSkill =
|
|
14583
|
-
const skillMd =
|
|
14638
|
+
const srcSkill = join19(universalDir, entry.name);
|
|
14639
|
+
const skillMd = join19(srcSkill, "SKILL.md");
|
|
14584
14640
|
try {
|
|
14585
14641
|
await fs26.access(skillMd);
|
|
14586
14642
|
} catch {
|
|
14587
14643
|
continue;
|
|
14588
14644
|
}
|
|
14589
|
-
const targetSkill =
|
|
14645
|
+
const targetSkill = join19(jai1SkillsDir, entry.name);
|
|
14590
14646
|
try {
|
|
14591
14647
|
await fs26.access(targetSkill);
|
|
14592
14648
|
} catch {
|
|
@@ -14625,7 +14681,7 @@ var SkillsService = class {
|
|
|
14625
14681
|
const target = this.getIDETarget(ide);
|
|
14626
14682
|
if (!target) continue;
|
|
14627
14683
|
for (const skill of skillsToSync) {
|
|
14628
|
-
const targetPath =
|
|
14684
|
+
const targetPath = join19(projectRoot, target.skillsPath, skill.slug);
|
|
14629
14685
|
try {
|
|
14630
14686
|
let status = "created";
|
|
14631
14687
|
try {
|
|
@@ -14689,7 +14745,7 @@ var SkillsService = class {
|
|
|
14689
14745
|
const entries = await fs26.readdir(dirPath, { withFileTypes: true });
|
|
14690
14746
|
for (const entry of entries) {
|
|
14691
14747
|
if (entry.isDirectory()) {
|
|
14692
|
-
count += await this.countFiles(
|
|
14748
|
+
count += await this.countFiles(join19(dirPath, entry.name));
|
|
14693
14749
|
} else {
|
|
14694
14750
|
count++;
|
|
14695
14751
|
}
|
|
@@ -14702,8 +14758,8 @@ var SkillsService = class {
|
|
|
14702
14758
|
async copyDir(source, target) {
|
|
14703
14759
|
const entries = await fs26.readdir(source, { withFileTypes: true });
|
|
14704
14760
|
for (const entry of entries) {
|
|
14705
|
-
const srcPath =
|
|
14706
|
-
const tgtPath =
|
|
14761
|
+
const srcPath = join19(source, entry.name);
|
|
14762
|
+
const tgtPath = join19(target, entry.name);
|
|
14707
14763
|
if (entry.isDirectory()) {
|
|
14708
14764
|
await fs26.mkdir(tgtPath, { recursive: true });
|
|
14709
14765
|
await this.copyDir(srcPath, tgtPath);
|
|
@@ -14777,7 +14833,7 @@ function createSkillsFindCommand() {
|
|
|
14777
14833
|
|
|
14778
14834
|
// src/commands/skills/add.ts
|
|
14779
14835
|
import { Command as Command88 } from "commander";
|
|
14780
|
-
import { join as
|
|
14836
|
+
import { join as join20 } from "path";
|
|
14781
14837
|
import chalk52 from "chalk";
|
|
14782
14838
|
import { checkbox as checkbox7 } from "@inquirer/prompts";
|
|
14783
14839
|
function createSkillsAddCommand() {
|
|
@@ -14799,7 +14855,7 @@ function createSkillsAddCommand() {
|
|
|
14799
14855
|
}
|
|
14800
14856
|
console.log(chalk52.cyan(`\u{1F4E6} \u0110ang c\xE0i \u0111\u1EB7t skill: ${name}...`));
|
|
14801
14857
|
console.log();
|
|
14802
|
-
const targetDir =
|
|
14858
|
+
const targetDir = join20(projectRoot, ".jai1");
|
|
14803
14859
|
await skillsService.installFromServer(config, name, targetDir);
|
|
14804
14860
|
console.log(chalk52.green(`\u2705 \u0110\xE3 c\xE0i \u0111\u1EB7t skill "${name}" v\xE0o .jai1/skills/${name}/`));
|
|
14805
14861
|
}
|
|
@@ -15289,8 +15345,8 @@ function getInstallCommand(packageManager2) {
|
|
|
15289
15345
|
import { Command as Command94 } from "commander";
|
|
15290
15346
|
import { confirm as confirm22, select as select6 } from "@inquirer/prompts";
|
|
15291
15347
|
import { promises as fs27 } from "fs";
|
|
15292
|
-
import { join as
|
|
15293
|
-
import { existsSync as
|
|
15348
|
+
import { join as join21 } from "path";
|
|
15349
|
+
import { existsSync as existsSync5 } from "fs";
|
|
15294
15350
|
function createCleanCommand() {
|
|
15295
15351
|
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) => {
|
|
15296
15352
|
await handleClean(options);
|
|
@@ -15303,7 +15359,7 @@ async function handleClean(options) {
|
|
|
15303
15359
|
{
|
|
15304
15360
|
name: "Backups",
|
|
15305
15361
|
description: "Component backup files (.jai1_backup/)",
|
|
15306
|
-
path:
|
|
15362
|
+
path: join21(cwd, ".jai1_backup"),
|
|
15307
15363
|
check: async () => {
|
|
15308
15364
|
const backups = await service.listBackups(cwd);
|
|
15309
15365
|
return { exists: backups.length > 0, count: backups.length };
|
|
@@ -15315,13 +15371,13 @@ async function handleClean(options) {
|
|
|
15315
15371
|
{
|
|
15316
15372
|
name: "Jai1 Config",
|
|
15317
15373
|
description: "Jai1 framework config (.jai1/)",
|
|
15318
|
-
path:
|
|
15374
|
+
path: join21(cwd, ".jai1"),
|
|
15319
15375
|
check: async () => {
|
|
15320
|
-
const exists =
|
|
15376
|
+
const exists = existsSync5(join21(cwd, ".jai1"));
|
|
15321
15377
|
return { exists };
|
|
15322
15378
|
},
|
|
15323
15379
|
clean: async () => {
|
|
15324
|
-
await fs27.rm(
|
|
15380
|
+
await fs27.rm(join21(cwd, ".jai1"), { recursive: true, force: true });
|
|
15325
15381
|
}
|
|
15326
15382
|
}
|
|
15327
15383
|
];
|
|
@@ -15333,8 +15389,8 @@ async function handleClean(options) {
|
|
|
15333
15389
|
{ name: "OpenCode", dir: ".opencode" }
|
|
15334
15390
|
];
|
|
15335
15391
|
for (const ide of ideDirectories) {
|
|
15336
|
-
const idePath =
|
|
15337
|
-
if (
|
|
15392
|
+
const idePath = join21(cwd, ide.dir);
|
|
15393
|
+
if (existsSync5(idePath)) {
|
|
15338
15394
|
targets.push({
|
|
15339
15395
|
name: `IDE: ${ide.name}`,
|
|
15340
15396
|
description: `${ide.name} IDE config (${ide.dir}/)`,
|
|
@@ -16342,7 +16398,7 @@ async function handleSyncProject(options) {
|
|
|
16342
16398
|
// src/commands/framework/info.ts
|
|
16343
16399
|
import { Command as Command98 } from "commander";
|
|
16344
16400
|
import { promises as fs28 } from "fs";
|
|
16345
|
-
import { join as
|
|
16401
|
+
import { join as join22 } from "path";
|
|
16346
16402
|
import { homedir as homedir4 } from "os";
|
|
16347
16403
|
function createInfoCommand() {
|
|
16348
16404
|
const cmd = new Command98("info").description("Show client configuration and status").option("--json", "Output as JSON").option("--verbose", "Show detailed information").action(async (options) => {
|
|
@@ -16356,7 +16412,7 @@ async function handleInfo(options) {
|
|
|
16356
16412
|
if (!config) {
|
|
16357
16413
|
throw new ValidationError(`Not initialized. Run "${getCliName()} auth" first.`);
|
|
16358
16414
|
}
|
|
16359
|
-
const frameworkPath =
|
|
16415
|
+
const frameworkPath = join22(homedir4(), ".jai1", "framework");
|
|
16360
16416
|
const projectStatus = await getProjectStatus2();
|
|
16361
16417
|
const info = {
|
|
16362
16418
|
configPath: configService.getConfigPath(),
|
|
@@ -16391,7 +16447,7 @@ function maskKey4(key) {
|
|
|
16391
16447
|
return "****" + key.slice(-4);
|
|
16392
16448
|
}
|
|
16393
16449
|
async function getProjectStatus2() {
|
|
16394
|
-
const projectJai1 =
|
|
16450
|
+
const projectJai1 = join22(process.cwd(), ".jai1");
|
|
16395
16451
|
try {
|
|
16396
16452
|
await fs28.access(projectJai1);
|
|
16397
16453
|
return { exists: true, version: "Synced" };
|
|
@@ -16585,7 +16641,7 @@ import { Command as Command101 } from "commander";
|
|
|
16585
16641
|
import { checkbox as checkbox9, confirm as confirm25, select as select7 } from "@inquirer/prompts";
|
|
16586
16642
|
import fs29 from "fs/promises";
|
|
16587
16643
|
import path12 from "path";
|
|
16588
|
-
import { existsSync as
|
|
16644
|
+
import { existsSync as existsSync6 } from "fs";
|
|
16589
16645
|
var PERFORMANCE_GROUPS2 = {
|
|
16590
16646
|
telemetry: {
|
|
16591
16647
|
name: "Telemetry",
|
|
@@ -16815,12 +16871,12 @@ async function applyGroups2(groupKeys, action) {
|
|
|
16815
16871
|
console.log(' \u{1F4A1} Ch\u1EA1y "jai1 vscode list" \u0111\u1EC3 xem danh s\xE1ch nh\xF3m c\xF3 s\u1EB5n.');
|
|
16816
16872
|
return;
|
|
16817
16873
|
}
|
|
16818
|
-
if (!
|
|
16874
|
+
if (!existsSync6(vscodeDir)) {
|
|
16819
16875
|
await fs29.mkdir(vscodeDir, { recursive: true });
|
|
16820
16876
|
console.log("\u{1F4C1} \u0110\xE3 t\u1EA1o th\u01B0 m\u1EE5c .vscode/");
|
|
16821
16877
|
}
|
|
16822
16878
|
let currentSettings = {};
|
|
16823
|
-
if (
|
|
16879
|
+
if (existsSync6(settingsPath)) {
|
|
16824
16880
|
try {
|
|
16825
16881
|
const content = await fs29.readFile(settingsPath, "utf-8");
|
|
16826
16882
|
currentSettings = JSON.parse(content);
|
|
@@ -16870,7 +16926,7 @@ async function applyGroups2(groupKeys, action) {
|
|
|
16870
16926
|
async function resetSettings2(groupKeys) {
|
|
16871
16927
|
const vscodeDir = path12.join(process.cwd(), ".vscode");
|
|
16872
16928
|
const settingsPath = path12.join(vscodeDir, "settings.json");
|
|
16873
|
-
if (!
|
|
16929
|
+
if (!existsSync6(settingsPath)) {
|
|
16874
16930
|
console.log("\n\u26A0\uFE0F Kh\xF4ng t\xECm th\u1EA5y file settings.json");
|
|
16875
16931
|
return;
|
|
16876
16932
|
}
|