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 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 __dirname = 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))));
347
- let servicesPath = path3__namespace.join(__dirname, "..", "..", "templates", "services");
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(__dirname, "..", "templates", "services");
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
- console.log(`\u2713 Services installed to: ${this.SERVICES_DIR}`);
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 packageJson = JSON.parse(content);
921
- return packageJson.junoCode || {};
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(`JSON streaming parse error: ${error instanceof Error ? error.message : String(error)}`);
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 JSON streaming events from script output
6678
- * Handles both generic StreamingEvent format and Claude CLI specific format
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
- this.emitProgressEvent(progressEvent).catch((error) => {
6712
- if (this.config?.debug) {
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 thinking event: ${error2 instanceof Error ? error2.message : String(error2)}`);
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 __filename = 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)));
15708
- const __dirname = path3__namespace.dirname(__filename);
15709
- process.env.JUNO_TASK_MCP_SERVER_PATH || path3__namespace.join(__dirname, "../../../roundtable_mcp_server/roundtable_mcp_server/server.py");
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 __filename = 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)));
15776
- const __dirname = path3__namespace.dirname(__filename);
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 (__dirname.includes("/dist/bin") || __dirname.includes("\\dist\\bin")) {
15779
- templatesScriptsDir = path3__namespace.join(__dirname, "../templates/scripts");
15780
- } else if (__dirname.includes("/src/cli/commands") || __dirname.includes("\\src\\cli\\commands")) {
15781
- templatesScriptsDir = path3__namespace.join(__dirname, "../../templates/scripts");
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(__dirname, "../../templates/scripts");
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 dirname11 = path3__namespace.dirname(filePath);
19472
- backupPath = path3__namespace.join(dirname11, `${basename11}.backup.${timestamp}${ext}`);
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 VERSION = "1.0.0";
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");