juno-code 1.0.17 → 1.0.20
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 +151 -44
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/cli.mjs +151 -45
- package/dist/bin/cli.mjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/templates/services/codex.py +11 -15
- package/package.json +1 -1
package/dist/bin/cli.js
CHANGED
|
@@ -5,6 +5,8 @@ var fs3 = require('fs-extra');
|
|
|
5
5
|
var path3 = require('path');
|
|
6
6
|
var os2 = require('os');
|
|
7
7
|
var url = require('url');
|
|
8
|
+
var module$1 = require('module');
|
|
9
|
+
var semver = require('semver');
|
|
8
10
|
var zod = require('zod');
|
|
9
11
|
var nodeFs = require('fs');
|
|
10
12
|
var yaml = require('js-yaml');
|
|
@@ -53,6 +55,7 @@ function _interopNamespace(e) {
|
|
|
53
55
|
var fs3__default = /*#__PURE__*/_interopDefault(fs3);
|
|
54
56
|
var path3__namespace = /*#__PURE__*/_interopNamespace(path3);
|
|
55
57
|
var os2__namespace = /*#__PURE__*/_interopNamespace(os2);
|
|
58
|
+
var semver__default = /*#__PURE__*/_interopDefault(semver);
|
|
56
59
|
var nodeFs__namespace = /*#__PURE__*/_interopNamespace(nodeFs);
|
|
57
60
|
var yaml__namespace = /*#__PURE__*/_interopNamespace(yaml);
|
|
58
61
|
var Table__default = /*#__PURE__*/_interopDefault(Table);
|
|
@@ -339,16 +342,80 @@ var init_service_installer = __esm({
|
|
|
339
342
|
init_version();
|
|
340
343
|
ServiceInstaller = class {
|
|
341
344
|
static SERVICES_DIR = path3__namespace.join(os2.homedir(), ".juno_code", "services");
|
|
345
|
+
static VERSION_FILE = path3__namespace.join(os2.homedir(), ".juno_code", "services", ".version");
|
|
346
|
+
/**
|
|
347
|
+
* Get the current package version
|
|
348
|
+
*/
|
|
349
|
+
static getPackageVersion() {
|
|
350
|
+
try {
|
|
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
|
+
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
|
+
let packageJsonPath = path3__namespace.join(__dirname2, "..", "..", "package.json");
|
|
354
|
+
if (fs3__default.default.existsSync(packageJsonPath)) {
|
|
355
|
+
const packageJson2 = require3(packageJsonPath);
|
|
356
|
+
return packageJson2.version;
|
|
357
|
+
}
|
|
358
|
+
packageJsonPath = path3__namespace.join(__dirname2, "..", "..", "..", "package.json");
|
|
359
|
+
if (fs3__default.default.existsSync(packageJsonPath)) {
|
|
360
|
+
const packageJson2 = require3(packageJsonPath);
|
|
361
|
+
return packageJson2.version;
|
|
362
|
+
}
|
|
363
|
+
return "0.0.0";
|
|
364
|
+
} catch {
|
|
365
|
+
return "0.0.0";
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Get the installed services version
|
|
370
|
+
*/
|
|
371
|
+
static async getInstalledVersion() {
|
|
372
|
+
try {
|
|
373
|
+
const exists = await fs3__default.default.pathExists(this.VERSION_FILE);
|
|
374
|
+
if (!exists) {
|
|
375
|
+
return null;
|
|
376
|
+
}
|
|
377
|
+
const version3 = await fs3__default.default.readFile(this.VERSION_FILE, "utf-8");
|
|
378
|
+
return version3.trim();
|
|
379
|
+
} catch {
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Save the current package version to the version file
|
|
385
|
+
*/
|
|
386
|
+
static async saveVersion() {
|
|
387
|
+
const version3 = this.getPackageVersion();
|
|
388
|
+
await fs3__default.default.writeFile(this.VERSION_FILE, version3, "utf-8");
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Check if services need to be updated based on version
|
|
392
|
+
*/
|
|
393
|
+
static async needsUpdate() {
|
|
394
|
+
try {
|
|
395
|
+
const packageVersion = this.getPackageVersion();
|
|
396
|
+
const installedVersion = await this.getInstalledVersion();
|
|
397
|
+
if (!installedVersion) {
|
|
398
|
+
return true;
|
|
399
|
+
}
|
|
400
|
+
const exists = await fs3__default.default.pathExists(this.SERVICES_DIR);
|
|
401
|
+
if (!exists) {
|
|
402
|
+
return true;
|
|
403
|
+
}
|
|
404
|
+
return semver__default.default.gt(packageVersion, installedVersion);
|
|
405
|
+
} catch {
|
|
406
|
+
return true;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
342
409
|
/**
|
|
343
410
|
* Get the path to the services directory in the package
|
|
344
411
|
*/
|
|
345
412
|
static getPackageServicesDir() {
|
|
346
|
-
const
|
|
347
|
-
let servicesPath = path3__namespace.join(
|
|
413
|
+
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))));
|
|
414
|
+
let servicesPath = path3__namespace.join(__dirname2, "..", "..", "templates", "services");
|
|
348
415
|
if (fs3__default.default.existsSync(servicesPath)) {
|
|
349
416
|
return servicesPath;
|
|
350
417
|
}
|
|
351
|
-
servicesPath = path3__namespace.join(
|
|
418
|
+
servicesPath = path3__namespace.join(__dirname2, "..", "templates", "services");
|
|
352
419
|
if (fs3__default.default.existsSync(servicesPath)) {
|
|
353
420
|
return servicesPath;
|
|
354
421
|
}
|
|
@@ -356,8 +423,9 @@ var init_service_installer = __esm({
|
|
|
356
423
|
}
|
|
357
424
|
/**
|
|
358
425
|
* Install all service scripts to ~/.juno_code/services/
|
|
426
|
+
* @param silent - If true, suppresses console output
|
|
359
427
|
*/
|
|
360
|
-
static async install() {
|
|
428
|
+
static async install(silent = false) {
|
|
361
429
|
try {
|
|
362
430
|
await fs3__default.default.ensureDir(this.SERVICES_DIR);
|
|
363
431
|
const packageServicesDir = this.getPackageServicesDir();
|
|
@@ -373,11 +441,30 @@ var init_service_installer = __esm({
|
|
|
373
441
|
await fs3__default.default.chmod(filePath, 493);
|
|
374
442
|
}
|
|
375
443
|
}
|
|
376
|
-
|
|
444
|
+
await this.saveVersion();
|
|
445
|
+
if (!silent) {
|
|
446
|
+
console.log(`\u2713 Services installed to: ${this.SERVICES_DIR}`);
|
|
447
|
+
}
|
|
377
448
|
} catch (error) {
|
|
378
449
|
throw new Error(`Failed to install services: ${error instanceof Error ? error.message : String(error)}`);
|
|
379
450
|
}
|
|
380
451
|
}
|
|
452
|
+
/**
|
|
453
|
+
* Automatically update services if needed (silent operation)
|
|
454
|
+
* This should be called on every CLI run to ensure services are up-to-date
|
|
455
|
+
*/
|
|
456
|
+
static async autoUpdate() {
|
|
457
|
+
try {
|
|
458
|
+
const needsUpdate = await this.needsUpdate();
|
|
459
|
+
if (needsUpdate) {
|
|
460
|
+
await this.install(true);
|
|
461
|
+
return true;
|
|
462
|
+
}
|
|
463
|
+
return false;
|
|
464
|
+
} catch {
|
|
465
|
+
return false;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
381
468
|
/**
|
|
382
469
|
* Check if services are installed
|
|
383
470
|
*/
|
|
@@ -917,8 +1004,8 @@ async function loadYamlConfig(filePath) {
|
|
|
917
1004
|
async function loadPackageJsonConfig(filePath) {
|
|
918
1005
|
try {
|
|
919
1006
|
const content = await nodeFs.promises.readFile(filePath, "utf-8");
|
|
920
|
-
const
|
|
921
|
-
return
|
|
1007
|
+
const packageJson2 = JSON.parse(content);
|
|
1008
|
+
return packageJson2.junoCode || {};
|
|
922
1009
|
} catch (error) {
|
|
923
1010
|
throw new Error(`Failed to load package.json config from ${filePath}: ${error}`);
|
|
924
1011
|
}
|
|
@@ -6615,7 +6702,7 @@ var init_shell_backend = __esm({
|
|
|
6615
6702
|
this.parseAndEmitStreamingEvents(data, request.metadata?.sessionId || "unknown");
|
|
6616
6703
|
} catch (error) {
|
|
6617
6704
|
if (this.config.debug) {
|
|
6618
|
-
engineLogger.warn(`
|
|
6705
|
+
engineLogger.warn(`Streaming parse error: ${error instanceof Error ? error.message : String(error)}`);
|
|
6619
6706
|
}
|
|
6620
6707
|
}
|
|
6621
6708
|
}
|
|
@@ -6674,8 +6761,13 @@ var init_shell_backend = __esm({
|
|
|
6674
6761
|
});
|
|
6675
6762
|
}
|
|
6676
6763
|
/**
|
|
6677
|
-
* Parse
|
|
6678
|
-
* Handles both
|
|
6764
|
+
* Parse streaming events from script output
|
|
6765
|
+
* Handles both JSON format (Claude) and TEXT format (Codex)
|
|
6766
|
+
*
|
|
6767
|
+
* Strategy:
|
|
6768
|
+
* 1. Try to parse each line as JSON first (for Claude)
|
|
6769
|
+
* 2. If JSON parsing fails, treat as TEXT streaming (for Codex and other text-based subagents)
|
|
6770
|
+
* 3. Emit all non-empty lines as progress events for real-time display
|
|
6679
6771
|
*/
|
|
6680
6772
|
parseAndEmitStreamingEvents(data, sessionId) {
|
|
6681
6773
|
if (!this.jsonBuffer) {
|
|
@@ -6687,11 +6779,13 @@ var init_shell_backend = __esm({
|
|
|
6687
6779
|
for (const line of lines) {
|
|
6688
6780
|
const trimmedLine = line.trim();
|
|
6689
6781
|
if (!trimmedLine) continue;
|
|
6782
|
+
let isJsonParsed = false;
|
|
6690
6783
|
try {
|
|
6691
6784
|
const jsonEvent = JSON.parse(trimmedLine);
|
|
6692
6785
|
let progressEvent;
|
|
6693
6786
|
if (this.isClaudeCliEvent(jsonEvent)) {
|
|
6694
6787
|
progressEvent = this.convertClaudeEventToProgress(jsonEvent, sessionId, trimmedLine);
|
|
6788
|
+
isJsonParsed = true;
|
|
6695
6789
|
} else if (this.isGenericStreamingEvent(jsonEvent)) {
|
|
6696
6790
|
progressEvent = {
|
|
6697
6791
|
sessionId,
|
|
@@ -6702,33 +6796,39 @@ var init_shell_backend = __esm({
|
|
|
6702
6796
|
content: jsonEvent.content,
|
|
6703
6797
|
metadata: jsonEvent.metadata
|
|
6704
6798
|
};
|
|
6799
|
+
isJsonParsed = true;
|
|
6705
6800
|
} else {
|
|
6706
6801
|
if (this.config?.debug) {
|
|
6707
|
-
engineLogger.debug(`Unknown JSON format: ${trimmedLine}`);
|
|
6802
|
+
engineLogger.debug(`Unknown JSON format, treating as text: ${trimmedLine}`);
|
|
6708
6803
|
}
|
|
6709
|
-
continue;
|
|
6710
6804
|
}
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
engineLogger.warn(`Failed to emit progress event: ${error instanceof Error ? error.message : String(error)}`);
|
|
6714
|
-
}
|
|
6715
|
-
});
|
|
6716
|
-
} catch (error) {
|
|
6717
|
-
if (trimmedLine.length > 0 && !trimmedLine.startsWith("#")) {
|
|
6718
|
-
this.emitProgressEvent({
|
|
6719
|
-
sessionId,
|
|
6720
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
6721
|
-
backend: "shell",
|
|
6722
|
-
count: ++this.eventCounter,
|
|
6723
|
-
type: "thinking",
|
|
6724
|
-
content: trimmedLine,
|
|
6725
|
-
metadata: { raw: true, parseError: true }
|
|
6726
|
-
}).catch((error2) => {
|
|
6805
|
+
if (isJsonParsed) {
|
|
6806
|
+
this.emitProgressEvent(progressEvent).catch((error) => {
|
|
6727
6807
|
if (this.config?.debug) {
|
|
6728
|
-
engineLogger.warn(`Failed to emit
|
|
6808
|
+
engineLogger.warn(`Failed to emit progress event: ${error instanceof Error ? error.message : String(error)}`);
|
|
6729
6809
|
}
|
|
6730
6810
|
});
|
|
6731
6811
|
}
|
|
6812
|
+
} catch (error) {
|
|
6813
|
+
isJsonParsed = false;
|
|
6814
|
+
}
|
|
6815
|
+
if (!isJsonParsed && trimmedLine.length > 0) {
|
|
6816
|
+
this.emitProgressEvent({
|
|
6817
|
+
sessionId,
|
|
6818
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
6819
|
+
backend: "shell",
|
|
6820
|
+
count: ++this.eventCounter,
|
|
6821
|
+
type: "thinking",
|
|
6822
|
+
content: trimmedLine,
|
|
6823
|
+
metadata: {
|
|
6824
|
+
format: "text",
|
|
6825
|
+
raw: true
|
|
6826
|
+
}
|
|
6827
|
+
}).catch((error) => {
|
|
6828
|
+
if (this.config?.debug) {
|
|
6829
|
+
engineLogger.warn(`Failed to emit text streaming event: ${error instanceof Error ? error.message : String(error)}`);
|
|
6830
|
+
}
|
|
6831
|
+
});
|
|
6732
6832
|
}
|
|
6733
6833
|
}
|
|
6734
6834
|
}
|
|
@@ -15704,9 +15804,9 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
15704
15804
|
async createMcpFile(junoTaskDir, targetDirectory) {
|
|
15705
15805
|
const projectName = path3__namespace.basename(targetDirectory);
|
|
15706
15806
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
15707
|
-
const
|
|
15708
|
-
const
|
|
15709
|
-
process.env.JUNO_TASK_MCP_SERVER_PATH || path3__namespace.join(
|
|
15807
|
+
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)));
|
|
15808
|
+
const __dirname2 = path3__namespace.dirname(__filename2);
|
|
15809
|
+
process.env.JUNO_TASK_MCP_SERVER_PATH || path3__namespace.join(__dirname2, "../../../roundtable_mcp_server/roundtable_mcp_server/server.py");
|
|
15710
15810
|
const mcpContent = {
|
|
15711
15811
|
mcpServers: {
|
|
15712
15812
|
"roundtable-ai": {
|
|
@@ -15772,15 +15872,15 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
15772
15872
|
try {
|
|
15773
15873
|
const scriptsDir = path3__namespace.join(junoTaskDir, "scripts");
|
|
15774
15874
|
await fs3__default.default.ensureDir(scriptsDir);
|
|
15775
|
-
const
|
|
15776
|
-
const
|
|
15875
|
+
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)));
|
|
15876
|
+
const __dirname2 = path3__namespace.dirname(__filename2);
|
|
15777
15877
|
let templatesScriptsDir;
|
|
15778
|
-
if (
|
|
15779
|
-
templatesScriptsDir = path3__namespace.join(
|
|
15780
|
-
} else if (
|
|
15781
|
-
templatesScriptsDir = path3__namespace.join(
|
|
15878
|
+
if (__dirname2.includes("/dist/bin") || __dirname2.includes("\\dist\\bin")) {
|
|
15879
|
+
templatesScriptsDir = path3__namespace.join(__dirname2, "../templates/scripts");
|
|
15880
|
+
} else if (__dirname2.includes("/src/cli/commands") || __dirname2.includes("\\src\\cli\\commands")) {
|
|
15881
|
+
templatesScriptsDir = path3__namespace.join(__dirname2, "../../templates/scripts");
|
|
15782
15882
|
} else {
|
|
15783
|
-
templatesScriptsDir = path3__namespace.join(
|
|
15883
|
+
templatesScriptsDir = path3__namespace.join(__dirname2, "../../templates/scripts");
|
|
15784
15884
|
}
|
|
15785
15885
|
if (!await fs3__default.default.pathExists(templatesScriptsDir)) {
|
|
15786
15886
|
console.log(chalk12__default.default.yellow(" \u26A0\uFE0F Template scripts directory not found, skipping script installation"));
|
|
@@ -19468,8 +19568,8 @@ async function compactConfigFile(filePath, options = {}) {
|
|
|
19468
19568
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
19469
19569
|
const ext = path3__namespace.extname(filePath);
|
|
19470
19570
|
const basename11 = path3__namespace.basename(filePath, ext);
|
|
19471
|
-
const
|
|
19472
|
-
backupPath = path3__namespace.join(
|
|
19571
|
+
const dirname12 = path3__namespace.dirname(filePath);
|
|
19572
|
+
backupPath = path3__namespace.join(dirname12, `${basename11}.backup.${timestamp}${ext}`);
|
|
19473
19573
|
await fs3__default.default.writeFile(backupPath, originalContent, "utf-8");
|
|
19474
19574
|
}
|
|
19475
19575
|
const compactionAnalysis = analyzeMarkdownStructure(originalContent);
|
|
@@ -24816,11 +24916,13 @@ var CompletionCommand = class {
|
|
|
24816
24916
|
}
|
|
24817
24917
|
};
|
|
24818
24918
|
var completion_default = CompletionCommand;
|
|
24819
|
-
|
|
24820
|
-
// src/bin/cli.ts
|
|
24821
24919
|
util.inspect.defaultOptions.maxStringLength = Infinity;
|
|
24822
24920
|
util.inspect.defaultOptions.breakLength = Infinity;
|
|
24823
|
-
var
|
|
24921
|
+
var __filename$1 = 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)));
|
|
24922
|
+
var __dirname$1 = path3.dirname(__filename$1);
|
|
24923
|
+
var require2 = 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)));
|
|
24924
|
+
var packageJson = require2(path3.join(__dirname$1, "../../package.json"));
|
|
24925
|
+
var VERSION = packageJson.version;
|
|
24824
24926
|
function isConnectionLikeError(err) {
|
|
24825
24927
|
const msg = err instanceof Error ? `${err.name}: ${err.message}` : String(err);
|
|
24826
24928
|
const lower = msg.toLowerCase();
|
|
@@ -25045,6 +25147,11 @@ function configureEnvironment() {
|
|
|
25045
25147
|
async function main() {
|
|
25046
25148
|
const program = new commander.Command();
|
|
25047
25149
|
configureEnvironment();
|
|
25150
|
+
try {
|
|
25151
|
+
const { ServiceInstaller: ServiceInstaller2 } = await Promise.resolve().then(() => (init_service_installer(), service_installer_exports));
|
|
25152
|
+
await ServiceInstaller2.autoUpdate();
|
|
25153
|
+
} catch {
|
|
25154
|
+
}
|
|
25048
25155
|
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");
|
|
25049
25156
|
setupGlobalOptions(program);
|
|
25050
25157
|
const isVerbose = process.argv.includes("--verbose") || process.argv.includes("-v");
|