juno-code 1.0.10 → 1.0.13

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/bin/feedback-collector.ts"],"names":["EOL","spawn"],"mappings":"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","file":"feedback-collector.js","sourcesContent":["/**\n * Concurrent Feedback Collector\n *\n * Minimal multi-submit feedback collector that runs concurrently with ongoing processes.\n * - Type/paste feedback (multiline)\n * - Press Enter on a BLANK line to SUBMIT that block\n * - The feedback block is sent to feedback command via stdin for each submission\n * - Multiple blocks allowed; exit with EOF (Ctrl-D / Ctrl-Z then Enter) or Ctrl-C\n * - Progress logs go to stderr; UI/instructions to stdout\n * - NO TTY/Raw mode - simple line-based stdin for AI agent compatibility\n *\n * Usage:\n * juno-collect-feedback <command> [arg1 arg2 ...]\n * Example:\n * juno-collect-feedback node dist/bin/cli.mjs feedback\n * juno-collect-feedback juno-ts-task feedback\n *\n * OR run standalone:\n * node dist/bin/feedback-collector.mjs\n */\n\nimport { spawn } from 'node:child_process';\nimport { EOL } from 'node:os';\n\n// Enable UTF-8 encoding for stdin\nprocess.stdin.setEncoding('utf8');\n\n// --- Parse command to run per submission ---\nconst [, , ...argv] = process.argv;\nconst cmd = argv.length > 0 ? argv[0] : 'node';\nconst cmdArgs = argv.length > 0 ? argv.slice(1) : ['dist/bin/cli.mjs', 'feedback'];\n\n// --- Progress ticker (simulates concurrent progress) ---\nlet tick = 0;\nconst start = Date.now();\nconst logTimer = setInterval(() => {\n tick += 1;\n const elapsed = ((Date.now() - start) / 1000).toFixed(1);\n process.stderr.write(`[progress] step=${tick} elapsed=${elapsed}s${EOL}`);\n}, 1200);\n\n// --- UI header ---\nfunction printHeader(): void {\n process.stdout.write(\n [\n '',\n '📝 Concurrent Feedback Collector',\n ' Type or paste your feedback. Submit by pressing Enter on an EMPTY line.',\n ' (EOF ends the session: Ctrl-D on macOS/Linux; Ctrl-Z then Enter on Windows.)',\n ''\n ].join(EOL) + EOL\n );\n}\nprintHeader();\n\n// --- Submission queue to keep commands sequential ---\nlet pending = Promise.resolve();\nlet submissionCount = 0;\n\n/**\n * Run feedback command with the collected input\n */\nfunction runCommandWithInput(input: string): Promise<number> {\n submissionCount += 1;\n const n = submissionCount;\n process.stderr.write(`${EOL}[submit ${n}] launching \"${cmd}\" ${cmdArgs.join(' ')}${EOL}`);\n\n return new Promise((resolve) => {\n const child = spawn(cmd, cmdArgs, { stdio: ['pipe', 'pipe', 'pipe'] });\n\n // Pipe child's output to stderr (treat as logs)\n child.stdout?.on('data', (d) => process.stderr.write(`[submit ${n}] stdout: ${d}`));\n child.stderr?.on('data', (d) => process.stderr.write(`[submit ${n}] stderr: ${d}`));\n\n child.on('close', (code) => {\n process.stderr.write(`[submit ${n}] exit code ${code ?? 0}${EOL}`);\n resolve(code ?? 0);\n });\n\n child.on('error', (err) => {\n process.stderr.write(`[submit ${n}] error: ${err.message}${EOL}`);\n resolve(1);\n });\n\n // Write the feedback block to child stdin\n if (child.stdin) {\n child.stdin.write(input);\n if (!input.endsWith(EOL)) {\n child.stdin.write(EOL);\n }\n child.stdin.end();\n }\n });\n}\n\n/**\n * Enqueue submission to ensure strict sequential order\n */\nfunction enqueueSubmission(input: string): Promise<void> {\n // Ensure strict order by chaining onto `pending`\n pending = pending.then(() => runCommandWithInput(input).then(() => {}));\n return pending;\n}\n\n// --- Input handling: multiline buffer; blank line => submit ---\nlet carry = '';\nlet buffer = ''; // current feedback block\nlet lastLineWasBlank = false;\n\n/**\n * Submit the current buffer if it has content\n */\nfunction submitBufferIfAny(): void {\n const content = buffer.trimEnd();\n buffer = ''; // \"clean stdin\" buffer for the next round\n\n if (content.length === 0) {\n return;\n }\n\n process.stdout.write(EOL + '===== SUBMITTING FEEDBACK BLOCK =====' + EOL);\n process.stdout.write(content + EOL);\n process.stdout.write('===== END BLOCK =====' + EOL);\n\n enqueueSubmission(content).then(() => {\n // After the command finishes (still sequential), re-prompt\n process.stdout.write(EOL + '✅ Submission processed. You can type another block.' + EOL);\n }).catch((err) => {\n process.stderr.write(`Error submitting feedback: ${err}${EOL}`);\n });\n}\n\n// Handle stdin data events\nprocess.stdin.on('data', (chunk: string) => {\n carry += chunk;\n\n // Split into complete lines, keep the last partial in carry\n const parts = carry.split(/\\r?\\n/);\n carry = parts.pop() ?? '';\n\n for (const line of parts) {\n const isBlank = line.trim().length === 0;\n\n if (isBlank && !lastLineWasBlank) {\n // A single blank line means \"submit this block\"\n submitBufferIfAny();\n lastLineWasBlank = true;\n continue;\n }\n\n if (!isBlank) {\n // Any non-blank line is part of the current block\n buffer += line + EOL;\n lastLineWasBlank = false;\n } else {\n // Consecutive blank lines: ignore (prevent accidental multiple submits)\n lastLineWasBlank = true;\n }\n }\n});\n\n// Handle stdin end event (EOF)\nprocess.stdin.on('end', async () => {\n // If there is remaining partial data, treat as part of the last block\n if (carry.length) {\n buffer += carry;\n }\n\n submitBufferIfAny();\n await pending; // wait for in-flight submissions\n\n clearInterval(logTimer);\n process.stderr.write(`${EOL}[progress] done. submissions=${submissionCount}${EOL}`);\n process.exit(0);\n});\n\n// Handle SIGINT (Ctrl+C)\nprocess.on('SIGINT', async () => {\n process.stderr.write(`${EOL}[progress] SIGINT received. Finalizing…${EOL}`);\n\n submitBufferIfAny();\n await pending;\n\n clearInterval(logTimer);\n process.stderr.write(`[progress] done. submissions=${submissionCount}${EOL}`);\n process.exit(0);\n});\n\n// Handle uncaught errors\nprocess.on('uncaughtException', (err) => {\n process.stderr.write(`${EOL}[error] Uncaught exception: ${err.message}${EOL}`);\n clearInterval(logTimer);\n process.exit(1);\n});\n\nprocess.on('unhandledRejection', (reason) => {\n process.stderr.write(`${EOL}[error] Unhandled rejection: ${reason}${EOL}`);\n clearInterval(logTimer);\n process.exit(1);\n});\n"]}
1
+ {"version":3,"sources":["../../src/bin/feedback-collector.ts"],"names":["EOL","spawn"],"mappings":"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","file":"feedback-collector.js","sourcesContent":["/**\n * Concurrent Feedback Collector\n *\n * Minimal multi-submit feedback collector that runs concurrently with ongoing processes.\n * - Type/paste feedback (multiline)\n * - Press Enter on a BLANK line to SUBMIT that block\n * - The feedback block is sent to feedback command via stdin for each submission\n * - Multiple blocks allowed; exit with EOF (Ctrl-D / Ctrl-Z then Enter) or Ctrl-C\n * - Progress logs go to stderr; UI/instructions to stdout\n * - NO TTY/Raw mode - simple line-based stdin for AI agent compatibility\n *\n * Usage:\n * juno-collect-feedback <command> [arg1 arg2 ...]\n * Example:\n * juno-collect-feedback node dist/bin/cli.mjs feedback\n * juno-collect-feedback juno-code feedback\n *\n * OR run standalone:\n * node dist/bin/feedback-collector.mjs\n */\n\nimport { spawn } from 'node:child_process';\nimport { EOL } from 'node:os';\n\n// Enable UTF-8 encoding for stdin\nprocess.stdin.setEncoding('utf8');\n\n// --- Parse command to run per submission ---\nconst [, , ...argv] = process.argv;\nconst cmd = argv.length > 0 ? argv[0] : 'node';\nconst cmdArgs = argv.length > 0 ? argv.slice(1) : ['dist/bin/cli.mjs', 'feedback'];\n\n// --- Progress ticker (simulates concurrent progress) ---\nlet tick = 0;\nconst start = Date.now();\nconst logTimer = setInterval(() => {\n tick += 1;\n const elapsed = ((Date.now() - start) / 1000).toFixed(1);\n process.stderr.write(`[progress] step=${tick} elapsed=${elapsed}s${EOL}`);\n}, 1200);\n\n// --- UI header ---\nfunction printHeader(): void {\n process.stdout.write(\n [\n '',\n '📝 Concurrent Feedback Collector',\n ' Type or paste your feedback. Submit by pressing Enter on an EMPTY line.',\n ' (EOF ends the session: Ctrl-D on macOS/Linux; Ctrl-Z then Enter on Windows.)',\n ''\n ].join(EOL) + EOL\n );\n}\nprintHeader();\n\n// --- Submission queue to keep commands sequential ---\nlet pending = Promise.resolve();\nlet submissionCount = 0;\n\n/**\n * Run feedback command with the collected input\n */\nfunction runCommandWithInput(input: string): Promise<number> {\n submissionCount += 1;\n const n = submissionCount;\n process.stderr.write(`${EOL}[submit ${n}] launching \"${cmd}\" ${cmdArgs.join(' ')}${EOL}`);\n\n return new Promise((resolve) => {\n const child = spawn(cmd, cmdArgs, { stdio: ['pipe', 'pipe', 'pipe'] });\n\n // Pipe child's output to stderr (treat as logs)\n child.stdout?.on('data', (d) => process.stderr.write(`[submit ${n}] stdout: ${d}`));\n child.stderr?.on('data', (d) => process.stderr.write(`[submit ${n}] stderr: ${d}`));\n\n child.on('close', (code) => {\n process.stderr.write(`[submit ${n}] exit code ${code ?? 0}${EOL}`);\n resolve(code ?? 0);\n });\n\n child.on('error', (err) => {\n process.stderr.write(`[submit ${n}] error: ${err.message}${EOL}`);\n resolve(1);\n });\n\n // Write the feedback block to child stdin\n if (child.stdin) {\n child.stdin.write(input);\n if (!input.endsWith(EOL)) {\n child.stdin.write(EOL);\n }\n child.stdin.end();\n }\n });\n}\n\n/**\n * Enqueue submission to ensure strict sequential order\n */\nfunction enqueueSubmission(input: string): Promise<void> {\n // Ensure strict order by chaining onto `pending`\n pending = pending.then(() => runCommandWithInput(input).then(() => {}));\n return pending;\n}\n\n// --- Input handling: multiline buffer; blank line => submit ---\nlet carry = '';\nlet buffer = ''; // current feedback block\nlet lastLineWasBlank = false;\n\n/**\n * Submit the current buffer if it has content\n */\nfunction submitBufferIfAny(): void {\n const content = buffer.trimEnd();\n buffer = ''; // \"clean stdin\" buffer for the next round\n\n if (content.length === 0) {\n return;\n }\n\n process.stdout.write(EOL + '===== SUBMITTING FEEDBACK BLOCK =====' + EOL);\n process.stdout.write(content + EOL);\n process.stdout.write('===== END BLOCK =====' + EOL);\n\n enqueueSubmission(content).then(() => {\n // After the command finishes (still sequential), re-prompt\n process.stdout.write(EOL + '✅ Submission processed. You can type another block.' + EOL);\n }).catch((err) => {\n process.stderr.write(`Error submitting feedback: ${err}${EOL}`);\n });\n}\n\n// Handle stdin data events\nprocess.stdin.on('data', (chunk: string) => {\n carry += chunk;\n\n // Split into complete lines, keep the last partial in carry\n const parts = carry.split(/\\r?\\n/);\n carry = parts.pop() ?? '';\n\n for (const line of parts) {\n const isBlank = line.trim().length === 0;\n\n if (isBlank && !lastLineWasBlank) {\n // A single blank line means \"submit this block\"\n submitBufferIfAny();\n lastLineWasBlank = true;\n continue;\n }\n\n if (!isBlank) {\n // Any non-blank line is part of the current block\n buffer += line + EOL;\n lastLineWasBlank = false;\n } else {\n // Consecutive blank lines: ignore (prevent accidental multiple submits)\n lastLineWasBlank = true;\n }\n }\n});\n\n// Handle stdin end event (EOF)\nprocess.stdin.on('end', async () => {\n // If there is remaining partial data, treat as part of the last block\n if (carry.length) {\n buffer += carry;\n }\n\n submitBufferIfAny();\n await pending; // wait for in-flight submissions\n\n clearInterval(logTimer);\n process.stderr.write(`${EOL}[progress] done. submissions=${submissionCount}${EOL}`);\n process.exit(0);\n});\n\n// Handle SIGINT (Ctrl+C)\nprocess.on('SIGINT', async () => {\n process.stderr.write(`${EOL}[progress] SIGINT received. Finalizing…${EOL}`);\n\n submitBufferIfAny();\n await pending;\n\n clearInterval(logTimer);\n process.stderr.write(`[progress] done. submissions=${submissionCount}${EOL}`);\n process.exit(0);\n});\n\n// Handle uncaught errors\nprocess.on('uncaughtException', (err) => {\n process.stderr.write(`${EOL}[error] Uncaught exception: ${err.message}${EOL}`);\n clearInterval(logTimer);\n process.exit(1);\n});\n\nprocess.on('unhandledRejection', (reason) => {\n process.stderr.write(`${EOL}[error] Unhandled rejection: ${reason}${EOL}`);\n clearInterval(logTimer);\n process.exit(1);\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/bin/feedback-collector.ts"],"names":[],"mappings":"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","file":"feedback-collector.mjs","sourcesContent":["/**\n * Concurrent Feedback Collector\n *\n * Minimal multi-submit feedback collector that runs concurrently with ongoing processes.\n * - Type/paste feedback (multiline)\n * - Press Enter on a BLANK line to SUBMIT that block\n * - The feedback block is sent to feedback command via stdin for each submission\n * - Multiple blocks allowed; exit with EOF (Ctrl-D / Ctrl-Z then Enter) or Ctrl-C\n * - Progress logs go to stderr; UI/instructions to stdout\n * - NO TTY/Raw mode - simple line-based stdin for AI agent compatibility\n *\n * Usage:\n * juno-collect-feedback <command> [arg1 arg2 ...]\n * Example:\n * juno-collect-feedback node dist/bin/cli.mjs feedback\n * juno-collect-feedback juno-ts-task feedback\n *\n * OR run standalone:\n * node dist/bin/feedback-collector.mjs\n */\n\nimport { spawn } from 'node:child_process';\nimport { EOL } from 'node:os';\n\n// Enable UTF-8 encoding for stdin\nprocess.stdin.setEncoding('utf8');\n\n// --- Parse command to run per submission ---\nconst [, , ...argv] = process.argv;\nconst cmd = argv.length > 0 ? argv[0] : 'node';\nconst cmdArgs = argv.length > 0 ? argv.slice(1) : ['dist/bin/cli.mjs', 'feedback'];\n\n// --- Progress ticker (simulates concurrent progress) ---\nlet tick = 0;\nconst start = Date.now();\nconst logTimer = setInterval(() => {\n tick += 1;\n const elapsed = ((Date.now() - start) / 1000).toFixed(1);\n process.stderr.write(`[progress] step=${tick} elapsed=${elapsed}s${EOL}`);\n}, 1200);\n\n// --- UI header ---\nfunction printHeader(): void {\n process.stdout.write(\n [\n '',\n '📝 Concurrent Feedback Collector',\n ' Type or paste your feedback. Submit by pressing Enter on an EMPTY line.',\n ' (EOF ends the session: Ctrl-D on macOS/Linux; Ctrl-Z then Enter on Windows.)',\n ''\n ].join(EOL) + EOL\n );\n}\nprintHeader();\n\n// --- Submission queue to keep commands sequential ---\nlet pending = Promise.resolve();\nlet submissionCount = 0;\n\n/**\n * Run feedback command with the collected input\n */\nfunction runCommandWithInput(input: string): Promise<number> {\n submissionCount += 1;\n const n = submissionCount;\n process.stderr.write(`${EOL}[submit ${n}] launching \"${cmd}\" ${cmdArgs.join(' ')}${EOL}`);\n\n return new Promise((resolve) => {\n const child = spawn(cmd, cmdArgs, { stdio: ['pipe', 'pipe', 'pipe'] });\n\n // Pipe child's output to stderr (treat as logs)\n child.stdout?.on('data', (d) => process.stderr.write(`[submit ${n}] stdout: ${d}`));\n child.stderr?.on('data', (d) => process.stderr.write(`[submit ${n}] stderr: ${d}`));\n\n child.on('close', (code) => {\n process.stderr.write(`[submit ${n}] exit code ${code ?? 0}${EOL}`);\n resolve(code ?? 0);\n });\n\n child.on('error', (err) => {\n process.stderr.write(`[submit ${n}] error: ${err.message}${EOL}`);\n resolve(1);\n });\n\n // Write the feedback block to child stdin\n if (child.stdin) {\n child.stdin.write(input);\n if (!input.endsWith(EOL)) {\n child.stdin.write(EOL);\n }\n child.stdin.end();\n }\n });\n}\n\n/**\n * Enqueue submission to ensure strict sequential order\n */\nfunction enqueueSubmission(input: string): Promise<void> {\n // Ensure strict order by chaining onto `pending`\n pending = pending.then(() => runCommandWithInput(input).then(() => {}));\n return pending;\n}\n\n// --- Input handling: multiline buffer; blank line => submit ---\nlet carry = '';\nlet buffer = ''; // current feedback block\nlet lastLineWasBlank = false;\n\n/**\n * Submit the current buffer if it has content\n */\nfunction submitBufferIfAny(): void {\n const content = buffer.trimEnd();\n buffer = ''; // \"clean stdin\" buffer for the next round\n\n if (content.length === 0) {\n return;\n }\n\n process.stdout.write(EOL + '===== SUBMITTING FEEDBACK BLOCK =====' + EOL);\n process.stdout.write(content + EOL);\n process.stdout.write('===== END BLOCK =====' + EOL);\n\n enqueueSubmission(content).then(() => {\n // After the command finishes (still sequential), re-prompt\n process.stdout.write(EOL + '✅ Submission processed. You can type another block.' + EOL);\n }).catch((err) => {\n process.stderr.write(`Error submitting feedback: ${err}${EOL}`);\n });\n}\n\n// Handle stdin data events\nprocess.stdin.on('data', (chunk: string) => {\n carry += chunk;\n\n // Split into complete lines, keep the last partial in carry\n const parts = carry.split(/\\r?\\n/);\n carry = parts.pop() ?? '';\n\n for (const line of parts) {\n const isBlank = line.trim().length === 0;\n\n if (isBlank && !lastLineWasBlank) {\n // A single blank line means \"submit this block\"\n submitBufferIfAny();\n lastLineWasBlank = true;\n continue;\n }\n\n if (!isBlank) {\n // Any non-blank line is part of the current block\n buffer += line + EOL;\n lastLineWasBlank = false;\n } else {\n // Consecutive blank lines: ignore (prevent accidental multiple submits)\n lastLineWasBlank = true;\n }\n }\n});\n\n// Handle stdin end event (EOF)\nprocess.stdin.on('end', async () => {\n // If there is remaining partial data, treat as part of the last block\n if (carry.length) {\n buffer += carry;\n }\n\n submitBufferIfAny();\n await pending; // wait for in-flight submissions\n\n clearInterval(logTimer);\n process.stderr.write(`${EOL}[progress] done. submissions=${submissionCount}${EOL}`);\n process.exit(0);\n});\n\n// Handle SIGINT (Ctrl+C)\nprocess.on('SIGINT', async () => {\n process.stderr.write(`${EOL}[progress] SIGINT received. Finalizing…${EOL}`);\n\n submitBufferIfAny();\n await pending;\n\n clearInterval(logTimer);\n process.stderr.write(`[progress] done. submissions=${submissionCount}${EOL}`);\n process.exit(0);\n});\n\n// Handle uncaught errors\nprocess.on('uncaughtException', (err) => {\n process.stderr.write(`${EOL}[error] Uncaught exception: ${err.message}${EOL}`);\n clearInterval(logTimer);\n process.exit(1);\n});\n\nprocess.on('unhandledRejection', (reason) => {\n process.stderr.write(`${EOL}[error] Unhandled rejection: ${reason}${EOL}`);\n clearInterval(logTimer);\n process.exit(1);\n});\n"]}
1
+ {"version":3,"sources":["../../src/bin/feedback-collector.ts"],"names":[],"mappings":"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","file":"feedback-collector.mjs","sourcesContent":["/**\n * Concurrent Feedback Collector\n *\n * Minimal multi-submit feedback collector that runs concurrently with ongoing processes.\n * - Type/paste feedback (multiline)\n * - Press Enter on a BLANK line to SUBMIT that block\n * - The feedback block is sent to feedback command via stdin for each submission\n * - Multiple blocks allowed; exit with EOF (Ctrl-D / Ctrl-Z then Enter) or Ctrl-C\n * - Progress logs go to stderr; UI/instructions to stdout\n * - NO TTY/Raw mode - simple line-based stdin for AI agent compatibility\n *\n * Usage:\n * juno-collect-feedback <command> [arg1 arg2 ...]\n * Example:\n * juno-collect-feedback node dist/bin/cli.mjs feedback\n * juno-collect-feedback juno-code feedback\n *\n * OR run standalone:\n * node dist/bin/feedback-collector.mjs\n */\n\nimport { spawn } from 'node:child_process';\nimport { EOL } from 'node:os';\n\n// Enable UTF-8 encoding for stdin\nprocess.stdin.setEncoding('utf8');\n\n// --- Parse command to run per submission ---\nconst [, , ...argv] = process.argv;\nconst cmd = argv.length > 0 ? argv[0] : 'node';\nconst cmdArgs = argv.length > 0 ? argv.slice(1) : ['dist/bin/cli.mjs', 'feedback'];\n\n// --- Progress ticker (simulates concurrent progress) ---\nlet tick = 0;\nconst start = Date.now();\nconst logTimer = setInterval(() => {\n tick += 1;\n const elapsed = ((Date.now() - start) / 1000).toFixed(1);\n process.stderr.write(`[progress] step=${tick} elapsed=${elapsed}s${EOL}`);\n}, 1200);\n\n// --- UI header ---\nfunction printHeader(): void {\n process.stdout.write(\n [\n '',\n '📝 Concurrent Feedback Collector',\n ' Type or paste your feedback. Submit by pressing Enter on an EMPTY line.',\n ' (EOF ends the session: Ctrl-D on macOS/Linux; Ctrl-Z then Enter on Windows.)',\n ''\n ].join(EOL) + EOL\n );\n}\nprintHeader();\n\n// --- Submission queue to keep commands sequential ---\nlet pending = Promise.resolve();\nlet submissionCount = 0;\n\n/**\n * Run feedback command with the collected input\n */\nfunction runCommandWithInput(input: string): Promise<number> {\n submissionCount += 1;\n const n = submissionCount;\n process.stderr.write(`${EOL}[submit ${n}] launching \"${cmd}\" ${cmdArgs.join(' ')}${EOL}`);\n\n return new Promise((resolve) => {\n const child = spawn(cmd, cmdArgs, { stdio: ['pipe', 'pipe', 'pipe'] });\n\n // Pipe child's output to stderr (treat as logs)\n child.stdout?.on('data', (d) => process.stderr.write(`[submit ${n}] stdout: ${d}`));\n child.stderr?.on('data', (d) => process.stderr.write(`[submit ${n}] stderr: ${d}`));\n\n child.on('close', (code) => {\n process.stderr.write(`[submit ${n}] exit code ${code ?? 0}${EOL}`);\n resolve(code ?? 0);\n });\n\n child.on('error', (err) => {\n process.stderr.write(`[submit ${n}] error: ${err.message}${EOL}`);\n resolve(1);\n });\n\n // Write the feedback block to child stdin\n if (child.stdin) {\n child.stdin.write(input);\n if (!input.endsWith(EOL)) {\n child.stdin.write(EOL);\n }\n child.stdin.end();\n }\n });\n}\n\n/**\n * Enqueue submission to ensure strict sequential order\n */\nfunction enqueueSubmission(input: string): Promise<void> {\n // Ensure strict order by chaining onto `pending`\n pending = pending.then(() => runCommandWithInput(input).then(() => {}));\n return pending;\n}\n\n// --- Input handling: multiline buffer; blank line => submit ---\nlet carry = '';\nlet buffer = ''; // current feedback block\nlet lastLineWasBlank = false;\n\n/**\n * Submit the current buffer if it has content\n */\nfunction submitBufferIfAny(): void {\n const content = buffer.trimEnd();\n buffer = ''; // \"clean stdin\" buffer for the next round\n\n if (content.length === 0) {\n return;\n }\n\n process.stdout.write(EOL + '===== SUBMITTING FEEDBACK BLOCK =====' + EOL);\n process.stdout.write(content + EOL);\n process.stdout.write('===== END BLOCK =====' + EOL);\n\n enqueueSubmission(content).then(() => {\n // After the command finishes (still sequential), re-prompt\n process.stdout.write(EOL + '✅ Submission processed. You can type another block.' + EOL);\n }).catch((err) => {\n process.stderr.write(`Error submitting feedback: ${err}${EOL}`);\n });\n}\n\n// Handle stdin data events\nprocess.stdin.on('data', (chunk: string) => {\n carry += chunk;\n\n // Split into complete lines, keep the last partial in carry\n const parts = carry.split(/\\r?\\n/);\n carry = parts.pop() ?? '';\n\n for (const line of parts) {\n const isBlank = line.trim().length === 0;\n\n if (isBlank && !lastLineWasBlank) {\n // A single blank line means \"submit this block\"\n submitBufferIfAny();\n lastLineWasBlank = true;\n continue;\n }\n\n if (!isBlank) {\n // Any non-blank line is part of the current block\n buffer += line + EOL;\n lastLineWasBlank = false;\n } else {\n // Consecutive blank lines: ignore (prevent accidental multiple submits)\n lastLineWasBlank = true;\n }\n }\n});\n\n// Handle stdin end event (EOF)\nprocess.stdin.on('end', async () => {\n // If there is remaining partial data, treat as part of the last block\n if (carry.length) {\n buffer += carry;\n }\n\n submitBufferIfAny();\n await pending; // wait for in-flight submissions\n\n clearInterval(logTimer);\n process.stderr.write(`${EOL}[progress] done. submissions=${submissionCount}${EOL}`);\n process.exit(0);\n});\n\n// Handle SIGINT (Ctrl+C)\nprocess.on('SIGINT', async () => {\n process.stderr.write(`${EOL}[progress] SIGINT received. Finalizing…${EOL}`);\n\n submitBufferIfAny();\n await pending;\n\n clearInterval(logTimer);\n process.stderr.write(`[progress] done. submissions=${submissionCount}${EOL}`);\n process.exit(0);\n});\n\n// Handle uncaught errors\nprocess.on('uncaughtException', (err) => {\n process.stderr.write(`${EOL}[error] Uncaught exception: ${err.message}${EOL}`);\n clearInterval(logTimer);\n process.exit(1);\n});\n\nprocess.on('unhandledRejection', (reason) => {\n process.stderr.write(`${EOL}[error] Unhandled rejection: ${reason}${EOL}`);\n clearInterval(logTimer);\n process.exit(1);\n});\n"]}
package/dist/index.js CHANGED
@@ -75,7 +75,7 @@ var __export = (target, all) => {
75
75
  exports.version = void 0;
76
76
  var init_version = __esm({
77
77
  "src/version.ts"() {
78
- exports.version = "1.0.10";
78
+ exports.version = "1.0.13";
79
79
  }
80
80
  });
81
81
  function isHeadlessEnvironment() {
@@ -4023,6 +4023,26 @@ init_version();
4023
4023
  // src/core/config.ts
4024
4024
  init_version();
4025
4025
 
4026
+ // src/templates/default-hooks.ts
4027
+ init_version();
4028
+ var DEFAULT_HOOKS = {
4029
+ START_ITERATION: {
4030
+ commands: [
4031
+ // Monitor CLAUDE.md file size
4032
+ 'file="CLAUDE.md"; lines=$(wc -l < "$file" 2>/dev/null || echo 0); chars=$(wc -m < "$file" 2>/dev/null || echo 0); if [ "$lines" -gt 450 ] || [ "$chars" -gt 60000 ]; then juno-kanban "[Critical] file $file is too large, keep it lean and useful for every run of the agent."; fi',
4033
+ // Monitor AGENTS.md file size
4034
+ 'file="AGENTS.md"; lines=$(wc -l < "$file" 2>/dev/null || echo 0); chars=$(wc -m < "$file" 2>/dev/null || echo 0); if [ "$lines" -gt 450 ] || [ "$chars" -gt 60000 ]; then juno-kanban "[Critical] file $file is too large, keep it lean and useful for every run of the agent."; fi',
4035
+ "./.juno_task/scripts/cleanup_feedback.sh"
4036
+ ]
4037
+ }
4038
+ };
4039
+ function getDefaultHooks() {
4040
+ return JSON.parse(JSON.stringify(DEFAULT_HOOKS));
4041
+ }
4042
+ function getDefaultHooksJson(indent = 2) {
4043
+ return JSON.stringify(DEFAULT_HOOKS, null, indent);
4044
+ }
4045
+
4026
4046
  // src/core/profiles.ts
4027
4047
  init_version();
4028
4048
  var PartialJunoTaskConfigSchema = zod.z.object({
@@ -4433,6 +4453,28 @@ var CircularInheritanceError = class extends ProfileError {
4433
4453
 
4434
4454
  // src/core/config.ts
4435
4455
  var ENV_VAR_MAPPING = {
4456
+ // Core settings
4457
+ JUNO_CODE_DEFAULT_SUBAGENT: "defaultSubagent",
4458
+ JUNO_CODE_DEFAULT_MAX_ITERATIONS: "defaultMaxIterations",
4459
+ JUNO_CODE_DEFAULT_MODEL: "defaultModel",
4460
+ // Logging settings
4461
+ JUNO_CODE_LOG_LEVEL: "logLevel",
4462
+ JUNO_CODE_LOG_FILE: "logFile",
4463
+ JUNO_CODE_VERBOSE: "verbose",
4464
+ JUNO_CODE_QUIET: "quiet",
4465
+ // MCP settings
4466
+ JUNO_CODE_MCP_TIMEOUT: "mcpTimeout",
4467
+ JUNO_CODE_MCP_RETRIES: "mcpRetries",
4468
+ JUNO_CODE_MCP_SERVER_PATH: "mcpServerPath",
4469
+ JUNO_CODE_MCP_SERVER_NAME: "mcpServerName",
4470
+ // TUI settings
4471
+ JUNO_CODE_INTERACTIVE: "interactive",
4472
+ JUNO_CODE_HEADLESS_MODE: "headlessMode",
4473
+ // Paths
4474
+ JUNO_CODE_WORKING_DIRECTORY: "workingDirectory",
4475
+ JUNO_CODE_SESSION_DIRECTORY: "sessionDirectory"
4476
+ };
4477
+ var LEGACY_ENV_VAR_MAPPING = {
4436
4478
  // Core settings
4437
4479
  JUNO_TASK_DEFAULT_SUBAGENT: "defaultSubagent",
4438
4480
  JUNO_TASK_DEFAULT_MAX_ITERATIONS: "defaultMaxIterations",
@@ -4505,16 +4547,16 @@ var DEFAULT_CONFIG = {
4505
4547
  // Paths
4506
4548
  workingDirectory: process.cwd(),
4507
4549
  sessionDirectory: path5__namespace.join(process.cwd(), ".juno_task"),
4508
- // Hooks configuration
4509
- hooks: {}
4550
+ // Hooks configuration - populated with default hooks template
4551
+ hooks: getDefaultHooks()
4510
4552
  };
4511
4553
  var GLOBAL_CONFIG_FILE_NAMES = [
4512
- "juno-task.config.json",
4513
- "juno-task.config.js",
4514
- ".juno-taskrc.json",
4515
- ".juno-taskrc.js",
4554
+ "juno-code.config.json",
4555
+ "juno-code.config.js",
4556
+ ".juno-coderc.json",
4557
+ ".juno-coderc.js",
4516
4558
  "package.json"
4517
- // Will look for 'junoTask' field
4559
+ // Will look for 'junoCode' field
4518
4560
  ];
4519
4561
  var PROJECT_CONFIG_FILE = ".juno_task/config.json";
4520
4562
  function resolvePath(inputPath, basePath = process.cwd()) {
@@ -4541,6 +4583,12 @@ function loadConfigFromEnv() {
4541
4583
  config[configKey] = parseEnvValue(value);
4542
4584
  }
4543
4585
  }
4586
+ for (const [envVar, configKey] of Object.entries(LEGACY_ENV_VAR_MAPPING)) {
4587
+ const value = process.env[envVar];
4588
+ if (value !== void 0 && config[configKey] === void 0) {
4589
+ config[configKey] = parseEnvValue(value);
4590
+ }
4591
+ }
4544
4592
  return config;
4545
4593
  }
4546
4594
  async function loadJsonConfig(filePath) {
@@ -4564,7 +4612,7 @@ async function loadPackageJsonConfig(filePath) {
4564
4612
  try {
4565
4613
  const content = await nodeFs.promises.readFile(filePath, "utf-8");
4566
4614
  const packageJson = JSON.parse(content);
4567
- return packageJson.junoTask || {};
4615
+ return packageJson.junoCode || {};
4568
4616
  } catch (error) {
4569
4617
  throw new Error(`Failed to load package.json config from ${filePath}: ${error}`);
4570
4618
  }
@@ -4799,12 +4847,7 @@ async function ensureHooksConfig(baseDir) {
4799
4847
  const configPath = path5__namespace.join(configDir, "config.json");
4800
4848
  await fs__default.default.ensureDir(configDir);
4801
4849
  const configExists = await fs__default.default.pathExists(configPath);
4802
- const allHookTypes = {
4803
- START_RUN: { commands: [] },
4804
- START_ITERATION: { commands: [] },
4805
- END_ITERATION: { commands: [] },
4806
- END_RUN: { commands: [] }
4807
- };
4850
+ const allHookTypes = getDefaultHooks();
4808
4851
  if (!configExists) {
4809
4852
  const defaultConfig = {
4810
4853
  ...DEFAULT_CONFIG,
@@ -14769,6 +14812,7 @@ exports.DEFAULT_CATEGORY_SEVERITY = DEFAULT_CATEGORY_SEVERITY;
14769
14812
  exports.DEFAULT_CATEGORY_STRATEGY = DEFAULT_CATEGORY_STRATEGY;
14770
14813
  exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
14771
14814
  exports.DEFAULT_ERROR_RECOVERY_CONFIG = DEFAULT_ERROR_RECOVERY_CONFIG;
14815
+ exports.DEFAULT_HOOKS = DEFAULT_HOOKS;
14772
14816
  exports.DEFAULT_PROGRESS_CONFIG = DEFAULT_PROGRESS_CONFIG;
14773
14817
  exports.DEFAULT_RATE_LIMIT_CONFIG = DEFAULT_RATE_LIMIT_CONFIG;
14774
14818
  exports.DependencyValidationError = DependencyValidationError;
@@ -14803,6 +14847,7 @@ exports.IterationsSchema = IterationsSchema;
14803
14847
  exports.JunoMCPClient = JunoMCPClient;
14804
14848
  exports.JunoTaskConfigSchema = JunoTaskConfigSchema;
14805
14849
  exports.JunoTaskError = JunoTaskError;
14850
+ exports.LEGACY_ENV_VAR_MAPPING = LEGACY_ENV_VAR_MAPPING;
14806
14851
  exports.LinearBackoffStrategy = LinearBackoffStrategy;
14807
14852
  exports.LoadingSpinner = LoadingSpinner;
14808
14853
  exports.LogLevelSchema = LogLevelSchema2;
@@ -14898,6 +14943,8 @@ exports.getColorSupport = getColorSupport;
14898
14943
  exports.getConfigDirectory = getConfigDirectory;
14899
14944
  exports.getCpuUsage = getCpuUsage;
14900
14945
  exports.getDataDirectory = getDataDirectory;
14946
+ exports.getDefaultHooks = getDefaultHooks;
14947
+ exports.getDefaultHooksJson = getDefaultHooksJson;
14901
14948
  exports.getEnvVar = getEnvVar;
14902
14949
  exports.getEnvVarWithDefault = getEnvVarWithDefault;
14903
14950
  exports.getEnvironmentType = getEnvironmentType;