juno-code 1.0.32 → 1.0.34
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 +339 -213
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/cli.mjs +301 -175
- package/dist/bin/cli.mjs.map +1 -1
- package/dist/index.js +3 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -7
- package/dist/index.mjs.map +1 -1
- package/dist/templates/services/__pycache__/codex.cpython-38.pyc +0 -0
- package/dist/templates/services/claude.py +31 -1
- package/dist/templates/services/codex.py +388 -16
- package/package.json +1 -1
package/dist/bin/cli.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
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
|
-
var
|
|
6
|
+
var os4 = require('os');
|
|
7
7
|
var url = require('url');
|
|
8
8
|
var module$1 = require('module');
|
|
9
9
|
var semver = require('semver');
|
|
@@ -52,9 +52,9 @@ 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
|
-
var
|
|
57
|
+
var os4__namespace = /*#__PURE__*/_interopNamespace(os4);
|
|
58
58
|
var semver__default = /*#__PURE__*/_interopDefault(semver);
|
|
59
59
|
var nodeFs__namespace = /*#__PURE__*/_interopNamespace(nodeFs);
|
|
60
60
|
var yaml__namespace = /*#__PURE__*/_interopNamespace(yaml);
|
|
@@ -341,8 +341,8 @@ var init_service_installer = __esm({
|
|
|
341
341
|
"src/utils/service-installer.ts"() {
|
|
342
342
|
init_version();
|
|
343
343
|
ServiceInstaller = class {
|
|
344
|
-
static SERVICES_DIR = path3__namespace.join(
|
|
345
|
-
static VERSION_FILE = path3__namespace.join(
|
|
344
|
+
static SERVICES_DIR = path3__namespace.join(os4.homedir(), ".juno_code", "services");
|
|
345
|
+
static VERSION_FILE = path3__namespace.join(os4.homedir(), ".juno_code", "services", ".version");
|
|
346
346
|
/**
|
|
347
347
|
* Get the current package version
|
|
348
348
|
*/
|
|
@@ -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) {
|
|
@@ -3312,13 +3331,9 @@ var init_advanced_logger = __esm({
|
|
|
3312
3331
|
/**
|
|
3313
3332
|
* Output formatted log
|
|
3314
3333
|
*/
|
|
3315
|
-
output(formatted,
|
|
3334
|
+
output(formatted, _level) {
|
|
3316
3335
|
if (this.options.output === "console" || this.options.output === "both") {
|
|
3317
|
-
|
|
3318
|
-
console.error(formatted);
|
|
3319
|
-
} else {
|
|
3320
|
-
console.log(formatted);
|
|
3321
|
-
}
|
|
3336
|
+
console.error(formatted);
|
|
3322
3337
|
}
|
|
3323
3338
|
if (this.options.output === "file" || this.options.output === "both") {
|
|
3324
3339
|
this.writeToFile(formatted);
|
|
@@ -4875,7 +4890,7 @@ var init_config2 = __esm({
|
|
|
4875
4890
|
return cached;
|
|
4876
4891
|
}
|
|
4877
4892
|
try {
|
|
4878
|
-
const configContent = await
|
|
4893
|
+
const configContent = await fs2__default.default.readFile(configPath, "utf-8");
|
|
4879
4894
|
const config = JSON.parse(configContent);
|
|
4880
4895
|
this.validateConfig(config);
|
|
4881
4896
|
const resolvedConfig = this.resolveConfigPaths(config, path3__namespace.dirname(configPath));
|
|
@@ -4897,7 +4912,7 @@ var init_config2 = __esm({
|
|
|
4897
4912
|
const rootDir = path3__namespace.parse(currentDir).root;
|
|
4898
4913
|
while (currentDir !== rootDir) {
|
|
4899
4914
|
const configPath = path3__namespace.join(currentDir, ".juno_task", "mcp.json");
|
|
4900
|
-
if (await
|
|
4915
|
+
if (await fs2__default.default.pathExists(configPath)) {
|
|
4901
4916
|
return configPath;
|
|
4902
4917
|
}
|
|
4903
4918
|
currentDir = path3__namespace.dirname(currentDir);
|
|
@@ -5083,7 +5098,7 @@ var init_logger = __esm({
|
|
|
5083
5098
|
* Matches Python's generate_log_file function
|
|
5084
5099
|
*/
|
|
5085
5100
|
async initialize(subagent = "mcp") {
|
|
5086
|
-
await
|
|
5101
|
+
await fs2__default.default.ensureDir(this.logDirectory);
|
|
5087
5102
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").split("T");
|
|
5088
5103
|
const dateStr = timestamp[0];
|
|
5089
5104
|
const timeStr = timestamp[1].split("-")[0].substring(0, 6);
|
|
@@ -5092,7 +5107,7 @@ var init_logger = __esm({
|
|
|
5092
5107
|
this.logFilePath = path3__namespace.default.join(this.logDirectory, logFileName);
|
|
5093
5108
|
const header = `# Juno-Task TypeScript Log - Started ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
5094
5109
|
`;
|
|
5095
|
-
await
|
|
5110
|
+
await fs2__default.default.writeFile(this.logFilePath, header);
|
|
5096
5111
|
}
|
|
5097
5112
|
/**
|
|
5098
5113
|
* Format log message matching Python version format
|
|
@@ -5110,7 +5125,7 @@ var init_logger = __esm({
|
|
|
5110
5125
|
if (!this.logFilePath) {
|
|
5111
5126
|
throw new Error("Logger not initialized. Call initialize() first.");
|
|
5112
5127
|
}
|
|
5113
|
-
await
|
|
5128
|
+
await fs2__default.default.appendFile(this.logFilePath, message);
|
|
5114
5129
|
}
|
|
5115
5130
|
/**
|
|
5116
5131
|
* Log message at specified level
|
|
@@ -5396,8 +5411,8 @@ var init_terminal_progress_writer = __esm({
|
|
|
5396
5411
|
this.options.stream.write("\r\x1B[K");
|
|
5397
5412
|
if (typeof content === "string") {
|
|
5398
5413
|
this.options.stream.write(content);
|
|
5399
|
-
if (!content.endsWith("\n") && !content.endsWith(
|
|
5400
|
-
this.options.stream.write(
|
|
5414
|
+
if (!content.endsWith("\n") && !content.endsWith(os4.EOL)) {
|
|
5415
|
+
this.options.stream.write(os4.EOL);
|
|
5401
5416
|
}
|
|
5402
5417
|
} else {
|
|
5403
5418
|
console.error(content);
|
|
@@ -5405,8 +5420,8 @@ var init_terminal_progress_writer = __esm({
|
|
|
5405
5420
|
} else {
|
|
5406
5421
|
if (typeof content === "string") {
|
|
5407
5422
|
this.options.stream.write(content);
|
|
5408
|
-
if (!content.endsWith("\n") && !content.endsWith(
|
|
5409
|
-
this.options.stream.write(
|
|
5423
|
+
if (!content.endsWith("\n") && !content.endsWith(os4.EOL)) {
|
|
5424
|
+
this.options.stream.write(os4.EOL);
|
|
5410
5425
|
}
|
|
5411
5426
|
} else {
|
|
5412
5427
|
console.error(content);
|
|
@@ -6014,7 +6029,7 @@ var init_client = __esm({
|
|
|
6014
6029
|
`${serverName}`,
|
|
6015
6030
|
// Assume it's in PATH
|
|
6016
6031
|
`/usr/local/bin/${serverName}`,
|
|
6017
|
-
path3__namespace.default.resolve(
|
|
6032
|
+
path3__namespace.default.resolve(os4__namespace.default.homedir(), `.local/bin/${serverName}`),
|
|
6018
6033
|
path3__namespace.default.resolve(this.options.workingDirectory || process.cwd(), `${serverName}`)
|
|
6019
6034
|
];
|
|
6020
6035
|
for (const serverPath of possiblePaths) {
|
|
@@ -7023,7 +7038,7 @@ var init_shell_backend = __esm({
|
|
|
7023
7038
|
});
|
|
7024
7039
|
try {
|
|
7025
7040
|
const scriptPath = await this.findScriptForSubagent(subagentType);
|
|
7026
|
-
const result = await this.executeScript(scriptPath, request, toolId);
|
|
7041
|
+
const result = await this.executeScript(scriptPath, request, toolId, subagentType);
|
|
7027
7042
|
const duration = Date.now() - startTime;
|
|
7028
7043
|
await this.emitProgressEvent({
|
|
7029
7044
|
sessionId: request.metadata?.sessionId || "unknown",
|
|
@@ -7040,8 +7055,9 @@ var init_shell_backend = __esm({
|
|
|
7040
7055
|
phase: "completion"
|
|
7041
7056
|
}
|
|
7042
7057
|
});
|
|
7058
|
+
const structuredResult = this.buildStructuredOutput(subagentType, result);
|
|
7043
7059
|
return {
|
|
7044
|
-
content:
|
|
7060
|
+
content: structuredResult.content,
|
|
7045
7061
|
status: result.success ? "completed" : "failed",
|
|
7046
7062
|
startTime: new Date(startTime),
|
|
7047
7063
|
endTime: /* @__PURE__ */ new Date(),
|
|
@@ -7049,6 +7065,7 @@ var init_shell_backend = __esm({
|
|
|
7049
7065
|
error: result.error ? { type: "shell_execution", message: result.error, timestamp: /* @__PURE__ */ new Date() } : void 0,
|
|
7050
7066
|
progressEvents: [],
|
|
7051
7067
|
// Progress events are handled via callbacks
|
|
7068
|
+
...structuredResult.metadata ? { metadata: structuredResult.metadata } : void 0,
|
|
7052
7069
|
request
|
|
7053
7070
|
};
|
|
7054
7071
|
} catch (error) {
|
|
@@ -7119,7 +7136,7 @@ var init_shell_backend = __esm({
|
|
|
7119
7136
|
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
7137
|
const logDir = path3__namespace.join(this.config.workingDirectory, ".juno_task", "logs");
|
|
7121
7138
|
try {
|
|
7122
|
-
await
|
|
7139
|
+
await fs2__default.default.ensureDir(logDir);
|
|
7123
7140
|
} catch (error) {
|
|
7124
7141
|
if (this.config?.debug) {
|
|
7125
7142
|
engineLogger.warn(`Failed to create log directory: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -7144,7 +7161,7 @@ var init_shell_backend = __esm({
|
|
|
7144
7161
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
7145
7162
|
const logEntry = `[${timestamp}] ${message}
|
|
7146
7163
|
`;
|
|
7147
|
-
await
|
|
7164
|
+
await fs2__default.default.appendFile(this.logFilePath, logEntry, "utf-8");
|
|
7148
7165
|
} catch (error) {
|
|
7149
7166
|
if (this.config?.debug) {
|
|
7150
7167
|
engineLogger.warn(`Failed to write to log file: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -7214,8 +7231,8 @@ var init_shell_backend = __esm({
|
|
|
7214
7231
|
/**
|
|
7215
7232
|
* Execute a shell script
|
|
7216
7233
|
*/
|
|
7217
|
-
async executeScript(scriptPath, request, toolId) {
|
|
7218
|
-
return new Promise((resolve9, reject) => {
|
|
7234
|
+
async executeScript(scriptPath, request, toolId, subagentType) {
|
|
7235
|
+
return new Promise(async (resolve9, reject) => {
|
|
7219
7236
|
const startTime = Date.now();
|
|
7220
7237
|
const isPython = scriptPath.endsWith(".py");
|
|
7221
7238
|
const env2 = {
|
|
@@ -7228,6 +7245,19 @@ var init_shell_backend = __esm({
|
|
|
7228
7245
|
JUNO_ITERATION: String(request.arguments?.iteration || 1),
|
|
7229
7246
|
JUNO_TOOL_ID: toolId
|
|
7230
7247
|
};
|
|
7248
|
+
let captureDir = null;
|
|
7249
|
+
let capturePath = null;
|
|
7250
|
+
if (subagentType === "claude") {
|
|
7251
|
+
try {
|
|
7252
|
+
captureDir = await nodeFs.promises.mkdtemp(path3__namespace.join(os4__namespace.default.tmpdir(), "juno-shell-"));
|
|
7253
|
+
capturePath = path3__namespace.join(captureDir, `subagent_${toolId}.json`);
|
|
7254
|
+
env2.JUNO_SUBAGENT_CAPTURE_PATH = capturePath;
|
|
7255
|
+
} catch (error) {
|
|
7256
|
+
if (this.config?.debug) {
|
|
7257
|
+
engineLogger.warn(`Failed to prepare subagent capture path: ${error instanceof Error ? error.message : String(error)}`);
|
|
7258
|
+
}
|
|
7259
|
+
}
|
|
7260
|
+
}
|
|
7231
7261
|
const command = isPython ? "python3" : "bash";
|
|
7232
7262
|
const args = [scriptPath];
|
|
7233
7263
|
if (isPython && request.arguments?.instruction) {
|
|
@@ -7302,20 +7332,46 @@ var init_shell_backend = __esm({
|
|
|
7302
7332
|
}
|
|
7303
7333
|
});
|
|
7304
7334
|
child.on("close", (exitCode) => {
|
|
7305
|
-
|
|
7306
|
-
|
|
7307
|
-
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
|
|
7312
|
-
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
|
|
7316
|
-
|
|
7317
|
-
|
|
7318
|
-
|
|
7335
|
+
void (async () => {
|
|
7336
|
+
if (isProcessKilled) return;
|
|
7337
|
+
const duration = Date.now() - startTime;
|
|
7338
|
+
const success = exitCode === 0;
|
|
7339
|
+
let subAgentResponse;
|
|
7340
|
+
if (capturePath) {
|
|
7341
|
+
try {
|
|
7342
|
+
const captured = await nodeFs.promises.readFile(capturePath, "utf-8");
|
|
7343
|
+
if (captured.trim()) {
|
|
7344
|
+
subAgentResponse = JSON.parse(captured);
|
|
7345
|
+
}
|
|
7346
|
+
} catch (error) {
|
|
7347
|
+
if (this.config?.debug) {
|
|
7348
|
+
engineLogger.warn(`Failed to read subagent capture: ${error instanceof Error ? error.message : String(error)}`);
|
|
7349
|
+
}
|
|
7350
|
+
} finally {
|
|
7351
|
+
if (captureDir) {
|
|
7352
|
+
try {
|
|
7353
|
+
await nodeFs.promises.rm(captureDir, { recursive: true, force: true });
|
|
7354
|
+
} catch (cleanupError) {
|
|
7355
|
+
if (this.config?.debug) {
|
|
7356
|
+
engineLogger.warn(`Failed to clean capture directory: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`);
|
|
7357
|
+
}
|
|
7358
|
+
}
|
|
7359
|
+
}
|
|
7360
|
+
}
|
|
7361
|
+
}
|
|
7362
|
+
if (this.config.debug) {
|
|
7363
|
+
engineLogger.debug(`Script execution completed with exit code: ${exitCode}, duration: ${duration}ms`);
|
|
7364
|
+
engineLogger.debug(`Stdout length: ${stdout2.length}, Stderr length: ${stderr.length}`);
|
|
7365
|
+
}
|
|
7366
|
+
resolve9({
|
|
7367
|
+
success,
|
|
7368
|
+
output: stdout2,
|
|
7369
|
+
error: stderr || void 0,
|
|
7370
|
+
exitCode: exitCode || 0,
|
|
7371
|
+
duration,
|
|
7372
|
+
...subAgentResponse ? { subAgentResponse } : void 0
|
|
7373
|
+
});
|
|
7374
|
+
})();
|
|
7319
7375
|
});
|
|
7320
7376
|
child.on("error", (error) => {
|
|
7321
7377
|
if (isProcessKilled) return;
|
|
@@ -7347,6 +7403,66 @@ var init_shell_backend = __esm({
|
|
|
7347
7403
|
});
|
|
7348
7404
|
});
|
|
7349
7405
|
}
|
|
7406
|
+
/**
|
|
7407
|
+
* Build a structured, JSON-parsable result payload for programmatic capture while
|
|
7408
|
+
* preserving the shell backend's existing on-screen streaming behavior.
|
|
7409
|
+
*/
|
|
7410
|
+
buildStructuredOutput(subagentType, result) {
|
|
7411
|
+
if (subagentType === "claude") {
|
|
7412
|
+
const claudeEvent = result.subAgentResponse ?? this.extractLastJsonEvent(result.output);
|
|
7413
|
+
const isError = claudeEvent?.is_error ?? claudeEvent?.subtype === "error" ?? !result.success;
|
|
7414
|
+
const structuredPayload = {
|
|
7415
|
+
type: "result",
|
|
7416
|
+
subtype: claudeEvent?.subtype || (isError ? "error" : "success"),
|
|
7417
|
+
is_error: isError,
|
|
7418
|
+
result: claudeEvent?.result ?? claudeEvent?.error ?? claudeEvent?.content ?? result.output,
|
|
7419
|
+
error: claudeEvent?.error,
|
|
7420
|
+
stderr: result.error,
|
|
7421
|
+
datetime: claudeEvent?.datetime,
|
|
7422
|
+
counter: claudeEvent?.counter,
|
|
7423
|
+
session_id: claudeEvent?.session_id,
|
|
7424
|
+
num_turns: claudeEvent?.num_turns,
|
|
7425
|
+
duration_ms: claudeEvent?.duration_ms ?? result.duration,
|
|
7426
|
+
exit_code: result.exitCode,
|
|
7427
|
+
total_cost_usd: claudeEvent?.total_cost_usd,
|
|
7428
|
+
usage: claudeEvent?.usage,
|
|
7429
|
+
modelUsage: claudeEvent?.modelUsage || claudeEvent?.model_usage || {},
|
|
7430
|
+
permission_denials: claudeEvent?.permission_denials || [],
|
|
7431
|
+
uuid: claudeEvent?.uuid,
|
|
7432
|
+
sub_agent_response: claudeEvent
|
|
7433
|
+
};
|
|
7434
|
+
const metadata = {
|
|
7435
|
+
...claudeEvent ? { subAgentResponse: claudeEvent } : void 0,
|
|
7436
|
+
structuredOutput: true,
|
|
7437
|
+
contentType: "application/json",
|
|
7438
|
+
rawOutput: result.output
|
|
7439
|
+
};
|
|
7440
|
+
return {
|
|
7441
|
+
content: JSON.stringify(structuredPayload),
|
|
7442
|
+
metadata
|
|
7443
|
+
};
|
|
7444
|
+
}
|
|
7445
|
+
return { content: result.output, metadata: result.metadata };
|
|
7446
|
+
}
|
|
7447
|
+
/**
|
|
7448
|
+
* Extract the last valid JSON object from a script's stdout to use as a structured payload fallback.
|
|
7449
|
+
*/
|
|
7450
|
+
extractLastJsonEvent(output) {
|
|
7451
|
+
if (!output) {
|
|
7452
|
+
return null;
|
|
7453
|
+
}
|
|
7454
|
+
const lines = output.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
7455
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
7456
|
+
try {
|
|
7457
|
+
const parsed = JSON.parse(lines[i]);
|
|
7458
|
+
if (parsed && typeof parsed === "object") {
|
|
7459
|
+
return parsed;
|
|
7460
|
+
}
|
|
7461
|
+
} catch {
|
|
7462
|
+
}
|
|
7463
|
+
}
|
|
7464
|
+
return null;
|
|
7465
|
+
}
|
|
7350
7466
|
/**
|
|
7351
7467
|
* Parse streaming events from script output
|
|
7352
7468
|
* Handles both JSON format (Claude) and TEXT format (Codex)
|
|
@@ -7871,7 +7987,7 @@ var init_concurrent_feedback_collector = __esm({
|
|
|
7871
7987
|
process.stdin.removeAllListeners("data");
|
|
7872
7988
|
process.stdin.removeAllListeners("end");
|
|
7873
7989
|
if (this.options.verbose) {
|
|
7874
|
-
process.stderr.write(`${
|
|
7990
|
+
process.stderr.write(`${os4.EOL}[feedback-collector] Stopped. Total submissions: ${this.submissionCount}${os4.EOL}`);
|
|
7875
7991
|
}
|
|
7876
7992
|
}
|
|
7877
7993
|
/**
|
|
@@ -7934,7 +8050,7 @@ var init_concurrent_feedback_collector = __esm({
|
|
|
7934
8050
|
chalk15__default.default.blue.bold("\u2551") + chalk15__default.default.gray(" Exit: Press Ctrl-D (or Ctrl-Z on Windows)") + " ".repeat(16) + chalk15__default.default.blue.bold("\u2551"),
|
|
7935
8051
|
chalk15__default.default.blue.bold("\u255A" + border + "\u255D"),
|
|
7936
8052
|
chalk15__default.default.cyan.bold("> ") + chalk15__default.default.gray("(Type F+Enter to start giving feedback)")
|
|
7937
|
-
].join(
|
|
8053
|
+
].join(os4.EOL) + os4.EOL
|
|
7938
8054
|
);
|
|
7939
8055
|
}
|
|
7940
8056
|
/**
|
|
@@ -7944,7 +8060,7 @@ var init_concurrent_feedback_collector = __esm({
|
|
|
7944
8060
|
this.progressTimer = setInterval(() => {
|
|
7945
8061
|
this.progressTick += 1;
|
|
7946
8062
|
const elapsed = ((Date.now() - this.startTime.getTime()) / 1e3).toFixed(1);
|
|
7947
|
-
process.stderr.write(`[progress] tick=${this.progressTick} elapsed=${elapsed}s${
|
|
8063
|
+
process.stderr.write(`[progress] tick=${this.progressTick} elapsed=${elapsed}s${os4.EOL}`);
|
|
7948
8064
|
}, this.options.progressInterval);
|
|
7949
8065
|
}
|
|
7950
8066
|
/**
|
|
@@ -7954,10 +8070,10 @@ var init_concurrent_feedback_collector = __esm({
|
|
|
7954
8070
|
this.feedbackMode = "feedback" /* FEEDBACK */;
|
|
7955
8071
|
setFeedbackActive(true);
|
|
7956
8072
|
this.buffer = "";
|
|
7957
|
-
process.stdout.write(
|
|
8073
|
+
process.stdout.write(os4.EOL + chalk15__default.default.yellow.bold("\u{1F4DD} FEEDBACK MODE") + chalk15__default.default.gray(" - Type feedback (multiline ok), then Q+Enter to submit | MCP progress paused") + os4.EOL);
|
|
7958
8074
|
process.stdout.write(chalk15__default.default.cyan.bold("> "));
|
|
7959
8075
|
if (this.options.verbose) {
|
|
7960
|
-
process.stderr.write(`[feedback-collector] Entered FEEDBACK mode - MCP progress buffering activated${
|
|
8076
|
+
process.stderr.write(`[feedback-collector] Entered FEEDBACK mode - MCP progress buffering activated${os4.EOL}`);
|
|
7961
8077
|
}
|
|
7962
8078
|
}
|
|
7963
8079
|
/**
|
|
@@ -7967,7 +8083,7 @@ var init_concurrent_feedback_collector = __esm({
|
|
|
7967
8083
|
this.feedbackMode = "normal" /* NORMAL */;
|
|
7968
8084
|
setFeedbackActive(false);
|
|
7969
8085
|
if (this.options.verbose) {
|
|
7970
|
-
process.stderr.write(`[feedback-collector] Exited FEEDBACK mode - MCP progress restored${
|
|
8086
|
+
process.stderr.write(`[feedback-collector] Exited FEEDBACK mode - MCP progress restored${os4.EOL}`);
|
|
7971
8087
|
}
|
|
7972
8088
|
}
|
|
7973
8089
|
/**
|
|
@@ -8010,7 +8126,7 @@ var init_concurrent_feedback_collector = __esm({
|
|
|
8010
8126
|
clearInterval(this.progressTimer);
|
|
8011
8127
|
}
|
|
8012
8128
|
if (this.options.verbose) {
|
|
8013
|
-
process.stderr.write(`${
|
|
8129
|
+
process.stderr.write(`${os4.EOL}[feedback-collector] EOF received. Total submissions: ${this.submissionCount}${os4.EOL}`);
|
|
8014
8130
|
}
|
|
8015
8131
|
});
|
|
8016
8132
|
}
|
|
@@ -8025,7 +8141,7 @@ var init_concurrent_feedback_collector = __esm({
|
|
|
8025
8141
|
return;
|
|
8026
8142
|
}
|
|
8027
8143
|
if (trimmed.length > 0) {
|
|
8028
|
-
process.stdout.write(chalk15__default.default.gray("Type F+Enter to enter feedback mode, or Ctrl-D to exit") +
|
|
8144
|
+
process.stdout.write(chalk15__default.default.gray("Type F+Enter to enter feedback mode, or Ctrl-D to exit") + os4.EOL);
|
|
8029
8145
|
process.stdout.write(chalk15__default.default.cyan.bold("> "));
|
|
8030
8146
|
}
|
|
8031
8147
|
return;
|
|
@@ -8034,10 +8150,10 @@ var init_concurrent_feedback_collector = __esm({
|
|
|
8034
8150
|
if (trimmed === "q") {
|
|
8035
8151
|
this.submitFeedback();
|
|
8036
8152
|
this.exitFeedbackMode();
|
|
8037
|
-
process.stdout.write(
|
|
8153
|
+
process.stdout.write(os4.EOL + chalk15__default.default.cyan.bold("> ") + chalk15__default.default.gray("(Type F+Enter for another feedback, or Ctrl-D to exit)") + os4.EOL);
|
|
8038
8154
|
return;
|
|
8039
8155
|
}
|
|
8040
|
-
this.buffer += line +
|
|
8156
|
+
this.buffer += line + os4.EOL;
|
|
8041
8157
|
}
|
|
8042
8158
|
}
|
|
8043
8159
|
/**
|
|
@@ -8047,18 +8163,18 @@ var init_concurrent_feedback_collector = __esm({
|
|
|
8047
8163
|
const content = this.buffer.trimEnd();
|
|
8048
8164
|
this.buffer = "";
|
|
8049
8165
|
if (content.length === 0) {
|
|
8050
|
-
process.stdout.write(
|
|
8166
|
+
process.stdout.write(os4.EOL + chalk15__default.default.yellow("\u26A0\uFE0F No feedback content to submit") + os4.EOL);
|
|
8051
8167
|
return;
|
|
8052
8168
|
}
|
|
8053
|
-
process.stdout.write(
|
|
8169
|
+
process.stdout.write(os4.EOL + chalk15__default.default.green.bold("\u2705 Feedback registered and being processed...") + os4.EOL);
|
|
8054
8170
|
if (this.options.verbose) {
|
|
8055
|
-
process.stdout.write(chalk15__default.default.gray("Feedback content:") +
|
|
8056
|
-
process.stdout.write(content +
|
|
8057
|
-
process.stdout.write(chalk15__default.default.cyan("===== END BLOCK =====") +
|
|
8171
|
+
process.stdout.write(chalk15__default.default.gray("Feedback content:") + os4.EOL);
|
|
8172
|
+
process.stdout.write(content + os4.EOL);
|
|
8173
|
+
process.stdout.write(chalk15__default.default.cyan("===== END BLOCK =====") + os4.EOL);
|
|
8058
8174
|
}
|
|
8059
8175
|
flushBufferedProgress();
|
|
8060
8176
|
this.enqueueSubmission(content).catch((err) => {
|
|
8061
|
-
process.stderr.write(`${
|
|
8177
|
+
process.stderr.write(`${os4.EOL}[feedback-collector] Error submitting feedback: ${err}${os4.EOL}`);
|
|
8062
8178
|
});
|
|
8063
8179
|
}
|
|
8064
8180
|
/**
|
|
@@ -8084,18 +8200,18 @@ var init_concurrent_feedback_collector = __esm({
|
|
|
8084
8200
|
this.submissions.push(submission);
|
|
8085
8201
|
if (this.options.onSubmit) {
|
|
8086
8202
|
if (this.options.verbose) {
|
|
8087
|
-
process.stderr.write(`${
|
|
8203
|
+
process.stderr.write(`${os4.EOL}[feedback-collector ${n}] Using custom submission handler${os4.EOL}`);
|
|
8088
8204
|
}
|
|
8089
8205
|
try {
|
|
8090
8206
|
await this.options.onSubmit(input);
|
|
8091
8207
|
if (this.options.verbose) {
|
|
8092
|
-
process.stderr.write(`[feedback-collector ${n}] Custom handler completed${
|
|
8208
|
+
process.stderr.write(`[feedback-collector ${n}] Custom handler completed${os4.EOL}`);
|
|
8093
8209
|
}
|
|
8094
|
-
process.stdout.write(
|
|
8095
|
-
process.stdout.write(
|
|
8210
|
+
process.stdout.write(os4.EOL + chalk15__default.default.green("\u2705 Feedback submitted successfully. You can type another block.") + os4.EOL);
|
|
8211
|
+
process.stdout.write(os4.EOL + chalk15__default.default.cyan.bold("> ") + chalk15__default.default.gray("(Ready for next feedback)") + os4.EOL);
|
|
8096
8212
|
} catch (error) {
|
|
8097
|
-
process.stderr.write(`[feedback-collector ${n}] Custom handler error: ${error}${
|
|
8098
|
-
process.stdout.write(
|
|
8213
|
+
process.stderr.write(`[feedback-collector ${n}] Custom handler error: ${error}${os4.EOL}`);
|
|
8214
|
+
process.stdout.write(os4.EOL + chalk15__default.default.red("\u274C Feedback submission failed. Please try again.") + os4.EOL);
|
|
8099
8215
|
}
|
|
8100
8216
|
} else {
|
|
8101
8217
|
await this.runCommandWithInput(n, input);
|
|
@@ -8106,7 +8222,7 @@ var init_concurrent_feedback_collector = __esm({
|
|
|
8106
8222
|
*/
|
|
8107
8223
|
async runCommandWithInput(n, input) {
|
|
8108
8224
|
if (this.options.verbose) {
|
|
8109
|
-
process.stderr.write(`${
|
|
8225
|
+
process.stderr.write(`${os4.EOL}[feedback-collector ${n}] Launching "${this.options.command}" ${this.options.commandArgs.join(" ")}${os4.EOL}`);
|
|
8110
8226
|
}
|
|
8111
8227
|
return new Promise((resolve9) => {
|
|
8112
8228
|
const child = child_process.spawn(this.options.command, this.options.commandArgs, {
|
|
@@ -8124,25 +8240,25 @@ var init_concurrent_feedback_collector = __esm({
|
|
|
8124
8240
|
});
|
|
8125
8241
|
child.on("close", (code) => {
|
|
8126
8242
|
if (this.options.verbose) {
|
|
8127
|
-
process.stderr.write(`[feedback-collector ${n}] exit code ${code ?? 0}${
|
|
8243
|
+
process.stderr.write(`[feedback-collector ${n}] exit code ${code ?? 0}${os4.EOL}`);
|
|
8128
8244
|
}
|
|
8129
8245
|
if (code === 0) {
|
|
8130
|
-
process.stdout.write(
|
|
8131
|
-
process.stdout.write(
|
|
8246
|
+
process.stdout.write(os4.EOL + chalk15__default.default.green("\u2705 Feedback submitted successfully. You can type another block.") + os4.EOL);
|
|
8247
|
+
process.stdout.write(os4.EOL + chalk15__default.default.cyan.bold("> ") + chalk15__default.default.gray("(Ready for next feedback)") + os4.EOL);
|
|
8132
8248
|
} else {
|
|
8133
|
-
process.stdout.write(
|
|
8249
|
+
process.stdout.write(os4.EOL + chalk15__default.default.red("\u274C Feedback submission failed. Please try again.") + os4.EOL);
|
|
8134
8250
|
}
|
|
8135
8251
|
resolve9();
|
|
8136
8252
|
});
|
|
8137
8253
|
child.on("error", (err) => {
|
|
8138
|
-
process.stderr.write(`[feedback-collector ${n}] error: ${err.message}${
|
|
8139
|
-
process.stdout.write(
|
|
8254
|
+
process.stderr.write(`[feedback-collector ${n}] error: ${err.message}${os4.EOL}`);
|
|
8255
|
+
process.stdout.write(os4.EOL + chalk15__default.default.red("\u274C Feedback submission failed. Please try again.") + os4.EOL);
|
|
8140
8256
|
resolve9();
|
|
8141
8257
|
});
|
|
8142
8258
|
if (child.stdin) {
|
|
8143
8259
|
child.stdin.write(input);
|
|
8144
|
-
if (!input.endsWith(
|
|
8145
|
-
child.stdin.write(
|
|
8260
|
+
if (!input.endsWith(os4.EOL)) {
|
|
8261
|
+
child.stdin.write(os4.EOL);
|
|
8146
8262
|
}
|
|
8147
8263
|
child.stdin.end();
|
|
8148
8264
|
}
|
|
@@ -12843,7 +12959,7 @@ var init_main = __esm({
|
|
|
12843
12959
|
return await this.collectInteractivePrompt();
|
|
12844
12960
|
} else {
|
|
12845
12961
|
const defaultPromptPath = path3__namespace.join(process.cwd(), ".juno_task", "prompt.md");
|
|
12846
|
-
if (await
|
|
12962
|
+
if (await fs2__default.default.pathExists(defaultPromptPath)) {
|
|
12847
12963
|
console.error(chalk15__default.default.blue(`\u{1F4C4} Using default prompt: ${chalk15__default.default.cyan(".juno_task/prompt.md")}`));
|
|
12848
12964
|
return await this.loadPromptFromFile(defaultPromptPath);
|
|
12849
12965
|
} else {
|
|
@@ -12871,7 +12987,7 @@ var init_main = __esm({
|
|
|
12871
12987
|
}
|
|
12872
12988
|
try {
|
|
12873
12989
|
const resolvedPath = path3__namespace.resolve(prompt);
|
|
12874
|
-
return await
|
|
12990
|
+
return await fs2__default.default.pathExists(resolvedPath);
|
|
12875
12991
|
} catch {
|
|
12876
12992
|
return false;
|
|
12877
12993
|
}
|
|
@@ -12879,7 +12995,7 @@ var init_main = __esm({
|
|
|
12879
12995
|
async loadPromptFromFile(filePath) {
|
|
12880
12996
|
try {
|
|
12881
12997
|
const resolvedPath = path3__namespace.resolve(filePath);
|
|
12882
|
-
const content = await
|
|
12998
|
+
const content = await fs2__default.default.readFile(resolvedPath, "utf-8");
|
|
12883
12999
|
if (!content.trim()) {
|
|
12884
13000
|
throw new FileSystemError(
|
|
12885
13001
|
"Prompt file is empty",
|
|
@@ -13086,7 +13202,11 @@ var init_main = __esm({
|
|
|
13086
13202
|
\u274C Execution failed (${elapsed})`));
|
|
13087
13203
|
}
|
|
13088
13204
|
const lastIteration = result.iterations[result.iterations.length - 1];
|
|
13089
|
-
|
|
13205
|
+
const structuredOutput = lastIteration?.toolResult.metadata?.structuredOutput === true;
|
|
13206
|
+
const shouldPrintResult = Boolean(
|
|
13207
|
+
lastIteration && lastIteration.toolResult.content && (!this.hasStreamedJsonOutput || structuredOutput)
|
|
13208
|
+
);
|
|
13209
|
+
if (shouldPrintResult) {
|
|
13090
13210
|
console.error(chalk15__default.default.blue("\n\u{1F4C4} Result:"));
|
|
13091
13211
|
console.log(lastIteration.toolResult.content);
|
|
13092
13212
|
}
|
|
@@ -13287,7 +13407,7 @@ async function validateJSONFile(configSchema, baseDir) {
|
|
|
13287
13407
|
const warnings = [];
|
|
13288
13408
|
const filePath = path3__namespace.default.join(baseDir, configSchema.file);
|
|
13289
13409
|
try {
|
|
13290
|
-
const exists = await
|
|
13410
|
+
const exists = await fs2__default.default.pathExists(filePath);
|
|
13291
13411
|
if (!exists) {
|
|
13292
13412
|
if (configSchema.required) {
|
|
13293
13413
|
errors.push({
|
|
@@ -13310,7 +13430,7 @@ async function validateJSONFile(configSchema, baseDir) {
|
|
|
13310
13430
|
return { isValid: !configSchema.required, errors, warnings };
|
|
13311
13431
|
}
|
|
13312
13432
|
try {
|
|
13313
|
-
await
|
|
13433
|
+
await fs2__default.default.access(filePath, fs2__default.default.constants.R_OK);
|
|
13314
13434
|
} catch (accessError) {
|
|
13315
13435
|
errors.push({
|
|
13316
13436
|
file: configSchema.file,
|
|
@@ -13326,7 +13446,7 @@ async function validateJSONFile(configSchema, baseDir) {
|
|
|
13326
13446
|
}
|
|
13327
13447
|
let jsonData;
|
|
13328
13448
|
try {
|
|
13329
|
-
const fileContent = await
|
|
13449
|
+
const fileContent = await fs2__default.default.readFile(filePath, "utf8");
|
|
13330
13450
|
jsonData = JSON.parse(fileContent);
|
|
13331
13451
|
} catch (parseError) {
|
|
13332
13452
|
const errorMessage = parseError instanceof Error ? parseError.message : String(parseError);
|
|
@@ -13424,7 +13544,7 @@ async function validateJSONConfigs(baseDir = process.cwd(), backendType = "mcp")
|
|
|
13424
13544
|
}
|
|
13425
13545
|
function displayValidationResults(result) {
|
|
13426
13546
|
if (result.isValid && result.warnings.length === 0) {
|
|
13427
|
-
console.
|
|
13547
|
+
console.error(chalk15__default.default.green("\u2705 All configuration files are valid\n"));
|
|
13428
13548
|
return;
|
|
13429
13549
|
}
|
|
13430
13550
|
if (result.errors.length > 0) {
|
|
@@ -13461,7 +13581,7 @@ function displayValidationResults(result) {
|
|
|
13461
13581
|
}
|
|
13462
13582
|
async function logValidationResults(result, baseDir = process.cwd()) {
|
|
13463
13583
|
const logDir = path3__namespace.default.join(baseDir, ".juno_task", "logs");
|
|
13464
|
-
await
|
|
13584
|
+
await fs2__default.default.ensureDir(logDir);
|
|
13465
13585
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
13466
13586
|
const logFile = path3__namespace.default.join(logDir, `startup-validation-${timestamp}.log`);
|
|
13467
13587
|
const logContent = [
|
|
@@ -13504,7 +13624,7 @@ async function logValidationResults(result, baseDir = process.cwd()) {
|
|
|
13504
13624
|
logContent.push(``);
|
|
13505
13625
|
}
|
|
13506
13626
|
}
|
|
13507
|
-
await
|
|
13627
|
+
await fs2__default.default.writeFile(logFile, logContent.join("\n"));
|
|
13508
13628
|
return logFile;
|
|
13509
13629
|
}
|
|
13510
13630
|
async function validateStartupConfigs(baseDir = process.cwd(), verbose = false) {
|
|
@@ -13838,7 +13958,7 @@ var TemplateEngine = class {
|
|
|
13838
13958
|
let overallError;
|
|
13839
13959
|
try {
|
|
13840
13960
|
if (!options.dryRun) {
|
|
13841
|
-
await
|
|
13961
|
+
await fs2__default.default.ensureDir(targetDirectory);
|
|
13842
13962
|
}
|
|
13843
13963
|
for (const template of templates) {
|
|
13844
13964
|
try {
|
|
@@ -15188,7 +15308,7 @@ This directory contains specification documents for your project.
|
|
|
15188
15308
|
const fileName = this.getTemplateFileName(template);
|
|
15189
15309
|
const targetPath = path3__namespace.join(targetDirectory, fileName);
|
|
15190
15310
|
try {
|
|
15191
|
-
const fileExists = await
|
|
15311
|
+
const fileExists = await fs2__default.default.pathExists(targetPath);
|
|
15192
15312
|
if (fileExists && !options.force && options.onConflict !== "overwrite") {
|
|
15193
15313
|
return {
|
|
15194
15314
|
path: targetPath,
|
|
@@ -15210,10 +15330,10 @@ This directory contains specification documents for your project.
|
|
|
15210
15330
|
}
|
|
15211
15331
|
if (options.createBackup && fileExists) {
|
|
15212
15332
|
const backupPath = `${targetPath}.backup.${Date.now()}`;
|
|
15213
|
-
await
|
|
15333
|
+
await fs2__default.default.copy(targetPath, backupPath);
|
|
15214
15334
|
}
|
|
15215
|
-
await
|
|
15216
|
-
await
|
|
15335
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(targetPath));
|
|
15336
|
+
await fs2__default.default.writeFile(targetPath, renderedContent, "utf8");
|
|
15217
15337
|
return {
|
|
15218
15338
|
path: targetPath,
|
|
15219
15339
|
content: renderedContent,
|
|
@@ -15477,7 +15597,7 @@ var SimpleInitTUI = class {
|
|
|
15477
15597
|
}
|
|
15478
15598
|
async confirmSave(targetDirectory) {
|
|
15479
15599
|
const junoTaskPath = path3__namespace.join(targetDirectory, ".juno_task");
|
|
15480
|
-
if (await
|
|
15600
|
+
if (await fs2__default.default.pathExists(junoTaskPath)) {
|
|
15481
15601
|
console.log(chalk15__default.default.yellow(" \u26A0\uFE0F .juno_task directory already exists"));
|
|
15482
15602
|
console.log(chalk15__default.default.gray(" Would you like to:"));
|
|
15483
15603
|
console.log(chalk15__default.default.gray(" 1) Override existing files"));
|
|
@@ -15522,16 +15642,16 @@ var SimpleProjectGenerator = class {
|
|
|
15522
15642
|
async generate() {
|
|
15523
15643
|
const { targetDirectory, variables, force } = this.context;
|
|
15524
15644
|
console.log(chalk15__default.default.blue("\u{1F4C1} Creating project directory..."));
|
|
15525
|
-
await
|
|
15645
|
+
await fs2__default.default.ensureDir(targetDirectory);
|
|
15526
15646
|
const junoTaskDir = path3__namespace.join(targetDirectory, ".juno_task");
|
|
15527
|
-
const junoTaskExists = await
|
|
15647
|
+
const junoTaskExists = await fs2__default.default.pathExists(junoTaskDir);
|
|
15528
15648
|
if (junoTaskExists && !force) {
|
|
15529
15649
|
throw new ValidationError(
|
|
15530
15650
|
"Project already initialized. Directory .juno_task already exists.",
|
|
15531
15651
|
["Use --force flag to overwrite existing files", "Choose a different directory"]
|
|
15532
15652
|
);
|
|
15533
15653
|
}
|
|
15534
|
-
await
|
|
15654
|
+
await fs2__default.default.ensureDir(junoTaskDir);
|
|
15535
15655
|
console.log(chalk15__default.default.blue("\u2699\uFE0F Creating project configuration..."));
|
|
15536
15656
|
await this.createConfigFile(junoTaskDir, targetDirectory);
|
|
15537
15657
|
console.log(chalk15__default.default.blue("\u{1F527} Setting up MCP configuration..."));
|
|
@@ -15565,21 +15685,21 @@ var SimpleProjectGenerator = class {
|
|
|
15565
15685
|
const promptContent = await templateEngine.render(promptTemplate, templateContext);
|
|
15566
15686
|
const initContent = await templateEngine.render(initTemplate, templateContext);
|
|
15567
15687
|
const implementContent = await templateEngine.render(implementTemplate, templateContext);
|
|
15568
|
-
await
|
|
15569
|
-
await
|
|
15570
|
-
await
|
|
15688
|
+
await fs2__default.default.writeFile(path3__namespace.join(junoTaskDir, "prompt.md"), promptContent);
|
|
15689
|
+
await fs2__default.default.writeFile(path3__namespace.join(junoTaskDir, "init.md"), initContent);
|
|
15690
|
+
await fs2__default.default.writeFile(path3__namespace.join(junoTaskDir, "implement.md"), implementContent);
|
|
15571
15691
|
const userFeedbackTemplate = templateEngine.getBuiltInTemplate("USER_FEEDBACK.md");
|
|
15572
15692
|
if (userFeedbackTemplate) {
|
|
15573
15693
|
const userFeedbackContent = await templateEngine.render(userFeedbackTemplate, templateContext);
|
|
15574
|
-
await
|
|
15694
|
+
await fs2__default.default.writeFile(path3__namespace.join(junoTaskDir, "USER_FEEDBACK.md"), userFeedbackContent);
|
|
15575
15695
|
}
|
|
15576
15696
|
const planTemplate = templateEngine.getBuiltInTemplate("plan.md");
|
|
15577
15697
|
if (planTemplate) {
|
|
15578
15698
|
const planContent = await templateEngine.render(planTemplate, templateContext);
|
|
15579
|
-
await
|
|
15699
|
+
await fs2__default.default.writeFile(path3__namespace.join(junoTaskDir, "plan.md"), planContent);
|
|
15580
15700
|
}
|
|
15581
15701
|
const specsDir = path3__namespace.join(junoTaskDir, "specs");
|
|
15582
|
-
await
|
|
15702
|
+
await fs2__default.default.ensureDir(specsDir);
|
|
15583
15703
|
const specsReadmeContent = `# Project Specifications
|
|
15584
15704
|
|
|
15585
15705
|
This directory contains detailed specifications for the project components.
|
|
@@ -15596,7 +15716,7 @@ This directory contains detailed specifications for the project components.
|
|
|
15596
15716
|
- Avoid conflicts with existing file names
|
|
15597
15717
|
- Use \`.md\` extension for all specification files
|
|
15598
15718
|
`;
|
|
15599
|
-
await
|
|
15719
|
+
await fs2__default.default.writeFile(path3__namespace.join(specsDir, "README.md"), specsReadmeContent);
|
|
15600
15720
|
const requirementsContent = `# Requirements Specification
|
|
15601
15721
|
|
|
15602
15722
|
## Functional Requirements
|
|
@@ -15643,7 +15763,7 @@ This directory contains detailed specifications for the project components.
|
|
|
15643
15763
|
- Code quality: Clean, maintainable codebase
|
|
15644
15764
|
- Documentation: Complete and accurate documentation
|
|
15645
15765
|
`;
|
|
15646
|
-
await
|
|
15766
|
+
await fs2__default.default.writeFile(path3__namespace.join(specsDir, "requirements.md"), requirementsContent);
|
|
15647
15767
|
const architectureContent = `# Architecture Specification
|
|
15648
15768
|
|
|
15649
15769
|
## System Overview
|
|
@@ -15725,7 +15845,7 @@ This project uses AI-assisted development with juno-code to achieve: ${variables
|
|
|
15725
15845
|
- Performance monitoring
|
|
15726
15846
|
- Security best practices
|
|
15727
15847
|
`;
|
|
15728
|
-
await
|
|
15848
|
+
await fs2__default.default.writeFile(path3__namespace.join(specsDir, "architecture.md"), architectureContent);
|
|
15729
15849
|
const claudeContent = `# Claude Development Session Learnings
|
|
15730
15850
|
|
|
15731
15851
|
## Project Overview
|
|
@@ -15797,7 +15917,7 @@ This file will be updated as development progresses to track:
|
|
|
15797
15917
|
- Solutions to complex problems
|
|
15798
15918
|
- Performance improvements and optimizations
|
|
15799
15919
|
`;
|
|
15800
|
-
await
|
|
15920
|
+
await fs2__default.default.writeFile(path3__namespace.join(targetDirectory, "CLAUDE.md"), claudeContent);
|
|
15801
15921
|
const agentsContent = `# AI Agent Selection and Performance
|
|
15802
15922
|
|
|
15803
15923
|
## Available Agents
|
|
@@ -15861,7 +15981,7 @@ Track agent performance for:
|
|
|
15861
15981
|
4. **Feedback Loop**: Provide feedback to improve agent performance
|
|
15862
15982
|
5. **Performance Monitoring**: Track and optimize agent usage
|
|
15863
15983
|
`;
|
|
15864
|
-
await
|
|
15984
|
+
await fs2__default.default.writeFile(path3__namespace.join(targetDirectory, "AGENTS.md"), agentsContent);
|
|
15865
15985
|
const readmeContent = `# ${variables.PROJECT_NAME}
|
|
15866
15986
|
|
|
15867
15987
|
${variables.DESCRIPTION}
|
|
@@ -15958,7 +16078,7 @@ ${variables.GIT_URL}` : ""}
|
|
|
15958
16078
|
Created with juno-code on ${variables.CURRENT_DATE}
|
|
15959
16079
|
${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
15960
16080
|
`;
|
|
15961
|
-
await
|
|
16081
|
+
await fs2__default.default.writeFile(path3__namespace.join(targetDirectory, "README.md"), readmeContent);
|
|
15962
16082
|
console.log(chalk15__default.default.blue("\u{1F4E6} Installing utility scripts..."));
|
|
15963
16083
|
await this.copyScriptsFromTemplates(junoTaskDir);
|
|
15964
16084
|
console.log(chalk15__default.default.blue("\u{1F40D} Installing Python requirements..."));
|
|
@@ -16010,7 +16130,7 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16010
16130
|
hooks: getDefaultHooks()
|
|
16011
16131
|
};
|
|
16012
16132
|
const configPath = path3__namespace.join(junoTaskDir, "config.json");
|
|
16013
|
-
await
|
|
16133
|
+
await fs2__default.default.writeFile(configPath, JSON.stringify(configContent, null, 2));
|
|
16014
16134
|
console.log(chalk15__default.default.green(` \u2713 Created .juno_task/config.json with ${this.context.subagent} as default subagent`));
|
|
16015
16135
|
}
|
|
16016
16136
|
async createMcpFile(junoTaskDir, targetDirectory) {
|
|
@@ -16064,7 +16184,7 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16064
16184
|
}
|
|
16065
16185
|
};
|
|
16066
16186
|
const mcpPath = path3__namespace.join(junoTaskDir, "mcp.json");
|
|
16067
|
-
await
|
|
16187
|
+
await fs2__default.default.writeFile(mcpPath, JSON.stringify(mcpContent, null, 2));
|
|
16068
16188
|
console.log(chalk15__default.default.green(` \u2713 Created .juno_task/mcp.json with roundtable-ai server configuration`));
|
|
16069
16189
|
}
|
|
16070
16190
|
getDefaultModelForSubagent(subagent) {
|
|
@@ -16083,7 +16203,7 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16083
16203
|
async copyScriptsFromTemplates(junoTaskDir) {
|
|
16084
16204
|
try {
|
|
16085
16205
|
const scriptsDir = path3__namespace.join(junoTaskDir, "scripts");
|
|
16086
|
-
await
|
|
16206
|
+
await fs2__default.default.ensureDir(scriptsDir);
|
|
16087
16207
|
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
16208
|
const __dirname2 = path3__namespace.dirname(__filename2);
|
|
16089
16209
|
let templatesScriptsDir;
|
|
@@ -16094,11 +16214,11 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16094
16214
|
} else {
|
|
16095
16215
|
templatesScriptsDir = path3__namespace.join(__dirname2, "../../templates/scripts");
|
|
16096
16216
|
}
|
|
16097
|
-
if (!await
|
|
16217
|
+
if (!await fs2__default.default.pathExists(templatesScriptsDir)) {
|
|
16098
16218
|
console.log(chalk15__default.default.yellow(" \u26A0\uFE0F Template scripts directory not found, skipping script installation"));
|
|
16099
16219
|
return;
|
|
16100
16220
|
}
|
|
16101
|
-
const scriptFiles = await
|
|
16221
|
+
const scriptFiles = await fs2__default.default.readdir(templatesScriptsDir);
|
|
16102
16222
|
if (scriptFiles.length === 0) {
|
|
16103
16223
|
console.log(chalk15__default.default.gray(" \u2139\uFE0F No template scripts found to install"));
|
|
16104
16224
|
return;
|
|
@@ -16107,11 +16227,11 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16107
16227
|
for (const scriptFile of scriptFiles) {
|
|
16108
16228
|
const sourcePath = path3__namespace.join(templatesScriptsDir, scriptFile);
|
|
16109
16229
|
const destPath = path3__namespace.join(scriptsDir, scriptFile);
|
|
16110
|
-
const stats = await
|
|
16230
|
+
const stats = await fs2__default.default.stat(sourcePath);
|
|
16111
16231
|
if (stats.isFile()) {
|
|
16112
|
-
await
|
|
16232
|
+
await fs2__default.default.copy(sourcePath, destPath);
|
|
16113
16233
|
if (scriptFile.endsWith(".sh")) {
|
|
16114
|
-
await
|
|
16234
|
+
await fs2__default.default.chmod(destPath, 493);
|
|
16115
16235
|
}
|
|
16116
16236
|
copiedCount++;
|
|
16117
16237
|
console.log(chalk15__default.default.green(` \u2713 Installed script: ${scriptFile}`));
|
|
@@ -16134,7 +16254,7 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16134
16254
|
try {
|
|
16135
16255
|
const scriptsDir = path3__namespace.join(junoTaskDir, "scripts");
|
|
16136
16256
|
const installScript = path3__namespace.join(scriptsDir, "install_requirements.sh");
|
|
16137
|
-
if (!await
|
|
16257
|
+
if (!await fs2__default.default.pathExists(installScript)) {
|
|
16138
16258
|
console.log(chalk15__default.default.yellow(" \u26A0\uFE0F install_requirements.sh not found, skipping Python dependencies installation"));
|
|
16139
16259
|
console.log(chalk15__default.default.gray(" You can install dependencies manually: juno-kanban, roundtable-ai"));
|
|
16140
16260
|
return;
|
|
@@ -16431,20 +16551,20 @@ init_types();
|
|
|
16431
16551
|
async function loadInitPrompt(directory) {
|
|
16432
16552
|
const junoTaskDir = path3__namespace.join(directory, ".juno_task");
|
|
16433
16553
|
const initFile = path3__namespace.join(junoTaskDir, "init.md");
|
|
16434
|
-
if (!await
|
|
16554
|
+
if (!await fs2__default.default.pathExists(junoTaskDir)) {
|
|
16435
16555
|
throw new FileSystemError(
|
|
16436
16556
|
'No .juno_task directory found. Run "juno-code init" first.',
|
|
16437
16557
|
junoTaskDir
|
|
16438
16558
|
);
|
|
16439
16559
|
}
|
|
16440
|
-
if (!await
|
|
16560
|
+
if (!await fs2__default.default.pathExists(initFile)) {
|
|
16441
16561
|
throw new FileSystemError(
|
|
16442
16562
|
"No init.md file found in .juno_task directory",
|
|
16443
16563
|
initFile
|
|
16444
16564
|
);
|
|
16445
16565
|
}
|
|
16446
16566
|
try {
|
|
16447
|
-
const content = await
|
|
16567
|
+
const content = await fs2__default.default.readFile(initFile, "utf-8");
|
|
16448
16568
|
if (!content.trim()) {
|
|
16449
16569
|
throw new FileSystemError(
|
|
16450
16570
|
"init.md file is empty. Please add task instructions.",
|
|
@@ -17476,8 +17596,8 @@ Focus on ${request.intelligence === "basic" ? "basic functionality" : request.in
|
|
|
17476
17596
|
for (const scenario of scenarios) {
|
|
17477
17597
|
const testContent = await this.generateTestContent(request, scenario, template);
|
|
17478
17598
|
const testFilePath = this.resolveTestFilePath(request, scenario);
|
|
17479
|
-
await
|
|
17480
|
-
await
|
|
17599
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(testFilePath));
|
|
17600
|
+
await fs2__default.default.writeFile(testFilePath, testContent);
|
|
17481
17601
|
testFiles.push(testFilePath);
|
|
17482
17602
|
}
|
|
17483
17603
|
return testFiles;
|
|
@@ -17729,8 +17849,8 @@ var TestExecutionEngine = class {
|
|
|
17729
17849
|
async collectCoverage(request) {
|
|
17730
17850
|
const coverageFile = path3__namespace.join(request.workingDirectory, "coverage", "coverage-summary.json");
|
|
17731
17851
|
try {
|
|
17732
|
-
if (await
|
|
17733
|
-
const coverageData = await
|
|
17852
|
+
if (await fs2__default.default.pathExists(coverageFile)) {
|
|
17853
|
+
const coverageData = await fs2__default.default.readJson(coverageFile);
|
|
17734
17854
|
return {
|
|
17735
17855
|
lines: coverageData.total?.lines?.pct || 0,
|
|
17736
17856
|
functions: coverageData.total?.functions?.pct || 0,
|
|
@@ -17913,8 +18033,8 @@ var TestReportEngine = class {
|
|
|
17913
18033
|
suggestions: analysis.suggestions,
|
|
17914
18034
|
recommendations: analysis.recommendations
|
|
17915
18035
|
};
|
|
17916
|
-
await
|
|
17917
|
-
await
|
|
18036
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(outputPath));
|
|
18037
|
+
await fs2__default.default.writeJson(outputPath, report, { spaces: 2 });
|
|
17918
18038
|
return outputPath;
|
|
17919
18039
|
}
|
|
17920
18040
|
async generateHTMLReport(analysis, outputPath, includeVisualizations) {
|
|
@@ -17977,8 +18097,8 @@ var TestReportEngine = class {
|
|
|
17977
18097
|
</body>
|
|
17978
18098
|
</html>
|
|
17979
18099
|
`.trim();
|
|
17980
|
-
await
|
|
17981
|
-
await
|
|
18100
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(outputPath));
|
|
18101
|
+
await fs2__default.default.writeFile(outputPath, html);
|
|
17982
18102
|
return outputPath;
|
|
17983
18103
|
}
|
|
17984
18104
|
generateCharts(analysis) {
|
|
@@ -18035,8 +18155,8 @@ ${analysis.suggestions.map((suggestion) => `- ${suggestion}`).join("\n")}
|
|
|
18035
18155
|
|
|
18036
18156
|
${analysis.recommendations.map((rec) => `- ${rec}`).join("\n")}
|
|
18037
18157
|
`.trim();
|
|
18038
|
-
await
|
|
18039
|
-
await
|
|
18158
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(outputPath));
|
|
18159
|
+
await fs2__default.default.writeFile(outputPath, markdown);
|
|
18040
18160
|
return outputPath;
|
|
18041
18161
|
}
|
|
18042
18162
|
async displayConsoleReport(analysis) {
|
|
@@ -18376,7 +18496,7 @@ async function compactConfigFile(filePath, options = {}) {
|
|
|
18376
18496
|
preserveDays = 30,
|
|
18377
18497
|
preservePatterns = []
|
|
18378
18498
|
} = options;
|
|
18379
|
-
const originalContent = await
|
|
18499
|
+
const originalContent = await fs2__default.default.readFile(filePath, "utf-8");
|
|
18380
18500
|
const originalSize = originalContent.length;
|
|
18381
18501
|
let backupPath = "";
|
|
18382
18502
|
if (createBackup && !dryRun) {
|
|
@@ -18385,7 +18505,7 @@ async function compactConfigFile(filePath, options = {}) {
|
|
|
18385
18505
|
const basename11 = path3__namespace.basename(filePath, ext);
|
|
18386
18506
|
const dirname12 = path3__namespace.dirname(filePath);
|
|
18387
18507
|
backupPath = path3__namespace.join(dirname12, `${basename11}.backup.${timestamp}${ext}`);
|
|
18388
|
-
await
|
|
18508
|
+
await fs2__default.default.writeFile(backupPath, originalContent, "utf-8");
|
|
18389
18509
|
}
|
|
18390
18510
|
const compactionAnalysis = analyzeMarkdownStructure(originalContent);
|
|
18391
18511
|
const compactedContent = compactMarkdownContent(
|
|
@@ -18400,7 +18520,7 @@ async function compactConfigFile(filePath, options = {}) {
|
|
|
18400
18520
|
const compactedSize = finalContent.length;
|
|
18401
18521
|
const reductionPercentage = Math.round((originalSize - compactedSize) / originalSize * 100);
|
|
18402
18522
|
if (!dryRun) {
|
|
18403
|
-
await
|
|
18523
|
+
await fs2__default.default.writeFile(filePath, finalContent, "utf-8");
|
|
18404
18524
|
}
|
|
18405
18525
|
return {
|
|
18406
18526
|
originalSize,
|
|
@@ -18530,7 +18650,7 @@ function formatFileSize(bytes) {
|
|
|
18530
18650
|
}
|
|
18531
18651
|
async function shouldCompactFile(filePath, sizeThresholdKB = 50, ageThresholdDays = 30) {
|
|
18532
18652
|
try {
|
|
18533
|
-
const stats = await
|
|
18653
|
+
const stats = await fs2__default.default.stat(filePath);
|
|
18534
18654
|
const sizeKB = stats.size / 1024;
|
|
18535
18655
|
if (sizeKB > sizeThresholdKB) {
|
|
18536
18656
|
return true;
|
|
@@ -18552,19 +18672,19 @@ async function archiveResolvedIssues(options) {
|
|
|
18552
18672
|
feedbackFile,
|
|
18553
18673
|
archiveDir = path3__namespace.join(path3__namespace.dirname(feedbackFile), "archives"),
|
|
18554
18674
|
openIssuesThreshold = 10} = options;
|
|
18555
|
-
if (!await
|
|
18675
|
+
if (!await fs2__default.default.pathExists(feedbackFile)) {
|
|
18556
18676
|
throw new Error(`Feedback file does not exist: ${feedbackFile}`);
|
|
18557
18677
|
}
|
|
18558
|
-
const content = await
|
|
18678
|
+
const content = await fs2__default.default.readFile(feedbackFile, "utf-8");
|
|
18559
18679
|
const parsed = parseUserFeedback(content);
|
|
18560
18680
|
const warningsGenerated = [];
|
|
18561
18681
|
if (parsed.openIssues.length > openIssuesThreshold) {
|
|
18562
18682
|
const warning = `Found ${parsed.openIssues.length} open issues (threshold: ${openIssuesThreshold}). Consider reviewing and prioritizing.`;
|
|
18563
18683
|
warningsGenerated.push(warning);
|
|
18564
18684
|
const logFile = path3__namespace.join(path3__namespace.dirname(feedbackFile), "logs", "feedback-warnings.log");
|
|
18565
|
-
await
|
|
18685
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(logFile));
|
|
18566
18686
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
18567
|
-
await
|
|
18687
|
+
await fs2__default.default.appendFile(logFile, `[${timestamp}] ${warning}
|
|
18568
18688
|
`);
|
|
18569
18689
|
}
|
|
18570
18690
|
if (parsed.resolvedIssues.length === 0) {
|
|
@@ -18581,10 +18701,10 @@ async function archiveResolvedIssues(options) {
|
|
|
18581
18701
|
const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
|
|
18582
18702
|
const archiveFile = path3__namespace.join(archiveDir, `USER_FEEDBACK_archive_${currentYear}.md`);
|
|
18583
18703
|
{
|
|
18584
|
-
await
|
|
18704
|
+
await fs2__default.default.ensureDir(archiveDir);
|
|
18585
18705
|
await appendToArchive(archiveFile, parsed.resolvedIssues);
|
|
18586
18706
|
const compactedContent = generateCompactedFeedback(parsed.openIssues, parsed.metadata);
|
|
18587
|
-
await
|
|
18707
|
+
await fs2__default.default.writeFile(feedbackFile, compactedContent, "utf-8");
|
|
18588
18708
|
}
|
|
18589
18709
|
{
|
|
18590
18710
|
console.log(chalk15__default.default.green(`\u2705 Archived ${parsed.resolvedIssues.length} resolved issues`));
|
|
@@ -18631,8 +18751,8 @@ function parseUserFeedback(content) {
|
|
|
18631
18751
|
async function appendToArchive(archiveFile, resolvedIssues) {
|
|
18632
18752
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
18633
18753
|
let archiveContent = "";
|
|
18634
|
-
if (await
|
|
18635
|
-
archiveContent = await
|
|
18754
|
+
if (await fs2__default.default.pathExists(archiveFile)) {
|
|
18755
|
+
archiveContent = await fs2__default.default.readFile(archiveFile, "utf-8");
|
|
18636
18756
|
} else {
|
|
18637
18757
|
const year = path3__namespace.basename(archiveFile).match(/(\d{4})/)?.[1] || (/* @__PURE__ */ new Date()).getFullYear();
|
|
18638
18758
|
archiveContent = `# User Feedback Archive ${year}
|
|
@@ -18666,7 +18786,7 @@ ${resolvedIssue}
|
|
|
18666
18786
|
`- Last updated: ${timestamp}`
|
|
18667
18787
|
);
|
|
18668
18788
|
}
|
|
18669
|
-
await
|
|
18789
|
+
await fs2__default.default.writeFile(archiveFile, archiveContent, "utf-8");
|
|
18670
18790
|
}
|
|
18671
18791
|
function generateCompactedFeedback(openIssues, metadata) {
|
|
18672
18792
|
let content = metadata.trim() + "\n";
|
|
@@ -18691,15 +18811,15 @@ async function shouldArchive(feedbackFile, options = {}) {
|
|
|
18691
18811
|
// 50KB
|
|
18692
18812
|
lineCountThreshold = 500
|
|
18693
18813
|
} = options;
|
|
18694
|
-
if (!await
|
|
18814
|
+
if (!await fs2__default.default.pathExists(feedbackFile)) {
|
|
18695
18815
|
return {
|
|
18696
18816
|
shouldArchive: false,
|
|
18697
18817
|
reasons: [],
|
|
18698
18818
|
stats: { openIssuesCount: 0, resolvedIssuesCount: 0, fileSizeBytes: 0, lineCount: 0 }
|
|
18699
18819
|
};
|
|
18700
18820
|
}
|
|
18701
|
-
const content = await
|
|
18702
|
-
const stats = await
|
|
18821
|
+
const content = await fs2__default.default.readFile(feedbackFile, "utf-8");
|
|
18822
|
+
const stats = await fs2__default.default.stat(feedbackFile);
|
|
18703
18823
|
const parsed = parseUserFeedback(content);
|
|
18704
18824
|
const lineCount = content.split("\n").length;
|
|
18705
18825
|
const reasons = [];
|
|
@@ -18773,16 +18893,16 @@ var EnhancedFeedbackFileManager = class {
|
|
|
18773
18893
|
this.feedbackFile = feedbackFile;
|
|
18774
18894
|
}
|
|
18775
18895
|
async ensureExists() {
|
|
18776
|
-
if (!await
|
|
18896
|
+
if (!await fs2__default.default.pathExists(this.feedbackFile)) {
|
|
18777
18897
|
await this.createInitialFile();
|
|
18778
18898
|
}
|
|
18779
18899
|
}
|
|
18780
18900
|
async addFeedback(issue, testCriteria) {
|
|
18781
18901
|
await this.ensureExists();
|
|
18782
18902
|
try {
|
|
18783
|
-
const content = await
|
|
18903
|
+
const content = await fs2__default.default.readFile(this.feedbackFile, "utf-8");
|
|
18784
18904
|
const updatedContent = this.addIssueToContent(content, issue, testCriteria);
|
|
18785
|
-
await
|
|
18905
|
+
await fs2__default.default.writeFile(this.feedbackFile, updatedContent, "utf-8");
|
|
18786
18906
|
} catch (error) {
|
|
18787
18907
|
throw new ValidationError(
|
|
18788
18908
|
`Failed to save feedback: ${error}`,
|
|
@@ -18795,12 +18915,12 @@ var EnhancedFeedbackFileManager = class {
|
|
|
18795
18915
|
*/
|
|
18796
18916
|
async repairMalformedFile() {
|
|
18797
18917
|
try {
|
|
18798
|
-
const content = await
|
|
18918
|
+
const content = await fs2__default.default.readFile(this.feedbackFile, "utf-8");
|
|
18799
18919
|
const hasOpenIssues = content.includes("<OPEN_ISSUES>");
|
|
18800
18920
|
const hasClosingTag = content.includes("</OPEN_ISSUES>");
|
|
18801
18921
|
if (!hasOpenIssues || !hasClosingTag) {
|
|
18802
18922
|
const backupPath = this.feedbackFile + ".backup." + Date.now();
|
|
18803
|
-
await
|
|
18923
|
+
await fs2__default.default.writeFile(backupPath, content, "utf-8");
|
|
18804
18924
|
const existingIssues = this.extractIssuesFromMalformedContent(content);
|
|
18805
18925
|
await this.createInitialFile(existingIssues);
|
|
18806
18926
|
}
|
|
@@ -18832,8 +18952,8 @@ List any features you'd like to see added or bugs you've encountered.
|
|
|
18832
18952
|
|
|
18833
18953
|
<!-- Resolved issues will be moved here -->
|
|
18834
18954
|
`;
|
|
18835
|
-
await
|
|
18836
|
-
await
|
|
18955
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(this.feedbackFile));
|
|
18956
|
+
await fs2__default.default.writeFile(this.feedbackFile, initialContent, "utf-8");
|
|
18837
18957
|
}
|
|
18838
18958
|
addIssueToContent(content, issue, testCriteria) {
|
|
18839
18959
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
@@ -18949,17 +19069,17 @@ async function handleCompactCommand(subArgs, options) {
|
|
|
18949
19069
|
if (subArgs.length > 0) {
|
|
18950
19070
|
for (const filePath of subArgs) {
|
|
18951
19071
|
const resolvedPath = path3__namespace.resolve(filePath);
|
|
18952
|
-
if (await
|
|
19072
|
+
if (await fs2__default.default.pathExists(resolvedPath)) {
|
|
18953
19073
|
filesToCompact.push(resolvedPath);
|
|
18954
19074
|
} else {
|
|
18955
19075
|
console.warn(chalk15__default.default.yellow(`\u26A0\uFE0F File not found: ${filePath}`));
|
|
18956
19076
|
}
|
|
18957
19077
|
}
|
|
18958
19078
|
} else {
|
|
18959
|
-
if (await
|
|
19079
|
+
if (await fs2__default.default.pathExists(defaultClaudeFile)) {
|
|
18960
19080
|
filesToCompact.push(defaultClaudeFile);
|
|
18961
19081
|
}
|
|
18962
|
-
if (await
|
|
19082
|
+
if (await fs2__default.default.pathExists(defaultAgentsFile)) {
|
|
18963
19083
|
filesToCompact.push(defaultAgentsFile);
|
|
18964
19084
|
}
|
|
18965
19085
|
}
|
|
@@ -19893,11 +20013,11 @@ var GitManager = class {
|
|
|
19893
20013
|
*/
|
|
19894
20014
|
async updateJunoTaskConfig(gitUrl) {
|
|
19895
20015
|
const configPath = path3__namespace.join(this.workingDirectory, ".juno_task", "init.md");
|
|
19896
|
-
if (!await
|
|
20016
|
+
if (!await fs2__default.default.pathExists(configPath)) {
|
|
19897
20017
|
return;
|
|
19898
20018
|
}
|
|
19899
20019
|
try {
|
|
19900
|
-
let content = await
|
|
20020
|
+
let content = await fs2__default.default.readFile(configPath, "utf-8");
|
|
19901
20021
|
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
19902
20022
|
if (frontmatterMatch) {
|
|
19903
20023
|
let frontmatter = frontmatterMatch[1];
|
|
@@ -19918,7 +20038,7 @@ GIT_URL: ${gitUrl}
|
|
|
19918
20038
|
`;
|
|
19919
20039
|
content = frontmatter + content;
|
|
19920
20040
|
}
|
|
19921
|
-
await
|
|
20041
|
+
await fs2__default.default.writeFile(configPath, content, "utf-8");
|
|
19922
20042
|
} catch (error) {
|
|
19923
20043
|
console.warn(`Warning: Failed to update juno-code configuration: ${error}`);
|
|
19924
20044
|
}
|
|
@@ -21850,6 +21970,11 @@ var QUICK_REFERENCE = [
|
|
|
21850
21970
|
description: "Shell completion setup",
|
|
21851
21971
|
usage: "juno-code completion <install|uninstall>"
|
|
21852
21972
|
},
|
|
21973
|
+
{
|
|
21974
|
+
name: "services",
|
|
21975
|
+
description: "Manage service scripts (use --force to refresh codex.py/claude.py)",
|
|
21976
|
+
usage: "juno-code services install --force"
|
|
21977
|
+
},
|
|
21853
21978
|
{
|
|
21854
21979
|
name: "help",
|
|
21855
21980
|
description: "Show help information",
|
|
@@ -22418,11 +22543,12 @@ init_service_installer();
|
|
|
22418
22543
|
function createServicesCommand() {
|
|
22419
22544
|
const servicesCmd = new commander.Command("services").description("Manage juno-code service scripts").addHelpText("after", `
|
|
22420
22545
|
Examples:
|
|
22421
|
-
$ juno-code services install
|
|
22422
|
-
$ juno-code services
|
|
22423
|
-
$ juno-code services
|
|
22424
|
-
$ juno-code services
|
|
22425
|
-
$ juno-code services
|
|
22546
|
+
$ juno-code services install Install service scripts to ~/.juno_code/services/
|
|
22547
|
+
$ juno-code services install --force Reinstall/refresh service scripts (codex.py/claude.py)
|
|
22548
|
+
$ juno-code services list List installed service scripts
|
|
22549
|
+
$ juno-code services status Check installation status
|
|
22550
|
+
$ juno-code services uninstall Remove all service scripts
|
|
22551
|
+
$ juno-code services path Show services directory path
|
|
22426
22552
|
|
|
22427
22553
|
Service scripts are Python/shell scripts that provide additional functionality
|
|
22428
22554
|
and can be customized by users. They are installed to ~/.juno_code/services/
|
|
@@ -22596,7 +22722,7 @@ var ShellDetector = class _ShellDetector {
|
|
|
22596
22722
|
* Get shell configuration file path
|
|
22597
22723
|
*/
|
|
22598
22724
|
getConfigPath(shell) {
|
|
22599
|
-
const homeDir =
|
|
22725
|
+
const homeDir = os4__namespace.homedir();
|
|
22600
22726
|
switch (shell) {
|
|
22601
22727
|
case "bash":
|
|
22602
22728
|
if (process.platform === "darwin") {
|
|
@@ -22620,7 +22746,7 @@ var ShellDetector = class _ShellDetector {
|
|
|
22620
22746
|
* Get shell completion script installation path
|
|
22621
22747
|
*/
|
|
22622
22748
|
getCompletionPath(shell) {
|
|
22623
|
-
const homeDir =
|
|
22749
|
+
const homeDir = os4__namespace.homedir();
|
|
22624
22750
|
switch (shell) {
|
|
22625
22751
|
case "bash":
|
|
22626
22752
|
if (process.platform === "darwin") {
|
|
@@ -22675,10 +22801,10 @@ autoload -U compinit && compinit`;
|
|
|
22675
22801
|
*/
|
|
22676
22802
|
async isSourceCommandPresent(configPath, sourceCommand) {
|
|
22677
22803
|
try {
|
|
22678
|
-
if (!await
|
|
22804
|
+
if (!await fs2__default.default.pathExists(configPath)) {
|
|
22679
22805
|
return false;
|
|
22680
22806
|
}
|
|
22681
|
-
const content = await
|
|
22807
|
+
const content = await fs2__default.default.readFile(configPath, "utf-8");
|
|
22682
22808
|
return content.includes("juno-code completion");
|
|
22683
22809
|
} catch {
|
|
22684
22810
|
return false;
|
|
@@ -22700,15 +22826,15 @@ autoload -U compinit && compinit`;
|
|
|
22700
22826
|
continue;
|
|
22701
22827
|
}
|
|
22702
22828
|
try {
|
|
22703
|
-
const completionExists = await
|
|
22704
|
-
const configExists = await
|
|
22829
|
+
const completionExists = await fs2__default.default.pathExists(shell.completionPath);
|
|
22830
|
+
const configExists = await fs2__default.default.pathExists(shell.configPath);
|
|
22705
22831
|
const isSourced = configExists && await this.isSourceCommandPresent(
|
|
22706
22832
|
shell.configPath,
|
|
22707
22833
|
this.getSourceCommand(shell.name, shell.completionPath)
|
|
22708
22834
|
);
|
|
22709
22835
|
let lastInstalled;
|
|
22710
22836
|
if (completionExists) {
|
|
22711
|
-
const stats = await
|
|
22837
|
+
const stats = await fs2__default.default.stat(shell.completionPath);
|
|
22712
22838
|
lastInstalled = stats.mtime;
|
|
22713
22839
|
}
|
|
22714
22840
|
statuses.push({
|
|
@@ -22734,7 +22860,7 @@ autoload -U compinit && compinit`;
|
|
|
22734
22860
|
async ensureCompletionDirectory(shell) {
|
|
22735
22861
|
const completionPath = this.getCompletionPath(shell);
|
|
22736
22862
|
const completionDir = path3__namespace.dirname(completionPath);
|
|
22737
|
-
await
|
|
22863
|
+
await fs2__default.default.ensureDir(completionDir);
|
|
22738
22864
|
}
|
|
22739
22865
|
/**
|
|
22740
22866
|
* Ensure directory exists for shell configuration
|
|
@@ -22742,7 +22868,7 @@ autoload -U compinit && compinit`;
|
|
|
22742
22868
|
async ensureConfigDirectory(shell) {
|
|
22743
22869
|
const configPath = this.getConfigPath(shell);
|
|
22744
22870
|
const configDir = path3__namespace.dirname(configPath);
|
|
22745
|
-
await
|
|
22871
|
+
await fs2__default.default.ensureDir(configDir);
|
|
22746
22872
|
}
|
|
22747
22873
|
/**
|
|
22748
22874
|
* Get shell version information
|
|
@@ -22766,15 +22892,15 @@ autoload -U compinit && compinit`;
|
|
|
22766
22892
|
try {
|
|
22767
22893
|
const configPath = this.getConfigPath(shell);
|
|
22768
22894
|
const configDir = path3__namespace.dirname(configPath);
|
|
22769
|
-
await
|
|
22895
|
+
await fs2__default.default.access(configDir, fs2__default.default.constants.W_OK);
|
|
22770
22896
|
} catch {
|
|
22771
22897
|
issues.push(`Cannot write to ${shell} configuration directory`);
|
|
22772
22898
|
}
|
|
22773
22899
|
try {
|
|
22774
22900
|
const completionPath = this.getCompletionPath(shell);
|
|
22775
22901
|
const completionDir = path3__namespace.dirname(completionPath);
|
|
22776
|
-
await
|
|
22777
|
-
await
|
|
22902
|
+
await fs2__default.default.ensureDir(completionDir);
|
|
22903
|
+
await fs2__default.default.access(completionDir, fs2__default.default.constants.W_OK);
|
|
22778
22904
|
} catch {
|
|
22779
22905
|
issues.push(`Cannot write to ${shell} completion directory`);
|
|
22780
22906
|
}
|
|
@@ -22845,10 +22971,10 @@ var ContextAwareCompletion = class {
|
|
|
22845
22971
|
async getSessionIds() {
|
|
22846
22972
|
try {
|
|
22847
22973
|
const sessionDir = path3__namespace.join(process.cwd(), ".juno_task", "sessions");
|
|
22848
|
-
if (!await
|
|
22974
|
+
if (!await fs2__default.default.pathExists(sessionDir)) {
|
|
22849
22975
|
return [];
|
|
22850
22976
|
}
|
|
22851
|
-
const sessions = await
|
|
22977
|
+
const sessions = await fs2__default.default.readdir(sessionDir);
|
|
22852
22978
|
return sessions.filter((name) => name.match(/^session_\d+$/)).map((name) => name.replace("session_", "")).sort((a, b) => parseInt(b) - parseInt(a));
|
|
22853
22979
|
} catch {
|
|
22854
22980
|
return [];
|
|
@@ -22862,8 +22988,8 @@ var ContextAwareCompletion = class {
|
|
|
22862
22988
|
const builtinTemplates = ["basic", "advanced", "research", "development"];
|
|
22863
22989
|
const customTemplatesDir = path3__namespace.join(process.cwd(), ".juno_task", "templates");
|
|
22864
22990
|
let customTemplates = [];
|
|
22865
|
-
if (await
|
|
22866
|
-
const files = await
|
|
22991
|
+
if (await fs2__default.default.pathExists(customTemplatesDir)) {
|
|
22992
|
+
const files = await fs2__default.default.readdir(customTemplatesDir);
|
|
22867
22993
|
customTemplates = files.filter((name) => name.endsWith(".md") || name.endsWith(".hbs")).map((name) => path3__namespace.basename(name, path3__namespace.extname(name)));
|
|
22868
22994
|
}
|
|
22869
22995
|
return [...builtinTemplates, ...customTemplates].sort();
|
|
@@ -22898,7 +23024,7 @@ var ContextAwareCompletion = class {
|
|
|
22898
23024
|
*/
|
|
22899
23025
|
expandPath(inputPath) {
|
|
22900
23026
|
if (inputPath.startsWith("~/")) {
|
|
22901
|
-
return path3__namespace.join(
|
|
23027
|
+
return path3__namespace.join(os4__namespace.homedir(), inputPath.slice(2));
|
|
22902
23028
|
}
|
|
22903
23029
|
if (inputPath.startsWith("./") || inputPath.startsWith("../")) {
|
|
22904
23030
|
return path3__namespace.resolve(inputPath);
|
|
@@ -22940,7 +23066,7 @@ var CompletionInstaller = class {
|
|
|
22940
23066
|
await this.shellDetector.ensureConfigDirectory(shell);
|
|
22941
23067
|
const script = this.generateEnhancedCompletion(shell, "juno-code");
|
|
22942
23068
|
const completionPath = this.shellDetector.getCompletionPath(shell);
|
|
22943
|
-
await
|
|
23069
|
+
await fs2__default.default.writeFile(completionPath, script, "utf-8");
|
|
22944
23070
|
const configPath = this.shellDetector.getConfigPath(shell);
|
|
22945
23071
|
const sourceCommand = this.shellDetector.getSourceCommand(shell, completionPath);
|
|
22946
23072
|
const warnings = [];
|
|
@@ -22948,7 +23074,7 @@ var CompletionInstaller = class {
|
|
|
22948
23074
|
const isPresent = await this.shellDetector.isSourceCommandPresent(configPath, sourceCommand);
|
|
22949
23075
|
if (!isPresent) {
|
|
22950
23076
|
try {
|
|
22951
|
-
await
|
|
23077
|
+
await fs2__default.default.appendFile(configPath, `
|
|
22952
23078
|
|
|
22953
23079
|
${sourceCommand}
|
|
22954
23080
|
`);
|
|
@@ -22979,8 +23105,8 @@ ${sourceCommand}
|
|
|
22979
23105
|
async uninstall(shell) {
|
|
22980
23106
|
try {
|
|
22981
23107
|
const completionPath = this.shellDetector.getCompletionPath(shell);
|
|
22982
|
-
if (await
|
|
22983
|
-
await
|
|
23108
|
+
if (await fs2__default.default.pathExists(completionPath)) {
|
|
23109
|
+
await fs2__default.default.remove(completionPath);
|
|
22984
23110
|
return true;
|
|
22985
23111
|
}
|
|
22986
23112
|
return false;
|
|
@@ -22994,7 +23120,7 @@ ${sourceCommand}
|
|
|
22994
23120
|
async isInstalled(shell) {
|
|
22995
23121
|
try {
|
|
22996
23122
|
const completionPath = this.shellDetector.getCompletionPath(shell);
|
|
22997
|
-
return await
|
|
23123
|
+
return await fs2__default.default.pathExists(completionPath);
|
|
22998
23124
|
} catch {
|
|
22999
23125
|
return false;
|
|
23000
23126
|
}
|