juno-code 1.0.32 → 1.0.33
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/bin/cli.js +158 -139
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/cli.mjs +157 -138
- package/dist/bin/cli.mjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/templates/services/__pycache__/codex.cpython-38.pyc +0 -0
- package/dist/templates/services/codex.py +254 -16
- package/package.json +1 -1
package/dist/bin/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var fs2 = require('fs-extra');
|
|
5
5
|
var path3 = require('path');
|
|
6
6
|
var os3 = require('os');
|
|
7
7
|
var url = require('url');
|
|
@@ -52,7 +52,7 @@ function _interopNamespace(e) {
|
|
|
52
52
|
return Object.freeze(n);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
var
|
|
55
|
+
var fs2__default = /*#__PURE__*/_interopDefault(fs2);
|
|
56
56
|
var path3__namespace = /*#__PURE__*/_interopNamespace(path3);
|
|
57
57
|
var os3__namespace = /*#__PURE__*/_interopNamespace(os3);
|
|
58
58
|
var semver__default = /*#__PURE__*/_interopDefault(semver);
|
|
@@ -351,12 +351,12 @@ var init_service_installer = __esm({
|
|
|
351
351
|
const __dirname2 = path3__namespace.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href))));
|
|
352
352
|
const require3 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)));
|
|
353
353
|
let packageJsonPath = path3__namespace.join(__dirname2, "..", "..", "package.json");
|
|
354
|
-
if (
|
|
354
|
+
if (fs2__default.default.existsSync(packageJsonPath)) {
|
|
355
355
|
const packageJson2 = require3(packageJsonPath);
|
|
356
356
|
return packageJson2.version;
|
|
357
357
|
}
|
|
358
358
|
packageJsonPath = path3__namespace.join(__dirname2, "..", "..", "..", "package.json");
|
|
359
|
-
if (
|
|
359
|
+
if (fs2__default.default.existsSync(packageJsonPath)) {
|
|
360
360
|
const packageJson2 = require3(packageJsonPath);
|
|
361
361
|
return packageJson2.version;
|
|
362
362
|
}
|
|
@@ -370,11 +370,11 @@ var init_service_installer = __esm({
|
|
|
370
370
|
*/
|
|
371
371
|
static async getInstalledVersion() {
|
|
372
372
|
try {
|
|
373
|
-
const exists = await
|
|
373
|
+
const exists = await fs2__default.default.pathExists(this.VERSION_FILE);
|
|
374
374
|
if (!exists) {
|
|
375
375
|
return null;
|
|
376
376
|
}
|
|
377
|
-
const version3 = await
|
|
377
|
+
const version3 = await fs2__default.default.readFile(this.VERSION_FILE, "utf-8");
|
|
378
378
|
return version3.trim();
|
|
379
379
|
} catch {
|
|
380
380
|
return null;
|
|
@@ -385,7 +385,7 @@ var init_service_installer = __esm({
|
|
|
385
385
|
*/
|
|
386
386
|
static async saveVersion() {
|
|
387
387
|
const version3 = this.getPackageVersion();
|
|
388
|
-
await
|
|
388
|
+
await fs2__default.default.writeFile(this.VERSION_FILE, version3, "utf-8");
|
|
389
389
|
}
|
|
390
390
|
/**
|
|
391
391
|
* Check if services need to be updated based on version
|
|
@@ -397,7 +397,7 @@ var init_service_installer = __esm({
|
|
|
397
397
|
if (!installedVersion) {
|
|
398
398
|
return true;
|
|
399
399
|
}
|
|
400
|
-
const exists = await
|
|
400
|
+
const exists = await fs2__default.default.pathExists(this.SERVICES_DIR);
|
|
401
401
|
if (!exists) {
|
|
402
402
|
return true;
|
|
403
403
|
}
|
|
@@ -405,8 +405,10 @@ var init_service_installer = __esm({
|
|
|
405
405
|
return true;
|
|
406
406
|
}
|
|
407
407
|
if (semver__default.default.eq(packageVersion, installedVersion)) {
|
|
408
|
-
const
|
|
409
|
-
const
|
|
408
|
+
const installedCodex = path3__namespace.join(this.SERVICES_DIR, "codex.py");
|
|
409
|
+
const installedClaude = path3__namespace.join(this.SERVICES_DIR, "claude.py");
|
|
410
|
+
const codexExists = await fs2__default.default.pathExists(installedCodex);
|
|
411
|
+
const claudeExists = await fs2__default.default.pathExists(installedClaude);
|
|
410
412
|
if (!codexExists || !claudeExists) {
|
|
411
413
|
return true;
|
|
412
414
|
}
|
|
@@ -414,15 +416,32 @@ var init_service_installer = __esm({
|
|
|
414
416
|
const packageServicesDir = this.getPackageServicesDir();
|
|
415
417
|
const packageCodex = path3__namespace.join(packageServicesDir, "codex.py");
|
|
416
418
|
const packageClaude = path3__namespace.join(packageServicesDir, "claude.py");
|
|
417
|
-
const packageCodexExists = await
|
|
418
|
-
const packageClaudeExists = await
|
|
419
|
-
if (packageCodexExists
|
|
420
|
-
const
|
|
421
|
-
|
|
419
|
+
const packageCodexExists = await fs2__default.default.pathExists(packageCodex);
|
|
420
|
+
const packageClaudeExists = await fs2__default.default.pathExists(packageClaude);
|
|
421
|
+
if (packageCodexExists) {
|
|
422
|
+
const [pkg, inst] = await Promise.all([
|
|
423
|
+
fs2__default.default.readFile(packageCodex, "utf-8"),
|
|
424
|
+
fs2__default.default.readFile(installedCodex, "utf-8")
|
|
425
|
+
]);
|
|
426
|
+
if (pkg !== inst) {
|
|
422
427
|
return true;
|
|
423
428
|
}
|
|
424
429
|
}
|
|
430
|
+
if (packageClaudeExists) {
|
|
431
|
+
const [pkg, inst] = await Promise.all([
|
|
432
|
+
fs2__default.default.readFile(packageClaude, "utf-8"),
|
|
433
|
+
fs2__default.default.readFile(installedClaude, "utf-8")
|
|
434
|
+
]);
|
|
435
|
+
if (pkg !== inst) {
|
|
436
|
+
return true;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
const isDevelopment2 = packageServicesDir.includes("/src/");
|
|
440
|
+
if (isDevelopment2) {
|
|
441
|
+
return true;
|
|
442
|
+
}
|
|
425
443
|
} catch {
|
|
444
|
+
return true;
|
|
426
445
|
}
|
|
427
446
|
}
|
|
428
447
|
return false;
|
|
@@ -436,11 +455,11 @@ var init_service_installer = __esm({
|
|
|
436
455
|
static getPackageServicesDir() {
|
|
437
456
|
const __dirname2 = path3__namespace.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href))));
|
|
438
457
|
let servicesPath = path3__namespace.join(__dirname2, "..", "..", "templates", "services");
|
|
439
|
-
if (
|
|
458
|
+
if (fs2__default.default.existsSync(servicesPath)) {
|
|
440
459
|
return servicesPath;
|
|
441
460
|
}
|
|
442
461
|
servicesPath = path3__namespace.join(__dirname2, "..", "templates", "services");
|
|
443
|
-
if (
|
|
462
|
+
if (fs2__default.default.existsSync(servicesPath)) {
|
|
444
463
|
return servicesPath;
|
|
445
464
|
}
|
|
446
465
|
throw new Error("Could not find services directory in package");
|
|
@@ -451,18 +470,18 @@ var init_service_installer = __esm({
|
|
|
451
470
|
*/
|
|
452
471
|
static async install(silent = false) {
|
|
453
472
|
try {
|
|
454
|
-
await
|
|
473
|
+
await fs2__default.default.ensureDir(this.SERVICES_DIR);
|
|
455
474
|
const packageServicesDir = this.getPackageServicesDir();
|
|
456
|
-
await
|
|
475
|
+
await fs2__default.default.copy(packageServicesDir, this.SERVICES_DIR, {
|
|
457
476
|
overwrite: true,
|
|
458
477
|
preserveTimestamps: true
|
|
459
478
|
});
|
|
460
|
-
const files = await
|
|
479
|
+
const files = await fs2__default.default.readdir(this.SERVICES_DIR);
|
|
461
480
|
for (const file of files) {
|
|
462
481
|
const filePath = path3__namespace.join(this.SERVICES_DIR, file);
|
|
463
|
-
const stat = await
|
|
482
|
+
const stat = await fs2__default.default.stat(filePath);
|
|
464
483
|
if (stat.isFile() && (file.endsWith(".py") || file.endsWith(".sh"))) {
|
|
465
|
-
await
|
|
484
|
+
await fs2__default.default.chmod(filePath, 493);
|
|
466
485
|
}
|
|
467
486
|
}
|
|
468
487
|
await this.saveVersion();
|
|
@@ -509,11 +528,11 @@ var init_service_installer = __esm({
|
|
|
509
528
|
*/
|
|
510
529
|
static async isInstalled() {
|
|
511
530
|
try {
|
|
512
|
-
const exists = await
|
|
531
|
+
const exists = await fs2__default.default.pathExists(this.SERVICES_DIR);
|
|
513
532
|
if (!exists) {
|
|
514
533
|
return false;
|
|
515
534
|
}
|
|
516
|
-
const files = await
|
|
535
|
+
const files = await fs2__default.default.readdir(this.SERVICES_DIR);
|
|
517
536
|
return files.length > 0;
|
|
518
537
|
} catch {
|
|
519
538
|
return false;
|
|
@@ -536,11 +555,11 @@ var init_service_installer = __esm({
|
|
|
536
555
|
*/
|
|
537
556
|
static async listServices() {
|
|
538
557
|
try {
|
|
539
|
-
const exists = await
|
|
558
|
+
const exists = await fs2__default.default.pathExists(this.SERVICES_DIR);
|
|
540
559
|
if (!exists) {
|
|
541
560
|
return [];
|
|
542
561
|
}
|
|
543
|
-
const files = await
|
|
562
|
+
const files = await fs2__default.default.readdir(this.SERVICES_DIR);
|
|
544
563
|
return files.filter((file) => file.endsWith(".py") || file.endsWith(".sh"));
|
|
545
564
|
} catch {
|
|
546
565
|
return [];
|
|
@@ -551,9 +570,9 @@ var init_service_installer = __esm({
|
|
|
551
570
|
*/
|
|
552
571
|
static async uninstall() {
|
|
553
572
|
try {
|
|
554
|
-
const exists = await
|
|
573
|
+
const exists = await fs2__default.default.pathExists(this.SERVICES_DIR);
|
|
555
574
|
if (exists) {
|
|
556
|
-
await
|
|
575
|
+
await fs2__default.default.remove(this.SERVICES_DIR);
|
|
557
576
|
console.log("\u2713 Services uninstalled");
|
|
558
577
|
}
|
|
559
578
|
} catch (error) {
|
|
@@ -1129,17 +1148,17 @@ async function ensureHooksConfig(baseDir) {
|
|
|
1129
1148
|
try {
|
|
1130
1149
|
const configDir = path3__namespace.join(baseDir, ".juno_task");
|
|
1131
1150
|
const configPath = path3__namespace.join(configDir, "config.json");
|
|
1132
|
-
await
|
|
1133
|
-
const configExists = await
|
|
1151
|
+
await fs2__default.default.ensureDir(configDir);
|
|
1152
|
+
const configExists = await fs2__default.default.pathExists(configPath);
|
|
1134
1153
|
const allHookTypes = getDefaultHooks();
|
|
1135
1154
|
if (!configExists) {
|
|
1136
1155
|
const defaultConfig = {
|
|
1137
1156
|
...DEFAULT_CONFIG,
|
|
1138
1157
|
hooks: allHookTypes
|
|
1139
1158
|
};
|
|
1140
|
-
await
|
|
1159
|
+
await fs2__default.default.writeJson(configPath, defaultConfig, { spaces: 2 });
|
|
1141
1160
|
} else {
|
|
1142
|
-
const existingConfig = await
|
|
1161
|
+
const existingConfig = await fs2__default.default.readJson(configPath);
|
|
1143
1162
|
let needsUpdate = false;
|
|
1144
1163
|
if (!existingConfig.hooks) {
|
|
1145
1164
|
existingConfig.hooks = allHookTypes;
|
|
@@ -1157,7 +1176,7 @@ async function ensureHooksConfig(baseDir) {
|
|
|
1157
1176
|
needsUpdate = true;
|
|
1158
1177
|
}
|
|
1159
1178
|
if (needsUpdate) {
|
|
1160
|
-
await
|
|
1179
|
+
await fs2__default.default.writeJson(configPath, existingConfig, { spaces: 2 });
|
|
1161
1180
|
}
|
|
1162
1181
|
}
|
|
1163
1182
|
} catch (error) {
|
|
@@ -4875,7 +4894,7 @@ var init_config2 = __esm({
|
|
|
4875
4894
|
return cached;
|
|
4876
4895
|
}
|
|
4877
4896
|
try {
|
|
4878
|
-
const configContent = await
|
|
4897
|
+
const configContent = await fs2__default.default.readFile(configPath, "utf-8");
|
|
4879
4898
|
const config = JSON.parse(configContent);
|
|
4880
4899
|
this.validateConfig(config);
|
|
4881
4900
|
const resolvedConfig = this.resolveConfigPaths(config, path3__namespace.dirname(configPath));
|
|
@@ -4897,7 +4916,7 @@ var init_config2 = __esm({
|
|
|
4897
4916
|
const rootDir = path3__namespace.parse(currentDir).root;
|
|
4898
4917
|
while (currentDir !== rootDir) {
|
|
4899
4918
|
const configPath = path3__namespace.join(currentDir, ".juno_task", "mcp.json");
|
|
4900
|
-
if (await
|
|
4919
|
+
if (await fs2__default.default.pathExists(configPath)) {
|
|
4901
4920
|
return configPath;
|
|
4902
4921
|
}
|
|
4903
4922
|
currentDir = path3__namespace.dirname(currentDir);
|
|
@@ -5083,7 +5102,7 @@ var init_logger = __esm({
|
|
|
5083
5102
|
* Matches Python's generate_log_file function
|
|
5084
5103
|
*/
|
|
5085
5104
|
async initialize(subagent = "mcp") {
|
|
5086
|
-
await
|
|
5105
|
+
await fs2__default.default.ensureDir(this.logDirectory);
|
|
5087
5106
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").split("T");
|
|
5088
5107
|
const dateStr = timestamp[0];
|
|
5089
5108
|
const timeStr = timestamp[1].split("-")[0].substring(0, 6);
|
|
@@ -5092,7 +5111,7 @@ var init_logger = __esm({
|
|
|
5092
5111
|
this.logFilePath = path3__namespace.default.join(this.logDirectory, logFileName);
|
|
5093
5112
|
const header = `# Juno-Task TypeScript Log - Started ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
5094
5113
|
`;
|
|
5095
|
-
await
|
|
5114
|
+
await fs2__default.default.writeFile(this.logFilePath, header);
|
|
5096
5115
|
}
|
|
5097
5116
|
/**
|
|
5098
5117
|
* Format log message matching Python version format
|
|
@@ -5110,7 +5129,7 @@ var init_logger = __esm({
|
|
|
5110
5129
|
if (!this.logFilePath) {
|
|
5111
5130
|
throw new Error("Logger not initialized. Call initialize() first.");
|
|
5112
5131
|
}
|
|
5113
|
-
await
|
|
5132
|
+
await fs2__default.default.appendFile(this.logFilePath, message);
|
|
5114
5133
|
}
|
|
5115
5134
|
/**
|
|
5116
5135
|
* Log message at specified level
|
|
@@ -7119,7 +7138,7 @@ var init_shell_backend = __esm({
|
|
|
7119
7138
|
const timestamp = now.getFullYear().toString() + (now.getMonth() + 1).toString().padStart(2, "0") + now.getDate().toString().padStart(2, "0") + "_" + now.getHours().toString().padStart(2, "0") + now.getMinutes().toString().padStart(2, "0") + now.getSeconds().toString().padStart(2, "0");
|
|
7120
7139
|
const logDir = path3__namespace.join(this.config.workingDirectory, ".juno_task", "logs");
|
|
7121
7140
|
try {
|
|
7122
|
-
await
|
|
7141
|
+
await fs2__default.default.ensureDir(logDir);
|
|
7123
7142
|
} catch (error) {
|
|
7124
7143
|
if (this.config?.debug) {
|
|
7125
7144
|
engineLogger.warn(`Failed to create log directory: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -7144,7 +7163,7 @@ var init_shell_backend = __esm({
|
|
|
7144
7163
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
7145
7164
|
const logEntry = `[${timestamp}] ${message}
|
|
7146
7165
|
`;
|
|
7147
|
-
await
|
|
7166
|
+
await fs2__default.default.appendFile(this.logFilePath, logEntry, "utf-8");
|
|
7148
7167
|
} catch (error) {
|
|
7149
7168
|
if (this.config?.debug) {
|
|
7150
7169
|
engineLogger.warn(`Failed to write to log file: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -12843,7 +12862,7 @@ var init_main = __esm({
|
|
|
12843
12862
|
return await this.collectInteractivePrompt();
|
|
12844
12863
|
} else {
|
|
12845
12864
|
const defaultPromptPath = path3__namespace.join(process.cwd(), ".juno_task", "prompt.md");
|
|
12846
|
-
if (await
|
|
12865
|
+
if (await fs2__default.default.pathExists(defaultPromptPath)) {
|
|
12847
12866
|
console.error(chalk15__default.default.blue(`\u{1F4C4} Using default prompt: ${chalk15__default.default.cyan(".juno_task/prompt.md")}`));
|
|
12848
12867
|
return await this.loadPromptFromFile(defaultPromptPath);
|
|
12849
12868
|
} else {
|
|
@@ -12871,7 +12890,7 @@ var init_main = __esm({
|
|
|
12871
12890
|
}
|
|
12872
12891
|
try {
|
|
12873
12892
|
const resolvedPath = path3__namespace.resolve(prompt);
|
|
12874
|
-
return await
|
|
12893
|
+
return await fs2__default.default.pathExists(resolvedPath);
|
|
12875
12894
|
} catch {
|
|
12876
12895
|
return false;
|
|
12877
12896
|
}
|
|
@@ -12879,7 +12898,7 @@ var init_main = __esm({
|
|
|
12879
12898
|
async loadPromptFromFile(filePath) {
|
|
12880
12899
|
try {
|
|
12881
12900
|
const resolvedPath = path3__namespace.resolve(filePath);
|
|
12882
|
-
const content = await
|
|
12901
|
+
const content = await fs2__default.default.readFile(resolvedPath, "utf-8");
|
|
12883
12902
|
if (!content.trim()) {
|
|
12884
12903
|
throw new FileSystemError(
|
|
12885
12904
|
"Prompt file is empty",
|
|
@@ -13287,7 +13306,7 @@ async function validateJSONFile(configSchema, baseDir) {
|
|
|
13287
13306
|
const warnings = [];
|
|
13288
13307
|
const filePath = path3__namespace.default.join(baseDir, configSchema.file);
|
|
13289
13308
|
try {
|
|
13290
|
-
const exists = await
|
|
13309
|
+
const exists = await fs2__default.default.pathExists(filePath);
|
|
13291
13310
|
if (!exists) {
|
|
13292
13311
|
if (configSchema.required) {
|
|
13293
13312
|
errors.push({
|
|
@@ -13310,7 +13329,7 @@ async function validateJSONFile(configSchema, baseDir) {
|
|
|
13310
13329
|
return { isValid: !configSchema.required, errors, warnings };
|
|
13311
13330
|
}
|
|
13312
13331
|
try {
|
|
13313
|
-
await
|
|
13332
|
+
await fs2__default.default.access(filePath, fs2__default.default.constants.R_OK);
|
|
13314
13333
|
} catch (accessError) {
|
|
13315
13334
|
errors.push({
|
|
13316
13335
|
file: configSchema.file,
|
|
@@ -13326,7 +13345,7 @@ async function validateJSONFile(configSchema, baseDir) {
|
|
|
13326
13345
|
}
|
|
13327
13346
|
let jsonData;
|
|
13328
13347
|
try {
|
|
13329
|
-
const fileContent = await
|
|
13348
|
+
const fileContent = await fs2__default.default.readFile(filePath, "utf8");
|
|
13330
13349
|
jsonData = JSON.parse(fileContent);
|
|
13331
13350
|
} catch (parseError) {
|
|
13332
13351
|
const errorMessage = parseError instanceof Error ? parseError.message : String(parseError);
|
|
@@ -13461,7 +13480,7 @@ function displayValidationResults(result) {
|
|
|
13461
13480
|
}
|
|
13462
13481
|
async function logValidationResults(result, baseDir = process.cwd()) {
|
|
13463
13482
|
const logDir = path3__namespace.default.join(baseDir, ".juno_task", "logs");
|
|
13464
|
-
await
|
|
13483
|
+
await fs2__default.default.ensureDir(logDir);
|
|
13465
13484
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
13466
13485
|
const logFile = path3__namespace.default.join(logDir, `startup-validation-${timestamp}.log`);
|
|
13467
13486
|
const logContent = [
|
|
@@ -13504,7 +13523,7 @@ async function logValidationResults(result, baseDir = process.cwd()) {
|
|
|
13504
13523
|
logContent.push(``);
|
|
13505
13524
|
}
|
|
13506
13525
|
}
|
|
13507
|
-
await
|
|
13526
|
+
await fs2__default.default.writeFile(logFile, logContent.join("\n"));
|
|
13508
13527
|
return logFile;
|
|
13509
13528
|
}
|
|
13510
13529
|
async function validateStartupConfigs(baseDir = process.cwd(), verbose = false) {
|
|
@@ -13838,7 +13857,7 @@ var TemplateEngine = class {
|
|
|
13838
13857
|
let overallError;
|
|
13839
13858
|
try {
|
|
13840
13859
|
if (!options.dryRun) {
|
|
13841
|
-
await
|
|
13860
|
+
await fs2__default.default.ensureDir(targetDirectory);
|
|
13842
13861
|
}
|
|
13843
13862
|
for (const template of templates) {
|
|
13844
13863
|
try {
|
|
@@ -15188,7 +15207,7 @@ This directory contains specification documents for your project.
|
|
|
15188
15207
|
const fileName = this.getTemplateFileName(template);
|
|
15189
15208
|
const targetPath = path3__namespace.join(targetDirectory, fileName);
|
|
15190
15209
|
try {
|
|
15191
|
-
const fileExists = await
|
|
15210
|
+
const fileExists = await fs2__default.default.pathExists(targetPath);
|
|
15192
15211
|
if (fileExists && !options.force && options.onConflict !== "overwrite") {
|
|
15193
15212
|
return {
|
|
15194
15213
|
path: targetPath,
|
|
@@ -15210,10 +15229,10 @@ This directory contains specification documents for your project.
|
|
|
15210
15229
|
}
|
|
15211
15230
|
if (options.createBackup && fileExists) {
|
|
15212
15231
|
const backupPath = `${targetPath}.backup.${Date.now()}`;
|
|
15213
|
-
await
|
|
15232
|
+
await fs2__default.default.copy(targetPath, backupPath);
|
|
15214
15233
|
}
|
|
15215
|
-
await
|
|
15216
|
-
await
|
|
15234
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(targetPath));
|
|
15235
|
+
await fs2__default.default.writeFile(targetPath, renderedContent, "utf8");
|
|
15217
15236
|
return {
|
|
15218
15237
|
path: targetPath,
|
|
15219
15238
|
content: renderedContent,
|
|
@@ -15477,7 +15496,7 @@ var SimpleInitTUI = class {
|
|
|
15477
15496
|
}
|
|
15478
15497
|
async confirmSave(targetDirectory) {
|
|
15479
15498
|
const junoTaskPath = path3__namespace.join(targetDirectory, ".juno_task");
|
|
15480
|
-
if (await
|
|
15499
|
+
if (await fs2__default.default.pathExists(junoTaskPath)) {
|
|
15481
15500
|
console.log(chalk15__default.default.yellow(" \u26A0\uFE0F .juno_task directory already exists"));
|
|
15482
15501
|
console.log(chalk15__default.default.gray(" Would you like to:"));
|
|
15483
15502
|
console.log(chalk15__default.default.gray(" 1) Override existing files"));
|
|
@@ -15522,16 +15541,16 @@ var SimpleProjectGenerator = class {
|
|
|
15522
15541
|
async generate() {
|
|
15523
15542
|
const { targetDirectory, variables, force } = this.context;
|
|
15524
15543
|
console.log(chalk15__default.default.blue("\u{1F4C1} Creating project directory..."));
|
|
15525
|
-
await
|
|
15544
|
+
await fs2__default.default.ensureDir(targetDirectory);
|
|
15526
15545
|
const junoTaskDir = path3__namespace.join(targetDirectory, ".juno_task");
|
|
15527
|
-
const junoTaskExists = await
|
|
15546
|
+
const junoTaskExists = await fs2__default.default.pathExists(junoTaskDir);
|
|
15528
15547
|
if (junoTaskExists && !force) {
|
|
15529
15548
|
throw new ValidationError(
|
|
15530
15549
|
"Project already initialized. Directory .juno_task already exists.",
|
|
15531
15550
|
["Use --force flag to overwrite existing files", "Choose a different directory"]
|
|
15532
15551
|
);
|
|
15533
15552
|
}
|
|
15534
|
-
await
|
|
15553
|
+
await fs2__default.default.ensureDir(junoTaskDir);
|
|
15535
15554
|
console.log(chalk15__default.default.blue("\u2699\uFE0F Creating project configuration..."));
|
|
15536
15555
|
await this.createConfigFile(junoTaskDir, targetDirectory);
|
|
15537
15556
|
console.log(chalk15__default.default.blue("\u{1F527} Setting up MCP configuration..."));
|
|
@@ -15565,21 +15584,21 @@ var SimpleProjectGenerator = class {
|
|
|
15565
15584
|
const promptContent = await templateEngine.render(promptTemplate, templateContext);
|
|
15566
15585
|
const initContent = await templateEngine.render(initTemplate, templateContext);
|
|
15567
15586
|
const implementContent = await templateEngine.render(implementTemplate, templateContext);
|
|
15568
|
-
await
|
|
15569
|
-
await
|
|
15570
|
-
await
|
|
15587
|
+
await fs2__default.default.writeFile(path3__namespace.join(junoTaskDir, "prompt.md"), promptContent);
|
|
15588
|
+
await fs2__default.default.writeFile(path3__namespace.join(junoTaskDir, "init.md"), initContent);
|
|
15589
|
+
await fs2__default.default.writeFile(path3__namespace.join(junoTaskDir, "implement.md"), implementContent);
|
|
15571
15590
|
const userFeedbackTemplate = templateEngine.getBuiltInTemplate("USER_FEEDBACK.md");
|
|
15572
15591
|
if (userFeedbackTemplate) {
|
|
15573
15592
|
const userFeedbackContent = await templateEngine.render(userFeedbackTemplate, templateContext);
|
|
15574
|
-
await
|
|
15593
|
+
await fs2__default.default.writeFile(path3__namespace.join(junoTaskDir, "USER_FEEDBACK.md"), userFeedbackContent);
|
|
15575
15594
|
}
|
|
15576
15595
|
const planTemplate = templateEngine.getBuiltInTemplate("plan.md");
|
|
15577
15596
|
if (planTemplate) {
|
|
15578
15597
|
const planContent = await templateEngine.render(planTemplate, templateContext);
|
|
15579
|
-
await
|
|
15598
|
+
await fs2__default.default.writeFile(path3__namespace.join(junoTaskDir, "plan.md"), planContent);
|
|
15580
15599
|
}
|
|
15581
15600
|
const specsDir = path3__namespace.join(junoTaskDir, "specs");
|
|
15582
|
-
await
|
|
15601
|
+
await fs2__default.default.ensureDir(specsDir);
|
|
15583
15602
|
const specsReadmeContent = `# Project Specifications
|
|
15584
15603
|
|
|
15585
15604
|
This directory contains detailed specifications for the project components.
|
|
@@ -15596,7 +15615,7 @@ This directory contains detailed specifications for the project components.
|
|
|
15596
15615
|
- Avoid conflicts with existing file names
|
|
15597
15616
|
- Use \`.md\` extension for all specification files
|
|
15598
15617
|
`;
|
|
15599
|
-
await
|
|
15618
|
+
await fs2__default.default.writeFile(path3__namespace.join(specsDir, "README.md"), specsReadmeContent);
|
|
15600
15619
|
const requirementsContent = `# Requirements Specification
|
|
15601
15620
|
|
|
15602
15621
|
## Functional Requirements
|
|
@@ -15643,7 +15662,7 @@ This directory contains detailed specifications for the project components.
|
|
|
15643
15662
|
- Code quality: Clean, maintainable codebase
|
|
15644
15663
|
- Documentation: Complete and accurate documentation
|
|
15645
15664
|
`;
|
|
15646
|
-
await
|
|
15665
|
+
await fs2__default.default.writeFile(path3__namespace.join(specsDir, "requirements.md"), requirementsContent);
|
|
15647
15666
|
const architectureContent = `# Architecture Specification
|
|
15648
15667
|
|
|
15649
15668
|
## System Overview
|
|
@@ -15725,7 +15744,7 @@ This project uses AI-assisted development with juno-code to achieve: ${variables
|
|
|
15725
15744
|
- Performance monitoring
|
|
15726
15745
|
- Security best practices
|
|
15727
15746
|
`;
|
|
15728
|
-
await
|
|
15747
|
+
await fs2__default.default.writeFile(path3__namespace.join(specsDir, "architecture.md"), architectureContent);
|
|
15729
15748
|
const claudeContent = `# Claude Development Session Learnings
|
|
15730
15749
|
|
|
15731
15750
|
## Project Overview
|
|
@@ -15797,7 +15816,7 @@ This file will be updated as development progresses to track:
|
|
|
15797
15816
|
- Solutions to complex problems
|
|
15798
15817
|
- Performance improvements and optimizations
|
|
15799
15818
|
`;
|
|
15800
|
-
await
|
|
15819
|
+
await fs2__default.default.writeFile(path3__namespace.join(targetDirectory, "CLAUDE.md"), claudeContent);
|
|
15801
15820
|
const agentsContent = `# AI Agent Selection and Performance
|
|
15802
15821
|
|
|
15803
15822
|
## Available Agents
|
|
@@ -15861,7 +15880,7 @@ Track agent performance for:
|
|
|
15861
15880
|
4. **Feedback Loop**: Provide feedback to improve agent performance
|
|
15862
15881
|
5. **Performance Monitoring**: Track and optimize agent usage
|
|
15863
15882
|
`;
|
|
15864
|
-
await
|
|
15883
|
+
await fs2__default.default.writeFile(path3__namespace.join(targetDirectory, "AGENTS.md"), agentsContent);
|
|
15865
15884
|
const readmeContent = `# ${variables.PROJECT_NAME}
|
|
15866
15885
|
|
|
15867
15886
|
${variables.DESCRIPTION}
|
|
@@ -15958,7 +15977,7 @@ ${variables.GIT_URL}` : ""}
|
|
|
15958
15977
|
Created with juno-code on ${variables.CURRENT_DATE}
|
|
15959
15978
|
${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
15960
15979
|
`;
|
|
15961
|
-
await
|
|
15980
|
+
await fs2__default.default.writeFile(path3__namespace.join(targetDirectory, "README.md"), readmeContent);
|
|
15962
15981
|
console.log(chalk15__default.default.blue("\u{1F4E6} Installing utility scripts..."));
|
|
15963
15982
|
await this.copyScriptsFromTemplates(junoTaskDir);
|
|
15964
15983
|
console.log(chalk15__default.default.blue("\u{1F40D} Installing Python requirements..."));
|
|
@@ -16010,7 +16029,7 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16010
16029
|
hooks: getDefaultHooks()
|
|
16011
16030
|
};
|
|
16012
16031
|
const configPath = path3__namespace.join(junoTaskDir, "config.json");
|
|
16013
|
-
await
|
|
16032
|
+
await fs2__default.default.writeFile(configPath, JSON.stringify(configContent, null, 2));
|
|
16014
16033
|
console.log(chalk15__default.default.green(` \u2713 Created .juno_task/config.json with ${this.context.subagent} as default subagent`));
|
|
16015
16034
|
}
|
|
16016
16035
|
async createMcpFile(junoTaskDir, targetDirectory) {
|
|
@@ -16064,7 +16083,7 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16064
16083
|
}
|
|
16065
16084
|
};
|
|
16066
16085
|
const mcpPath = path3__namespace.join(junoTaskDir, "mcp.json");
|
|
16067
|
-
await
|
|
16086
|
+
await fs2__default.default.writeFile(mcpPath, JSON.stringify(mcpContent, null, 2));
|
|
16068
16087
|
console.log(chalk15__default.default.green(` \u2713 Created .juno_task/mcp.json with roundtable-ai server configuration`));
|
|
16069
16088
|
}
|
|
16070
16089
|
getDefaultModelForSubagent(subagent) {
|
|
@@ -16083,7 +16102,7 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16083
16102
|
async copyScriptsFromTemplates(junoTaskDir) {
|
|
16084
16103
|
try {
|
|
16085
16104
|
const scriptsDir = path3__namespace.join(junoTaskDir, "scripts");
|
|
16086
|
-
await
|
|
16105
|
+
await fs2__default.default.ensureDir(scriptsDir);
|
|
16087
16106
|
const __filename2 = url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)));
|
|
16088
16107
|
const __dirname2 = path3__namespace.dirname(__filename2);
|
|
16089
16108
|
let templatesScriptsDir;
|
|
@@ -16094,11 +16113,11 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16094
16113
|
} else {
|
|
16095
16114
|
templatesScriptsDir = path3__namespace.join(__dirname2, "../../templates/scripts");
|
|
16096
16115
|
}
|
|
16097
|
-
if (!await
|
|
16116
|
+
if (!await fs2__default.default.pathExists(templatesScriptsDir)) {
|
|
16098
16117
|
console.log(chalk15__default.default.yellow(" \u26A0\uFE0F Template scripts directory not found, skipping script installation"));
|
|
16099
16118
|
return;
|
|
16100
16119
|
}
|
|
16101
|
-
const scriptFiles = await
|
|
16120
|
+
const scriptFiles = await fs2__default.default.readdir(templatesScriptsDir);
|
|
16102
16121
|
if (scriptFiles.length === 0) {
|
|
16103
16122
|
console.log(chalk15__default.default.gray(" \u2139\uFE0F No template scripts found to install"));
|
|
16104
16123
|
return;
|
|
@@ -16107,11 +16126,11 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16107
16126
|
for (const scriptFile of scriptFiles) {
|
|
16108
16127
|
const sourcePath = path3__namespace.join(templatesScriptsDir, scriptFile);
|
|
16109
16128
|
const destPath = path3__namespace.join(scriptsDir, scriptFile);
|
|
16110
|
-
const stats = await
|
|
16129
|
+
const stats = await fs2__default.default.stat(sourcePath);
|
|
16111
16130
|
if (stats.isFile()) {
|
|
16112
|
-
await
|
|
16131
|
+
await fs2__default.default.copy(sourcePath, destPath);
|
|
16113
16132
|
if (scriptFile.endsWith(".sh")) {
|
|
16114
|
-
await
|
|
16133
|
+
await fs2__default.default.chmod(destPath, 493);
|
|
16115
16134
|
}
|
|
16116
16135
|
copiedCount++;
|
|
16117
16136
|
console.log(chalk15__default.default.green(` \u2713 Installed script: ${scriptFile}`));
|
|
@@ -16134,7 +16153,7 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16134
16153
|
try {
|
|
16135
16154
|
const scriptsDir = path3__namespace.join(junoTaskDir, "scripts");
|
|
16136
16155
|
const installScript = path3__namespace.join(scriptsDir, "install_requirements.sh");
|
|
16137
|
-
if (!await
|
|
16156
|
+
if (!await fs2__default.default.pathExists(installScript)) {
|
|
16138
16157
|
console.log(chalk15__default.default.yellow(" \u26A0\uFE0F install_requirements.sh not found, skipping Python dependencies installation"));
|
|
16139
16158
|
console.log(chalk15__default.default.gray(" You can install dependencies manually: juno-kanban, roundtable-ai"));
|
|
16140
16159
|
return;
|
|
@@ -16431,20 +16450,20 @@ init_types();
|
|
|
16431
16450
|
async function loadInitPrompt(directory) {
|
|
16432
16451
|
const junoTaskDir = path3__namespace.join(directory, ".juno_task");
|
|
16433
16452
|
const initFile = path3__namespace.join(junoTaskDir, "init.md");
|
|
16434
|
-
if (!await
|
|
16453
|
+
if (!await fs2__default.default.pathExists(junoTaskDir)) {
|
|
16435
16454
|
throw new FileSystemError(
|
|
16436
16455
|
'No .juno_task directory found. Run "juno-code init" first.',
|
|
16437
16456
|
junoTaskDir
|
|
16438
16457
|
);
|
|
16439
16458
|
}
|
|
16440
|
-
if (!await
|
|
16459
|
+
if (!await fs2__default.default.pathExists(initFile)) {
|
|
16441
16460
|
throw new FileSystemError(
|
|
16442
16461
|
"No init.md file found in .juno_task directory",
|
|
16443
16462
|
initFile
|
|
16444
16463
|
);
|
|
16445
16464
|
}
|
|
16446
16465
|
try {
|
|
16447
|
-
const content = await
|
|
16466
|
+
const content = await fs2__default.default.readFile(initFile, "utf-8");
|
|
16448
16467
|
if (!content.trim()) {
|
|
16449
16468
|
throw new FileSystemError(
|
|
16450
16469
|
"init.md file is empty. Please add task instructions.",
|
|
@@ -17476,8 +17495,8 @@ Focus on ${request.intelligence === "basic" ? "basic functionality" : request.in
|
|
|
17476
17495
|
for (const scenario of scenarios) {
|
|
17477
17496
|
const testContent = await this.generateTestContent(request, scenario, template);
|
|
17478
17497
|
const testFilePath = this.resolveTestFilePath(request, scenario);
|
|
17479
|
-
await
|
|
17480
|
-
await
|
|
17498
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(testFilePath));
|
|
17499
|
+
await fs2__default.default.writeFile(testFilePath, testContent);
|
|
17481
17500
|
testFiles.push(testFilePath);
|
|
17482
17501
|
}
|
|
17483
17502
|
return testFiles;
|
|
@@ -17729,8 +17748,8 @@ var TestExecutionEngine = class {
|
|
|
17729
17748
|
async collectCoverage(request) {
|
|
17730
17749
|
const coverageFile = path3__namespace.join(request.workingDirectory, "coverage", "coverage-summary.json");
|
|
17731
17750
|
try {
|
|
17732
|
-
if (await
|
|
17733
|
-
const coverageData = await
|
|
17751
|
+
if (await fs2__default.default.pathExists(coverageFile)) {
|
|
17752
|
+
const coverageData = await fs2__default.default.readJson(coverageFile);
|
|
17734
17753
|
return {
|
|
17735
17754
|
lines: coverageData.total?.lines?.pct || 0,
|
|
17736
17755
|
functions: coverageData.total?.functions?.pct || 0,
|
|
@@ -17913,8 +17932,8 @@ var TestReportEngine = class {
|
|
|
17913
17932
|
suggestions: analysis.suggestions,
|
|
17914
17933
|
recommendations: analysis.recommendations
|
|
17915
17934
|
};
|
|
17916
|
-
await
|
|
17917
|
-
await
|
|
17935
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(outputPath));
|
|
17936
|
+
await fs2__default.default.writeJson(outputPath, report, { spaces: 2 });
|
|
17918
17937
|
return outputPath;
|
|
17919
17938
|
}
|
|
17920
17939
|
async generateHTMLReport(analysis, outputPath, includeVisualizations) {
|
|
@@ -17977,8 +17996,8 @@ var TestReportEngine = class {
|
|
|
17977
17996
|
</body>
|
|
17978
17997
|
</html>
|
|
17979
17998
|
`.trim();
|
|
17980
|
-
await
|
|
17981
|
-
await
|
|
17999
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(outputPath));
|
|
18000
|
+
await fs2__default.default.writeFile(outputPath, html);
|
|
17982
18001
|
return outputPath;
|
|
17983
18002
|
}
|
|
17984
18003
|
generateCharts(analysis) {
|
|
@@ -18035,8 +18054,8 @@ ${analysis.suggestions.map((suggestion) => `- ${suggestion}`).join("\n")}
|
|
|
18035
18054
|
|
|
18036
18055
|
${analysis.recommendations.map((rec) => `- ${rec}`).join("\n")}
|
|
18037
18056
|
`.trim();
|
|
18038
|
-
await
|
|
18039
|
-
await
|
|
18057
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(outputPath));
|
|
18058
|
+
await fs2__default.default.writeFile(outputPath, markdown);
|
|
18040
18059
|
return outputPath;
|
|
18041
18060
|
}
|
|
18042
18061
|
async displayConsoleReport(analysis) {
|
|
@@ -18376,7 +18395,7 @@ async function compactConfigFile(filePath, options = {}) {
|
|
|
18376
18395
|
preserveDays = 30,
|
|
18377
18396
|
preservePatterns = []
|
|
18378
18397
|
} = options;
|
|
18379
|
-
const originalContent = await
|
|
18398
|
+
const originalContent = await fs2__default.default.readFile(filePath, "utf-8");
|
|
18380
18399
|
const originalSize = originalContent.length;
|
|
18381
18400
|
let backupPath = "";
|
|
18382
18401
|
if (createBackup && !dryRun) {
|
|
@@ -18385,7 +18404,7 @@ async function compactConfigFile(filePath, options = {}) {
|
|
|
18385
18404
|
const basename11 = path3__namespace.basename(filePath, ext);
|
|
18386
18405
|
const dirname12 = path3__namespace.dirname(filePath);
|
|
18387
18406
|
backupPath = path3__namespace.join(dirname12, `${basename11}.backup.${timestamp}${ext}`);
|
|
18388
|
-
await
|
|
18407
|
+
await fs2__default.default.writeFile(backupPath, originalContent, "utf-8");
|
|
18389
18408
|
}
|
|
18390
18409
|
const compactionAnalysis = analyzeMarkdownStructure(originalContent);
|
|
18391
18410
|
const compactedContent = compactMarkdownContent(
|
|
@@ -18400,7 +18419,7 @@ async function compactConfigFile(filePath, options = {}) {
|
|
|
18400
18419
|
const compactedSize = finalContent.length;
|
|
18401
18420
|
const reductionPercentage = Math.round((originalSize - compactedSize) / originalSize * 100);
|
|
18402
18421
|
if (!dryRun) {
|
|
18403
|
-
await
|
|
18422
|
+
await fs2__default.default.writeFile(filePath, finalContent, "utf-8");
|
|
18404
18423
|
}
|
|
18405
18424
|
return {
|
|
18406
18425
|
originalSize,
|
|
@@ -18530,7 +18549,7 @@ function formatFileSize(bytes) {
|
|
|
18530
18549
|
}
|
|
18531
18550
|
async function shouldCompactFile(filePath, sizeThresholdKB = 50, ageThresholdDays = 30) {
|
|
18532
18551
|
try {
|
|
18533
|
-
const stats = await
|
|
18552
|
+
const stats = await fs2__default.default.stat(filePath);
|
|
18534
18553
|
const sizeKB = stats.size / 1024;
|
|
18535
18554
|
if (sizeKB > sizeThresholdKB) {
|
|
18536
18555
|
return true;
|
|
@@ -18552,19 +18571,19 @@ async function archiveResolvedIssues(options) {
|
|
|
18552
18571
|
feedbackFile,
|
|
18553
18572
|
archiveDir = path3__namespace.join(path3__namespace.dirname(feedbackFile), "archives"),
|
|
18554
18573
|
openIssuesThreshold = 10} = options;
|
|
18555
|
-
if (!await
|
|
18574
|
+
if (!await fs2__default.default.pathExists(feedbackFile)) {
|
|
18556
18575
|
throw new Error(`Feedback file does not exist: ${feedbackFile}`);
|
|
18557
18576
|
}
|
|
18558
|
-
const content = await
|
|
18577
|
+
const content = await fs2__default.default.readFile(feedbackFile, "utf-8");
|
|
18559
18578
|
const parsed = parseUserFeedback(content);
|
|
18560
18579
|
const warningsGenerated = [];
|
|
18561
18580
|
if (parsed.openIssues.length > openIssuesThreshold) {
|
|
18562
18581
|
const warning = `Found ${parsed.openIssues.length} open issues (threshold: ${openIssuesThreshold}). Consider reviewing and prioritizing.`;
|
|
18563
18582
|
warningsGenerated.push(warning);
|
|
18564
18583
|
const logFile = path3__namespace.join(path3__namespace.dirname(feedbackFile), "logs", "feedback-warnings.log");
|
|
18565
|
-
await
|
|
18584
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(logFile));
|
|
18566
18585
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
18567
|
-
await
|
|
18586
|
+
await fs2__default.default.appendFile(logFile, `[${timestamp}] ${warning}
|
|
18568
18587
|
`);
|
|
18569
18588
|
}
|
|
18570
18589
|
if (parsed.resolvedIssues.length === 0) {
|
|
@@ -18581,10 +18600,10 @@ async function archiveResolvedIssues(options) {
|
|
|
18581
18600
|
const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
|
|
18582
18601
|
const archiveFile = path3__namespace.join(archiveDir, `USER_FEEDBACK_archive_${currentYear}.md`);
|
|
18583
18602
|
{
|
|
18584
|
-
await
|
|
18603
|
+
await fs2__default.default.ensureDir(archiveDir);
|
|
18585
18604
|
await appendToArchive(archiveFile, parsed.resolvedIssues);
|
|
18586
18605
|
const compactedContent = generateCompactedFeedback(parsed.openIssues, parsed.metadata);
|
|
18587
|
-
await
|
|
18606
|
+
await fs2__default.default.writeFile(feedbackFile, compactedContent, "utf-8");
|
|
18588
18607
|
}
|
|
18589
18608
|
{
|
|
18590
18609
|
console.log(chalk15__default.default.green(`\u2705 Archived ${parsed.resolvedIssues.length} resolved issues`));
|
|
@@ -18631,8 +18650,8 @@ function parseUserFeedback(content) {
|
|
|
18631
18650
|
async function appendToArchive(archiveFile, resolvedIssues) {
|
|
18632
18651
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
18633
18652
|
let archiveContent = "";
|
|
18634
|
-
if (await
|
|
18635
|
-
archiveContent = await
|
|
18653
|
+
if (await fs2__default.default.pathExists(archiveFile)) {
|
|
18654
|
+
archiveContent = await fs2__default.default.readFile(archiveFile, "utf-8");
|
|
18636
18655
|
} else {
|
|
18637
18656
|
const year = path3__namespace.basename(archiveFile).match(/(\d{4})/)?.[1] || (/* @__PURE__ */ new Date()).getFullYear();
|
|
18638
18657
|
archiveContent = `# User Feedback Archive ${year}
|
|
@@ -18666,7 +18685,7 @@ ${resolvedIssue}
|
|
|
18666
18685
|
`- Last updated: ${timestamp}`
|
|
18667
18686
|
);
|
|
18668
18687
|
}
|
|
18669
|
-
await
|
|
18688
|
+
await fs2__default.default.writeFile(archiveFile, archiveContent, "utf-8");
|
|
18670
18689
|
}
|
|
18671
18690
|
function generateCompactedFeedback(openIssues, metadata) {
|
|
18672
18691
|
let content = metadata.trim() + "\n";
|
|
@@ -18691,15 +18710,15 @@ async function shouldArchive(feedbackFile, options = {}) {
|
|
|
18691
18710
|
// 50KB
|
|
18692
18711
|
lineCountThreshold = 500
|
|
18693
18712
|
} = options;
|
|
18694
|
-
if (!await
|
|
18713
|
+
if (!await fs2__default.default.pathExists(feedbackFile)) {
|
|
18695
18714
|
return {
|
|
18696
18715
|
shouldArchive: false,
|
|
18697
18716
|
reasons: [],
|
|
18698
18717
|
stats: { openIssuesCount: 0, resolvedIssuesCount: 0, fileSizeBytes: 0, lineCount: 0 }
|
|
18699
18718
|
};
|
|
18700
18719
|
}
|
|
18701
|
-
const content = await
|
|
18702
|
-
const stats = await
|
|
18720
|
+
const content = await fs2__default.default.readFile(feedbackFile, "utf-8");
|
|
18721
|
+
const stats = await fs2__default.default.stat(feedbackFile);
|
|
18703
18722
|
const parsed = parseUserFeedback(content);
|
|
18704
18723
|
const lineCount = content.split("\n").length;
|
|
18705
18724
|
const reasons = [];
|
|
@@ -18773,16 +18792,16 @@ var EnhancedFeedbackFileManager = class {
|
|
|
18773
18792
|
this.feedbackFile = feedbackFile;
|
|
18774
18793
|
}
|
|
18775
18794
|
async ensureExists() {
|
|
18776
|
-
if (!await
|
|
18795
|
+
if (!await fs2__default.default.pathExists(this.feedbackFile)) {
|
|
18777
18796
|
await this.createInitialFile();
|
|
18778
18797
|
}
|
|
18779
18798
|
}
|
|
18780
18799
|
async addFeedback(issue, testCriteria) {
|
|
18781
18800
|
await this.ensureExists();
|
|
18782
18801
|
try {
|
|
18783
|
-
const content = await
|
|
18802
|
+
const content = await fs2__default.default.readFile(this.feedbackFile, "utf-8");
|
|
18784
18803
|
const updatedContent = this.addIssueToContent(content, issue, testCriteria);
|
|
18785
|
-
await
|
|
18804
|
+
await fs2__default.default.writeFile(this.feedbackFile, updatedContent, "utf-8");
|
|
18786
18805
|
} catch (error) {
|
|
18787
18806
|
throw new ValidationError(
|
|
18788
18807
|
`Failed to save feedback: ${error}`,
|
|
@@ -18795,12 +18814,12 @@ var EnhancedFeedbackFileManager = class {
|
|
|
18795
18814
|
*/
|
|
18796
18815
|
async repairMalformedFile() {
|
|
18797
18816
|
try {
|
|
18798
|
-
const content = await
|
|
18817
|
+
const content = await fs2__default.default.readFile(this.feedbackFile, "utf-8");
|
|
18799
18818
|
const hasOpenIssues = content.includes("<OPEN_ISSUES>");
|
|
18800
18819
|
const hasClosingTag = content.includes("</OPEN_ISSUES>");
|
|
18801
18820
|
if (!hasOpenIssues || !hasClosingTag) {
|
|
18802
18821
|
const backupPath = this.feedbackFile + ".backup." + Date.now();
|
|
18803
|
-
await
|
|
18822
|
+
await fs2__default.default.writeFile(backupPath, content, "utf-8");
|
|
18804
18823
|
const existingIssues = this.extractIssuesFromMalformedContent(content);
|
|
18805
18824
|
await this.createInitialFile(existingIssues);
|
|
18806
18825
|
}
|
|
@@ -18832,8 +18851,8 @@ List any features you'd like to see added or bugs you've encountered.
|
|
|
18832
18851
|
|
|
18833
18852
|
<!-- Resolved issues will be moved here -->
|
|
18834
18853
|
`;
|
|
18835
|
-
await
|
|
18836
|
-
await
|
|
18854
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(this.feedbackFile));
|
|
18855
|
+
await fs2__default.default.writeFile(this.feedbackFile, initialContent, "utf-8");
|
|
18837
18856
|
}
|
|
18838
18857
|
addIssueToContent(content, issue, testCriteria) {
|
|
18839
18858
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
@@ -18949,17 +18968,17 @@ async function handleCompactCommand(subArgs, options) {
|
|
|
18949
18968
|
if (subArgs.length > 0) {
|
|
18950
18969
|
for (const filePath of subArgs) {
|
|
18951
18970
|
const resolvedPath = path3__namespace.resolve(filePath);
|
|
18952
|
-
if (await
|
|
18971
|
+
if (await fs2__default.default.pathExists(resolvedPath)) {
|
|
18953
18972
|
filesToCompact.push(resolvedPath);
|
|
18954
18973
|
} else {
|
|
18955
18974
|
console.warn(chalk15__default.default.yellow(`\u26A0\uFE0F File not found: ${filePath}`));
|
|
18956
18975
|
}
|
|
18957
18976
|
}
|
|
18958
18977
|
} else {
|
|
18959
|
-
if (await
|
|
18978
|
+
if (await fs2__default.default.pathExists(defaultClaudeFile)) {
|
|
18960
18979
|
filesToCompact.push(defaultClaudeFile);
|
|
18961
18980
|
}
|
|
18962
|
-
if (await
|
|
18981
|
+
if (await fs2__default.default.pathExists(defaultAgentsFile)) {
|
|
18963
18982
|
filesToCompact.push(defaultAgentsFile);
|
|
18964
18983
|
}
|
|
18965
18984
|
}
|
|
@@ -19893,11 +19912,11 @@ var GitManager = class {
|
|
|
19893
19912
|
*/
|
|
19894
19913
|
async updateJunoTaskConfig(gitUrl) {
|
|
19895
19914
|
const configPath = path3__namespace.join(this.workingDirectory, ".juno_task", "init.md");
|
|
19896
|
-
if (!await
|
|
19915
|
+
if (!await fs2__default.default.pathExists(configPath)) {
|
|
19897
19916
|
return;
|
|
19898
19917
|
}
|
|
19899
19918
|
try {
|
|
19900
|
-
let content = await
|
|
19919
|
+
let content = await fs2__default.default.readFile(configPath, "utf-8");
|
|
19901
19920
|
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
19902
19921
|
if (frontmatterMatch) {
|
|
19903
19922
|
let frontmatter = frontmatterMatch[1];
|
|
@@ -19918,7 +19937,7 @@ GIT_URL: ${gitUrl}
|
|
|
19918
19937
|
`;
|
|
19919
19938
|
content = frontmatter + content;
|
|
19920
19939
|
}
|
|
19921
|
-
await
|
|
19940
|
+
await fs2__default.default.writeFile(configPath, content, "utf-8");
|
|
19922
19941
|
} catch (error) {
|
|
19923
19942
|
console.warn(`Warning: Failed to update juno-code configuration: ${error}`);
|
|
19924
19943
|
}
|
|
@@ -22675,10 +22694,10 @@ autoload -U compinit && compinit`;
|
|
|
22675
22694
|
*/
|
|
22676
22695
|
async isSourceCommandPresent(configPath, sourceCommand) {
|
|
22677
22696
|
try {
|
|
22678
|
-
if (!await
|
|
22697
|
+
if (!await fs2__default.default.pathExists(configPath)) {
|
|
22679
22698
|
return false;
|
|
22680
22699
|
}
|
|
22681
|
-
const content = await
|
|
22700
|
+
const content = await fs2__default.default.readFile(configPath, "utf-8");
|
|
22682
22701
|
return content.includes("juno-code completion");
|
|
22683
22702
|
} catch {
|
|
22684
22703
|
return false;
|
|
@@ -22700,15 +22719,15 @@ autoload -U compinit && compinit`;
|
|
|
22700
22719
|
continue;
|
|
22701
22720
|
}
|
|
22702
22721
|
try {
|
|
22703
|
-
const completionExists = await
|
|
22704
|
-
const configExists = await
|
|
22722
|
+
const completionExists = await fs2__default.default.pathExists(shell.completionPath);
|
|
22723
|
+
const configExists = await fs2__default.default.pathExists(shell.configPath);
|
|
22705
22724
|
const isSourced = configExists && await this.isSourceCommandPresent(
|
|
22706
22725
|
shell.configPath,
|
|
22707
22726
|
this.getSourceCommand(shell.name, shell.completionPath)
|
|
22708
22727
|
);
|
|
22709
22728
|
let lastInstalled;
|
|
22710
22729
|
if (completionExists) {
|
|
22711
|
-
const stats = await
|
|
22730
|
+
const stats = await fs2__default.default.stat(shell.completionPath);
|
|
22712
22731
|
lastInstalled = stats.mtime;
|
|
22713
22732
|
}
|
|
22714
22733
|
statuses.push({
|
|
@@ -22734,7 +22753,7 @@ autoload -U compinit && compinit`;
|
|
|
22734
22753
|
async ensureCompletionDirectory(shell) {
|
|
22735
22754
|
const completionPath = this.getCompletionPath(shell);
|
|
22736
22755
|
const completionDir = path3__namespace.dirname(completionPath);
|
|
22737
|
-
await
|
|
22756
|
+
await fs2__default.default.ensureDir(completionDir);
|
|
22738
22757
|
}
|
|
22739
22758
|
/**
|
|
22740
22759
|
* Ensure directory exists for shell configuration
|
|
@@ -22742,7 +22761,7 @@ autoload -U compinit && compinit`;
|
|
|
22742
22761
|
async ensureConfigDirectory(shell) {
|
|
22743
22762
|
const configPath = this.getConfigPath(shell);
|
|
22744
22763
|
const configDir = path3__namespace.dirname(configPath);
|
|
22745
|
-
await
|
|
22764
|
+
await fs2__default.default.ensureDir(configDir);
|
|
22746
22765
|
}
|
|
22747
22766
|
/**
|
|
22748
22767
|
* Get shell version information
|
|
@@ -22766,15 +22785,15 @@ autoload -U compinit && compinit`;
|
|
|
22766
22785
|
try {
|
|
22767
22786
|
const configPath = this.getConfigPath(shell);
|
|
22768
22787
|
const configDir = path3__namespace.dirname(configPath);
|
|
22769
|
-
await
|
|
22788
|
+
await fs2__default.default.access(configDir, fs2__default.default.constants.W_OK);
|
|
22770
22789
|
} catch {
|
|
22771
22790
|
issues.push(`Cannot write to ${shell} configuration directory`);
|
|
22772
22791
|
}
|
|
22773
22792
|
try {
|
|
22774
22793
|
const completionPath = this.getCompletionPath(shell);
|
|
22775
22794
|
const completionDir = path3__namespace.dirname(completionPath);
|
|
22776
|
-
await
|
|
22777
|
-
await
|
|
22795
|
+
await fs2__default.default.ensureDir(completionDir);
|
|
22796
|
+
await fs2__default.default.access(completionDir, fs2__default.default.constants.W_OK);
|
|
22778
22797
|
} catch {
|
|
22779
22798
|
issues.push(`Cannot write to ${shell} completion directory`);
|
|
22780
22799
|
}
|
|
@@ -22845,10 +22864,10 @@ var ContextAwareCompletion = class {
|
|
|
22845
22864
|
async getSessionIds() {
|
|
22846
22865
|
try {
|
|
22847
22866
|
const sessionDir = path3__namespace.join(process.cwd(), ".juno_task", "sessions");
|
|
22848
|
-
if (!await
|
|
22867
|
+
if (!await fs2__default.default.pathExists(sessionDir)) {
|
|
22849
22868
|
return [];
|
|
22850
22869
|
}
|
|
22851
|
-
const sessions = await
|
|
22870
|
+
const sessions = await fs2__default.default.readdir(sessionDir);
|
|
22852
22871
|
return sessions.filter((name) => name.match(/^session_\d+$/)).map((name) => name.replace("session_", "")).sort((a, b) => parseInt(b) - parseInt(a));
|
|
22853
22872
|
} catch {
|
|
22854
22873
|
return [];
|
|
@@ -22862,8 +22881,8 @@ var ContextAwareCompletion = class {
|
|
|
22862
22881
|
const builtinTemplates = ["basic", "advanced", "research", "development"];
|
|
22863
22882
|
const customTemplatesDir = path3__namespace.join(process.cwd(), ".juno_task", "templates");
|
|
22864
22883
|
let customTemplates = [];
|
|
22865
|
-
if (await
|
|
22866
|
-
const files = await
|
|
22884
|
+
if (await fs2__default.default.pathExists(customTemplatesDir)) {
|
|
22885
|
+
const files = await fs2__default.default.readdir(customTemplatesDir);
|
|
22867
22886
|
customTemplates = files.filter((name) => name.endsWith(".md") || name.endsWith(".hbs")).map((name) => path3__namespace.basename(name, path3__namespace.extname(name)));
|
|
22868
22887
|
}
|
|
22869
22888
|
return [...builtinTemplates, ...customTemplates].sort();
|
|
@@ -22940,7 +22959,7 @@ var CompletionInstaller = class {
|
|
|
22940
22959
|
await this.shellDetector.ensureConfigDirectory(shell);
|
|
22941
22960
|
const script = this.generateEnhancedCompletion(shell, "juno-code");
|
|
22942
22961
|
const completionPath = this.shellDetector.getCompletionPath(shell);
|
|
22943
|
-
await
|
|
22962
|
+
await fs2__default.default.writeFile(completionPath, script, "utf-8");
|
|
22944
22963
|
const configPath = this.shellDetector.getConfigPath(shell);
|
|
22945
22964
|
const sourceCommand = this.shellDetector.getSourceCommand(shell, completionPath);
|
|
22946
22965
|
const warnings = [];
|
|
@@ -22948,7 +22967,7 @@ var CompletionInstaller = class {
|
|
|
22948
22967
|
const isPresent = await this.shellDetector.isSourceCommandPresent(configPath, sourceCommand);
|
|
22949
22968
|
if (!isPresent) {
|
|
22950
22969
|
try {
|
|
22951
|
-
await
|
|
22970
|
+
await fs2__default.default.appendFile(configPath, `
|
|
22952
22971
|
|
|
22953
22972
|
${sourceCommand}
|
|
22954
22973
|
`);
|
|
@@ -22979,8 +22998,8 @@ ${sourceCommand}
|
|
|
22979
22998
|
async uninstall(shell) {
|
|
22980
22999
|
try {
|
|
22981
23000
|
const completionPath = this.shellDetector.getCompletionPath(shell);
|
|
22982
|
-
if (await
|
|
22983
|
-
await
|
|
23001
|
+
if (await fs2__default.default.pathExists(completionPath)) {
|
|
23002
|
+
await fs2__default.default.remove(completionPath);
|
|
22984
23003
|
return true;
|
|
22985
23004
|
}
|
|
22986
23005
|
return false;
|
|
@@ -22994,7 +23013,7 @@ ${sourceCommand}
|
|
|
22994
23013
|
async isInstalled(shell) {
|
|
22995
23014
|
try {
|
|
22996
23015
|
const completionPath = this.shellDetector.getCompletionPath(shell);
|
|
22997
|
-
return await
|
|
23016
|
+
return await fs2__default.default.pathExists(completionPath);
|
|
22998
23017
|
} catch {
|
|
22999
23018
|
return false;
|
|
23000
23019
|
}
|