juno-code 1.0.34 → 1.0.36
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/README.md +364 -64
- package/dist/bin/cli.js +471 -186
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/cli.mjs +470 -185
- package/dist/bin/cli.mjs.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/index.mjs.map +1 -1
- package/dist/templates/scripts/clean_logs_folder.sh +0 -0
- package/dist/templates/scripts/run_until_completion.sh +202 -0
- package/dist/templates/services/README.md +43 -0
- package/dist/templates/services/__pycache__/codex.cpython-38.pyc +0 -0
- package/dist/templates/services/claude.py +1 -1
- package/dist/templates/services/codex.py +68 -14
- package/dist/templates/services/gemini.py +473 -0
- package/package.json +3 -3
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 fs3 = require('fs-extra');
|
|
5
5
|
var path3 = require('path');
|
|
6
6
|
var os4 = 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 fs3__default = /*#__PURE__*/_interopDefault(fs3);
|
|
56
56
|
var path3__namespace = /*#__PURE__*/_interopNamespace(path3);
|
|
57
57
|
var os4__namespace = /*#__PURE__*/_interopNamespace(os4);
|
|
58
58
|
var semver__default = /*#__PURE__*/_interopDefault(semver);
|
|
@@ -178,8 +178,8 @@ var init_types = __esm({
|
|
|
178
178
|
};
|
|
179
179
|
FileSystemError = class extends CLIError {
|
|
180
180
|
code = "FILESYSTEM_ERROR";
|
|
181
|
-
constructor(message,
|
|
182
|
-
super(
|
|
181
|
+
constructor(message, path24) {
|
|
182
|
+
super(path24 ? `${message}: ${path24}` : message);
|
|
183
183
|
this.suggestions = [
|
|
184
184
|
"Check file/directory permissions",
|
|
185
185
|
"Verify path exists and is accessible",
|
|
@@ -341,8 +341,21 @@ var init_service_installer = __esm({
|
|
|
341
341
|
"src/utils/service-installer.ts"() {
|
|
342
342
|
init_version();
|
|
343
343
|
ServiceInstaller = class {
|
|
344
|
+
static REQUIRED_SCRIPTS = ["codex.py", "claude.py", "gemini.py"];
|
|
344
345
|
static SERVICES_DIR = path3__namespace.join(os4.homedir(), ".juno_code", "services");
|
|
345
346
|
static VERSION_FILE = path3__namespace.join(os4.homedir(), ".juno_code", "services", ".version");
|
|
347
|
+
static missingScripts(baseDir) {
|
|
348
|
+
return this.REQUIRED_SCRIPTS.filter((file) => !fs3__default.default.existsSync(path3__namespace.join(baseDir, file)));
|
|
349
|
+
}
|
|
350
|
+
static async missingScriptsAsync(baseDir) {
|
|
351
|
+
const results = await Promise.all(
|
|
352
|
+
this.REQUIRED_SCRIPTS.map(async (file) => ({
|
|
353
|
+
file,
|
|
354
|
+
exists: await fs3__default.default.pathExists(path3__namespace.join(baseDir, file))
|
|
355
|
+
}))
|
|
356
|
+
);
|
|
357
|
+
return results.filter((result) => !result.exists).map((result) => result.file);
|
|
358
|
+
}
|
|
346
359
|
/**
|
|
347
360
|
* Get the current package version
|
|
348
361
|
*/
|
|
@@ -351,12 +364,12 @@ var init_service_installer = __esm({
|
|
|
351
364
|
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
365
|
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
366
|
let packageJsonPath = path3__namespace.join(__dirname2, "..", "..", "package.json");
|
|
354
|
-
if (
|
|
367
|
+
if (fs3__default.default.existsSync(packageJsonPath)) {
|
|
355
368
|
const packageJson2 = require3(packageJsonPath);
|
|
356
369
|
return packageJson2.version;
|
|
357
370
|
}
|
|
358
371
|
packageJsonPath = path3__namespace.join(__dirname2, "..", "..", "..", "package.json");
|
|
359
|
-
if (
|
|
372
|
+
if (fs3__default.default.existsSync(packageJsonPath)) {
|
|
360
373
|
const packageJson2 = require3(packageJsonPath);
|
|
361
374
|
return packageJson2.version;
|
|
362
375
|
}
|
|
@@ -370,11 +383,11 @@ var init_service_installer = __esm({
|
|
|
370
383
|
*/
|
|
371
384
|
static async getInstalledVersion() {
|
|
372
385
|
try {
|
|
373
|
-
const exists = await
|
|
386
|
+
const exists = await fs3__default.default.pathExists(this.VERSION_FILE);
|
|
374
387
|
if (!exists) {
|
|
375
388
|
return null;
|
|
376
389
|
}
|
|
377
|
-
const version3 = await
|
|
390
|
+
const version3 = await fs3__default.default.readFile(this.VERSION_FILE, "utf-8");
|
|
378
391
|
return version3.trim();
|
|
379
392
|
} catch {
|
|
380
393
|
return null;
|
|
@@ -385,7 +398,7 @@ var init_service_installer = __esm({
|
|
|
385
398
|
*/
|
|
386
399
|
static async saveVersion() {
|
|
387
400
|
const version3 = this.getPackageVersion();
|
|
388
|
-
await
|
|
401
|
+
await fs3__default.default.writeFile(this.VERSION_FILE, version3, "utf-8");
|
|
389
402
|
}
|
|
390
403
|
/**
|
|
391
404
|
* Check if services need to be updated based on version
|
|
@@ -397,7 +410,7 @@ var init_service_installer = __esm({
|
|
|
397
410
|
if (!installedVersion) {
|
|
398
411
|
return true;
|
|
399
412
|
}
|
|
400
|
-
const exists = await
|
|
413
|
+
const exists = await fs3__default.default.pathExists(this.SERVICES_DIR);
|
|
401
414
|
if (!exists) {
|
|
402
415
|
return true;
|
|
403
416
|
}
|
|
@@ -405,32 +418,22 @@ var init_service_installer = __esm({
|
|
|
405
418
|
return true;
|
|
406
419
|
}
|
|
407
420
|
if (semver__default.default.eq(packageVersion, installedVersion)) {
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
const codexExists = await fs2__default.default.pathExists(installedCodex);
|
|
411
|
-
const claudeExists = await fs2__default.default.pathExists(installedClaude);
|
|
412
|
-
if (!codexExists || !claudeExists) {
|
|
421
|
+
const missingInstalled = await this.missingScriptsAsync(this.SERVICES_DIR);
|
|
422
|
+
if (missingInstalled.length > 0) {
|
|
413
423
|
return true;
|
|
414
424
|
}
|
|
415
425
|
try {
|
|
416
426
|
const packageServicesDir = this.getPackageServicesDir();
|
|
417
|
-
const
|
|
418
|
-
|
|
419
|
-
|
|
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) {
|
|
427
|
-
return true;
|
|
428
|
-
}
|
|
427
|
+
const missingPackageScripts = this.missingScripts(packageServicesDir);
|
|
428
|
+
if (missingPackageScripts.length > 0) {
|
|
429
|
+
throw new Error(`Missing required service scripts: ${missingPackageScripts.join(", ")}`);
|
|
429
430
|
}
|
|
430
|
-
|
|
431
|
+
for (const script of this.REQUIRED_SCRIPTS) {
|
|
432
|
+
const packageScript = path3__namespace.join(packageServicesDir, script);
|
|
433
|
+
const installedScript = path3__namespace.join(this.SERVICES_DIR, script);
|
|
431
434
|
const [pkg, inst] = await Promise.all([
|
|
432
|
-
|
|
433
|
-
|
|
435
|
+
fs3__default.default.readFile(packageScript, "utf-8"),
|
|
436
|
+
fs3__default.default.readFile(installedScript, "utf-8")
|
|
434
437
|
]);
|
|
435
438
|
if (pkg !== inst) {
|
|
436
439
|
return true;
|
|
@@ -454,15 +457,27 @@ var init_service_installer = __esm({
|
|
|
454
457
|
*/
|
|
455
458
|
static getPackageServicesDir() {
|
|
456
459
|
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))));
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
460
|
+
const candidates = [
|
|
461
|
+
path3__namespace.join(__dirname2, "..", "..", "templates", "services"),
|
|
462
|
+
// dist (production)
|
|
463
|
+
path3__namespace.join(__dirname2, "..", "templates", "services")
|
|
464
|
+
// src (development)
|
|
465
|
+
];
|
|
466
|
+
for (const servicesPath of candidates) {
|
|
467
|
+
if (!fs3__default.default.existsSync(servicesPath)) {
|
|
468
|
+
continue;
|
|
469
|
+
}
|
|
470
|
+
const missing = this.missingScripts(servicesPath);
|
|
471
|
+
if (missing.length === 0) {
|
|
472
|
+
return servicesPath;
|
|
473
|
+
}
|
|
474
|
+
if (process.env.JUNO_CODE_DEBUG === "1") {
|
|
475
|
+
console.error(`[DEBUG] Services path missing required scripts (${servicesPath}): ${missing.join(", ")}`);
|
|
476
|
+
}
|
|
464
477
|
}
|
|
465
|
-
throw new Error(
|
|
478
|
+
throw new Error(
|
|
479
|
+
"Could not find services directory in package containing codex.py, claude.py, and gemini.py. Try reinstalling juno-code or re-running npm run build to refresh service scripts."
|
|
480
|
+
);
|
|
466
481
|
}
|
|
467
482
|
/**
|
|
468
483
|
* Install all service scripts to ~/.juno_code/services/
|
|
@@ -470,18 +485,22 @@ var init_service_installer = __esm({
|
|
|
470
485
|
*/
|
|
471
486
|
static async install(silent = false) {
|
|
472
487
|
try {
|
|
473
|
-
await
|
|
488
|
+
await fs3__default.default.ensureDir(this.SERVICES_DIR);
|
|
474
489
|
const packageServicesDir = this.getPackageServicesDir();
|
|
475
|
-
await
|
|
490
|
+
await fs3__default.default.copy(packageServicesDir, this.SERVICES_DIR, {
|
|
476
491
|
overwrite: true,
|
|
477
492
|
preserveTimestamps: true
|
|
478
493
|
});
|
|
479
|
-
const
|
|
494
|
+
const missingAfterCopy = await this.missingScriptsAsync(this.SERVICES_DIR);
|
|
495
|
+
if (missingAfterCopy.length > 0) {
|
|
496
|
+
throw new Error(`Installed services missing required service scripts: ${missingAfterCopy.join(", ")}`);
|
|
497
|
+
}
|
|
498
|
+
const files = await fs3__default.default.readdir(this.SERVICES_DIR);
|
|
480
499
|
for (const file of files) {
|
|
481
500
|
const filePath = path3__namespace.join(this.SERVICES_DIR, file);
|
|
482
|
-
const stat = await
|
|
501
|
+
const stat = await fs3__default.default.stat(filePath);
|
|
483
502
|
if (stat.isFile() && (file.endsWith(".py") || file.endsWith(".sh"))) {
|
|
484
|
-
await
|
|
503
|
+
await fs3__default.default.chmod(filePath, 493);
|
|
485
504
|
}
|
|
486
505
|
}
|
|
487
506
|
await this.saveVersion();
|
|
@@ -528,11 +547,11 @@ var init_service_installer = __esm({
|
|
|
528
547
|
*/
|
|
529
548
|
static async isInstalled() {
|
|
530
549
|
try {
|
|
531
|
-
const exists = await
|
|
550
|
+
const exists = await fs3__default.default.pathExists(this.SERVICES_DIR);
|
|
532
551
|
if (!exists) {
|
|
533
552
|
return false;
|
|
534
553
|
}
|
|
535
|
-
const files = await
|
|
554
|
+
const files = await fs3__default.default.readdir(this.SERVICES_DIR);
|
|
536
555
|
return files.length > 0;
|
|
537
556
|
} catch {
|
|
538
557
|
return false;
|
|
@@ -555,11 +574,11 @@ var init_service_installer = __esm({
|
|
|
555
574
|
*/
|
|
556
575
|
static async listServices() {
|
|
557
576
|
try {
|
|
558
|
-
const exists = await
|
|
577
|
+
const exists = await fs3__default.default.pathExists(this.SERVICES_DIR);
|
|
559
578
|
if (!exists) {
|
|
560
579
|
return [];
|
|
561
580
|
}
|
|
562
|
-
const files = await
|
|
581
|
+
const files = await fs3__default.default.readdir(this.SERVICES_DIR);
|
|
563
582
|
return files.filter((file) => file.endsWith(".py") || file.endsWith(".sh"));
|
|
564
583
|
} catch {
|
|
565
584
|
return [];
|
|
@@ -570,9 +589,9 @@ var init_service_installer = __esm({
|
|
|
570
589
|
*/
|
|
571
590
|
static async uninstall() {
|
|
572
591
|
try {
|
|
573
|
-
const exists = await
|
|
592
|
+
const exists = await fs3__default.default.pathExists(this.SERVICES_DIR);
|
|
574
593
|
if (exists) {
|
|
575
|
-
await
|
|
594
|
+
await fs3__default.default.remove(this.SERVICES_DIR);
|
|
576
595
|
console.log("\u2713 Services uninstalled");
|
|
577
596
|
}
|
|
578
597
|
} catch (error) {
|
|
@@ -1148,17 +1167,17 @@ async function ensureHooksConfig(baseDir) {
|
|
|
1148
1167
|
try {
|
|
1149
1168
|
const configDir = path3__namespace.join(baseDir, ".juno_task");
|
|
1150
1169
|
const configPath = path3__namespace.join(configDir, "config.json");
|
|
1151
|
-
await
|
|
1152
|
-
const configExists = await
|
|
1170
|
+
await fs3__default.default.ensureDir(configDir);
|
|
1171
|
+
const configExists = await fs3__default.default.pathExists(configPath);
|
|
1153
1172
|
const allHookTypes = getDefaultHooks();
|
|
1154
1173
|
if (!configExists) {
|
|
1155
1174
|
const defaultConfig = {
|
|
1156
1175
|
...DEFAULT_CONFIG,
|
|
1157
1176
|
hooks: allHookTypes
|
|
1158
1177
|
};
|
|
1159
|
-
await
|
|
1178
|
+
await fs3__default.default.writeJson(configPath, defaultConfig, { spaces: 2 });
|
|
1160
1179
|
} else {
|
|
1161
|
-
const existingConfig = await
|
|
1180
|
+
const existingConfig = await fs3__default.default.readJson(configPath);
|
|
1162
1181
|
let needsUpdate = false;
|
|
1163
1182
|
if (!existingConfig.hooks) {
|
|
1164
1183
|
existingConfig.hooks = allHookTypes;
|
|
@@ -1176,7 +1195,7 @@ async function ensureHooksConfig(baseDir) {
|
|
|
1176
1195
|
needsUpdate = true;
|
|
1177
1196
|
}
|
|
1178
1197
|
if (needsUpdate) {
|
|
1179
|
-
await
|
|
1198
|
+
await fs3__default.default.writeJson(configPath, existingConfig, { spaces: 2 });
|
|
1180
1199
|
}
|
|
1181
1200
|
}
|
|
1182
1201
|
} catch (error) {
|
|
@@ -1786,6 +1805,12 @@ ${helpText}
|
|
|
1786
1805
|
}
|
|
1787
1806
|
}
|
|
1788
1807
|
if (options.maxIterations !== void 0) {
|
|
1808
|
+
if (Number.isNaN(options.maxIterations)) {
|
|
1809
|
+
throw new ValidationError(
|
|
1810
|
+
"Max iterations must be a valid number",
|
|
1811
|
+
["Use -1 for unlimited iterations", "Use positive integers like 1, 5, or 10", "Example: -i 5"]
|
|
1812
|
+
);
|
|
1813
|
+
}
|
|
1789
1814
|
if (options.maxIterations !== -1 && options.maxIterations < 1) {
|
|
1790
1815
|
throw new ValidationError(
|
|
1791
1816
|
"Max iterations must be -1 (unlimited) or a positive number",
|
|
@@ -1794,8 +1819,8 @@ ${helpText}
|
|
|
1794
1819
|
}
|
|
1795
1820
|
}
|
|
1796
1821
|
if (options.cwd) {
|
|
1797
|
-
const
|
|
1798
|
-
if (!await
|
|
1822
|
+
const fs22 = await import('fs-extra');
|
|
1823
|
+
if (!await fs22.pathExists(options.cwd)) {
|
|
1799
1824
|
throw new ValidationError(
|
|
1800
1825
|
`Working directory does not exist: ${options.cwd}`,
|
|
1801
1826
|
["Verify the path exists", "Use absolute paths to avoid ambiguity"]
|
|
@@ -3879,8 +3904,8 @@ var init_engine = __esm({
|
|
|
3879
3904
|
if (!request.workingDirectory?.trim()) {
|
|
3880
3905
|
throw new Error("Working directory is required");
|
|
3881
3906
|
}
|
|
3882
|
-
if (request.maxIterations < -1 || request.maxIterations === 0) {
|
|
3883
|
-
throw new Error("Max iterations must be positive or -1 for unlimited");
|
|
3907
|
+
if (Number.isNaN(request.maxIterations) || request.maxIterations < -1 || request.maxIterations === 0) {
|
|
3908
|
+
throw new Error("Max iterations must be a positive number or -1 for unlimited");
|
|
3884
3909
|
}
|
|
3885
3910
|
}
|
|
3886
3911
|
/**
|
|
@@ -4890,7 +4915,7 @@ var init_config2 = __esm({
|
|
|
4890
4915
|
return cached;
|
|
4891
4916
|
}
|
|
4892
4917
|
try {
|
|
4893
|
-
const configContent = await
|
|
4918
|
+
const configContent = await fs3__default.default.readFile(configPath, "utf-8");
|
|
4894
4919
|
const config = JSON.parse(configContent);
|
|
4895
4920
|
this.validateConfig(config);
|
|
4896
4921
|
const resolvedConfig = this.resolveConfigPaths(config, path3__namespace.dirname(configPath));
|
|
@@ -4912,7 +4937,7 @@ var init_config2 = __esm({
|
|
|
4912
4937
|
const rootDir = path3__namespace.parse(currentDir).root;
|
|
4913
4938
|
while (currentDir !== rootDir) {
|
|
4914
4939
|
const configPath = path3__namespace.join(currentDir, ".juno_task", "mcp.json");
|
|
4915
|
-
if (await
|
|
4940
|
+
if (await fs3__default.default.pathExists(configPath)) {
|
|
4916
4941
|
return configPath;
|
|
4917
4942
|
}
|
|
4918
4943
|
currentDir = path3__namespace.dirname(currentDir);
|
|
@@ -5098,7 +5123,7 @@ var init_logger = __esm({
|
|
|
5098
5123
|
* Matches Python's generate_log_file function
|
|
5099
5124
|
*/
|
|
5100
5125
|
async initialize(subagent = "mcp") {
|
|
5101
|
-
await
|
|
5126
|
+
await fs3__default.default.ensureDir(this.logDirectory);
|
|
5102
5127
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").split("T");
|
|
5103
5128
|
const dateStr = timestamp[0];
|
|
5104
5129
|
const timeStr = timestamp[1].split("-")[0].substring(0, 6);
|
|
@@ -5107,7 +5132,7 @@ var init_logger = __esm({
|
|
|
5107
5132
|
this.logFilePath = path3__namespace.default.join(this.logDirectory, logFileName);
|
|
5108
5133
|
const header = `# Juno-Task TypeScript Log - Started ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
5109
5134
|
`;
|
|
5110
|
-
await
|
|
5135
|
+
await fs3__default.default.writeFile(this.logFilePath, header);
|
|
5111
5136
|
}
|
|
5112
5137
|
/**
|
|
5113
5138
|
* Format log message matching Python version format
|
|
@@ -5125,7 +5150,7 @@ var init_logger = __esm({
|
|
|
5125
5150
|
if (!this.logFilePath) {
|
|
5126
5151
|
throw new Error("Logger not initialized. Call initialize() first.");
|
|
5127
5152
|
}
|
|
5128
|
-
await
|
|
5153
|
+
await fs3__default.default.appendFile(this.logFilePath, message);
|
|
5129
5154
|
}
|
|
5130
5155
|
/**
|
|
5131
5156
|
* Log message at specified level
|
|
@@ -7136,7 +7161,7 @@ var init_shell_backend = __esm({
|
|
|
7136
7161
|
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");
|
|
7137
7162
|
const logDir = path3__namespace.join(this.config.workingDirectory, ".juno_task", "logs");
|
|
7138
7163
|
try {
|
|
7139
|
-
await
|
|
7164
|
+
await fs3__default.default.ensureDir(logDir);
|
|
7140
7165
|
} catch (error) {
|
|
7141
7166
|
if (this.config?.debug) {
|
|
7142
7167
|
engineLogger.warn(`Failed to create log directory: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -7161,7 +7186,7 @@ var init_shell_backend = __esm({
|
|
|
7161
7186
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
7162
7187
|
const logEntry = `[${timestamp}] ${message}
|
|
7163
7188
|
`;
|
|
7164
|
-
await
|
|
7189
|
+
await fs3__default.default.appendFile(this.logFilePath, logEntry, "utf-8");
|
|
7165
7190
|
} catch (error) {
|
|
7166
7191
|
if (this.config?.debug) {
|
|
7167
7192
|
engineLogger.warn(`Failed to write to log file: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -7235,6 +7260,7 @@ var init_shell_backend = __esm({
|
|
|
7235
7260
|
return new Promise(async (resolve9, reject) => {
|
|
7236
7261
|
const startTime = Date.now();
|
|
7237
7262
|
const isPython = scriptPath.endsWith(".py");
|
|
7263
|
+
const isGemini = subagentType === "gemini";
|
|
7238
7264
|
const env2 = {
|
|
7239
7265
|
...process.env,
|
|
7240
7266
|
...this.config.environment,
|
|
@@ -7245,6 +7271,9 @@ var init_shell_backend = __esm({
|
|
|
7245
7271
|
JUNO_ITERATION: String(request.arguments?.iteration || 1),
|
|
7246
7272
|
JUNO_TOOL_ID: toolId
|
|
7247
7273
|
};
|
|
7274
|
+
if (isGemini) {
|
|
7275
|
+
env2.GEMINI_OUTPUT_FORMAT = env2.GEMINI_OUTPUT_FORMAT || "stream-json";
|
|
7276
|
+
}
|
|
7248
7277
|
let captureDir = null;
|
|
7249
7278
|
let capturePath = null;
|
|
7250
7279
|
if (subagentType === "claude") {
|
|
@@ -7266,6 +7295,9 @@ var init_shell_backend = __esm({
|
|
|
7266
7295
|
if (isPython && request.arguments?.model) {
|
|
7267
7296
|
args.push("-m", request.arguments.model);
|
|
7268
7297
|
}
|
|
7298
|
+
if (isPython && isGemini) {
|
|
7299
|
+
args.push("--output-format", env2.GEMINI_OUTPUT_FORMAT || "stream-json");
|
|
7300
|
+
}
|
|
7269
7301
|
if (isPython && request.arguments?.agents) {
|
|
7270
7302
|
args.push("--agents", request.arguments.agents);
|
|
7271
7303
|
}
|
|
@@ -7470,7 +7502,7 @@ var init_shell_backend = __esm({
|
|
|
7470
7502
|
* Strategy:
|
|
7471
7503
|
* 1. Try to parse each line as JSON first (for Claude)
|
|
7472
7504
|
* 2. If JSON parsing fails, treat as TEXT streaming (for Codex and other text-based subagents)
|
|
7473
|
-
* 3. Emit all
|
|
7505
|
+
* 3. Emit all text lines (including whitespace-only) as progress events for real-time display
|
|
7474
7506
|
*/
|
|
7475
7507
|
parseAndEmitStreamingEvents(data, sessionId) {
|
|
7476
7508
|
if (!this.jsonBuffer) {
|
|
@@ -7480,14 +7512,35 @@ var init_shell_backend = __esm({
|
|
|
7480
7512
|
const lines = this.jsonBuffer.split("\n");
|
|
7481
7513
|
this.jsonBuffer = lines.pop() || "";
|
|
7482
7514
|
for (const line of lines) {
|
|
7483
|
-
const
|
|
7484
|
-
if (!
|
|
7515
|
+
const rawLine = line.endsWith("\r") ? line.slice(0, -1) : line;
|
|
7516
|
+
if (!rawLine) continue;
|
|
7517
|
+
const hasNonWhitespace = rawLine.trim().length > 0;
|
|
7518
|
+
if (!hasNonWhitespace) {
|
|
7519
|
+
this.emitProgressEvent({
|
|
7520
|
+
sessionId,
|
|
7521
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
7522
|
+
backend: "shell",
|
|
7523
|
+
count: ++this.eventCounter,
|
|
7524
|
+
type: "thinking",
|
|
7525
|
+
content: rawLine,
|
|
7526
|
+
metadata: {
|
|
7527
|
+
format: "text",
|
|
7528
|
+
raw: true
|
|
7529
|
+
}
|
|
7530
|
+
}).catch((error) => {
|
|
7531
|
+
if (this.config?.debug) {
|
|
7532
|
+
engineLogger.warn(`Failed to emit whitespace-only streaming event: ${error instanceof Error ? error.message : String(error)}`);
|
|
7533
|
+
}
|
|
7534
|
+
});
|
|
7535
|
+
continue;
|
|
7536
|
+
}
|
|
7537
|
+
const trimmedLine = rawLine.trim();
|
|
7485
7538
|
let isJsonParsed = false;
|
|
7486
7539
|
try {
|
|
7487
7540
|
const jsonEvent = JSON.parse(trimmedLine);
|
|
7488
7541
|
let progressEvent;
|
|
7489
7542
|
if (this.isClaudeCliEvent(jsonEvent)) {
|
|
7490
|
-
progressEvent = this.convertClaudeEventToProgress(jsonEvent, sessionId,
|
|
7543
|
+
progressEvent = this.convertClaudeEventToProgress(jsonEvent, sessionId, rawLine);
|
|
7491
7544
|
isJsonParsed = true;
|
|
7492
7545
|
} else if (this.isGenericStreamingEvent(jsonEvent)) {
|
|
7493
7546
|
progressEvent = {
|
|
@@ -7522,7 +7575,7 @@ var init_shell_backend = __esm({
|
|
|
7522
7575
|
backend: "shell",
|
|
7523
7576
|
count: ++this.eventCounter,
|
|
7524
7577
|
type: "thinking",
|
|
7525
|
-
content:
|
|
7578
|
+
content: rawLine,
|
|
7526
7579
|
metadata: {
|
|
7527
7580
|
format: "text",
|
|
7528
7581
|
raw: true
|
|
@@ -12789,12 +12842,18 @@ async function mainCommandHandler(args, options, command) {
|
|
|
12789
12842
|
console.error(chalk15__default.default.red("\n\u274C Error: --allowed-tools and --append-allowed-tools are mutually exclusive. Use one or the other."));
|
|
12790
12843
|
process.exit(1);
|
|
12791
12844
|
}
|
|
12845
|
+
if (options.maxIterations !== void 0 && Number.isNaN(options.maxIterations)) {
|
|
12846
|
+
throw new ValidationError(
|
|
12847
|
+
"Max iterations must be a valid number",
|
|
12848
|
+
["Use -1 for unlimited iterations", "Use positive integers like 1, 5, or 10", "Example: -i 5"]
|
|
12849
|
+
);
|
|
12850
|
+
}
|
|
12792
12851
|
const executionRequest = createExecutionRequest({
|
|
12793
12852
|
instruction,
|
|
12794
12853
|
subagent: options.subagent,
|
|
12795
12854
|
backend: selectedBackend,
|
|
12796
12855
|
workingDirectory: config.workingDirectory,
|
|
12797
|
-
maxIterations: options.maxIterations
|
|
12856
|
+
maxIterations: options.maxIterations ?? config.defaultMaxIterations,
|
|
12798
12857
|
model: options.model || config.defaultModel,
|
|
12799
12858
|
agents: options.agents,
|
|
12800
12859
|
tools: options.tools,
|
|
@@ -12959,7 +13018,7 @@ var init_main = __esm({
|
|
|
12959
13018
|
return await this.collectInteractivePrompt();
|
|
12960
13019
|
} else {
|
|
12961
13020
|
const defaultPromptPath = path3__namespace.join(process.cwd(), ".juno_task", "prompt.md");
|
|
12962
|
-
if (await
|
|
13021
|
+
if (await fs3__default.default.pathExists(defaultPromptPath)) {
|
|
12963
13022
|
console.error(chalk15__default.default.blue(`\u{1F4C4} Using default prompt: ${chalk15__default.default.cyan(".juno_task/prompt.md")}`));
|
|
12964
13023
|
return await this.loadPromptFromFile(defaultPromptPath);
|
|
12965
13024
|
} else {
|
|
@@ -12987,7 +13046,7 @@ var init_main = __esm({
|
|
|
12987
13046
|
}
|
|
12988
13047
|
try {
|
|
12989
13048
|
const resolvedPath = path3__namespace.resolve(prompt);
|
|
12990
|
-
return await
|
|
13049
|
+
return await fs3__default.default.pathExists(resolvedPath);
|
|
12991
13050
|
} catch {
|
|
12992
13051
|
return false;
|
|
12993
13052
|
}
|
|
@@ -12995,7 +13054,7 @@ var init_main = __esm({
|
|
|
12995
13054
|
async loadPromptFromFile(filePath) {
|
|
12996
13055
|
try {
|
|
12997
13056
|
const resolvedPath = path3__namespace.resolve(filePath);
|
|
12998
|
-
const content = await
|
|
13057
|
+
const content = await fs3__default.default.readFile(resolvedPath, "utf-8");
|
|
12999
13058
|
if (!content.trim()) {
|
|
13000
13059
|
throw new FileSystemError(
|
|
13001
13060
|
"Prompt file is empty",
|
|
@@ -13317,6 +13376,221 @@ var init_main = __esm({
|
|
|
13317
13376
|
}
|
|
13318
13377
|
});
|
|
13319
13378
|
|
|
13379
|
+
// src/utils/script-installer.ts
|
|
13380
|
+
var script_installer_exports = {};
|
|
13381
|
+
__export(script_installer_exports, {
|
|
13382
|
+
ScriptInstaller: () => ScriptInstaller
|
|
13383
|
+
});
|
|
13384
|
+
var ScriptInstaller;
|
|
13385
|
+
var init_script_installer = __esm({
|
|
13386
|
+
"src/utils/script-installer.ts"() {
|
|
13387
|
+
init_version();
|
|
13388
|
+
ScriptInstaller = class {
|
|
13389
|
+
/**
|
|
13390
|
+
* Scripts that should be auto-installed if missing
|
|
13391
|
+
* These are critical scripts that users expect to be available
|
|
13392
|
+
*/
|
|
13393
|
+
/**
|
|
13394
|
+
* Required scripts include both standalone scripts and their dependencies.
|
|
13395
|
+
* kanban.sh depends on install_requirements.sh for Python venv setup.
|
|
13396
|
+
*/
|
|
13397
|
+
static REQUIRED_SCRIPTS = [
|
|
13398
|
+
"run_until_completion.sh",
|
|
13399
|
+
"kanban.sh",
|
|
13400
|
+
"install_requirements.sh"
|
|
13401
|
+
// Required by kanban.sh for Python venv creation
|
|
13402
|
+
];
|
|
13403
|
+
/**
|
|
13404
|
+
* Get the templates scripts directory from the package
|
|
13405
|
+
*/
|
|
13406
|
+
static getPackageScriptsDir() {
|
|
13407
|
+
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))));
|
|
13408
|
+
const candidates = [
|
|
13409
|
+
path3__namespace.join(__dirname2, "..", "..", "templates", "scripts"),
|
|
13410
|
+
// dist (production)
|
|
13411
|
+
path3__namespace.join(__dirname2, "..", "templates", "scripts")
|
|
13412
|
+
// src (development)
|
|
13413
|
+
];
|
|
13414
|
+
for (const scriptsPath of candidates) {
|
|
13415
|
+
if (fs3__default.default.existsSync(scriptsPath)) {
|
|
13416
|
+
return scriptsPath;
|
|
13417
|
+
}
|
|
13418
|
+
}
|
|
13419
|
+
if (process.env.JUNO_CODE_DEBUG === "1") {
|
|
13420
|
+
console.error("[DEBUG] ScriptInstaller: Could not find templates/scripts directory");
|
|
13421
|
+
console.error("[DEBUG] Tried:", candidates);
|
|
13422
|
+
}
|
|
13423
|
+
return null;
|
|
13424
|
+
}
|
|
13425
|
+
/**
|
|
13426
|
+
* Check if a specific script exists in the project's .juno_task/scripts/ directory
|
|
13427
|
+
*/
|
|
13428
|
+
static async scriptExists(projectDir, scriptName) {
|
|
13429
|
+
const scriptPath = path3__namespace.join(projectDir, ".juno_task", "scripts", scriptName);
|
|
13430
|
+
return fs3__default.default.pathExists(scriptPath);
|
|
13431
|
+
}
|
|
13432
|
+
/**
|
|
13433
|
+
* Install a specific script to the project's .juno_task/scripts/ directory
|
|
13434
|
+
* @param projectDir - The project root directory
|
|
13435
|
+
* @param scriptName - Name of the script to install (e.g., 'run_until_completion.sh')
|
|
13436
|
+
* @param silent - If true, suppresses console output
|
|
13437
|
+
* @returns true if script was installed, false if installation was skipped or failed
|
|
13438
|
+
*/
|
|
13439
|
+
static async installScript(projectDir, scriptName, silent = false) {
|
|
13440
|
+
try {
|
|
13441
|
+
const packageScriptsDir = this.getPackageScriptsDir();
|
|
13442
|
+
if (!packageScriptsDir) {
|
|
13443
|
+
if (!silent && process.env.JUNO_CODE_DEBUG === "1") {
|
|
13444
|
+
console.error("[DEBUG] ScriptInstaller: Package scripts directory not found");
|
|
13445
|
+
}
|
|
13446
|
+
return false;
|
|
13447
|
+
}
|
|
13448
|
+
const sourcePath = path3__namespace.join(packageScriptsDir, scriptName);
|
|
13449
|
+
if (!await fs3__default.default.pathExists(sourcePath)) {
|
|
13450
|
+
if (!silent && process.env.JUNO_CODE_DEBUG === "1") {
|
|
13451
|
+
console.error(`[DEBUG] ScriptInstaller: Source script not found: ${sourcePath}`);
|
|
13452
|
+
}
|
|
13453
|
+
return false;
|
|
13454
|
+
}
|
|
13455
|
+
const destDir = path3__namespace.join(projectDir, ".juno_task", "scripts");
|
|
13456
|
+
await fs3__default.default.ensureDir(destDir);
|
|
13457
|
+
const destPath = path3__namespace.join(destDir, scriptName);
|
|
13458
|
+
await fs3__default.default.copy(sourcePath, destPath, { overwrite: true });
|
|
13459
|
+
if (scriptName.endsWith(".sh") || scriptName.endsWith(".py")) {
|
|
13460
|
+
await fs3__default.default.chmod(destPath, 493);
|
|
13461
|
+
}
|
|
13462
|
+
if (!silent) {
|
|
13463
|
+
console.log(`\u2713 Installed script: ${scriptName} to .juno_task/scripts/`);
|
|
13464
|
+
}
|
|
13465
|
+
if (process.env.JUNO_CODE_DEBUG === "1") {
|
|
13466
|
+
console.error(`[DEBUG] ScriptInstaller: Installed ${scriptName} to ${destPath}`);
|
|
13467
|
+
}
|
|
13468
|
+
return true;
|
|
13469
|
+
} catch (error) {
|
|
13470
|
+
if (!silent && process.env.JUNO_CODE_DEBUG === "1") {
|
|
13471
|
+
console.error(`[DEBUG] ScriptInstaller: Failed to install ${scriptName}:`, error);
|
|
13472
|
+
}
|
|
13473
|
+
return false;
|
|
13474
|
+
}
|
|
13475
|
+
}
|
|
13476
|
+
/**
|
|
13477
|
+
* Check which required scripts are missing from the project
|
|
13478
|
+
* @param projectDir - The project root directory
|
|
13479
|
+
* @returns Array of missing script names
|
|
13480
|
+
*/
|
|
13481
|
+
static async getMissingScripts(projectDir) {
|
|
13482
|
+
const missing = [];
|
|
13483
|
+
for (const script of this.REQUIRED_SCRIPTS) {
|
|
13484
|
+
if (!await this.scriptExists(projectDir, script)) {
|
|
13485
|
+
missing.push(script);
|
|
13486
|
+
}
|
|
13487
|
+
}
|
|
13488
|
+
return missing;
|
|
13489
|
+
}
|
|
13490
|
+
/**
|
|
13491
|
+
* Auto-install any missing required scripts
|
|
13492
|
+
* This should be called on CLI startup for initialized projects
|
|
13493
|
+
* @param projectDir - The project root directory
|
|
13494
|
+
* @param silent - If true, suppresses console output
|
|
13495
|
+
* @returns true if any scripts were installed
|
|
13496
|
+
*/
|
|
13497
|
+
static async autoInstallMissing(projectDir, silent = true) {
|
|
13498
|
+
try {
|
|
13499
|
+
const junoTaskDir = path3__namespace.join(projectDir, ".juno_task");
|
|
13500
|
+
if (!await fs3__default.default.pathExists(junoTaskDir)) {
|
|
13501
|
+
return false;
|
|
13502
|
+
}
|
|
13503
|
+
const missing = await this.getMissingScripts(projectDir);
|
|
13504
|
+
if (missing.length === 0) {
|
|
13505
|
+
return false;
|
|
13506
|
+
}
|
|
13507
|
+
if (process.env.JUNO_CODE_DEBUG === "1") {
|
|
13508
|
+
console.error(`[DEBUG] ScriptInstaller: Missing scripts: ${missing.join(", ")}`);
|
|
13509
|
+
}
|
|
13510
|
+
let installedAny = false;
|
|
13511
|
+
for (const script of missing) {
|
|
13512
|
+
const installed = await this.installScript(projectDir, script, silent);
|
|
13513
|
+
if (installed) {
|
|
13514
|
+
installedAny = true;
|
|
13515
|
+
}
|
|
13516
|
+
}
|
|
13517
|
+
if (installedAny && !silent) {
|
|
13518
|
+
console.log(`\u2713 Auto-installed ${missing.length} missing script(s)`);
|
|
13519
|
+
}
|
|
13520
|
+
return installedAny;
|
|
13521
|
+
} catch (error) {
|
|
13522
|
+
if (process.env.JUNO_CODE_DEBUG === "1") {
|
|
13523
|
+
console.error("[DEBUG] ScriptInstaller: autoInstallMissing error:", error);
|
|
13524
|
+
}
|
|
13525
|
+
return false;
|
|
13526
|
+
}
|
|
13527
|
+
}
|
|
13528
|
+
/**
|
|
13529
|
+
* Update a script if the package version is newer (by content comparison)
|
|
13530
|
+
* @param projectDir - The project root directory
|
|
13531
|
+
* @param scriptName - Name of the script to update
|
|
13532
|
+
* @param silent - If true, suppresses console output
|
|
13533
|
+
* @returns true if script was updated
|
|
13534
|
+
*/
|
|
13535
|
+
static async updateScriptIfNewer(projectDir, scriptName, silent = true) {
|
|
13536
|
+
try {
|
|
13537
|
+
const packageScriptsDir = this.getPackageScriptsDir();
|
|
13538
|
+
if (!packageScriptsDir) {
|
|
13539
|
+
return false;
|
|
13540
|
+
}
|
|
13541
|
+
const sourcePath = path3__namespace.join(packageScriptsDir, scriptName);
|
|
13542
|
+
const destPath = path3__namespace.join(projectDir, ".juno_task", "scripts", scriptName);
|
|
13543
|
+
if (!await fs3__default.default.pathExists(destPath)) {
|
|
13544
|
+
return this.installScript(projectDir, scriptName, silent);
|
|
13545
|
+
}
|
|
13546
|
+
const [sourceContent, destContent] = await Promise.all([
|
|
13547
|
+
fs3__default.default.readFile(sourcePath, "utf-8"),
|
|
13548
|
+
fs3__default.default.readFile(destPath, "utf-8")
|
|
13549
|
+
]);
|
|
13550
|
+
if (sourceContent !== destContent) {
|
|
13551
|
+
await fs3__default.default.copy(sourcePath, destPath, { overwrite: true });
|
|
13552
|
+
if (scriptName.endsWith(".sh") || scriptName.endsWith(".py")) {
|
|
13553
|
+
await fs3__default.default.chmod(destPath, 493);
|
|
13554
|
+
}
|
|
13555
|
+
if (!silent) {
|
|
13556
|
+
console.log(`\u2713 Updated script: ${scriptName}`);
|
|
13557
|
+
}
|
|
13558
|
+
if (process.env.JUNO_CODE_DEBUG === "1") {
|
|
13559
|
+
console.error(`[DEBUG] ScriptInstaller: Updated ${scriptName} (content changed)`);
|
|
13560
|
+
}
|
|
13561
|
+
return true;
|
|
13562
|
+
}
|
|
13563
|
+
return false;
|
|
13564
|
+
} catch (error) {
|
|
13565
|
+
if (process.env.JUNO_CODE_DEBUG === "1") {
|
|
13566
|
+
console.error(`[DEBUG] ScriptInstaller: updateScriptIfNewer error for ${scriptName}:`, error);
|
|
13567
|
+
}
|
|
13568
|
+
return false;
|
|
13569
|
+
}
|
|
13570
|
+
}
|
|
13571
|
+
/**
|
|
13572
|
+
* Get the path to a script in the project's .juno_task/scripts/ directory
|
|
13573
|
+
*/
|
|
13574
|
+
static getScriptPath(projectDir, scriptName) {
|
|
13575
|
+
return path3__namespace.join(projectDir, ".juno_task", "scripts", scriptName);
|
|
13576
|
+
}
|
|
13577
|
+
/**
|
|
13578
|
+
* List all required scripts and their installation status
|
|
13579
|
+
*/
|
|
13580
|
+
static async listRequiredScripts(projectDir) {
|
|
13581
|
+
const results = [];
|
|
13582
|
+
for (const script of this.REQUIRED_SCRIPTS) {
|
|
13583
|
+
results.push({
|
|
13584
|
+
name: script,
|
|
13585
|
+
installed: await this.scriptExists(projectDir, script)
|
|
13586
|
+
});
|
|
13587
|
+
}
|
|
13588
|
+
return results;
|
|
13589
|
+
}
|
|
13590
|
+
};
|
|
13591
|
+
}
|
|
13592
|
+
});
|
|
13593
|
+
|
|
13320
13594
|
// src/utils/startup-validation.ts
|
|
13321
13595
|
var startup_validation_exports = {};
|
|
13322
13596
|
__export(startup_validation_exports, {
|
|
@@ -13407,7 +13681,7 @@ async function validateJSONFile(configSchema, baseDir) {
|
|
|
13407
13681
|
const warnings = [];
|
|
13408
13682
|
const filePath = path3__namespace.default.join(baseDir, configSchema.file);
|
|
13409
13683
|
try {
|
|
13410
|
-
const exists = await
|
|
13684
|
+
const exists = await fs3__default.default.pathExists(filePath);
|
|
13411
13685
|
if (!exists) {
|
|
13412
13686
|
if (configSchema.required) {
|
|
13413
13687
|
errors.push({
|
|
@@ -13430,7 +13704,7 @@ async function validateJSONFile(configSchema, baseDir) {
|
|
|
13430
13704
|
return { isValid: !configSchema.required, errors, warnings };
|
|
13431
13705
|
}
|
|
13432
13706
|
try {
|
|
13433
|
-
await
|
|
13707
|
+
await fs3__default.default.access(filePath, fs3__default.default.constants.R_OK);
|
|
13434
13708
|
} catch (accessError) {
|
|
13435
13709
|
errors.push({
|
|
13436
13710
|
file: configSchema.file,
|
|
@@ -13446,7 +13720,7 @@ async function validateJSONFile(configSchema, baseDir) {
|
|
|
13446
13720
|
}
|
|
13447
13721
|
let jsonData;
|
|
13448
13722
|
try {
|
|
13449
|
-
const fileContent = await
|
|
13723
|
+
const fileContent = await fs3__default.default.readFile(filePath, "utf8");
|
|
13450
13724
|
jsonData = JSON.parse(fileContent);
|
|
13451
13725
|
} catch (parseError) {
|
|
13452
13726
|
const errorMessage = parseError instanceof Error ? parseError.message : String(parseError);
|
|
@@ -13581,7 +13855,7 @@ function displayValidationResults(result) {
|
|
|
13581
13855
|
}
|
|
13582
13856
|
async function logValidationResults(result, baseDir = process.cwd()) {
|
|
13583
13857
|
const logDir = path3__namespace.default.join(baseDir, ".juno_task", "logs");
|
|
13584
|
-
await
|
|
13858
|
+
await fs3__default.default.ensureDir(logDir);
|
|
13585
13859
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
13586
13860
|
const logFile = path3__namespace.default.join(logDir, `startup-validation-${timestamp}.log`);
|
|
13587
13861
|
const logContent = [
|
|
@@ -13624,7 +13898,7 @@ async function logValidationResults(result, baseDir = process.cwd()) {
|
|
|
13624
13898
|
logContent.push(``);
|
|
13625
13899
|
}
|
|
13626
13900
|
}
|
|
13627
|
-
await
|
|
13901
|
+
await fs3__default.default.writeFile(logFile, logContent.join("\n"));
|
|
13628
13902
|
return logFile;
|
|
13629
13903
|
}
|
|
13630
13904
|
async function validateStartupConfigs(baseDir = process.cwd(), verbose = false) {
|
|
@@ -13958,7 +14232,7 @@ var TemplateEngine = class {
|
|
|
13958
14232
|
let overallError;
|
|
13959
14233
|
try {
|
|
13960
14234
|
if (!options.dryRun) {
|
|
13961
|
-
await
|
|
14235
|
+
await fs3__default.default.ensureDir(targetDirectory);
|
|
13962
14236
|
}
|
|
13963
14237
|
for (const template of templates) {
|
|
13964
14238
|
try {
|
|
@@ -15308,7 +15582,7 @@ This directory contains specification documents for your project.
|
|
|
15308
15582
|
const fileName = this.getTemplateFileName(template);
|
|
15309
15583
|
const targetPath = path3__namespace.join(targetDirectory, fileName);
|
|
15310
15584
|
try {
|
|
15311
|
-
const fileExists = await
|
|
15585
|
+
const fileExists = await fs3__default.default.pathExists(targetPath);
|
|
15312
15586
|
if (fileExists && !options.force && options.onConflict !== "overwrite") {
|
|
15313
15587
|
return {
|
|
15314
15588
|
path: targetPath,
|
|
@@ -15330,10 +15604,10 @@ This directory contains specification documents for your project.
|
|
|
15330
15604
|
}
|
|
15331
15605
|
if (options.createBackup && fileExists) {
|
|
15332
15606
|
const backupPath = `${targetPath}.backup.${Date.now()}`;
|
|
15333
|
-
await
|
|
15607
|
+
await fs3__default.default.copy(targetPath, backupPath);
|
|
15334
15608
|
}
|
|
15335
|
-
await
|
|
15336
|
-
await
|
|
15609
|
+
await fs3__default.default.ensureDir(path3__namespace.dirname(targetPath));
|
|
15610
|
+
await fs3__default.default.writeFile(targetPath, renderedContent, "utf8");
|
|
15337
15611
|
return {
|
|
15338
15612
|
path: targetPath,
|
|
15339
15613
|
content: renderedContent,
|
|
@@ -15597,7 +15871,7 @@ var SimpleInitTUI = class {
|
|
|
15597
15871
|
}
|
|
15598
15872
|
async confirmSave(targetDirectory) {
|
|
15599
15873
|
const junoTaskPath = path3__namespace.join(targetDirectory, ".juno_task");
|
|
15600
|
-
if (await
|
|
15874
|
+
if (await fs3__default.default.pathExists(junoTaskPath)) {
|
|
15601
15875
|
console.log(chalk15__default.default.yellow(" \u26A0\uFE0F .juno_task directory already exists"));
|
|
15602
15876
|
console.log(chalk15__default.default.gray(" Would you like to:"));
|
|
15603
15877
|
console.log(chalk15__default.default.gray(" 1) Override existing files"));
|
|
@@ -15642,16 +15916,16 @@ var SimpleProjectGenerator = class {
|
|
|
15642
15916
|
async generate() {
|
|
15643
15917
|
const { targetDirectory, variables, force } = this.context;
|
|
15644
15918
|
console.log(chalk15__default.default.blue("\u{1F4C1} Creating project directory..."));
|
|
15645
|
-
await
|
|
15919
|
+
await fs3__default.default.ensureDir(targetDirectory);
|
|
15646
15920
|
const junoTaskDir = path3__namespace.join(targetDirectory, ".juno_task");
|
|
15647
|
-
const junoTaskExists = await
|
|
15921
|
+
const junoTaskExists = await fs3__default.default.pathExists(junoTaskDir);
|
|
15648
15922
|
if (junoTaskExists && !force) {
|
|
15649
15923
|
throw new ValidationError(
|
|
15650
15924
|
"Project already initialized. Directory .juno_task already exists.",
|
|
15651
15925
|
["Use --force flag to overwrite existing files", "Choose a different directory"]
|
|
15652
15926
|
);
|
|
15653
15927
|
}
|
|
15654
|
-
await
|
|
15928
|
+
await fs3__default.default.ensureDir(junoTaskDir);
|
|
15655
15929
|
console.log(chalk15__default.default.blue("\u2699\uFE0F Creating project configuration..."));
|
|
15656
15930
|
await this.createConfigFile(junoTaskDir, targetDirectory);
|
|
15657
15931
|
console.log(chalk15__default.default.blue("\u{1F527} Setting up MCP configuration..."));
|
|
@@ -15685,21 +15959,21 @@ var SimpleProjectGenerator = class {
|
|
|
15685
15959
|
const promptContent = await templateEngine.render(promptTemplate, templateContext);
|
|
15686
15960
|
const initContent = await templateEngine.render(initTemplate, templateContext);
|
|
15687
15961
|
const implementContent = await templateEngine.render(implementTemplate, templateContext);
|
|
15688
|
-
await
|
|
15689
|
-
await
|
|
15690
|
-
await
|
|
15962
|
+
await fs3__default.default.writeFile(path3__namespace.join(junoTaskDir, "prompt.md"), promptContent);
|
|
15963
|
+
await fs3__default.default.writeFile(path3__namespace.join(junoTaskDir, "init.md"), initContent);
|
|
15964
|
+
await fs3__default.default.writeFile(path3__namespace.join(junoTaskDir, "implement.md"), implementContent);
|
|
15691
15965
|
const userFeedbackTemplate = templateEngine.getBuiltInTemplate("USER_FEEDBACK.md");
|
|
15692
15966
|
if (userFeedbackTemplate) {
|
|
15693
15967
|
const userFeedbackContent = await templateEngine.render(userFeedbackTemplate, templateContext);
|
|
15694
|
-
await
|
|
15968
|
+
await fs3__default.default.writeFile(path3__namespace.join(junoTaskDir, "USER_FEEDBACK.md"), userFeedbackContent);
|
|
15695
15969
|
}
|
|
15696
15970
|
const planTemplate = templateEngine.getBuiltInTemplate("plan.md");
|
|
15697
15971
|
if (planTemplate) {
|
|
15698
15972
|
const planContent = await templateEngine.render(planTemplate, templateContext);
|
|
15699
|
-
await
|
|
15973
|
+
await fs3__default.default.writeFile(path3__namespace.join(junoTaskDir, "plan.md"), planContent);
|
|
15700
15974
|
}
|
|
15701
15975
|
const specsDir = path3__namespace.join(junoTaskDir, "specs");
|
|
15702
|
-
await
|
|
15976
|
+
await fs3__default.default.ensureDir(specsDir);
|
|
15703
15977
|
const specsReadmeContent = `# Project Specifications
|
|
15704
15978
|
|
|
15705
15979
|
This directory contains detailed specifications for the project components.
|
|
@@ -15716,7 +15990,7 @@ This directory contains detailed specifications for the project components.
|
|
|
15716
15990
|
- Avoid conflicts with existing file names
|
|
15717
15991
|
- Use \`.md\` extension for all specification files
|
|
15718
15992
|
`;
|
|
15719
|
-
await
|
|
15993
|
+
await fs3__default.default.writeFile(path3__namespace.join(specsDir, "README.md"), specsReadmeContent);
|
|
15720
15994
|
const requirementsContent = `# Requirements Specification
|
|
15721
15995
|
|
|
15722
15996
|
## Functional Requirements
|
|
@@ -15763,7 +16037,7 @@ This directory contains detailed specifications for the project components.
|
|
|
15763
16037
|
- Code quality: Clean, maintainable codebase
|
|
15764
16038
|
- Documentation: Complete and accurate documentation
|
|
15765
16039
|
`;
|
|
15766
|
-
await
|
|
16040
|
+
await fs3__default.default.writeFile(path3__namespace.join(specsDir, "requirements.md"), requirementsContent);
|
|
15767
16041
|
const architectureContent = `# Architecture Specification
|
|
15768
16042
|
|
|
15769
16043
|
## System Overview
|
|
@@ -15845,7 +16119,7 @@ This project uses AI-assisted development with juno-code to achieve: ${variables
|
|
|
15845
16119
|
- Performance monitoring
|
|
15846
16120
|
- Security best practices
|
|
15847
16121
|
`;
|
|
15848
|
-
await
|
|
16122
|
+
await fs3__default.default.writeFile(path3__namespace.join(specsDir, "architecture.md"), architectureContent);
|
|
15849
16123
|
const claudeContent = `# Claude Development Session Learnings
|
|
15850
16124
|
|
|
15851
16125
|
## Project Overview
|
|
@@ -15917,7 +16191,7 @@ This file will be updated as development progresses to track:
|
|
|
15917
16191
|
- Solutions to complex problems
|
|
15918
16192
|
- Performance improvements and optimizations
|
|
15919
16193
|
`;
|
|
15920
|
-
await
|
|
16194
|
+
await fs3__default.default.writeFile(path3__namespace.join(targetDirectory, "CLAUDE.md"), claudeContent);
|
|
15921
16195
|
const agentsContent = `# AI Agent Selection and Performance
|
|
15922
16196
|
|
|
15923
16197
|
## Available Agents
|
|
@@ -15981,7 +16255,7 @@ Track agent performance for:
|
|
|
15981
16255
|
4. **Feedback Loop**: Provide feedback to improve agent performance
|
|
15982
16256
|
5. **Performance Monitoring**: Track and optimize agent usage
|
|
15983
16257
|
`;
|
|
15984
|
-
await
|
|
16258
|
+
await fs3__default.default.writeFile(path3__namespace.join(targetDirectory, "AGENTS.md"), agentsContent);
|
|
15985
16259
|
const readmeContent = `# ${variables.PROJECT_NAME}
|
|
15986
16260
|
|
|
15987
16261
|
${variables.DESCRIPTION}
|
|
@@ -16078,7 +16352,7 @@ ${variables.GIT_URL}` : ""}
|
|
|
16078
16352
|
Created with juno-code on ${variables.CURRENT_DATE}
|
|
16079
16353
|
${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
16080
16354
|
`;
|
|
16081
|
-
await
|
|
16355
|
+
await fs3__default.default.writeFile(path3__namespace.join(targetDirectory, "README.md"), readmeContent);
|
|
16082
16356
|
console.log(chalk15__default.default.blue("\u{1F4E6} Installing utility scripts..."));
|
|
16083
16357
|
await this.copyScriptsFromTemplates(junoTaskDir);
|
|
16084
16358
|
console.log(chalk15__default.default.blue("\u{1F40D} Installing Python requirements..."));
|
|
@@ -16130,7 +16404,7 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16130
16404
|
hooks: getDefaultHooks()
|
|
16131
16405
|
};
|
|
16132
16406
|
const configPath = path3__namespace.join(junoTaskDir, "config.json");
|
|
16133
|
-
await
|
|
16407
|
+
await fs3__default.default.writeFile(configPath, JSON.stringify(configContent, null, 2));
|
|
16134
16408
|
console.log(chalk15__default.default.green(` \u2713 Created .juno_task/config.json with ${this.context.subagent} as default subagent`));
|
|
16135
16409
|
}
|
|
16136
16410
|
async createMcpFile(junoTaskDir, targetDirectory) {
|
|
@@ -16184,7 +16458,7 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16184
16458
|
}
|
|
16185
16459
|
};
|
|
16186
16460
|
const mcpPath = path3__namespace.join(junoTaskDir, "mcp.json");
|
|
16187
|
-
await
|
|
16461
|
+
await fs3__default.default.writeFile(mcpPath, JSON.stringify(mcpContent, null, 2));
|
|
16188
16462
|
console.log(chalk15__default.default.green(` \u2713 Created .juno_task/mcp.json with roundtable-ai server configuration`));
|
|
16189
16463
|
}
|
|
16190
16464
|
getDefaultModelForSubagent(subagent) {
|
|
@@ -16203,7 +16477,7 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16203
16477
|
async copyScriptsFromTemplates(junoTaskDir) {
|
|
16204
16478
|
try {
|
|
16205
16479
|
const scriptsDir = path3__namespace.join(junoTaskDir, "scripts");
|
|
16206
|
-
await
|
|
16480
|
+
await fs3__default.default.ensureDir(scriptsDir);
|
|
16207
16481
|
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)));
|
|
16208
16482
|
const __dirname2 = path3__namespace.dirname(__filename2);
|
|
16209
16483
|
let templatesScriptsDir;
|
|
@@ -16214,11 +16488,11 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16214
16488
|
} else {
|
|
16215
16489
|
templatesScriptsDir = path3__namespace.join(__dirname2, "../../templates/scripts");
|
|
16216
16490
|
}
|
|
16217
|
-
if (!await
|
|
16491
|
+
if (!await fs3__default.default.pathExists(templatesScriptsDir)) {
|
|
16218
16492
|
console.log(chalk15__default.default.yellow(" \u26A0\uFE0F Template scripts directory not found, skipping script installation"));
|
|
16219
16493
|
return;
|
|
16220
16494
|
}
|
|
16221
|
-
const scriptFiles = await
|
|
16495
|
+
const scriptFiles = await fs3__default.default.readdir(templatesScriptsDir);
|
|
16222
16496
|
if (scriptFiles.length === 0) {
|
|
16223
16497
|
console.log(chalk15__default.default.gray(" \u2139\uFE0F No template scripts found to install"));
|
|
16224
16498
|
return;
|
|
@@ -16227,11 +16501,11 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16227
16501
|
for (const scriptFile of scriptFiles) {
|
|
16228
16502
|
const sourcePath = path3__namespace.join(templatesScriptsDir, scriptFile);
|
|
16229
16503
|
const destPath = path3__namespace.join(scriptsDir, scriptFile);
|
|
16230
|
-
const stats = await
|
|
16504
|
+
const stats = await fs3__default.default.stat(sourcePath);
|
|
16231
16505
|
if (stats.isFile()) {
|
|
16232
|
-
await
|
|
16506
|
+
await fs3__default.default.copy(sourcePath, destPath);
|
|
16233
16507
|
if (scriptFile.endsWith(".sh")) {
|
|
16234
|
-
await
|
|
16508
|
+
await fs3__default.default.chmod(destPath, 493);
|
|
16235
16509
|
}
|
|
16236
16510
|
copiedCount++;
|
|
16237
16511
|
console.log(chalk15__default.default.green(` \u2713 Installed script: ${scriptFile}`));
|
|
@@ -16254,7 +16528,7 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
16254
16528
|
try {
|
|
16255
16529
|
const scriptsDir = path3__namespace.join(junoTaskDir, "scripts");
|
|
16256
16530
|
const installScript = path3__namespace.join(scriptsDir, "install_requirements.sh");
|
|
16257
|
-
if (!await
|
|
16531
|
+
if (!await fs3__default.default.pathExists(installScript)) {
|
|
16258
16532
|
console.log(chalk15__default.default.yellow(" \u26A0\uFE0F install_requirements.sh not found, skipping Python dependencies installation"));
|
|
16259
16533
|
console.log(chalk15__default.default.gray(" You can install dependencies manually: juno-kanban, roundtable-ai"));
|
|
16260
16534
|
return;
|
|
@@ -16551,20 +16825,20 @@ init_types();
|
|
|
16551
16825
|
async function loadInitPrompt(directory) {
|
|
16552
16826
|
const junoTaskDir = path3__namespace.join(directory, ".juno_task");
|
|
16553
16827
|
const initFile = path3__namespace.join(junoTaskDir, "init.md");
|
|
16554
|
-
if (!await
|
|
16828
|
+
if (!await fs3__default.default.pathExists(junoTaskDir)) {
|
|
16555
16829
|
throw new FileSystemError(
|
|
16556
16830
|
'No .juno_task directory found. Run "juno-code init" first.',
|
|
16557
16831
|
junoTaskDir
|
|
16558
16832
|
);
|
|
16559
16833
|
}
|
|
16560
|
-
if (!await
|
|
16834
|
+
if (!await fs3__default.default.pathExists(initFile)) {
|
|
16561
16835
|
throw new FileSystemError(
|
|
16562
16836
|
"No init.md file found in .juno_task directory",
|
|
16563
16837
|
initFile
|
|
16564
16838
|
);
|
|
16565
16839
|
}
|
|
16566
16840
|
try {
|
|
16567
|
-
const content = await
|
|
16841
|
+
const content = await fs3__default.default.readFile(initFile, "utf-8");
|
|
16568
16842
|
if (!content.trim()) {
|
|
16569
16843
|
throw new FileSystemError(
|
|
16570
16844
|
"init.md file is empty. Please add task instructions.",
|
|
@@ -17596,8 +17870,8 @@ Focus on ${request.intelligence === "basic" ? "basic functionality" : request.in
|
|
|
17596
17870
|
for (const scenario of scenarios) {
|
|
17597
17871
|
const testContent = await this.generateTestContent(request, scenario, template);
|
|
17598
17872
|
const testFilePath = this.resolveTestFilePath(request, scenario);
|
|
17599
|
-
await
|
|
17600
|
-
await
|
|
17873
|
+
await fs3__default.default.ensureDir(path3__namespace.dirname(testFilePath));
|
|
17874
|
+
await fs3__default.default.writeFile(testFilePath, testContent);
|
|
17601
17875
|
testFiles.push(testFilePath);
|
|
17602
17876
|
}
|
|
17603
17877
|
return testFiles;
|
|
@@ -17849,8 +18123,8 @@ var TestExecutionEngine = class {
|
|
|
17849
18123
|
async collectCoverage(request) {
|
|
17850
18124
|
const coverageFile = path3__namespace.join(request.workingDirectory, "coverage", "coverage-summary.json");
|
|
17851
18125
|
try {
|
|
17852
|
-
if (await
|
|
17853
|
-
const coverageData = await
|
|
18126
|
+
if (await fs3__default.default.pathExists(coverageFile)) {
|
|
18127
|
+
const coverageData = await fs3__default.default.readJson(coverageFile);
|
|
17854
18128
|
return {
|
|
17855
18129
|
lines: coverageData.total?.lines?.pct || 0,
|
|
17856
18130
|
functions: coverageData.total?.functions?.pct || 0,
|
|
@@ -18033,8 +18307,8 @@ var TestReportEngine = class {
|
|
|
18033
18307
|
suggestions: analysis.suggestions,
|
|
18034
18308
|
recommendations: analysis.recommendations
|
|
18035
18309
|
};
|
|
18036
|
-
await
|
|
18037
|
-
await
|
|
18310
|
+
await fs3__default.default.ensureDir(path3__namespace.dirname(outputPath));
|
|
18311
|
+
await fs3__default.default.writeJson(outputPath, report, { spaces: 2 });
|
|
18038
18312
|
return outputPath;
|
|
18039
18313
|
}
|
|
18040
18314
|
async generateHTMLReport(analysis, outputPath, includeVisualizations) {
|
|
@@ -18097,8 +18371,8 @@ var TestReportEngine = class {
|
|
|
18097
18371
|
</body>
|
|
18098
18372
|
</html>
|
|
18099
18373
|
`.trim();
|
|
18100
|
-
await
|
|
18101
|
-
await
|
|
18374
|
+
await fs3__default.default.ensureDir(path3__namespace.dirname(outputPath));
|
|
18375
|
+
await fs3__default.default.writeFile(outputPath, html);
|
|
18102
18376
|
return outputPath;
|
|
18103
18377
|
}
|
|
18104
18378
|
generateCharts(analysis) {
|
|
@@ -18155,8 +18429,8 @@ ${analysis.suggestions.map((suggestion) => `- ${suggestion}`).join("\n")}
|
|
|
18155
18429
|
|
|
18156
18430
|
${analysis.recommendations.map((rec) => `- ${rec}`).join("\n")}
|
|
18157
18431
|
`.trim();
|
|
18158
|
-
await
|
|
18159
|
-
await
|
|
18432
|
+
await fs3__default.default.ensureDir(path3__namespace.dirname(outputPath));
|
|
18433
|
+
await fs3__default.default.writeFile(outputPath, markdown);
|
|
18160
18434
|
return outputPath;
|
|
18161
18435
|
}
|
|
18162
18436
|
async displayConsoleReport(analysis) {
|
|
@@ -18496,16 +18770,16 @@ async function compactConfigFile(filePath, options = {}) {
|
|
|
18496
18770
|
preserveDays = 30,
|
|
18497
18771
|
preservePatterns = []
|
|
18498
18772
|
} = options;
|
|
18499
|
-
const originalContent = await
|
|
18773
|
+
const originalContent = await fs3__default.default.readFile(filePath, "utf-8");
|
|
18500
18774
|
const originalSize = originalContent.length;
|
|
18501
18775
|
let backupPath = "";
|
|
18502
18776
|
if (createBackup && !dryRun) {
|
|
18503
18777
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
18504
18778
|
const ext = path3__namespace.extname(filePath);
|
|
18505
18779
|
const basename11 = path3__namespace.basename(filePath, ext);
|
|
18506
|
-
const
|
|
18507
|
-
backupPath = path3__namespace.join(
|
|
18508
|
-
await
|
|
18780
|
+
const dirname13 = path3__namespace.dirname(filePath);
|
|
18781
|
+
backupPath = path3__namespace.join(dirname13, `${basename11}.backup.${timestamp}${ext}`);
|
|
18782
|
+
await fs3__default.default.writeFile(backupPath, originalContent, "utf-8");
|
|
18509
18783
|
}
|
|
18510
18784
|
const compactionAnalysis = analyzeMarkdownStructure(originalContent);
|
|
18511
18785
|
const compactedContent = compactMarkdownContent(
|
|
@@ -18520,7 +18794,7 @@ async function compactConfigFile(filePath, options = {}) {
|
|
|
18520
18794
|
const compactedSize = finalContent.length;
|
|
18521
18795
|
const reductionPercentage = Math.round((originalSize - compactedSize) / originalSize * 100);
|
|
18522
18796
|
if (!dryRun) {
|
|
18523
|
-
await
|
|
18797
|
+
await fs3__default.default.writeFile(filePath, finalContent, "utf-8");
|
|
18524
18798
|
}
|
|
18525
18799
|
return {
|
|
18526
18800
|
originalSize,
|
|
@@ -18650,7 +18924,7 @@ function formatFileSize(bytes) {
|
|
|
18650
18924
|
}
|
|
18651
18925
|
async function shouldCompactFile(filePath, sizeThresholdKB = 50, ageThresholdDays = 30) {
|
|
18652
18926
|
try {
|
|
18653
|
-
const stats = await
|
|
18927
|
+
const stats = await fs3__default.default.stat(filePath);
|
|
18654
18928
|
const sizeKB = stats.size / 1024;
|
|
18655
18929
|
if (sizeKB > sizeThresholdKB) {
|
|
18656
18930
|
return true;
|
|
@@ -18672,19 +18946,19 @@ async function archiveResolvedIssues(options) {
|
|
|
18672
18946
|
feedbackFile,
|
|
18673
18947
|
archiveDir = path3__namespace.join(path3__namespace.dirname(feedbackFile), "archives"),
|
|
18674
18948
|
openIssuesThreshold = 10} = options;
|
|
18675
|
-
if (!await
|
|
18949
|
+
if (!await fs3__default.default.pathExists(feedbackFile)) {
|
|
18676
18950
|
throw new Error(`Feedback file does not exist: ${feedbackFile}`);
|
|
18677
18951
|
}
|
|
18678
|
-
const content = await
|
|
18952
|
+
const content = await fs3__default.default.readFile(feedbackFile, "utf-8");
|
|
18679
18953
|
const parsed = parseUserFeedback(content);
|
|
18680
18954
|
const warningsGenerated = [];
|
|
18681
18955
|
if (parsed.openIssues.length > openIssuesThreshold) {
|
|
18682
18956
|
const warning = `Found ${parsed.openIssues.length} open issues (threshold: ${openIssuesThreshold}). Consider reviewing and prioritizing.`;
|
|
18683
18957
|
warningsGenerated.push(warning);
|
|
18684
18958
|
const logFile = path3__namespace.join(path3__namespace.dirname(feedbackFile), "logs", "feedback-warnings.log");
|
|
18685
|
-
await
|
|
18959
|
+
await fs3__default.default.ensureDir(path3__namespace.dirname(logFile));
|
|
18686
18960
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
18687
|
-
await
|
|
18961
|
+
await fs3__default.default.appendFile(logFile, `[${timestamp}] ${warning}
|
|
18688
18962
|
`);
|
|
18689
18963
|
}
|
|
18690
18964
|
if (parsed.resolvedIssues.length === 0) {
|
|
@@ -18701,10 +18975,10 @@ async function archiveResolvedIssues(options) {
|
|
|
18701
18975
|
const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
|
|
18702
18976
|
const archiveFile = path3__namespace.join(archiveDir, `USER_FEEDBACK_archive_${currentYear}.md`);
|
|
18703
18977
|
{
|
|
18704
|
-
await
|
|
18978
|
+
await fs3__default.default.ensureDir(archiveDir);
|
|
18705
18979
|
await appendToArchive(archiveFile, parsed.resolvedIssues);
|
|
18706
18980
|
const compactedContent = generateCompactedFeedback(parsed.openIssues, parsed.metadata);
|
|
18707
|
-
await
|
|
18981
|
+
await fs3__default.default.writeFile(feedbackFile, compactedContent, "utf-8");
|
|
18708
18982
|
}
|
|
18709
18983
|
{
|
|
18710
18984
|
console.log(chalk15__default.default.green(`\u2705 Archived ${parsed.resolvedIssues.length} resolved issues`));
|
|
@@ -18751,8 +19025,8 @@ function parseUserFeedback(content) {
|
|
|
18751
19025
|
async function appendToArchive(archiveFile, resolvedIssues) {
|
|
18752
19026
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
18753
19027
|
let archiveContent = "";
|
|
18754
|
-
if (await
|
|
18755
|
-
archiveContent = await
|
|
19028
|
+
if (await fs3__default.default.pathExists(archiveFile)) {
|
|
19029
|
+
archiveContent = await fs3__default.default.readFile(archiveFile, "utf-8");
|
|
18756
19030
|
} else {
|
|
18757
19031
|
const year = path3__namespace.basename(archiveFile).match(/(\d{4})/)?.[1] || (/* @__PURE__ */ new Date()).getFullYear();
|
|
18758
19032
|
archiveContent = `# User Feedback Archive ${year}
|
|
@@ -18786,7 +19060,7 @@ ${resolvedIssue}
|
|
|
18786
19060
|
`- Last updated: ${timestamp}`
|
|
18787
19061
|
);
|
|
18788
19062
|
}
|
|
18789
|
-
await
|
|
19063
|
+
await fs3__default.default.writeFile(archiveFile, archiveContent, "utf-8");
|
|
18790
19064
|
}
|
|
18791
19065
|
function generateCompactedFeedback(openIssues, metadata) {
|
|
18792
19066
|
let content = metadata.trim() + "\n";
|
|
@@ -18811,15 +19085,15 @@ async function shouldArchive(feedbackFile, options = {}) {
|
|
|
18811
19085
|
// 50KB
|
|
18812
19086
|
lineCountThreshold = 500
|
|
18813
19087
|
} = options;
|
|
18814
|
-
if (!await
|
|
19088
|
+
if (!await fs3__default.default.pathExists(feedbackFile)) {
|
|
18815
19089
|
return {
|
|
18816
19090
|
shouldArchive: false,
|
|
18817
19091
|
reasons: [],
|
|
18818
19092
|
stats: { openIssuesCount: 0, resolvedIssuesCount: 0, fileSizeBytes: 0, lineCount: 0 }
|
|
18819
19093
|
};
|
|
18820
19094
|
}
|
|
18821
|
-
const content = await
|
|
18822
|
-
const stats = await
|
|
19095
|
+
const content = await fs3__default.default.readFile(feedbackFile, "utf-8");
|
|
19096
|
+
const stats = await fs3__default.default.stat(feedbackFile);
|
|
18823
19097
|
const parsed = parseUserFeedback(content);
|
|
18824
19098
|
const lineCount = content.split("\n").length;
|
|
18825
19099
|
const reasons = [];
|
|
@@ -18893,16 +19167,16 @@ var EnhancedFeedbackFileManager = class {
|
|
|
18893
19167
|
this.feedbackFile = feedbackFile;
|
|
18894
19168
|
}
|
|
18895
19169
|
async ensureExists() {
|
|
18896
|
-
if (!await
|
|
19170
|
+
if (!await fs3__default.default.pathExists(this.feedbackFile)) {
|
|
18897
19171
|
await this.createInitialFile();
|
|
18898
19172
|
}
|
|
18899
19173
|
}
|
|
18900
19174
|
async addFeedback(issue, testCriteria) {
|
|
18901
19175
|
await this.ensureExists();
|
|
18902
19176
|
try {
|
|
18903
|
-
const content = await
|
|
19177
|
+
const content = await fs3__default.default.readFile(this.feedbackFile, "utf-8");
|
|
18904
19178
|
const updatedContent = this.addIssueToContent(content, issue, testCriteria);
|
|
18905
|
-
await
|
|
19179
|
+
await fs3__default.default.writeFile(this.feedbackFile, updatedContent, "utf-8");
|
|
18906
19180
|
} catch (error) {
|
|
18907
19181
|
throw new ValidationError(
|
|
18908
19182
|
`Failed to save feedback: ${error}`,
|
|
@@ -18915,12 +19189,12 @@ var EnhancedFeedbackFileManager = class {
|
|
|
18915
19189
|
*/
|
|
18916
19190
|
async repairMalformedFile() {
|
|
18917
19191
|
try {
|
|
18918
|
-
const content = await
|
|
19192
|
+
const content = await fs3__default.default.readFile(this.feedbackFile, "utf-8");
|
|
18919
19193
|
const hasOpenIssues = content.includes("<OPEN_ISSUES>");
|
|
18920
19194
|
const hasClosingTag = content.includes("</OPEN_ISSUES>");
|
|
18921
19195
|
if (!hasOpenIssues || !hasClosingTag) {
|
|
18922
19196
|
const backupPath = this.feedbackFile + ".backup." + Date.now();
|
|
18923
|
-
await
|
|
19197
|
+
await fs3__default.default.writeFile(backupPath, content, "utf-8");
|
|
18924
19198
|
const existingIssues = this.extractIssuesFromMalformedContent(content);
|
|
18925
19199
|
await this.createInitialFile(existingIssues);
|
|
18926
19200
|
}
|
|
@@ -18952,8 +19226,8 @@ List any features you'd like to see added or bugs you've encountered.
|
|
|
18952
19226
|
|
|
18953
19227
|
<!-- Resolved issues will be moved here -->
|
|
18954
19228
|
`;
|
|
18955
|
-
await
|
|
18956
|
-
await
|
|
19229
|
+
await fs3__default.default.ensureDir(path3__namespace.dirname(this.feedbackFile));
|
|
19230
|
+
await fs3__default.default.writeFile(this.feedbackFile, initialContent, "utf-8");
|
|
18957
19231
|
}
|
|
18958
19232
|
addIssueToContent(content, issue, testCriteria) {
|
|
18959
19233
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
@@ -19069,17 +19343,17 @@ async function handleCompactCommand(subArgs, options) {
|
|
|
19069
19343
|
if (subArgs.length > 0) {
|
|
19070
19344
|
for (const filePath of subArgs) {
|
|
19071
19345
|
const resolvedPath = path3__namespace.resolve(filePath);
|
|
19072
|
-
if (await
|
|
19346
|
+
if (await fs3__default.default.pathExists(resolvedPath)) {
|
|
19073
19347
|
filesToCompact.push(resolvedPath);
|
|
19074
19348
|
} else {
|
|
19075
19349
|
console.warn(chalk15__default.default.yellow(`\u26A0\uFE0F File not found: ${filePath}`));
|
|
19076
19350
|
}
|
|
19077
19351
|
}
|
|
19078
19352
|
} else {
|
|
19079
|
-
if (await
|
|
19353
|
+
if (await fs3__default.default.pathExists(defaultClaudeFile)) {
|
|
19080
19354
|
filesToCompact.push(defaultClaudeFile);
|
|
19081
19355
|
}
|
|
19082
|
-
if (await
|
|
19356
|
+
if (await fs3__default.default.pathExists(defaultAgentsFile)) {
|
|
19083
19357
|
filesToCompact.push(defaultAgentsFile);
|
|
19084
19358
|
}
|
|
19085
19359
|
}
|
|
@@ -20013,11 +20287,11 @@ var GitManager = class {
|
|
|
20013
20287
|
*/
|
|
20014
20288
|
async updateJunoTaskConfig(gitUrl) {
|
|
20015
20289
|
const configPath = path3__namespace.join(this.workingDirectory, ".juno_task", "init.md");
|
|
20016
|
-
if (!await
|
|
20290
|
+
if (!await fs3__default.default.pathExists(configPath)) {
|
|
20017
20291
|
return;
|
|
20018
20292
|
}
|
|
20019
20293
|
try {
|
|
20020
|
-
let content = await
|
|
20294
|
+
let content = await fs3__default.default.readFile(configPath, "utf-8");
|
|
20021
20295
|
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
20022
20296
|
if (frontmatterMatch) {
|
|
20023
20297
|
let frontmatter = frontmatterMatch[1];
|
|
@@ -20038,7 +20312,7 @@ GIT_URL: ${gitUrl}
|
|
|
20038
20312
|
`;
|
|
20039
20313
|
content = frontmatter + content;
|
|
20040
20314
|
}
|
|
20041
|
-
await
|
|
20315
|
+
await fs3__default.default.writeFile(configPath, content, "utf-8");
|
|
20042
20316
|
} catch (error) {
|
|
20043
20317
|
console.warn(`Warning: Failed to update juno-code configuration: ${error}`);
|
|
20044
20318
|
}
|
|
@@ -20970,7 +21244,7 @@ var LogViewer = ({
|
|
|
20970
21244
|
init_types();
|
|
20971
21245
|
async function exportLogs(logger2, filepath, options) {
|
|
20972
21246
|
try {
|
|
20973
|
-
const
|
|
21247
|
+
const fs22 = await import('fs-extra');
|
|
20974
21248
|
let entries = logger2.getRecentEntries(options.tail || 1e3);
|
|
20975
21249
|
if (options.level) {
|
|
20976
21250
|
const level = LogLevel[options.level.toUpperCase()];
|
|
@@ -21000,7 +21274,7 @@ async function exportLogs(logger2, filepath, options) {
|
|
|
21000
21274
|
},
|
|
21001
21275
|
entries
|
|
21002
21276
|
};
|
|
21003
|
-
await
|
|
21277
|
+
await fs22.writeFile(filepath, JSON.stringify(exportData, null, 2));
|
|
21004
21278
|
console.log(chalk15__default.default.green(`\u2705 Exported ${entries.length} log entries to: ${filepath}`));
|
|
21005
21279
|
} catch (error) {
|
|
21006
21280
|
console.error(chalk15__default.default.red(`\u274C Failed to export logs: ${error}`));
|
|
@@ -22544,7 +22818,7 @@ function createServicesCommand() {
|
|
|
22544
22818
|
const servicesCmd = new commander.Command("services").description("Manage juno-code service scripts").addHelpText("after", `
|
|
22545
22819
|
Examples:
|
|
22546
22820
|
$ 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)
|
|
22821
|
+
$ juno-code services install --force Reinstall/refresh service scripts (codex.py/claude.py/gemini.py)
|
|
22548
22822
|
$ juno-code services list List installed service scripts
|
|
22549
22823
|
$ juno-code services status Check installation status
|
|
22550
22824
|
$ juno-code services uninstall Remove all service scripts
|
|
@@ -22801,10 +23075,10 @@ autoload -U compinit && compinit`;
|
|
|
22801
23075
|
*/
|
|
22802
23076
|
async isSourceCommandPresent(configPath, sourceCommand) {
|
|
22803
23077
|
try {
|
|
22804
|
-
if (!await
|
|
23078
|
+
if (!await fs3__default.default.pathExists(configPath)) {
|
|
22805
23079
|
return false;
|
|
22806
23080
|
}
|
|
22807
|
-
const content = await
|
|
23081
|
+
const content = await fs3__default.default.readFile(configPath, "utf-8");
|
|
22808
23082
|
return content.includes("juno-code completion");
|
|
22809
23083
|
} catch {
|
|
22810
23084
|
return false;
|
|
@@ -22826,15 +23100,15 @@ autoload -U compinit && compinit`;
|
|
|
22826
23100
|
continue;
|
|
22827
23101
|
}
|
|
22828
23102
|
try {
|
|
22829
|
-
const completionExists = await
|
|
22830
|
-
const configExists = await
|
|
23103
|
+
const completionExists = await fs3__default.default.pathExists(shell.completionPath);
|
|
23104
|
+
const configExists = await fs3__default.default.pathExists(shell.configPath);
|
|
22831
23105
|
const isSourced = configExists && await this.isSourceCommandPresent(
|
|
22832
23106
|
shell.configPath,
|
|
22833
23107
|
this.getSourceCommand(shell.name, shell.completionPath)
|
|
22834
23108
|
);
|
|
22835
23109
|
let lastInstalled;
|
|
22836
23110
|
if (completionExists) {
|
|
22837
|
-
const stats = await
|
|
23111
|
+
const stats = await fs3__default.default.stat(shell.completionPath);
|
|
22838
23112
|
lastInstalled = stats.mtime;
|
|
22839
23113
|
}
|
|
22840
23114
|
statuses.push({
|
|
@@ -22860,7 +23134,7 @@ autoload -U compinit && compinit`;
|
|
|
22860
23134
|
async ensureCompletionDirectory(shell) {
|
|
22861
23135
|
const completionPath = this.getCompletionPath(shell);
|
|
22862
23136
|
const completionDir = path3__namespace.dirname(completionPath);
|
|
22863
|
-
await
|
|
23137
|
+
await fs3__default.default.ensureDir(completionDir);
|
|
22864
23138
|
}
|
|
22865
23139
|
/**
|
|
22866
23140
|
* Ensure directory exists for shell configuration
|
|
@@ -22868,7 +23142,7 @@ autoload -U compinit && compinit`;
|
|
|
22868
23142
|
async ensureConfigDirectory(shell) {
|
|
22869
23143
|
const configPath = this.getConfigPath(shell);
|
|
22870
23144
|
const configDir = path3__namespace.dirname(configPath);
|
|
22871
|
-
await
|
|
23145
|
+
await fs3__default.default.ensureDir(configDir);
|
|
22872
23146
|
}
|
|
22873
23147
|
/**
|
|
22874
23148
|
* Get shell version information
|
|
@@ -22892,15 +23166,15 @@ autoload -U compinit && compinit`;
|
|
|
22892
23166
|
try {
|
|
22893
23167
|
const configPath = this.getConfigPath(shell);
|
|
22894
23168
|
const configDir = path3__namespace.dirname(configPath);
|
|
22895
|
-
await
|
|
23169
|
+
await fs3__default.default.access(configDir, fs3__default.default.constants.W_OK);
|
|
22896
23170
|
} catch {
|
|
22897
23171
|
issues.push(`Cannot write to ${shell} configuration directory`);
|
|
22898
23172
|
}
|
|
22899
23173
|
try {
|
|
22900
23174
|
const completionPath = this.getCompletionPath(shell);
|
|
22901
23175
|
const completionDir = path3__namespace.dirname(completionPath);
|
|
22902
|
-
await
|
|
22903
|
-
await
|
|
23176
|
+
await fs3__default.default.ensureDir(completionDir);
|
|
23177
|
+
await fs3__default.default.access(completionDir, fs3__default.default.constants.W_OK);
|
|
22904
23178
|
} catch {
|
|
22905
23179
|
issues.push(`Cannot write to ${shell} completion directory`);
|
|
22906
23180
|
}
|
|
@@ -22971,10 +23245,10 @@ var ContextAwareCompletion = class {
|
|
|
22971
23245
|
async getSessionIds() {
|
|
22972
23246
|
try {
|
|
22973
23247
|
const sessionDir = path3__namespace.join(process.cwd(), ".juno_task", "sessions");
|
|
22974
|
-
if (!await
|
|
23248
|
+
if (!await fs3__default.default.pathExists(sessionDir)) {
|
|
22975
23249
|
return [];
|
|
22976
23250
|
}
|
|
22977
|
-
const sessions = await
|
|
23251
|
+
const sessions = await fs3__default.default.readdir(sessionDir);
|
|
22978
23252
|
return sessions.filter((name) => name.match(/^session_\d+$/)).map((name) => name.replace("session_", "")).sort((a, b) => parseInt(b) - parseInt(a));
|
|
22979
23253
|
} catch {
|
|
22980
23254
|
return [];
|
|
@@ -22988,8 +23262,8 @@ var ContextAwareCompletion = class {
|
|
|
22988
23262
|
const builtinTemplates = ["basic", "advanced", "research", "development"];
|
|
22989
23263
|
const customTemplatesDir = path3__namespace.join(process.cwd(), ".juno_task", "templates");
|
|
22990
23264
|
let customTemplates = [];
|
|
22991
|
-
if (await
|
|
22992
|
-
const files = await
|
|
23265
|
+
if (await fs3__default.default.pathExists(customTemplatesDir)) {
|
|
23266
|
+
const files = await fs3__default.default.readdir(customTemplatesDir);
|
|
22993
23267
|
customTemplates = files.filter((name) => name.endsWith(".md") || name.endsWith(".hbs")).map((name) => path3__namespace.basename(name, path3__namespace.extname(name)));
|
|
22994
23268
|
}
|
|
22995
23269
|
return [...builtinTemplates, ...customTemplates].sort();
|
|
@@ -23066,7 +23340,7 @@ var CompletionInstaller = class {
|
|
|
23066
23340
|
await this.shellDetector.ensureConfigDirectory(shell);
|
|
23067
23341
|
const script = this.generateEnhancedCompletion(shell, "juno-code");
|
|
23068
23342
|
const completionPath = this.shellDetector.getCompletionPath(shell);
|
|
23069
|
-
await
|
|
23343
|
+
await fs3__default.default.writeFile(completionPath, script, "utf-8");
|
|
23070
23344
|
const configPath = this.shellDetector.getConfigPath(shell);
|
|
23071
23345
|
const sourceCommand = this.shellDetector.getSourceCommand(shell, completionPath);
|
|
23072
23346
|
const warnings = [];
|
|
@@ -23074,7 +23348,7 @@ var CompletionInstaller = class {
|
|
|
23074
23348
|
const isPresent = await this.shellDetector.isSourceCommandPresent(configPath, sourceCommand);
|
|
23075
23349
|
if (!isPresent) {
|
|
23076
23350
|
try {
|
|
23077
|
-
await
|
|
23351
|
+
await fs3__default.default.appendFile(configPath, `
|
|
23078
23352
|
|
|
23079
23353
|
${sourceCommand}
|
|
23080
23354
|
`);
|
|
@@ -23105,8 +23379,8 @@ ${sourceCommand}
|
|
|
23105
23379
|
async uninstall(shell) {
|
|
23106
23380
|
try {
|
|
23107
23381
|
const completionPath = this.shellDetector.getCompletionPath(shell);
|
|
23108
|
-
if (await
|
|
23109
|
-
await
|
|
23382
|
+
if (await fs3__default.default.pathExists(completionPath)) {
|
|
23383
|
+
await fs3__default.default.remove(completionPath);
|
|
23110
23384
|
return true;
|
|
23111
23385
|
}
|
|
23112
23386
|
return false;
|
|
@@ -23120,7 +23394,7 @@ ${sourceCommand}
|
|
|
23120
23394
|
async isInstalled(shell) {
|
|
23121
23395
|
try {
|
|
23122
23396
|
const completionPath = this.shellDetector.getCompletionPath(shell);
|
|
23123
|
-
return await
|
|
23397
|
+
return await fs3__default.default.pathExists(completionPath);
|
|
23124
23398
|
} catch {
|
|
23125
23399
|
return false;
|
|
23126
23400
|
}
|
|
@@ -23921,11 +24195,11 @@ function setupMainCommand(program) {
|
|
|
23921
24195
|
);
|
|
23922
24196
|
const allOptions2 = { ...definedGlobalOptions, ...options };
|
|
23923
24197
|
if (!globalOptions.subagent && !options.prompt && !options.interactive && !options.interactivePrompt) {
|
|
23924
|
-
const
|
|
23925
|
-
const
|
|
24198
|
+
const fs22 = await import('fs-extra');
|
|
24199
|
+
const path24 = await import('path');
|
|
23926
24200
|
const cwd2 = process.cwd();
|
|
23927
|
-
const junoTaskDir =
|
|
23928
|
-
if (await
|
|
24201
|
+
const junoTaskDir = path24.join(cwd2, ".juno_task");
|
|
24202
|
+
if (await fs22.pathExists(junoTaskDir)) {
|
|
23929
24203
|
console.log(chalk15__default.default.blue.bold("\u{1F3AF} Juno Code - Auto-detected Initialized Project\n"));
|
|
23930
24204
|
try {
|
|
23931
24205
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
@@ -23942,12 +24216,12 @@ function setupMainCommand(program) {
|
|
|
23942
24216
|
allOptions2.subagent = config.defaultSubagent;
|
|
23943
24217
|
console.log(chalk15__default.default.gray(`\u{1F916} Using configured subagent: ${chalk15__default.default.cyan(config.defaultSubagent)}`));
|
|
23944
24218
|
}
|
|
23945
|
-
const promptFile =
|
|
23946
|
-
if (!allOptions2.prompt && await
|
|
24219
|
+
const promptFile = path24.join(junoTaskDir, "prompt.md");
|
|
24220
|
+
if (!allOptions2.prompt && await fs22.pathExists(promptFile)) {
|
|
23947
24221
|
allOptions2.prompt = promptFile;
|
|
23948
24222
|
console.log(chalk15__default.default.gray(`\u{1F4C4} Using default prompt: ${chalk15__default.default.cyan(".juno_task/prompt.md")}`));
|
|
23949
24223
|
}
|
|
23950
|
-
if (allOptions2.subagent && (allOptions2.prompt || await
|
|
24224
|
+
if (allOptions2.subagent && (allOptions2.prompt || await fs22.pathExists(promptFile))) {
|
|
23951
24225
|
console.log(chalk15__default.default.green("\u2713 Auto-detected project configuration\n"));
|
|
23952
24226
|
const { mainCommandHandler: mainCommandHandler3 } = await Promise.resolve().then(() => (init_main(), main_exports));
|
|
23953
24227
|
await mainCommandHandler3([], allOptions2, command);
|
|
@@ -24104,6 +24378,17 @@ async function main() {
|
|
|
24104
24378
|
console.error("[DEBUG] Service auto-update failed:", error instanceof Error ? error.message : String(error));
|
|
24105
24379
|
}
|
|
24106
24380
|
}
|
|
24381
|
+
try {
|
|
24382
|
+
const { ScriptInstaller: ScriptInstaller2 } = await Promise.resolve().then(() => (init_script_installer(), script_installer_exports));
|
|
24383
|
+
const installed = await ScriptInstaller2.autoInstallMissing(process.cwd(), true);
|
|
24384
|
+
if (installed && (process.argv.includes("--verbose") || process.argv.includes("-v") || process.env.JUNO_CODE_DEBUG === "1")) {
|
|
24385
|
+
console.error("[DEBUG] Project scripts auto-installed to .juno_task/scripts/");
|
|
24386
|
+
}
|
|
24387
|
+
} catch (error) {
|
|
24388
|
+
if (process.env.JUNO_CODE_DEBUG === "1") {
|
|
24389
|
+
console.error("[DEBUG] Script auto-install failed:", error instanceof Error ? error.message : String(error));
|
|
24390
|
+
}
|
|
24391
|
+
}
|
|
24107
24392
|
program.name("juno-code").description("TypeScript implementation of juno-code CLI tool for AI subagent orchestration").version(VERSION, "-V, --version", "Display version information").helpOption("-h, --help", "Display help information");
|
|
24108
24393
|
setupGlobalOptions(program);
|
|
24109
24394
|
const isVerbose = process.argv.includes("--verbose") || process.argv.includes("-v");
|
|
@@ -24111,10 +24396,10 @@ async function main() {
|
|
|
24111
24396
|
const isHelpOrVersion = process.argv.includes("--help") || process.argv.includes("-h") || process.argv.includes("--version") || process.argv.includes("-V");
|
|
24112
24397
|
const hasNoArguments = process.argv.length <= 2;
|
|
24113
24398
|
const isInitCommand = process.argv.includes("init");
|
|
24114
|
-
const
|
|
24115
|
-
const
|
|
24116
|
-
const junoTaskDir =
|
|
24117
|
-
const isInitialized = await
|
|
24399
|
+
const fs22 = await import('fs-extra');
|
|
24400
|
+
const path24 = await import('path');
|
|
24401
|
+
const junoTaskDir = path24.join(process.cwd(), ".juno_task");
|
|
24402
|
+
const isInitialized = await fs22.pathExists(junoTaskDir);
|
|
24118
24403
|
if (!isHelpOrVersion && !hasNoArguments && !isInitCommand && isInitialized) {
|
|
24119
24404
|
try {
|
|
24120
24405
|
const { validateStartupConfigs: validateStartupConfigs2 } = await Promise.resolve().then(() => (init_startup_validation(), startup_validation_exports));
|