juno-code 1.0.31 → 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 +201 -143
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/cli.mjs +200 -142
- package/dist/bin/cli.mjs.map +1 -1
- package/dist/index.js +32 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +32 -3
- package/dist/index.mjs.map +1 -1
- package/dist/templates/services/__pycache__/codex.cpython-38.pyc +0 -0
- package/dist/templates/services/claude.py +14 -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) {
|
|
@@ -1210,6 +1229,8 @@ var init_config = __esm({
|
|
|
1210
1229
|
JUNO_CODE_MCP_RETRIES: "mcpRetries",
|
|
1211
1230
|
JUNO_CODE_MCP_SERVER_PATH: "mcpServerPath",
|
|
1212
1231
|
JUNO_CODE_MCP_SERVER_NAME: "mcpServerName",
|
|
1232
|
+
// Hook settings
|
|
1233
|
+
JUNO_CODE_HOOK_COMMAND_TIMEOUT: "hookCommandTimeout",
|
|
1213
1234
|
// TUI settings
|
|
1214
1235
|
JUNO_CODE_INTERACTIVE: "interactive",
|
|
1215
1236
|
JUNO_CODE_HEADLESS_MODE: "headlessMode",
|
|
@@ -1233,6 +1254,8 @@ var init_config = __esm({
|
|
|
1233
1254
|
JUNO_TASK_MCP_RETRIES: "mcpRetries",
|
|
1234
1255
|
JUNO_TASK_MCP_SERVER_PATH: "mcpServerPath",
|
|
1235
1256
|
JUNO_TASK_MCP_SERVER_NAME: "mcpServerName",
|
|
1257
|
+
// Hook settings
|
|
1258
|
+
JUNO_TASK_HOOK_COMMAND_TIMEOUT: "hookCommandTimeout",
|
|
1236
1259
|
// TUI settings
|
|
1237
1260
|
JUNO_TASK_INTERACTIVE: "interactive",
|
|
1238
1261
|
JUNO_TASK_HEADLESS_MODE: "headlessMode",
|
|
@@ -1264,6 +1287,8 @@ var init_config = __esm({
|
|
|
1264
1287
|
mcpRetries: zod.z.number().int().min(0).max(10).describe("Number of retries for MCP operations"),
|
|
1265
1288
|
mcpServerPath: zod.z.string().optional().describe("Path to MCP server executable (auto-discovered if not specified)"),
|
|
1266
1289
|
mcpServerName: zod.z.string().optional().describe('Named MCP server to connect to (e.g., "roundtable-ai")'),
|
|
1290
|
+
// Hook settings
|
|
1291
|
+
hookCommandTimeout: zod.z.number().int().min(1e3).max(36e5).optional().describe("Timeout for individual hook commands in milliseconds (default: 300000 = 5 minutes)"),
|
|
1267
1292
|
// TUI settings
|
|
1268
1293
|
interactive: zod.z.boolean().describe("Enable interactive mode"),
|
|
1269
1294
|
headlessMode: zod.z.boolean().describe("Enable headless mode (no TUI)"),
|
|
@@ -3373,7 +3398,8 @@ var init_advanced_logger = __esm({
|
|
|
3373
3398
|
async function executeHook(hookType, hooks, context = {}, options = {}) {
|
|
3374
3399
|
const startTime = Date.now();
|
|
3375
3400
|
const {
|
|
3376
|
-
commandTimeout =
|
|
3401
|
+
commandTimeout = 3e5,
|
|
3402
|
+
// 5 minutes default (increased from 30s to support long-running hook scripts)
|
|
3377
3403
|
env: env2 = {},
|
|
3378
3404
|
continueOnError = true,
|
|
3379
3405
|
logContext = "SYSTEM" /* SYSTEM */
|
|
@@ -3448,8 +3474,12 @@ async function executeHook(hookType, hooks, context = {}, options = {}) {
|
|
|
3448
3474
|
env: execEnv,
|
|
3449
3475
|
// Capture both stdout and stderr
|
|
3450
3476
|
all: true,
|
|
3451
|
-
reject: false
|
|
3477
|
+
reject: false,
|
|
3452
3478
|
// Don't throw on non-zero exit codes
|
|
3479
|
+
// Use input: '' to provide empty stdin and properly close it (sends EOF)
|
|
3480
|
+
// This prevents commands from hanging waiting for stdin while still
|
|
3481
|
+
// allowing internal pipe operations to work correctly
|
|
3482
|
+
input: ""
|
|
3453
3483
|
});
|
|
3454
3484
|
const duration = Date.now() - commandStartTime;
|
|
3455
3485
|
const success2 = result2.exitCode === 0;
|
|
@@ -3595,6 +3625,12 @@ function createExecutionRequest(options) {
|
|
|
3595
3625
|
if (options.mcpServerName !== void 0) {
|
|
3596
3626
|
result.mcpServerName = options.mcpServerName;
|
|
3597
3627
|
}
|
|
3628
|
+
if (options.resume !== void 0) {
|
|
3629
|
+
result.resume = options.resume;
|
|
3630
|
+
}
|
|
3631
|
+
if (options.continueConversation !== void 0) {
|
|
3632
|
+
result.continueConversation = options.continueConversation;
|
|
3633
|
+
}
|
|
3598
3634
|
return result;
|
|
3599
3635
|
}
|
|
3600
3636
|
var DEFAULT_ERROR_RECOVERY_CONFIG, DEFAULT_RATE_LIMIT_CONFIG, DEFAULT_PROGRESS_CONFIG, ExecutionEngine;
|
|
@@ -3945,6 +3981,8 @@ var init_engine = __esm({
|
|
|
3945
3981
|
maxIterations: context.request.maxIterations,
|
|
3946
3982
|
instruction: context.request.instruction
|
|
3947
3983
|
}
|
|
3984
|
+
}, {
|
|
3985
|
+
commandTimeout: this.engineConfig.config.hookCommandTimeout
|
|
3948
3986
|
});
|
|
3949
3987
|
}
|
|
3950
3988
|
} catch (error) {
|
|
@@ -3977,6 +4015,8 @@ var init_engine = __esm({
|
|
|
3977
4015
|
duration: context.endTime ? context.endTime.getTime() - context.startTime.getTime() : 0,
|
|
3978
4016
|
success: context.status === "completed" /* COMPLETED */
|
|
3979
4017
|
}
|
|
4018
|
+
}, {
|
|
4019
|
+
commandTimeout: this.engineConfig.config.hookCommandTimeout
|
|
3980
4020
|
});
|
|
3981
4021
|
}
|
|
3982
4022
|
} catch (error) {
|
|
@@ -4028,6 +4068,8 @@ var init_engine = __esm({
|
|
|
4028
4068
|
maxIterations: context.request.maxIterations,
|
|
4029
4069
|
subagent: context.request.subagent
|
|
4030
4070
|
}
|
|
4071
|
+
}, {
|
|
4072
|
+
commandTimeout: this.engineConfig.config.hookCommandTimeout
|
|
4031
4073
|
});
|
|
4032
4074
|
}
|
|
4033
4075
|
} catch (error) {
|
|
@@ -4045,6 +4087,8 @@ var init_engine = __esm({
|
|
|
4045
4087
|
...context.request.allowedTools !== void 0 && { allowedTools: context.request.allowedTools },
|
|
4046
4088
|
...context.request.appendAllowedTools !== void 0 && { appendAllowedTools: context.request.appendAllowedTools },
|
|
4047
4089
|
...context.request.disallowedTools !== void 0 && { disallowedTools: context.request.disallowedTools },
|
|
4090
|
+
...context.request.resume !== void 0 && { resume: context.request.resume },
|
|
4091
|
+
...context.request.continueConversation !== void 0 && { continueConversation: context.request.continueConversation },
|
|
4048
4092
|
iteration: iterationNumber
|
|
4049
4093
|
},
|
|
4050
4094
|
timeout: context.request.timeoutMs || this.engineConfig.config.mcpTimeout,
|
|
@@ -4092,6 +4136,8 @@ var init_engine = __esm({
|
|
|
4092
4136
|
duration: iterationResult.duration,
|
|
4093
4137
|
toolCallStatus: iterationResult.toolResult.status
|
|
4094
4138
|
}
|
|
4139
|
+
}, {
|
|
4140
|
+
commandTimeout: this.engineConfig.config.hookCommandTimeout
|
|
4095
4141
|
});
|
|
4096
4142
|
}
|
|
4097
4143
|
} catch (error) {
|
|
@@ -4140,6 +4186,8 @@ var init_engine = __esm({
|
|
|
4140
4186
|
error: mcpError.message,
|
|
4141
4187
|
errorType: mcpError.type
|
|
4142
4188
|
}
|
|
4189
|
+
}, {
|
|
4190
|
+
commandTimeout: this.engineConfig.config.hookCommandTimeout
|
|
4143
4191
|
});
|
|
4144
4192
|
}
|
|
4145
4193
|
} catch (hookError) {
|
|
@@ -4846,7 +4894,7 @@ var init_config2 = __esm({
|
|
|
4846
4894
|
return cached;
|
|
4847
4895
|
}
|
|
4848
4896
|
try {
|
|
4849
|
-
const configContent = await
|
|
4897
|
+
const configContent = await fs2__default.default.readFile(configPath, "utf-8");
|
|
4850
4898
|
const config = JSON.parse(configContent);
|
|
4851
4899
|
this.validateConfig(config);
|
|
4852
4900
|
const resolvedConfig = this.resolveConfigPaths(config, path3__namespace.dirname(configPath));
|
|
@@ -4868,7 +4916,7 @@ var init_config2 = __esm({
|
|
|
4868
4916
|
const rootDir = path3__namespace.parse(currentDir).root;
|
|
4869
4917
|
while (currentDir !== rootDir) {
|
|
4870
4918
|
const configPath = path3__namespace.join(currentDir, ".juno_task", "mcp.json");
|
|
4871
|
-
if (await
|
|
4919
|
+
if (await fs2__default.default.pathExists(configPath)) {
|
|
4872
4920
|
return configPath;
|
|
4873
4921
|
}
|
|
4874
4922
|
currentDir = path3__namespace.dirname(currentDir);
|
|
@@ -5054,7 +5102,7 @@ var init_logger = __esm({
|
|
|
5054
5102
|
* Matches Python's generate_log_file function
|
|
5055
5103
|
*/
|
|
5056
5104
|
async initialize(subagent = "mcp") {
|
|
5057
|
-
await
|
|
5105
|
+
await fs2__default.default.ensureDir(this.logDirectory);
|
|
5058
5106
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").split("T");
|
|
5059
5107
|
const dateStr = timestamp[0];
|
|
5060
5108
|
const timeStr = timestamp[1].split("-")[0].substring(0, 6);
|
|
@@ -5063,7 +5111,7 @@ var init_logger = __esm({
|
|
|
5063
5111
|
this.logFilePath = path3__namespace.default.join(this.logDirectory, logFileName);
|
|
5064
5112
|
const header = `# Juno-Task TypeScript Log - Started ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
5065
5113
|
`;
|
|
5066
|
-
await
|
|
5114
|
+
await fs2__default.default.writeFile(this.logFilePath, header);
|
|
5067
5115
|
}
|
|
5068
5116
|
/**
|
|
5069
5117
|
* Format log message matching Python version format
|
|
@@ -5081,7 +5129,7 @@ var init_logger = __esm({
|
|
|
5081
5129
|
if (!this.logFilePath) {
|
|
5082
5130
|
throw new Error("Logger not initialized. Call initialize() first.");
|
|
5083
5131
|
}
|
|
5084
|
-
await
|
|
5132
|
+
await fs2__default.default.appendFile(this.logFilePath, message);
|
|
5085
5133
|
}
|
|
5086
5134
|
/**
|
|
5087
5135
|
* Log message at specified level
|
|
@@ -7090,7 +7138,7 @@ var init_shell_backend = __esm({
|
|
|
7090
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");
|
|
7091
7139
|
const logDir = path3__namespace.join(this.config.workingDirectory, ".juno_task", "logs");
|
|
7092
7140
|
try {
|
|
7093
|
-
await
|
|
7141
|
+
await fs2__default.default.ensureDir(logDir);
|
|
7094
7142
|
} catch (error) {
|
|
7095
7143
|
if (this.config?.debug) {
|
|
7096
7144
|
engineLogger.warn(`Failed to create log directory: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -7115,7 +7163,7 @@ var init_shell_backend = __esm({
|
|
|
7115
7163
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
7116
7164
|
const logEntry = `[${timestamp}] ${message}
|
|
7117
7165
|
`;
|
|
7118
|
-
await
|
|
7166
|
+
await fs2__default.default.appendFile(this.logFilePath, logEntry, "utf-8");
|
|
7119
7167
|
} catch (error) {
|
|
7120
7168
|
if (this.config?.debug) {
|
|
7121
7169
|
engineLogger.warn(`Failed to write to log file: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -7226,6 +7274,12 @@ var init_shell_backend = __esm({
|
|
|
7226
7274
|
args.push("--disallowedTools");
|
|
7227
7275
|
args.push(...request.arguments.disallowedTools);
|
|
7228
7276
|
}
|
|
7277
|
+
if (isPython && request.arguments?.resume) {
|
|
7278
|
+
args.push("--resume", request.arguments.resume);
|
|
7279
|
+
}
|
|
7280
|
+
if (isPython && request.arguments?.continueConversation) {
|
|
7281
|
+
args.push("--continue");
|
|
7282
|
+
}
|
|
7229
7283
|
if (this.config.debug) {
|
|
7230
7284
|
engineLogger.debug(`Executing script: ${command} ${args.join(" ")}`);
|
|
7231
7285
|
engineLogger.debug(`Working directory: ${this.config.workingDirectory}`);
|
|
@@ -12649,7 +12703,9 @@ async function mainCommandHandler(args, options, command) {
|
|
|
12649
12703
|
tools: options.tools,
|
|
12650
12704
|
allowedTools: options.allowedTools,
|
|
12651
12705
|
appendAllowedTools: options.appendAllowedTools,
|
|
12652
|
-
disallowedTools: options.disallowedTools
|
|
12706
|
+
disallowedTools: options.disallowedTools,
|
|
12707
|
+
resume: options.resume,
|
|
12708
|
+
continueConversation: options.continue
|
|
12653
12709
|
});
|
|
12654
12710
|
const coordinator = new MainExecutionCoordinator(config, options.verbose, options.enableFeedback || false);
|
|
12655
12711
|
const result = await coordinator.execute(executionRequest);
|
|
@@ -12806,7 +12862,7 @@ var init_main = __esm({
|
|
|
12806
12862
|
return await this.collectInteractivePrompt();
|
|
12807
12863
|
} else {
|
|
12808
12864
|
const defaultPromptPath = path3__namespace.join(process.cwd(), ".juno_task", "prompt.md");
|
|
12809
|
-
if (await
|
|
12865
|
+
if (await fs2__default.default.pathExists(defaultPromptPath)) {
|
|
12810
12866
|
console.error(chalk15__default.default.blue(`\u{1F4C4} Using default prompt: ${chalk15__default.default.cyan(".juno_task/prompt.md")}`));
|
|
12811
12867
|
return await this.loadPromptFromFile(defaultPromptPath);
|
|
12812
12868
|
} else {
|
|
@@ -12834,7 +12890,7 @@ var init_main = __esm({
|
|
|
12834
12890
|
}
|
|
12835
12891
|
try {
|
|
12836
12892
|
const resolvedPath = path3__namespace.resolve(prompt);
|
|
12837
|
-
return await
|
|
12893
|
+
return await fs2__default.default.pathExists(resolvedPath);
|
|
12838
12894
|
} catch {
|
|
12839
12895
|
return false;
|
|
12840
12896
|
}
|
|
@@ -12842,7 +12898,7 @@ var init_main = __esm({
|
|
|
12842
12898
|
async loadPromptFromFile(filePath) {
|
|
12843
12899
|
try {
|
|
12844
12900
|
const resolvedPath = path3__namespace.resolve(filePath);
|
|
12845
|
-
const content = await
|
|
12901
|
+
const content = await fs2__default.default.readFile(resolvedPath, "utf-8");
|
|
12846
12902
|
if (!content.trim()) {
|
|
12847
12903
|
throw new FileSystemError(
|
|
12848
12904
|
"Prompt file is empty",
|
|
@@ -13250,7 +13306,7 @@ async function validateJSONFile(configSchema, baseDir) {
|
|
|
13250
13306
|
const warnings = [];
|
|
13251
13307
|
const filePath = path3__namespace.default.join(baseDir, configSchema.file);
|
|
13252
13308
|
try {
|
|
13253
|
-
const exists = await
|
|
13309
|
+
const exists = await fs2__default.default.pathExists(filePath);
|
|
13254
13310
|
if (!exists) {
|
|
13255
13311
|
if (configSchema.required) {
|
|
13256
13312
|
errors.push({
|
|
@@ -13273,7 +13329,7 @@ async function validateJSONFile(configSchema, baseDir) {
|
|
|
13273
13329
|
return { isValid: !configSchema.required, errors, warnings };
|
|
13274
13330
|
}
|
|
13275
13331
|
try {
|
|
13276
|
-
await
|
|
13332
|
+
await fs2__default.default.access(filePath, fs2__default.default.constants.R_OK);
|
|
13277
13333
|
} catch (accessError) {
|
|
13278
13334
|
errors.push({
|
|
13279
13335
|
file: configSchema.file,
|
|
@@ -13289,7 +13345,7 @@ async function validateJSONFile(configSchema, baseDir) {
|
|
|
13289
13345
|
}
|
|
13290
13346
|
let jsonData;
|
|
13291
13347
|
try {
|
|
13292
|
-
const fileContent = await
|
|
13348
|
+
const fileContent = await fs2__default.default.readFile(filePath, "utf8");
|
|
13293
13349
|
jsonData = JSON.parse(fileContent);
|
|
13294
13350
|
} catch (parseError) {
|
|
13295
13351
|
const errorMessage = parseError instanceof Error ? parseError.message : String(parseError);
|
|
@@ -13424,7 +13480,7 @@ function displayValidationResults(result) {
|
|
|
13424
13480
|
}
|
|
13425
13481
|
async function logValidationResults(result, baseDir = process.cwd()) {
|
|
13426
13482
|
const logDir = path3__namespace.default.join(baseDir, ".juno_task", "logs");
|
|
13427
|
-
await
|
|
13483
|
+
await fs2__default.default.ensureDir(logDir);
|
|
13428
13484
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
13429
13485
|
const logFile = path3__namespace.default.join(logDir, `startup-validation-${timestamp}.log`);
|
|
13430
13486
|
const logContent = [
|
|
@@ -13467,7 +13523,7 @@ async function logValidationResults(result, baseDir = process.cwd()) {
|
|
|
13467
13523
|
logContent.push(``);
|
|
13468
13524
|
}
|
|
13469
13525
|
}
|
|
13470
|
-
await
|
|
13526
|
+
await fs2__default.default.writeFile(logFile, logContent.join("\n"));
|
|
13471
13527
|
return logFile;
|
|
13472
13528
|
}
|
|
13473
13529
|
async function validateStartupConfigs(baseDir = process.cwd(), verbose = false) {
|
|
@@ -13801,7 +13857,7 @@ var TemplateEngine = class {
|
|
|
13801
13857
|
let overallError;
|
|
13802
13858
|
try {
|
|
13803
13859
|
if (!options.dryRun) {
|
|
13804
|
-
await
|
|
13860
|
+
await fs2__default.default.ensureDir(targetDirectory);
|
|
13805
13861
|
}
|
|
13806
13862
|
for (const template of templates) {
|
|
13807
13863
|
try {
|
|
@@ -15151,7 +15207,7 @@ This directory contains specification documents for your project.
|
|
|
15151
15207
|
const fileName = this.getTemplateFileName(template);
|
|
15152
15208
|
const targetPath = path3__namespace.join(targetDirectory, fileName);
|
|
15153
15209
|
try {
|
|
15154
|
-
const fileExists = await
|
|
15210
|
+
const fileExists = await fs2__default.default.pathExists(targetPath);
|
|
15155
15211
|
if (fileExists && !options.force && options.onConflict !== "overwrite") {
|
|
15156
15212
|
return {
|
|
15157
15213
|
path: targetPath,
|
|
@@ -15173,10 +15229,10 @@ This directory contains specification documents for your project.
|
|
|
15173
15229
|
}
|
|
15174
15230
|
if (options.createBackup && fileExists) {
|
|
15175
15231
|
const backupPath = `${targetPath}.backup.${Date.now()}`;
|
|
15176
|
-
await
|
|
15232
|
+
await fs2__default.default.copy(targetPath, backupPath);
|
|
15177
15233
|
}
|
|
15178
|
-
await
|
|
15179
|
-
await
|
|
15234
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(targetPath));
|
|
15235
|
+
await fs2__default.default.writeFile(targetPath, renderedContent, "utf8");
|
|
15180
15236
|
return {
|
|
15181
15237
|
path: targetPath,
|
|
15182
15238
|
content: renderedContent,
|
|
@@ -15440,7 +15496,7 @@ var SimpleInitTUI = class {
|
|
|
15440
15496
|
}
|
|
15441
15497
|
async confirmSave(targetDirectory) {
|
|
15442
15498
|
const junoTaskPath = path3__namespace.join(targetDirectory, ".juno_task");
|
|
15443
|
-
if (await
|
|
15499
|
+
if (await fs2__default.default.pathExists(junoTaskPath)) {
|
|
15444
15500
|
console.log(chalk15__default.default.yellow(" \u26A0\uFE0F .juno_task directory already exists"));
|
|
15445
15501
|
console.log(chalk15__default.default.gray(" Would you like to:"));
|
|
15446
15502
|
console.log(chalk15__default.default.gray(" 1) Override existing files"));
|
|
@@ -15485,16 +15541,16 @@ var SimpleProjectGenerator = class {
|
|
|
15485
15541
|
async generate() {
|
|
15486
15542
|
const { targetDirectory, variables, force } = this.context;
|
|
15487
15543
|
console.log(chalk15__default.default.blue("\u{1F4C1} Creating project directory..."));
|
|
15488
|
-
await
|
|
15544
|
+
await fs2__default.default.ensureDir(targetDirectory);
|
|
15489
15545
|
const junoTaskDir = path3__namespace.join(targetDirectory, ".juno_task");
|
|
15490
|
-
const junoTaskExists = await
|
|
15546
|
+
const junoTaskExists = await fs2__default.default.pathExists(junoTaskDir);
|
|
15491
15547
|
if (junoTaskExists && !force) {
|
|
15492
15548
|
throw new ValidationError(
|
|
15493
15549
|
"Project already initialized. Directory .juno_task already exists.",
|
|
15494
15550
|
["Use --force flag to overwrite existing files", "Choose a different directory"]
|
|
15495
15551
|
);
|
|
15496
15552
|
}
|
|
15497
|
-
await
|
|
15553
|
+
await fs2__default.default.ensureDir(junoTaskDir);
|
|
15498
15554
|
console.log(chalk15__default.default.blue("\u2699\uFE0F Creating project configuration..."));
|
|
15499
15555
|
await this.createConfigFile(junoTaskDir, targetDirectory);
|
|
15500
15556
|
console.log(chalk15__default.default.blue("\u{1F527} Setting up MCP configuration..."));
|
|
@@ -15528,21 +15584,21 @@ var SimpleProjectGenerator = class {
|
|
|
15528
15584
|
const promptContent = await templateEngine.render(promptTemplate, templateContext);
|
|
15529
15585
|
const initContent = await templateEngine.render(initTemplate, templateContext);
|
|
15530
15586
|
const implementContent = await templateEngine.render(implementTemplate, templateContext);
|
|
15531
|
-
await
|
|
15532
|
-
await
|
|
15533
|
-
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);
|
|
15534
15590
|
const userFeedbackTemplate = templateEngine.getBuiltInTemplate("USER_FEEDBACK.md");
|
|
15535
15591
|
if (userFeedbackTemplate) {
|
|
15536
15592
|
const userFeedbackContent = await templateEngine.render(userFeedbackTemplate, templateContext);
|
|
15537
|
-
await
|
|
15593
|
+
await fs2__default.default.writeFile(path3__namespace.join(junoTaskDir, "USER_FEEDBACK.md"), userFeedbackContent);
|
|
15538
15594
|
}
|
|
15539
15595
|
const planTemplate = templateEngine.getBuiltInTemplate("plan.md");
|
|
15540
15596
|
if (planTemplate) {
|
|
15541
15597
|
const planContent = await templateEngine.render(planTemplate, templateContext);
|
|
15542
|
-
await
|
|
15598
|
+
await fs2__default.default.writeFile(path3__namespace.join(junoTaskDir, "plan.md"), planContent);
|
|
15543
15599
|
}
|
|
15544
15600
|
const specsDir = path3__namespace.join(junoTaskDir, "specs");
|
|
15545
|
-
await
|
|
15601
|
+
await fs2__default.default.ensureDir(specsDir);
|
|
15546
15602
|
const specsReadmeContent = `# Project Specifications
|
|
15547
15603
|
|
|
15548
15604
|
This directory contains detailed specifications for the project components.
|
|
@@ -15559,7 +15615,7 @@ This directory contains detailed specifications for the project components.
|
|
|
15559
15615
|
- Avoid conflicts with existing file names
|
|
15560
15616
|
- Use \`.md\` extension for all specification files
|
|
15561
15617
|
`;
|
|
15562
|
-
await
|
|
15618
|
+
await fs2__default.default.writeFile(path3__namespace.join(specsDir, "README.md"), specsReadmeContent);
|
|
15563
15619
|
const requirementsContent = `# Requirements Specification
|
|
15564
15620
|
|
|
15565
15621
|
## Functional Requirements
|
|
@@ -15606,7 +15662,7 @@ This directory contains detailed specifications for the project components.
|
|
|
15606
15662
|
- Code quality: Clean, maintainable codebase
|
|
15607
15663
|
- Documentation: Complete and accurate documentation
|
|
15608
15664
|
`;
|
|
15609
|
-
await
|
|
15665
|
+
await fs2__default.default.writeFile(path3__namespace.join(specsDir, "requirements.md"), requirementsContent);
|
|
15610
15666
|
const architectureContent = `# Architecture Specification
|
|
15611
15667
|
|
|
15612
15668
|
## System Overview
|
|
@@ -15688,7 +15744,7 @@ This project uses AI-assisted development with juno-code to achieve: ${variables
|
|
|
15688
15744
|
- Performance monitoring
|
|
15689
15745
|
- Security best practices
|
|
15690
15746
|
`;
|
|
15691
|
-
await
|
|
15747
|
+
await fs2__default.default.writeFile(path3__namespace.join(specsDir, "architecture.md"), architectureContent);
|
|
15692
15748
|
const claudeContent = `# Claude Development Session Learnings
|
|
15693
15749
|
|
|
15694
15750
|
## Project Overview
|
|
@@ -15760,7 +15816,7 @@ This file will be updated as development progresses to track:
|
|
|
15760
15816
|
- Solutions to complex problems
|
|
15761
15817
|
- Performance improvements and optimizations
|
|
15762
15818
|
`;
|
|
15763
|
-
await
|
|
15819
|
+
await fs2__default.default.writeFile(path3__namespace.join(targetDirectory, "CLAUDE.md"), claudeContent);
|
|
15764
15820
|
const agentsContent = `# AI Agent Selection and Performance
|
|
15765
15821
|
|
|
15766
15822
|
## Available Agents
|
|
@@ -15824,7 +15880,7 @@ Track agent performance for:
|
|
|
15824
15880
|
4. **Feedback Loop**: Provide feedback to improve agent performance
|
|
15825
15881
|
5. **Performance Monitoring**: Track and optimize agent usage
|
|
15826
15882
|
`;
|
|
15827
|
-
await
|
|
15883
|
+
await fs2__default.default.writeFile(path3__namespace.join(targetDirectory, "AGENTS.md"), agentsContent);
|
|
15828
15884
|
const readmeContent = `# ${variables.PROJECT_NAME}
|
|
15829
15885
|
|
|
15830
15886
|
${variables.DESCRIPTION}
|
|
@@ -15921,7 +15977,7 @@ ${variables.GIT_URL}` : ""}
|
|
|
15921
15977
|
Created with juno-code on ${variables.CURRENT_DATE}
|
|
15922
15978
|
${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
15923
15979
|
`;
|
|
15924
|
-
await
|
|
15980
|
+
await fs2__default.default.writeFile(path3__namespace.join(targetDirectory, "README.md"), readmeContent);
|
|
15925
15981
|
console.log(chalk15__default.default.blue("\u{1F4E6} Installing utility scripts..."));
|
|
15926
15982
|
await this.copyScriptsFromTemplates(junoTaskDir);
|
|
15927
15983
|
console.log(chalk15__default.default.blue("\u{1F40D} Installing Python requirements..."));
|
|
@@ -15973,7 +16029,7 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
15973
16029
|
hooks: getDefaultHooks()
|
|
15974
16030
|
};
|
|
15975
16031
|
const configPath = path3__namespace.join(junoTaskDir, "config.json");
|
|
15976
|
-
await
|
|
16032
|
+
await fs2__default.default.writeFile(configPath, JSON.stringify(configContent, null, 2));
|
|
15977
16033
|
console.log(chalk15__default.default.green(` \u2713 Created .juno_task/config.json with ${this.context.subagent} as default subagent`));
|
|
15978
16034
|
}
|
|
15979
16035
|
async createMcpFile(junoTaskDir, targetDirectory) {
|
|
@@ -16027,7 +16083,7 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16027
16083
|
}
|
|
16028
16084
|
};
|
|
16029
16085
|
const mcpPath = path3__namespace.join(junoTaskDir, "mcp.json");
|
|
16030
|
-
await
|
|
16086
|
+
await fs2__default.default.writeFile(mcpPath, JSON.stringify(mcpContent, null, 2));
|
|
16031
16087
|
console.log(chalk15__default.default.green(` \u2713 Created .juno_task/mcp.json with roundtable-ai server configuration`));
|
|
16032
16088
|
}
|
|
16033
16089
|
getDefaultModelForSubagent(subagent) {
|
|
@@ -16046,7 +16102,7 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16046
16102
|
async copyScriptsFromTemplates(junoTaskDir) {
|
|
16047
16103
|
try {
|
|
16048
16104
|
const scriptsDir = path3__namespace.join(junoTaskDir, "scripts");
|
|
16049
|
-
await
|
|
16105
|
+
await fs2__default.default.ensureDir(scriptsDir);
|
|
16050
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)));
|
|
16051
16107
|
const __dirname2 = path3__namespace.dirname(__filename2);
|
|
16052
16108
|
let templatesScriptsDir;
|
|
@@ -16057,11 +16113,11 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16057
16113
|
} else {
|
|
16058
16114
|
templatesScriptsDir = path3__namespace.join(__dirname2, "../../templates/scripts");
|
|
16059
16115
|
}
|
|
16060
|
-
if (!await
|
|
16116
|
+
if (!await fs2__default.default.pathExists(templatesScriptsDir)) {
|
|
16061
16117
|
console.log(chalk15__default.default.yellow(" \u26A0\uFE0F Template scripts directory not found, skipping script installation"));
|
|
16062
16118
|
return;
|
|
16063
16119
|
}
|
|
16064
|
-
const scriptFiles = await
|
|
16120
|
+
const scriptFiles = await fs2__default.default.readdir(templatesScriptsDir);
|
|
16065
16121
|
if (scriptFiles.length === 0) {
|
|
16066
16122
|
console.log(chalk15__default.default.gray(" \u2139\uFE0F No template scripts found to install"));
|
|
16067
16123
|
return;
|
|
@@ -16070,11 +16126,11 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16070
16126
|
for (const scriptFile of scriptFiles) {
|
|
16071
16127
|
const sourcePath = path3__namespace.join(templatesScriptsDir, scriptFile);
|
|
16072
16128
|
const destPath = path3__namespace.join(scriptsDir, scriptFile);
|
|
16073
|
-
const stats = await
|
|
16129
|
+
const stats = await fs2__default.default.stat(sourcePath);
|
|
16074
16130
|
if (stats.isFile()) {
|
|
16075
|
-
await
|
|
16131
|
+
await fs2__default.default.copy(sourcePath, destPath);
|
|
16076
16132
|
if (scriptFile.endsWith(".sh")) {
|
|
16077
|
-
await
|
|
16133
|
+
await fs2__default.default.chmod(destPath, 493);
|
|
16078
16134
|
}
|
|
16079
16135
|
copiedCount++;
|
|
16080
16136
|
console.log(chalk15__default.default.green(` \u2713 Installed script: ${scriptFile}`));
|
|
@@ -16097,7 +16153,7 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16097
16153
|
try {
|
|
16098
16154
|
const scriptsDir = path3__namespace.join(junoTaskDir, "scripts");
|
|
16099
16155
|
const installScript = path3__namespace.join(scriptsDir, "install_requirements.sh");
|
|
16100
|
-
if (!await
|
|
16156
|
+
if (!await fs2__default.default.pathExists(installScript)) {
|
|
16101
16157
|
console.log(chalk15__default.default.yellow(" \u26A0\uFE0F install_requirements.sh not found, skipping Python dependencies installation"));
|
|
16102
16158
|
console.log(chalk15__default.default.gray(" You can install dependencies manually: juno-kanban, roundtable-ai"));
|
|
16103
16159
|
return;
|
|
@@ -16394,20 +16450,20 @@ init_types();
|
|
|
16394
16450
|
async function loadInitPrompt(directory) {
|
|
16395
16451
|
const junoTaskDir = path3__namespace.join(directory, ".juno_task");
|
|
16396
16452
|
const initFile = path3__namespace.join(junoTaskDir, "init.md");
|
|
16397
|
-
if (!await
|
|
16453
|
+
if (!await fs2__default.default.pathExists(junoTaskDir)) {
|
|
16398
16454
|
throw new FileSystemError(
|
|
16399
16455
|
'No .juno_task directory found. Run "juno-code init" first.',
|
|
16400
16456
|
junoTaskDir
|
|
16401
16457
|
);
|
|
16402
16458
|
}
|
|
16403
|
-
if (!await
|
|
16459
|
+
if (!await fs2__default.default.pathExists(initFile)) {
|
|
16404
16460
|
throw new FileSystemError(
|
|
16405
16461
|
"No init.md file found in .juno_task directory",
|
|
16406
16462
|
initFile
|
|
16407
16463
|
);
|
|
16408
16464
|
}
|
|
16409
16465
|
try {
|
|
16410
|
-
const content = await
|
|
16466
|
+
const content = await fs2__default.default.readFile(initFile, "utf-8");
|
|
16411
16467
|
if (!content.trim()) {
|
|
16412
16468
|
throw new FileSystemError(
|
|
16413
16469
|
"init.md file is empty. Please add task instructions.",
|
|
@@ -16453,6 +16509,8 @@ async function startCommandHandler(args, options, command) {
|
|
|
16453
16509
|
allowedTools: options.allowedTools,
|
|
16454
16510
|
appendAllowedTools: options.appendAllowedTools,
|
|
16455
16511
|
disallowedTools: options.disallowedTools,
|
|
16512
|
+
resume: options.resume,
|
|
16513
|
+
continue: options.continue,
|
|
16456
16514
|
directory: options.directory,
|
|
16457
16515
|
verbose: options.verbose,
|
|
16458
16516
|
quiet: options.quiet,
|
|
@@ -17437,8 +17495,8 @@ Focus on ${request.intelligence === "basic" ? "basic functionality" : request.in
|
|
|
17437
17495
|
for (const scenario of scenarios) {
|
|
17438
17496
|
const testContent = await this.generateTestContent(request, scenario, template);
|
|
17439
17497
|
const testFilePath = this.resolveTestFilePath(request, scenario);
|
|
17440
|
-
await
|
|
17441
|
-
await
|
|
17498
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(testFilePath));
|
|
17499
|
+
await fs2__default.default.writeFile(testFilePath, testContent);
|
|
17442
17500
|
testFiles.push(testFilePath);
|
|
17443
17501
|
}
|
|
17444
17502
|
return testFiles;
|
|
@@ -17690,8 +17748,8 @@ var TestExecutionEngine = class {
|
|
|
17690
17748
|
async collectCoverage(request) {
|
|
17691
17749
|
const coverageFile = path3__namespace.join(request.workingDirectory, "coverage", "coverage-summary.json");
|
|
17692
17750
|
try {
|
|
17693
|
-
if (await
|
|
17694
|
-
const coverageData = await
|
|
17751
|
+
if (await fs2__default.default.pathExists(coverageFile)) {
|
|
17752
|
+
const coverageData = await fs2__default.default.readJson(coverageFile);
|
|
17695
17753
|
return {
|
|
17696
17754
|
lines: coverageData.total?.lines?.pct || 0,
|
|
17697
17755
|
functions: coverageData.total?.functions?.pct || 0,
|
|
@@ -17874,8 +17932,8 @@ var TestReportEngine = class {
|
|
|
17874
17932
|
suggestions: analysis.suggestions,
|
|
17875
17933
|
recommendations: analysis.recommendations
|
|
17876
17934
|
};
|
|
17877
|
-
await
|
|
17878
|
-
await
|
|
17935
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(outputPath));
|
|
17936
|
+
await fs2__default.default.writeJson(outputPath, report, { spaces: 2 });
|
|
17879
17937
|
return outputPath;
|
|
17880
17938
|
}
|
|
17881
17939
|
async generateHTMLReport(analysis, outputPath, includeVisualizations) {
|
|
@@ -17938,8 +17996,8 @@ var TestReportEngine = class {
|
|
|
17938
17996
|
</body>
|
|
17939
17997
|
</html>
|
|
17940
17998
|
`.trim();
|
|
17941
|
-
await
|
|
17942
|
-
await
|
|
17999
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(outputPath));
|
|
18000
|
+
await fs2__default.default.writeFile(outputPath, html);
|
|
17943
18001
|
return outputPath;
|
|
17944
18002
|
}
|
|
17945
18003
|
generateCharts(analysis) {
|
|
@@ -17996,8 +18054,8 @@ ${analysis.suggestions.map((suggestion) => `- ${suggestion}`).join("\n")}
|
|
|
17996
18054
|
|
|
17997
18055
|
${analysis.recommendations.map((rec) => `- ${rec}`).join("\n")}
|
|
17998
18056
|
`.trim();
|
|
17999
|
-
await
|
|
18000
|
-
await
|
|
18057
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(outputPath));
|
|
18058
|
+
await fs2__default.default.writeFile(outputPath, markdown);
|
|
18001
18059
|
return outputPath;
|
|
18002
18060
|
}
|
|
18003
18061
|
async displayConsoleReport(analysis) {
|
|
@@ -18337,7 +18395,7 @@ async function compactConfigFile(filePath, options = {}) {
|
|
|
18337
18395
|
preserveDays = 30,
|
|
18338
18396
|
preservePatterns = []
|
|
18339
18397
|
} = options;
|
|
18340
|
-
const originalContent = await
|
|
18398
|
+
const originalContent = await fs2__default.default.readFile(filePath, "utf-8");
|
|
18341
18399
|
const originalSize = originalContent.length;
|
|
18342
18400
|
let backupPath = "";
|
|
18343
18401
|
if (createBackup && !dryRun) {
|
|
@@ -18346,7 +18404,7 @@ async function compactConfigFile(filePath, options = {}) {
|
|
|
18346
18404
|
const basename11 = path3__namespace.basename(filePath, ext);
|
|
18347
18405
|
const dirname12 = path3__namespace.dirname(filePath);
|
|
18348
18406
|
backupPath = path3__namespace.join(dirname12, `${basename11}.backup.${timestamp}${ext}`);
|
|
18349
|
-
await
|
|
18407
|
+
await fs2__default.default.writeFile(backupPath, originalContent, "utf-8");
|
|
18350
18408
|
}
|
|
18351
18409
|
const compactionAnalysis = analyzeMarkdownStructure(originalContent);
|
|
18352
18410
|
const compactedContent = compactMarkdownContent(
|
|
@@ -18361,7 +18419,7 @@ async function compactConfigFile(filePath, options = {}) {
|
|
|
18361
18419
|
const compactedSize = finalContent.length;
|
|
18362
18420
|
const reductionPercentage = Math.round((originalSize - compactedSize) / originalSize * 100);
|
|
18363
18421
|
if (!dryRun) {
|
|
18364
|
-
await
|
|
18422
|
+
await fs2__default.default.writeFile(filePath, finalContent, "utf-8");
|
|
18365
18423
|
}
|
|
18366
18424
|
return {
|
|
18367
18425
|
originalSize,
|
|
@@ -18491,7 +18549,7 @@ function formatFileSize(bytes) {
|
|
|
18491
18549
|
}
|
|
18492
18550
|
async function shouldCompactFile(filePath, sizeThresholdKB = 50, ageThresholdDays = 30) {
|
|
18493
18551
|
try {
|
|
18494
|
-
const stats = await
|
|
18552
|
+
const stats = await fs2__default.default.stat(filePath);
|
|
18495
18553
|
const sizeKB = stats.size / 1024;
|
|
18496
18554
|
if (sizeKB > sizeThresholdKB) {
|
|
18497
18555
|
return true;
|
|
@@ -18513,19 +18571,19 @@ async function archiveResolvedIssues(options) {
|
|
|
18513
18571
|
feedbackFile,
|
|
18514
18572
|
archiveDir = path3__namespace.join(path3__namespace.dirname(feedbackFile), "archives"),
|
|
18515
18573
|
openIssuesThreshold = 10} = options;
|
|
18516
|
-
if (!await
|
|
18574
|
+
if (!await fs2__default.default.pathExists(feedbackFile)) {
|
|
18517
18575
|
throw new Error(`Feedback file does not exist: ${feedbackFile}`);
|
|
18518
18576
|
}
|
|
18519
|
-
const content = await
|
|
18577
|
+
const content = await fs2__default.default.readFile(feedbackFile, "utf-8");
|
|
18520
18578
|
const parsed = parseUserFeedback(content);
|
|
18521
18579
|
const warningsGenerated = [];
|
|
18522
18580
|
if (parsed.openIssues.length > openIssuesThreshold) {
|
|
18523
18581
|
const warning = `Found ${parsed.openIssues.length} open issues (threshold: ${openIssuesThreshold}). Consider reviewing and prioritizing.`;
|
|
18524
18582
|
warningsGenerated.push(warning);
|
|
18525
18583
|
const logFile = path3__namespace.join(path3__namespace.dirname(feedbackFile), "logs", "feedback-warnings.log");
|
|
18526
|
-
await
|
|
18584
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(logFile));
|
|
18527
18585
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
18528
|
-
await
|
|
18586
|
+
await fs2__default.default.appendFile(logFile, `[${timestamp}] ${warning}
|
|
18529
18587
|
`);
|
|
18530
18588
|
}
|
|
18531
18589
|
if (parsed.resolvedIssues.length === 0) {
|
|
@@ -18542,10 +18600,10 @@ async function archiveResolvedIssues(options) {
|
|
|
18542
18600
|
const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
|
|
18543
18601
|
const archiveFile = path3__namespace.join(archiveDir, `USER_FEEDBACK_archive_${currentYear}.md`);
|
|
18544
18602
|
{
|
|
18545
|
-
await
|
|
18603
|
+
await fs2__default.default.ensureDir(archiveDir);
|
|
18546
18604
|
await appendToArchive(archiveFile, parsed.resolvedIssues);
|
|
18547
18605
|
const compactedContent = generateCompactedFeedback(parsed.openIssues, parsed.metadata);
|
|
18548
|
-
await
|
|
18606
|
+
await fs2__default.default.writeFile(feedbackFile, compactedContent, "utf-8");
|
|
18549
18607
|
}
|
|
18550
18608
|
{
|
|
18551
18609
|
console.log(chalk15__default.default.green(`\u2705 Archived ${parsed.resolvedIssues.length} resolved issues`));
|
|
@@ -18592,8 +18650,8 @@ function parseUserFeedback(content) {
|
|
|
18592
18650
|
async function appendToArchive(archiveFile, resolvedIssues) {
|
|
18593
18651
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
18594
18652
|
let archiveContent = "";
|
|
18595
|
-
if (await
|
|
18596
|
-
archiveContent = await
|
|
18653
|
+
if (await fs2__default.default.pathExists(archiveFile)) {
|
|
18654
|
+
archiveContent = await fs2__default.default.readFile(archiveFile, "utf-8");
|
|
18597
18655
|
} else {
|
|
18598
18656
|
const year = path3__namespace.basename(archiveFile).match(/(\d{4})/)?.[1] || (/* @__PURE__ */ new Date()).getFullYear();
|
|
18599
18657
|
archiveContent = `# User Feedback Archive ${year}
|
|
@@ -18627,7 +18685,7 @@ ${resolvedIssue}
|
|
|
18627
18685
|
`- Last updated: ${timestamp}`
|
|
18628
18686
|
);
|
|
18629
18687
|
}
|
|
18630
|
-
await
|
|
18688
|
+
await fs2__default.default.writeFile(archiveFile, archiveContent, "utf-8");
|
|
18631
18689
|
}
|
|
18632
18690
|
function generateCompactedFeedback(openIssues, metadata) {
|
|
18633
18691
|
let content = metadata.trim() + "\n";
|
|
@@ -18652,15 +18710,15 @@ async function shouldArchive(feedbackFile, options = {}) {
|
|
|
18652
18710
|
// 50KB
|
|
18653
18711
|
lineCountThreshold = 500
|
|
18654
18712
|
} = options;
|
|
18655
|
-
if (!await
|
|
18713
|
+
if (!await fs2__default.default.pathExists(feedbackFile)) {
|
|
18656
18714
|
return {
|
|
18657
18715
|
shouldArchive: false,
|
|
18658
18716
|
reasons: [],
|
|
18659
18717
|
stats: { openIssuesCount: 0, resolvedIssuesCount: 0, fileSizeBytes: 0, lineCount: 0 }
|
|
18660
18718
|
};
|
|
18661
18719
|
}
|
|
18662
|
-
const content = await
|
|
18663
|
-
const stats = await
|
|
18720
|
+
const content = await fs2__default.default.readFile(feedbackFile, "utf-8");
|
|
18721
|
+
const stats = await fs2__default.default.stat(feedbackFile);
|
|
18664
18722
|
const parsed = parseUserFeedback(content);
|
|
18665
18723
|
const lineCount = content.split("\n").length;
|
|
18666
18724
|
const reasons = [];
|
|
@@ -18734,16 +18792,16 @@ var EnhancedFeedbackFileManager = class {
|
|
|
18734
18792
|
this.feedbackFile = feedbackFile;
|
|
18735
18793
|
}
|
|
18736
18794
|
async ensureExists() {
|
|
18737
|
-
if (!await
|
|
18795
|
+
if (!await fs2__default.default.pathExists(this.feedbackFile)) {
|
|
18738
18796
|
await this.createInitialFile();
|
|
18739
18797
|
}
|
|
18740
18798
|
}
|
|
18741
18799
|
async addFeedback(issue, testCriteria) {
|
|
18742
18800
|
await this.ensureExists();
|
|
18743
18801
|
try {
|
|
18744
|
-
const content = await
|
|
18802
|
+
const content = await fs2__default.default.readFile(this.feedbackFile, "utf-8");
|
|
18745
18803
|
const updatedContent = this.addIssueToContent(content, issue, testCriteria);
|
|
18746
|
-
await
|
|
18804
|
+
await fs2__default.default.writeFile(this.feedbackFile, updatedContent, "utf-8");
|
|
18747
18805
|
} catch (error) {
|
|
18748
18806
|
throw new ValidationError(
|
|
18749
18807
|
`Failed to save feedback: ${error}`,
|
|
@@ -18756,12 +18814,12 @@ var EnhancedFeedbackFileManager = class {
|
|
|
18756
18814
|
*/
|
|
18757
18815
|
async repairMalformedFile() {
|
|
18758
18816
|
try {
|
|
18759
|
-
const content = await
|
|
18817
|
+
const content = await fs2__default.default.readFile(this.feedbackFile, "utf-8");
|
|
18760
18818
|
const hasOpenIssues = content.includes("<OPEN_ISSUES>");
|
|
18761
18819
|
const hasClosingTag = content.includes("</OPEN_ISSUES>");
|
|
18762
18820
|
if (!hasOpenIssues || !hasClosingTag) {
|
|
18763
18821
|
const backupPath = this.feedbackFile + ".backup." + Date.now();
|
|
18764
|
-
await
|
|
18822
|
+
await fs2__default.default.writeFile(backupPath, content, "utf-8");
|
|
18765
18823
|
const existingIssues = this.extractIssuesFromMalformedContent(content);
|
|
18766
18824
|
await this.createInitialFile(existingIssues);
|
|
18767
18825
|
}
|
|
@@ -18793,8 +18851,8 @@ List any features you'd like to see added or bugs you've encountered.
|
|
|
18793
18851
|
|
|
18794
18852
|
<!-- Resolved issues will be moved here -->
|
|
18795
18853
|
`;
|
|
18796
|
-
await
|
|
18797
|
-
await
|
|
18854
|
+
await fs2__default.default.ensureDir(path3__namespace.dirname(this.feedbackFile));
|
|
18855
|
+
await fs2__default.default.writeFile(this.feedbackFile, initialContent, "utf-8");
|
|
18798
18856
|
}
|
|
18799
18857
|
addIssueToContent(content, issue, testCriteria) {
|
|
18800
18858
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
@@ -18910,17 +18968,17 @@ async function handleCompactCommand(subArgs, options) {
|
|
|
18910
18968
|
if (subArgs.length > 0) {
|
|
18911
18969
|
for (const filePath of subArgs) {
|
|
18912
18970
|
const resolvedPath = path3__namespace.resolve(filePath);
|
|
18913
|
-
if (await
|
|
18971
|
+
if (await fs2__default.default.pathExists(resolvedPath)) {
|
|
18914
18972
|
filesToCompact.push(resolvedPath);
|
|
18915
18973
|
} else {
|
|
18916
18974
|
console.warn(chalk15__default.default.yellow(`\u26A0\uFE0F File not found: ${filePath}`));
|
|
18917
18975
|
}
|
|
18918
18976
|
}
|
|
18919
18977
|
} else {
|
|
18920
|
-
if (await
|
|
18978
|
+
if (await fs2__default.default.pathExists(defaultClaudeFile)) {
|
|
18921
18979
|
filesToCompact.push(defaultClaudeFile);
|
|
18922
18980
|
}
|
|
18923
|
-
if (await
|
|
18981
|
+
if (await fs2__default.default.pathExists(defaultAgentsFile)) {
|
|
18924
18982
|
filesToCompact.push(defaultAgentsFile);
|
|
18925
18983
|
}
|
|
18926
18984
|
}
|
|
@@ -19854,11 +19912,11 @@ var GitManager = class {
|
|
|
19854
19912
|
*/
|
|
19855
19913
|
async updateJunoTaskConfig(gitUrl) {
|
|
19856
19914
|
const configPath = path3__namespace.join(this.workingDirectory, ".juno_task", "init.md");
|
|
19857
|
-
if (!await
|
|
19915
|
+
if (!await fs2__default.default.pathExists(configPath)) {
|
|
19858
19916
|
return;
|
|
19859
19917
|
}
|
|
19860
19918
|
try {
|
|
19861
|
-
let content = await
|
|
19919
|
+
let content = await fs2__default.default.readFile(configPath, "utf-8");
|
|
19862
19920
|
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
19863
19921
|
if (frontmatterMatch) {
|
|
19864
19922
|
let frontmatter = frontmatterMatch[1];
|
|
@@ -19879,7 +19937,7 @@ GIT_URL: ${gitUrl}
|
|
|
19879
19937
|
`;
|
|
19880
19938
|
content = frontmatter + content;
|
|
19881
19939
|
}
|
|
19882
|
-
await
|
|
19940
|
+
await fs2__default.default.writeFile(configPath, content, "utf-8");
|
|
19883
19941
|
} catch (error) {
|
|
19884
19942
|
console.warn(`Warning: Failed to update juno-code configuration: ${error}`);
|
|
19885
19943
|
}
|
|
@@ -22636,10 +22694,10 @@ autoload -U compinit && compinit`;
|
|
|
22636
22694
|
*/
|
|
22637
22695
|
async isSourceCommandPresent(configPath, sourceCommand) {
|
|
22638
22696
|
try {
|
|
22639
|
-
if (!await
|
|
22697
|
+
if (!await fs2__default.default.pathExists(configPath)) {
|
|
22640
22698
|
return false;
|
|
22641
22699
|
}
|
|
22642
|
-
const content = await
|
|
22700
|
+
const content = await fs2__default.default.readFile(configPath, "utf-8");
|
|
22643
22701
|
return content.includes("juno-code completion");
|
|
22644
22702
|
} catch {
|
|
22645
22703
|
return false;
|
|
@@ -22661,15 +22719,15 @@ autoload -U compinit && compinit`;
|
|
|
22661
22719
|
continue;
|
|
22662
22720
|
}
|
|
22663
22721
|
try {
|
|
22664
|
-
const completionExists = await
|
|
22665
|
-
const configExists = await
|
|
22722
|
+
const completionExists = await fs2__default.default.pathExists(shell.completionPath);
|
|
22723
|
+
const configExists = await fs2__default.default.pathExists(shell.configPath);
|
|
22666
22724
|
const isSourced = configExists && await this.isSourceCommandPresent(
|
|
22667
22725
|
shell.configPath,
|
|
22668
22726
|
this.getSourceCommand(shell.name, shell.completionPath)
|
|
22669
22727
|
);
|
|
22670
22728
|
let lastInstalled;
|
|
22671
22729
|
if (completionExists) {
|
|
22672
|
-
const stats = await
|
|
22730
|
+
const stats = await fs2__default.default.stat(shell.completionPath);
|
|
22673
22731
|
lastInstalled = stats.mtime;
|
|
22674
22732
|
}
|
|
22675
22733
|
statuses.push({
|
|
@@ -22695,7 +22753,7 @@ autoload -U compinit && compinit`;
|
|
|
22695
22753
|
async ensureCompletionDirectory(shell) {
|
|
22696
22754
|
const completionPath = this.getCompletionPath(shell);
|
|
22697
22755
|
const completionDir = path3__namespace.dirname(completionPath);
|
|
22698
|
-
await
|
|
22756
|
+
await fs2__default.default.ensureDir(completionDir);
|
|
22699
22757
|
}
|
|
22700
22758
|
/**
|
|
22701
22759
|
* Ensure directory exists for shell configuration
|
|
@@ -22703,7 +22761,7 @@ autoload -U compinit && compinit`;
|
|
|
22703
22761
|
async ensureConfigDirectory(shell) {
|
|
22704
22762
|
const configPath = this.getConfigPath(shell);
|
|
22705
22763
|
const configDir = path3__namespace.dirname(configPath);
|
|
22706
|
-
await
|
|
22764
|
+
await fs2__default.default.ensureDir(configDir);
|
|
22707
22765
|
}
|
|
22708
22766
|
/**
|
|
22709
22767
|
* Get shell version information
|
|
@@ -22727,15 +22785,15 @@ autoload -U compinit && compinit`;
|
|
|
22727
22785
|
try {
|
|
22728
22786
|
const configPath = this.getConfigPath(shell);
|
|
22729
22787
|
const configDir = path3__namespace.dirname(configPath);
|
|
22730
|
-
await
|
|
22788
|
+
await fs2__default.default.access(configDir, fs2__default.default.constants.W_OK);
|
|
22731
22789
|
} catch {
|
|
22732
22790
|
issues.push(`Cannot write to ${shell} configuration directory`);
|
|
22733
22791
|
}
|
|
22734
22792
|
try {
|
|
22735
22793
|
const completionPath = this.getCompletionPath(shell);
|
|
22736
22794
|
const completionDir = path3__namespace.dirname(completionPath);
|
|
22737
|
-
await
|
|
22738
|
-
await
|
|
22795
|
+
await fs2__default.default.ensureDir(completionDir);
|
|
22796
|
+
await fs2__default.default.access(completionDir, fs2__default.default.constants.W_OK);
|
|
22739
22797
|
} catch {
|
|
22740
22798
|
issues.push(`Cannot write to ${shell} completion directory`);
|
|
22741
22799
|
}
|
|
@@ -22806,10 +22864,10 @@ var ContextAwareCompletion = class {
|
|
|
22806
22864
|
async getSessionIds() {
|
|
22807
22865
|
try {
|
|
22808
22866
|
const sessionDir = path3__namespace.join(process.cwd(), ".juno_task", "sessions");
|
|
22809
|
-
if (!await
|
|
22867
|
+
if (!await fs2__default.default.pathExists(sessionDir)) {
|
|
22810
22868
|
return [];
|
|
22811
22869
|
}
|
|
22812
|
-
const sessions = await
|
|
22870
|
+
const sessions = await fs2__default.default.readdir(sessionDir);
|
|
22813
22871
|
return sessions.filter((name) => name.match(/^session_\d+$/)).map((name) => name.replace("session_", "")).sort((a, b) => parseInt(b) - parseInt(a));
|
|
22814
22872
|
} catch {
|
|
22815
22873
|
return [];
|
|
@@ -22823,8 +22881,8 @@ var ContextAwareCompletion = class {
|
|
|
22823
22881
|
const builtinTemplates = ["basic", "advanced", "research", "development"];
|
|
22824
22882
|
const customTemplatesDir = path3__namespace.join(process.cwd(), ".juno_task", "templates");
|
|
22825
22883
|
let customTemplates = [];
|
|
22826
|
-
if (await
|
|
22827
|
-
const files = await
|
|
22884
|
+
if (await fs2__default.default.pathExists(customTemplatesDir)) {
|
|
22885
|
+
const files = await fs2__default.default.readdir(customTemplatesDir);
|
|
22828
22886
|
customTemplates = files.filter((name) => name.endsWith(".md") || name.endsWith(".hbs")).map((name) => path3__namespace.basename(name, path3__namespace.extname(name)));
|
|
22829
22887
|
}
|
|
22830
22888
|
return [...builtinTemplates, ...customTemplates].sort();
|
|
@@ -22901,7 +22959,7 @@ var CompletionInstaller = class {
|
|
|
22901
22959
|
await this.shellDetector.ensureConfigDirectory(shell);
|
|
22902
22960
|
const script = this.generateEnhancedCompletion(shell, "juno-code");
|
|
22903
22961
|
const completionPath = this.shellDetector.getCompletionPath(shell);
|
|
22904
|
-
await
|
|
22962
|
+
await fs2__default.default.writeFile(completionPath, script, "utf-8");
|
|
22905
22963
|
const configPath = this.shellDetector.getConfigPath(shell);
|
|
22906
22964
|
const sourceCommand = this.shellDetector.getSourceCommand(shell, completionPath);
|
|
22907
22965
|
const warnings = [];
|
|
@@ -22909,7 +22967,7 @@ var CompletionInstaller = class {
|
|
|
22909
22967
|
const isPresent = await this.shellDetector.isSourceCommandPresent(configPath, sourceCommand);
|
|
22910
22968
|
if (!isPresent) {
|
|
22911
22969
|
try {
|
|
22912
|
-
await
|
|
22970
|
+
await fs2__default.default.appendFile(configPath, `
|
|
22913
22971
|
|
|
22914
22972
|
${sourceCommand}
|
|
22915
22973
|
`);
|
|
@@ -22940,8 +22998,8 @@ ${sourceCommand}
|
|
|
22940
22998
|
async uninstall(shell) {
|
|
22941
22999
|
try {
|
|
22942
23000
|
const completionPath = this.shellDetector.getCompletionPath(shell);
|
|
22943
|
-
if (await
|
|
22944
|
-
await
|
|
23001
|
+
if (await fs2__default.default.pathExists(completionPath)) {
|
|
23002
|
+
await fs2__default.default.remove(completionPath);
|
|
22945
23003
|
return true;
|
|
22946
23004
|
}
|
|
22947
23005
|
return false;
|
|
@@ -22955,7 +23013,7 @@ ${sourceCommand}
|
|
|
22955
23013
|
async isInstalled(shell) {
|
|
22956
23014
|
try {
|
|
22957
23015
|
const completionPath = this.shellDetector.getCompletionPath(shell);
|
|
22958
|
-
return await
|
|
23016
|
+
return await fs2__default.default.pathExists(completionPath);
|
|
22959
23017
|
} catch {
|
|
22960
23018
|
return false;
|
|
22961
23019
|
}
|
|
@@ -23730,7 +23788,7 @@ function handleCLIError(error, verbose = false) {
|
|
|
23730
23788
|
process.exit(EXIT_CODES.UNEXPECTED_ERROR);
|
|
23731
23789
|
}
|
|
23732
23790
|
function setupGlobalOptions(program) {
|
|
23733
|
-
program.option("-v, --verbose", "Enable verbose output with detailed progress").option("-q, --quiet", "Disable rich formatting, use plain text").option("-c, --config <path>", "Configuration file path (.json, .toml, pyproject.toml)").option("-l, --log-file <path>", "Log file path (auto-generated if not specified)").option("--no-color", "Disable colored output").option("--log-level <level>", "Log level for output (error, warn, info, debug, trace)", "info").option("-s, --subagent <name>", "Subagent to use (claude, cursor, codex, gemini)").option("-b, --backend <type>", "Backend to use (mcp, shell)").option("-m, --model <name>", "Model to use (subagent-specific)").option("--agents <config>", "Agents configuration (forwarded to shell backend, ignored for MCP)").option("--tools <tools...>", 'Specify the list of available tools from the built-in set (only works with --print mode). Use "" to disable all tools, "default" to use all tools, or specify tool names (e.g. "Bash,Edit,Read"). Passed to shell backend, ignored for MCP.').option("--allowed-tools <tools...>", 'Permission-based filtering of specific tool instances (e.g. "Bash(git:*) Edit"). Default when not specified: Task, Bash, Glob, Grep, ExitPlanMode, Read, Edit, Write, NotebookEdit, WebFetch, TodoWrite, WebSearch, BashOutput, KillShell, Skill, SlashCommand, EnterPlanMode. Passed to shell backend, ignored for MCP.').option("--disallowed-tools <tools...>", "Disallowed tools for Claude (passed to shell backend, ignored for MCP). By default, no tools are disallowed").option("--append-allowed-tools <tools...>", "Append tools to the default allowed-tools list (mutually exclusive with --allowed-tools). Passed to shell backend, ignored for MCP.").option("--mcp-timeout <number>", "MCP server timeout in milliseconds", parseInt).option("--enable-feedback", "Enable interactive feedback mode (F+Enter to enter, Q+Enter to submit)");
|
|
23791
|
+
program.option("-v, --verbose", "Enable verbose output with detailed progress").option("-q, --quiet", "Disable rich formatting, use plain text").option("-c, --config <path>", "Configuration file path (.json, .toml, pyproject.toml)").option("-l, --log-file <path>", "Log file path (auto-generated if not specified)").option("--no-color", "Disable colored output").option("--log-level <level>", "Log level for output (error, warn, info, debug, trace)", "info").option("-s, --subagent <name>", "Subagent to use (claude, cursor, codex, gemini)").option("-b, --backend <type>", "Backend to use (mcp, shell)").option("-m, --model <name>", "Model to use (subagent-specific)").option("--agents <config>", "Agents configuration (forwarded to shell backend, ignored for MCP)").option("--tools <tools...>", 'Specify the list of available tools from the built-in set (only works with --print mode). Use "" to disable all tools, "default" to use all tools, or specify tool names (e.g. "Bash,Edit,Read"). Passed to shell backend, ignored for MCP.').option("--allowed-tools <tools...>", 'Permission-based filtering of specific tool instances (e.g. "Bash(git:*) Edit"). Default when not specified: Task, Bash, Glob, Grep, ExitPlanMode, Read, Edit, Write, NotebookEdit, WebFetch, TodoWrite, WebSearch, BashOutput, KillShell, Skill, SlashCommand, EnterPlanMode. Passed to shell backend, ignored for MCP.').option("--disallowed-tools <tools...>", "Disallowed tools for Claude (passed to shell backend, ignored for MCP). By default, no tools are disallowed").option("--append-allowed-tools <tools...>", "Append tools to the default allowed-tools list (mutually exclusive with --allowed-tools). Passed to shell backend, ignored for MCP.").option("--mcp-timeout <number>", "MCP server timeout in milliseconds", parseInt).option("--enable-feedback", "Enable interactive feedback mode (F+Enter to enter, Q+Enter to submit)").option("-r, --resume <sessionId>", "Resume a conversation by session ID (shell backend only)").option("--continue", "Continue the most recent conversation (shell backend only)");
|
|
23734
23792
|
program.exitOverride((err) => {
|
|
23735
23793
|
if (err.code === "commander.helpDisplayed") {
|
|
23736
23794
|
process.exit(0);
|