juno-code 1.0.33 → 1.0.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/cli.js CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  var fs2 = require('fs-extra');
5
5
  var path3 = require('path');
6
- var os3 = require('os');
6
+ var os4 = require('os');
7
7
  var url = require('url');
8
8
  var module$1 = require('module');
9
9
  var semver = require('semver');
@@ -54,7 +54,7 @@ function _interopNamespace(e) {
54
54
 
55
55
  var fs2__default = /*#__PURE__*/_interopDefault(fs2);
56
56
  var path3__namespace = /*#__PURE__*/_interopNamespace(path3);
57
- var os3__namespace = /*#__PURE__*/_interopNamespace(os3);
57
+ var os4__namespace = /*#__PURE__*/_interopNamespace(os4);
58
58
  var semver__default = /*#__PURE__*/_interopDefault(semver);
59
59
  var nodeFs__namespace = /*#__PURE__*/_interopNamespace(nodeFs);
60
60
  var yaml__namespace = /*#__PURE__*/_interopNamespace(yaml);
@@ -341,8 +341,8 @@ var init_service_installer = __esm({
341
341
  "src/utils/service-installer.ts"() {
342
342
  init_version();
343
343
  ServiceInstaller = class {
344
- static SERVICES_DIR = path3__namespace.join(os3.homedir(), ".juno_code", "services");
345
- static VERSION_FILE = path3__namespace.join(os3.homedir(), ".juno_code", "services", ".version");
344
+ static SERVICES_DIR = path3__namespace.join(os4.homedir(), ".juno_code", "services");
345
+ static VERSION_FILE = path3__namespace.join(os4.homedir(), ".juno_code", "services", ".version");
346
346
  /**
347
347
  * Get the current package version
348
348
  */
@@ -3331,13 +3331,9 @@ var init_advanced_logger = __esm({
3331
3331
  /**
3332
3332
  * Output formatted log
3333
3333
  */
3334
- output(formatted, level) {
3334
+ output(formatted, _level) {
3335
3335
  if (this.options.output === "console" || this.options.output === "both") {
3336
- if (level >= 3 /* WARN */) {
3337
- console.error(formatted);
3338
- } else {
3339
- console.log(formatted);
3340
- }
3336
+ console.error(formatted);
3341
3337
  }
3342
3338
  if (this.options.output === "file" || this.options.output === "both") {
3343
3339
  this.writeToFile(formatted);
@@ -5415,8 +5411,8 @@ var init_terminal_progress_writer = __esm({
5415
5411
  this.options.stream.write("\r\x1B[K");
5416
5412
  if (typeof content === "string") {
5417
5413
  this.options.stream.write(content);
5418
- if (!content.endsWith("\n") && !content.endsWith(os3.EOL)) {
5419
- this.options.stream.write(os3.EOL);
5414
+ if (!content.endsWith("\n") && !content.endsWith(os4.EOL)) {
5415
+ this.options.stream.write(os4.EOL);
5420
5416
  }
5421
5417
  } else {
5422
5418
  console.error(content);
@@ -5424,8 +5420,8 @@ var init_terminal_progress_writer = __esm({
5424
5420
  } else {
5425
5421
  if (typeof content === "string") {
5426
5422
  this.options.stream.write(content);
5427
- if (!content.endsWith("\n") && !content.endsWith(os3.EOL)) {
5428
- this.options.stream.write(os3.EOL);
5423
+ if (!content.endsWith("\n") && !content.endsWith(os4.EOL)) {
5424
+ this.options.stream.write(os4.EOL);
5429
5425
  }
5430
5426
  } else {
5431
5427
  console.error(content);
@@ -6033,7 +6029,7 @@ var init_client = __esm({
6033
6029
  `${serverName}`,
6034
6030
  // Assume it's in PATH
6035
6031
  `/usr/local/bin/${serverName}`,
6036
- path3__namespace.default.resolve(os3__namespace.default.homedir(), `.local/bin/${serverName}`),
6032
+ path3__namespace.default.resolve(os4__namespace.default.homedir(), `.local/bin/${serverName}`),
6037
6033
  path3__namespace.default.resolve(this.options.workingDirectory || process.cwd(), `${serverName}`)
6038
6034
  ];
6039
6035
  for (const serverPath of possiblePaths) {
@@ -7042,7 +7038,7 @@ var init_shell_backend = __esm({
7042
7038
  });
7043
7039
  try {
7044
7040
  const scriptPath = await this.findScriptForSubagent(subagentType);
7045
- const result = await this.executeScript(scriptPath, request, toolId);
7041
+ const result = await this.executeScript(scriptPath, request, toolId, subagentType);
7046
7042
  const duration = Date.now() - startTime;
7047
7043
  await this.emitProgressEvent({
7048
7044
  sessionId: request.metadata?.sessionId || "unknown",
@@ -7059,8 +7055,9 @@ var init_shell_backend = __esm({
7059
7055
  phase: "completion"
7060
7056
  }
7061
7057
  });
7058
+ const structuredResult = this.buildStructuredOutput(subagentType, result);
7062
7059
  return {
7063
- content: result.output,
7060
+ content: structuredResult.content,
7064
7061
  status: result.success ? "completed" : "failed",
7065
7062
  startTime: new Date(startTime),
7066
7063
  endTime: /* @__PURE__ */ new Date(),
@@ -7068,6 +7065,7 @@ var init_shell_backend = __esm({
7068
7065
  error: result.error ? { type: "shell_execution", message: result.error, timestamp: /* @__PURE__ */ new Date() } : void 0,
7069
7066
  progressEvents: [],
7070
7067
  // Progress events are handled via callbacks
7068
+ ...structuredResult.metadata ? { metadata: structuredResult.metadata } : void 0,
7071
7069
  request
7072
7070
  };
7073
7071
  } catch (error) {
@@ -7233,8 +7231,8 @@ var init_shell_backend = __esm({
7233
7231
  /**
7234
7232
  * Execute a shell script
7235
7233
  */
7236
- async executeScript(scriptPath, request, toolId) {
7237
- return new Promise((resolve9, reject) => {
7234
+ async executeScript(scriptPath, request, toolId, subagentType) {
7235
+ return new Promise(async (resolve9, reject) => {
7238
7236
  const startTime = Date.now();
7239
7237
  const isPython = scriptPath.endsWith(".py");
7240
7238
  const env2 = {
@@ -7247,6 +7245,19 @@ var init_shell_backend = __esm({
7247
7245
  JUNO_ITERATION: String(request.arguments?.iteration || 1),
7248
7246
  JUNO_TOOL_ID: toolId
7249
7247
  };
7248
+ let captureDir = null;
7249
+ let capturePath = null;
7250
+ if (subagentType === "claude") {
7251
+ try {
7252
+ captureDir = await nodeFs.promises.mkdtemp(path3__namespace.join(os4__namespace.default.tmpdir(), "juno-shell-"));
7253
+ capturePath = path3__namespace.join(captureDir, `subagent_${toolId}.json`);
7254
+ env2.JUNO_SUBAGENT_CAPTURE_PATH = capturePath;
7255
+ } catch (error) {
7256
+ if (this.config?.debug) {
7257
+ engineLogger.warn(`Failed to prepare subagent capture path: ${error instanceof Error ? error.message : String(error)}`);
7258
+ }
7259
+ }
7260
+ }
7250
7261
  const command = isPython ? "python3" : "bash";
7251
7262
  const args = [scriptPath];
7252
7263
  if (isPython && request.arguments?.instruction) {
@@ -7321,20 +7332,46 @@ var init_shell_backend = __esm({
7321
7332
  }
7322
7333
  });
7323
7334
  child.on("close", (exitCode) => {
7324
- if (isProcessKilled) return;
7325
- const duration = Date.now() - startTime;
7326
- const success = exitCode === 0;
7327
- if (this.config.debug) {
7328
- engineLogger.debug(`Script execution completed with exit code: ${exitCode}, duration: ${duration}ms`);
7329
- engineLogger.debug(`Stdout length: ${stdout2.length}, Stderr length: ${stderr.length}`);
7330
- }
7331
- resolve9({
7332
- success,
7333
- output: stdout2,
7334
- error: stderr || void 0,
7335
- exitCode: exitCode || 0,
7336
- duration
7337
- });
7335
+ void (async () => {
7336
+ if (isProcessKilled) return;
7337
+ const duration = Date.now() - startTime;
7338
+ const success = exitCode === 0;
7339
+ let subAgentResponse;
7340
+ if (capturePath) {
7341
+ try {
7342
+ const captured = await nodeFs.promises.readFile(capturePath, "utf-8");
7343
+ if (captured.trim()) {
7344
+ subAgentResponse = JSON.parse(captured);
7345
+ }
7346
+ } catch (error) {
7347
+ if (this.config?.debug) {
7348
+ engineLogger.warn(`Failed to read subagent capture: ${error instanceof Error ? error.message : String(error)}`);
7349
+ }
7350
+ } finally {
7351
+ if (captureDir) {
7352
+ try {
7353
+ await nodeFs.promises.rm(captureDir, { recursive: true, force: true });
7354
+ } catch (cleanupError) {
7355
+ if (this.config?.debug) {
7356
+ engineLogger.warn(`Failed to clean capture directory: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`);
7357
+ }
7358
+ }
7359
+ }
7360
+ }
7361
+ }
7362
+ if (this.config.debug) {
7363
+ engineLogger.debug(`Script execution completed with exit code: ${exitCode}, duration: ${duration}ms`);
7364
+ engineLogger.debug(`Stdout length: ${stdout2.length}, Stderr length: ${stderr.length}`);
7365
+ }
7366
+ resolve9({
7367
+ success,
7368
+ output: stdout2,
7369
+ error: stderr || void 0,
7370
+ exitCode: exitCode || 0,
7371
+ duration,
7372
+ ...subAgentResponse ? { subAgentResponse } : void 0
7373
+ });
7374
+ })();
7338
7375
  });
7339
7376
  child.on("error", (error) => {
7340
7377
  if (isProcessKilled) return;
@@ -7366,6 +7403,66 @@ var init_shell_backend = __esm({
7366
7403
  });
7367
7404
  });
7368
7405
  }
7406
+ /**
7407
+ * Build a structured, JSON-parsable result payload for programmatic capture while
7408
+ * preserving the shell backend's existing on-screen streaming behavior.
7409
+ */
7410
+ buildStructuredOutput(subagentType, result) {
7411
+ if (subagentType === "claude") {
7412
+ const claudeEvent = result.subAgentResponse ?? this.extractLastJsonEvent(result.output);
7413
+ const isError = claudeEvent?.is_error ?? claudeEvent?.subtype === "error" ?? !result.success;
7414
+ const structuredPayload = {
7415
+ type: "result",
7416
+ subtype: claudeEvent?.subtype || (isError ? "error" : "success"),
7417
+ is_error: isError,
7418
+ result: claudeEvent?.result ?? claudeEvent?.error ?? claudeEvent?.content ?? result.output,
7419
+ error: claudeEvent?.error,
7420
+ stderr: result.error,
7421
+ datetime: claudeEvent?.datetime,
7422
+ counter: claudeEvent?.counter,
7423
+ session_id: claudeEvent?.session_id,
7424
+ num_turns: claudeEvent?.num_turns,
7425
+ duration_ms: claudeEvent?.duration_ms ?? result.duration,
7426
+ exit_code: result.exitCode,
7427
+ total_cost_usd: claudeEvent?.total_cost_usd,
7428
+ usage: claudeEvent?.usage,
7429
+ modelUsage: claudeEvent?.modelUsage || claudeEvent?.model_usage || {},
7430
+ permission_denials: claudeEvent?.permission_denials || [],
7431
+ uuid: claudeEvent?.uuid,
7432
+ sub_agent_response: claudeEvent
7433
+ };
7434
+ const metadata = {
7435
+ ...claudeEvent ? { subAgentResponse: claudeEvent } : void 0,
7436
+ structuredOutput: true,
7437
+ contentType: "application/json",
7438
+ rawOutput: result.output
7439
+ };
7440
+ return {
7441
+ content: JSON.stringify(structuredPayload),
7442
+ metadata
7443
+ };
7444
+ }
7445
+ return { content: result.output, metadata: result.metadata };
7446
+ }
7447
+ /**
7448
+ * Extract the last valid JSON object from a script's stdout to use as a structured payload fallback.
7449
+ */
7450
+ extractLastJsonEvent(output) {
7451
+ if (!output) {
7452
+ return null;
7453
+ }
7454
+ const lines = output.split("\n").map((line) => line.trim()).filter(Boolean);
7455
+ for (let i = lines.length - 1; i >= 0; i--) {
7456
+ try {
7457
+ const parsed = JSON.parse(lines[i]);
7458
+ if (parsed && typeof parsed === "object") {
7459
+ return parsed;
7460
+ }
7461
+ } catch {
7462
+ }
7463
+ }
7464
+ return null;
7465
+ }
7369
7466
  /**
7370
7467
  * Parse streaming events from script output
7371
7468
  * Handles both JSON format (Claude) and TEXT format (Codex)
@@ -7890,7 +7987,7 @@ var init_concurrent_feedback_collector = __esm({
7890
7987
  process.stdin.removeAllListeners("data");
7891
7988
  process.stdin.removeAllListeners("end");
7892
7989
  if (this.options.verbose) {
7893
- process.stderr.write(`${os3.EOL}[feedback-collector] Stopped. Total submissions: ${this.submissionCount}${os3.EOL}`);
7990
+ process.stderr.write(`${os4.EOL}[feedback-collector] Stopped. Total submissions: ${this.submissionCount}${os4.EOL}`);
7894
7991
  }
7895
7992
  }
7896
7993
  /**
@@ -7953,7 +8050,7 @@ var init_concurrent_feedback_collector = __esm({
7953
8050
  chalk15__default.default.blue.bold("\u2551") + chalk15__default.default.gray(" Exit: Press Ctrl-D (or Ctrl-Z on Windows)") + " ".repeat(16) + chalk15__default.default.blue.bold("\u2551"),
7954
8051
  chalk15__default.default.blue.bold("\u255A" + border + "\u255D"),
7955
8052
  chalk15__default.default.cyan.bold("> ") + chalk15__default.default.gray("(Type F+Enter to start giving feedback)")
7956
- ].join(os3.EOL) + os3.EOL
8053
+ ].join(os4.EOL) + os4.EOL
7957
8054
  );
7958
8055
  }
7959
8056
  /**
@@ -7963,7 +8060,7 @@ var init_concurrent_feedback_collector = __esm({
7963
8060
  this.progressTimer = setInterval(() => {
7964
8061
  this.progressTick += 1;
7965
8062
  const elapsed = ((Date.now() - this.startTime.getTime()) / 1e3).toFixed(1);
7966
- process.stderr.write(`[progress] tick=${this.progressTick} elapsed=${elapsed}s${os3.EOL}`);
8063
+ process.stderr.write(`[progress] tick=${this.progressTick} elapsed=${elapsed}s${os4.EOL}`);
7967
8064
  }, this.options.progressInterval);
7968
8065
  }
7969
8066
  /**
@@ -7973,10 +8070,10 @@ var init_concurrent_feedback_collector = __esm({
7973
8070
  this.feedbackMode = "feedback" /* FEEDBACK */;
7974
8071
  setFeedbackActive(true);
7975
8072
  this.buffer = "";
7976
- process.stdout.write(os3.EOL + chalk15__default.default.yellow.bold("\u{1F4DD} FEEDBACK MODE") + chalk15__default.default.gray(" - Type feedback (multiline ok), then Q+Enter to submit | MCP progress paused") + os3.EOL);
8073
+ process.stdout.write(os4.EOL + chalk15__default.default.yellow.bold("\u{1F4DD} FEEDBACK MODE") + chalk15__default.default.gray(" - Type feedback (multiline ok), then Q+Enter to submit | MCP progress paused") + os4.EOL);
7977
8074
  process.stdout.write(chalk15__default.default.cyan.bold("> "));
7978
8075
  if (this.options.verbose) {
7979
- process.stderr.write(`[feedback-collector] Entered FEEDBACK mode - MCP progress buffering activated${os3.EOL}`);
8076
+ process.stderr.write(`[feedback-collector] Entered FEEDBACK mode - MCP progress buffering activated${os4.EOL}`);
7980
8077
  }
7981
8078
  }
7982
8079
  /**
@@ -7986,7 +8083,7 @@ var init_concurrent_feedback_collector = __esm({
7986
8083
  this.feedbackMode = "normal" /* NORMAL */;
7987
8084
  setFeedbackActive(false);
7988
8085
  if (this.options.verbose) {
7989
- process.stderr.write(`[feedback-collector] Exited FEEDBACK mode - MCP progress restored${os3.EOL}`);
8086
+ process.stderr.write(`[feedback-collector] Exited FEEDBACK mode - MCP progress restored${os4.EOL}`);
7990
8087
  }
7991
8088
  }
7992
8089
  /**
@@ -8029,7 +8126,7 @@ var init_concurrent_feedback_collector = __esm({
8029
8126
  clearInterval(this.progressTimer);
8030
8127
  }
8031
8128
  if (this.options.verbose) {
8032
- process.stderr.write(`${os3.EOL}[feedback-collector] EOF received. Total submissions: ${this.submissionCount}${os3.EOL}`);
8129
+ process.stderr.write(`${os4.EOL}[feedback-collector] EOF received. Total submissions: ${this.submissionCount}${os4.EOL}`);
8033
8130
  }
8034
8131
  });
8035
8132
  }
@@ -8044,7 +8141,7 @@ var init_concurrent_feedback_collector = __esm({
8044
8141
  return;
8045
8142
  }
8046
8143
  if (trimmed.length > 0) {
8047
- process.stdout.write(chalk15__default.default.gray("Type F+Enter to enter feedback mode, or Ctrl-D to exit") + os3.EOL);
8144
+ process.stdout.write(chalk15__default.default.gray("Type F+Enter to enter feedback mode, or Ctrl-D to exit") + os4.EOL);
8048
8145
  process.stdout.write(chalk15__default.default.cyan.bold("> "));
8049
8146
  }
8050
8147
  return;
@@ -8053,10 +8150,10 @@ var init_concurrent_feedback_collector = __esm({
8053
8150
  if (trimmed === "q") {
8054
8151
  this.submitFeedback();
8055
8152
  this.exitFeedbackMode();
8056
- process.stdout.write(os3.EOL + chalk15__default.default.cyan.bold("> ") + chalk15__default.default.gray("(Type F+Enter for another feedback, or Ctrl-D to exit)") + os3.EOL);
8153
+ process.stdout.write(os4.EOL + chalk15__default.default.cyan.bold("> ") + chalk15__default.default.gray("(Type F+Enter for another feedback, or Ctrl-D to exit)") + os4.EOL);
8057
8154
  return;
8058
8155
  }
8059
- this.buffer += line + os3.EOL;
8156
+ this.buffer += line + os4.EOL;
8060
8157
  }
8061
8158
  }
8062
8159
  /**
@@ -8066,18 +8163,18 @@ var init_concurrent_feedback_collector = __esm({
8066
8163
  const content = this.buffer.trimEnd();
8067
8164
  this.buffer = "";
8068
8165
  if (content.length === 0) {
8069
- process.stdout.write(os3.EOL + chalk15__default.default.yellow("\u26A0\uFE0F No feedback content to submit") + os3.EOL);
8166
+ process.stdout.write(os4.EOL + chalk15__default.default.yellow("\u26A0\uFE0F No feedback content to submit") + os4.EOL);
8070
8167
  return;
8071
8168
  }
8072
- process.stdout.write(os3.EOL + chalk15__default.default.green.bold("\u2705 Feedback registered and being processed...") + os3.EOL);
8169
+ process.stdout.write(os4.EOL + chalk15__default.default.green.bold("\u2705 Feedback registered and being processed...") + os4.EOL);
8073
8170
  if (this.options.verbose) {
8074
- process.stdout.write(chalk15__default.default.gray("Feedback content:") + os3.EOL);
8075
- process.stdout.write(content + os3.EOL);
8076
- process.stdout.write(chalk15__default.default.cyan("===== END BLOCK =====") + os3.EOL);
8171
+ process.stdout.write(chalk15__default.default.gray("Feedback content:") + os4.EOL);
8172
+ process.stdout.write(content + os4.EOL);
8173
+ process.stdout.write(chalk15__default.default.cyan("===== END BLOCK =====") + os4.EOL);
8077
8174
  }
8078
8175
  flushBufferedProgress();
8079
8176
  this.enqueueSubmission(content).catch((err) => {
8080
- process.stderr.write(`${os3.EOL}[feedback-collector] Error submitting feedback: ${err}${os3.EOL}`);
8177
+ process.stderr.write(`${os4.EOL}[feedback-collector] Error submitting feedback: ${err}${os4.EOL}`);
8081
8178
  });
8082
8179
  }
8083
8180
  /**
@@ -8103,18 +8200,18 @@ var init_concurrent_feedback_collector = __esm({
8103
8200
  this.submissions.push(submission);
8104
8201
  if (this.options.onSubmit) {
8105
8202
  if (this.options.verbose) {
8106
- process.stderr.write(`${os3.EOL}[feedback-collector ${n}] Using custom submission handler${os3.EOL}`);
8203
+ process.stderr.write(`${os4.EOL}[feedback-collector ${n}] Using custom submission handler${os4.EOL}`);
8107
8204
  }
8108
8205
  try {
8109
8206
  await this.options.onSubmit(input);
8110
8207
  if (this.options.verbose) {
8111
- process.stderr.write(`[feedback-collector ${n}] Custom handler completed${os3.EOL}`);
8208
+ process.stderr.write(`[feedback-collector ${n}] Custom handler completed${os4.EOL}`);
8112
8209
  }
8113
- process.stdout.write(os3.EOL + chalk15__default.default.green("\u2705 Feedback submitted successfully. You can type another block.") + os3.EOL);
8114
- process.stdout.write(os3.EOL + chalk15__default.default.cyan.bold("> ") + chalk15__default.default.gray("(Ready for next feedback)") + os3.EOL);
8210
+ process.stdout.write(os4.EOL + chalk15__default.default.green("\u2705 Feedback submitted successfully. You can type another block.") + os4.EOL);
8211
+ process.stdout.write(os4.EOL + chalk15__default.default.cyan.bold("> ") + chalk15__default.default.gray("(Ready for next feedback)") + os4.EOL);
8115
8212
  } catch (error) {
8116
- process.stderr.write(`[feedback-collector ${n}] Custom handler error: ${error}${os3.EOL}`);
8117
- process.stdout.write(os3.EOL + chalk15__default.default.red("\u274C Feedback submission failed. Please try again.") + os3.EOL);
8213
+ process.stderr.write(`[feedback-collector ${n}] Custom handler error: ${error}${os4.EOL}`);
8214
+ process.stdout.write(os4.EOL + chalk15__default.default.red("\u274C Feedback submission failed. Please try again.") + os4.EOL);
8118
8215
  }
8119
8216
  } else {
8120
8217
  await this.runCommandWithInput(n, input);
@@ -8125,7 +8222,7 @@ var init_concurrent_feedback_collector = __esm({
8125
8222
  */
8126
8223
  async runCommandWithInput(n, input) {
8127
8224
  if (this.options.verbose) {
8128
- process.stderr.write(`${os3.EOL}[feedback-collector ${n}] Launching "${this.options.command}" ${this.options.commandArgs.join(" ")}${os3.EOL}`);
8225
+ process.stderr.write(`${os4.EOL}[feedback-collector ${n}] Launching "${this.options.command}" ${this.options.commandArgs.join(" ")}${os4.EOL}`);
8129
8226
  }
8130
8227
  return new Promise((resolve9) => {
8131
8228
  const child = child_process.spawn(this.options.command, this.options.commandArgs, {
@@ -8143,25 +8240,25 @@ var init_concurrent_feedback_collector = __esm({
8143
8240
  });
8144
8241
  child.on("close", (code) => {
8145
8242
  if (this.options.verbose) {
8146
- process.stderr.write(`[feedback-collector ${n}] exit code ${code ?? 0}${os3.EOL}`);
8243
+ process.stderr.write(`[feedback-collector ${n}] exit code ${code ?? 0}${os4.EOL}`);
8147
8244
  }
8148
8245
  if (code === 0) {
8149
- process.stdout.write(os3.EOL + chalk15__default.default.green("\u2705 Feedback submitted successfully. You can type another block.") + os3.EOL);
8150
- process.stdout.write(os3.EOL + chalk15__default.default.cyan.bold("> ") + chalk15__default.default.gray("(Ready for next feedback)") + os3.EOL);
8246
+ process.stdout.write(os4.EOL + chalk15__default.default.green("\u2705 Feedback submitted successfully. You can type another block.") + os4.EOL);
8247
+ process.stdout.write(os4.EOL + chalk15__default.default.cyan.bold("> ") + chalk15__default.default.gray("(Ready for next feedback)") + os4.EOL);
8151
8248
  } else {
8152
- process.stdout.write(os3.EOL + chalk15__default.default.red("\u274C Feedback submission failed. Please try again.") + os3.EOL);
8249
+ process.stdout.write(os4.EOL + chalk15__default.default.red("\u274C Feedback submission failed. Please try again.") + os4.EOL);
8153
8250
  }
8154
8251
  resolve9();
8155
8252
  });
8156
8253
  child.on("error", (err) => {
8157
- process.stderr.write(`[feedback-collector ${n}] error: ${err.message}${os3.EOL}`);
8158
- process.stdout.write(os3.EOL + chalk15__default.default.red("\u274C Feedback submission failed. Please try again.") + os3.EOL);
8254
+ process.stderr.write(`[feedback-collector ${n}] error: ${err.message}${os4.EOL}`);
8255
+ process.stdout.write(os4.EOL + chalk15__default.default.red("\u274C Feedback submission failed. Please try again.") + os4.EOL);
8159
8256
  resolve9();
8160
8257
  });
8161
8258
  if (child.stdin) {
8162
8259
  child.stdin.write(input);
8163
- if (!input.endsWith(os3.EOL)) {
8164
- child.stdin.write(os3.EOL);
8260
+ if (!input.endsWith(os4.EOL)) {
8261
+ child.stdin.write(os4.EOL);
8165
8262
  }
8166
8263
  child.stdin.end();
8167
8264
  }
@@ -13105,7 +13202,11 @@ var init_main = __esm({
13105
13202
  \u274C Execution failed (${elapsed})`));
13106
13203
  }
13107
13204
  const lastIteration = result.iterations[result.iterations.length - 1];
13108
- if (lastIteration && lastIteration.toolResult.content && !this.hasStreamedJsonOutput) {
13205
+ const structuredOutput = lastIteration?.toolResult.metadata?.structuredOutput === true;
13206
+ const shouldPrintResult = Boolean(
13207
+ lastIteration && lastIteration.toolResult.content && (!this.hasStreamedJsonOutput || structuredOutput)
13208
+ );
13209
+ if (shouldPrintResult) {
13109
13210
  console.error(chalk15__default.default.blue("\n\u{1F4C4} Result:"));
13110
13211
  console.log(lastIteration.toolResult.content);
13111
13212
  }
@@ -13443,7 +13544,7 @@ async function validateJSONConfigs(baseDir = process.cwd(), backendType = "mcp")
13443
13544
  }
13444
13545
  function displayValidationResults(result) {
13445
13546
  if (result.isValid && result.warnings.length === 0) {
13446
- console.log(chalk15__default.default.green("\u2705 All configuration files are valid\n"));
13547
+ console.error(chalk15__default.default.green("\u2705 All configuration files are valid\n"));
13447
13548
  return;
13448
13549
  }
13449
13550
  if (result.errors.length > 0) {
@@ -21869,6 +21970,11 @@ var QUICK_REFERENCE = [
21869
21970
  description: "Shell completion setup",
21870
21971
  usage: "juno-code completion <install|uninstall>"
21871
21972
  },
21973
+ {
21974
+ name: "services",
21975
+ description: "Manage service scripts (use --force to refresh codex.py/claude.py)",
21976
+ usage: "juno-code services install --force"
21977
+ },
21872
21978
  {
21873
21979
  name: "help",
21874
21980
  description: "Show help information",
@@ -22437,11 +22543,12 @@ init_service_installer();
22437
22543
  function createServicesCommand() {
22438
22544
  const servicesCmd = new commander.Command("services").description("Manage juno-code service scripts").addHelpText("after", `
22439
22545
  Examples:
22440
- $ juno-code services install Install service scripts to ~/.juno_code/services/
22441
- $ juno-code services list List installed service scripts
22442
- $ juno-code services status Check installation status
22443
- $ juno-code services uninstall Remove all service scripts
22444
- $ juno-code services path Show services directory path
22546
+ $ juno-code services install Install service scripts to ~/.juno_code/services/
22547
+ $ juno-code services install --force Reinstall/refresh service scripts (codex.py/claude.py)
22548
+ $ juno-code services list List installed service scripts
22549
+ $ juno-code services status Check installation status
22550
+ $ juno-code services uninstall Remove all service scripts
22551
+ $ juno-code services path Show services directory path
22445
22552
 
22446
22553
  Service scripts are Python/shell scripts that provide additional functionality
22447
22554
  and can be customized by users. They are installed to ~/.juno_code/services/
@@ -22615,7 +22722,7 @@ var ShellDetector = class _ShellDetector {
22615
22722
  * Get shell configuration file path
22616
22723
  */
22617
22724
  getConfigPath(shell) {
22618
- const homeDir = os3__namespace.homedir();
22725
+ const homeDir = os4__namespace.homedir();
22619
22726
  switch (shell) {
22620
22727
  case "bash":
22621
22728
  if (process.platform === "darwin") {
@@ -22639,7 +22746,7 @@ var ShellDetector = class _ShellDetector {
22639
22746
  * Get shell completion script installation path
22640
22747
  */
22641
22748
  getCompletionPath(shell) {
22642
- const homeDir = os3__namespace.homedir();
22749
+ const homeDir = os4__namespace.homedir();
22643
22750
  switch (shell) {
22644
22751
  case "bash":
22645
22752
  if (process.platform === "darwin") {
@@ -22917,7 +23024,7 @@ var ContextAwareCompletion = class {
22917
23024
  */
22918
23025
  expandPath(inputPath) {
22919
23026
  if (inputPath.startsWith("~/")) {
22920
- return path3__namespace.join(os3__namespace.homedir(), inputPath.slice(2));
23027
+ return path3__namespace.join(os4__namespace.homedir(), inputPath.slice(2));
22921
23028
  }
22922
23029
  if (inputPath.startsWith("./") || inputPath.startsWith("../")) {
22923
23030
  return path3__namespace.resolve(inputPath);