juno-code 1.0.49 → 1.0.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +417 -203
- package/dist/bin/cli.d.mts +1 -1
- package/dist/bin/cli.d.ts +1 -1
- package/dist/bin/cli.js +1736 -976
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/cli.mjs +1735 -975
- package/dist/bin/cli.mjs.map +1 -1
- package/dist/bin/feedback-collector.js.map +1 -1
- package/dist/bin/feedback-collector.mjs.map +1 -1
- package/dist/index.d.mts +33 -7
- package/dist/index.d.ts +33 -7
- package/dist/index.js +202 -27
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +202 -27
- package/dist/index.mjs.map +1 -1
- package/dist/templates/scripts/install_requirements.sh +41 -3
- package/dist/templates/scripts/kanban.sh +4 -0
- package/dist/templates/services/__pycache__/pi.cpython-313.pyc +0 -0
- package/dist/templates/services/pi.py +1281 -238
- package/dist/templates/skills/claude/kanban-workflow/SKILL.md +138 -0
- package/dist/templates/skills/claude/plan-kanban-tasks/SKILL.md +1 -1
- package/dist/templates/skills/claude/ralph-loop/scripts/kanban.sh +4 -0
- package/dist/templates/skills/claude/understand-project/SKILL.md +1 -1
- package/dist/templates/skills/codex/kanban-workflow/SKILL.md +139 -0
- package/dist/templates/skills/codex/plan-kanban-tasks/SKILL.md +32 -0
- package/dist/templates/skills/codex/ralph-loop/scripts/kanban.sh +4 -0
- package/dist/templates/skills/codex/understand-project/SKILL.md +46 -0
- package/dist/templates/skills/pi/kanban-workflow/SKILL.md +139 -0
- package/dist/templates/skills/pi/plan-kanban-tasks/SKILL.md +1 -1
- package/dist/templates/skills/pi/ralph-loop/SKILL.md +4 -0
- package/dist/templates/skills/pi/understand-project/SKILL.md +1 -1
- package/package.json +7 -5
|
@@ -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-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 as string, cmdArgs, { stdio: ['pipe', 'pipe', 'pipe'] });\n\n // Pipe child's output to stderr (treat as logs)\n child.stdout?.on('data', (d: Buffer) => process.stderr.write(`[submit ${n}] stdout: ${d}`));\n child.stderr?.on('data', (d: Buffer) => process.stderr.write(`[submit ${n}] stderr: ${d}`));\n\n child.on('close', (code: number | null) => {\n process.stderr.write(`[submit ${n}] exit code ${code ?? 0}${EOL}`);\n resolve(code ?? 0);\n });\n\n child.on('error', (err: Error) => {\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)\n .then(() => {\n // After the command finishes (still sequential), re-prompt\n process.stdout.write(EOL + '✅ Submission processed. You can type another block.' + EOL);\n })\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 * feedback-juno-code <command> [arg1 arg2 ...]\n * Example:\n * feedback-juno-code node dist/bin/cli.mjs feedback\n * feedback-juno-code 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 as string, cmdArgs, { stdio: ['pipe', 'pipe', 'pipe'] });\n\n // Pipe child's output to stderr (treat as logs)\n child.stdout?.on('data', (d: Buffer) => process.stderr.write(`[submit ${n}] stdout: ${d}`));\n child.stderr?.on('data', (d: Buffer) => process.stderr.write(`[submit ${n}] stderr: ${d}`));\n\n child.on('close', (code: number | null) => {\n process.stderr.write(`[submit ${n}] exit code ${code ?? 0}${EOL}`);\n resolve(code ?? 0);\n });\n\n child.on('error', (err: Error) => {\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)\n .then(() => {\n // After the command finishes (still sequential), re-prompt\n process.stdout.write(EOL + '✅ Submission processed. You can type another block.' + EOL);\n })\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-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 as string, cmdArgs, { stdio: ['pipe', 'pipe', 'pipe'] });\n\n // Pipe child's output to stderr (treat as logs)\n child.stdout?.on('data', (d: Buffer) => process.stderr.write(`[submit ${n}] stdout: ${d}`));\n child.stderr?.on('data', (d: Buffer) => process.stderr.write(`[submit ${n}] stderr: ${d}`));\n\n child.on('close', (code: number | null) => {\n process.stderr.write(`[submit ${n}] exit code ${code ?? 0}${EOL}`);\n resolve(code ?? 0);\n });\n\n child.on('error', (err: Error) => {\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)\n .then(() => {\n // After the command finishes (still sequential), re-prompt\n process.stdout.write(EOL + '✅ Submission processed. You can type another block.' + EOL);\n })\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 * feedback-juno-code <command> [arg1 arg2 ...]\n * Example:\n * feedback-juno-code node dist/bin/cli.mjs feedback\n * feedback-juno-code 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 as string, cmdArgs, { stdio: ['pipe', 'pipe', 'pipe'] });\n\n // Pipe child's output to stderr (treat as logs)\n child.stdout?.on('data', (d: Buffer) => process.stderr.write(`[submit ${n}] stdout: ${d}`));\n child.stderr?.on('data', (d: Buffer) => process.stderr.write(`[submit ${n}] stderr: ${d}`));\n\n child.on('close', (code: number | null) => {\n process.stderr.write(`[submit ${n}] exit code ${code ?? 0}${EOL}`);\n resolve(code ?? 0);\n });\n\n child.on('error', (err: Error) => {\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)\n .then(() => {\n // After the command finishes (still sequential), re-prompt\n process.stdout.write(EOL + '✅ Submission processed. You can type another block.' + EOL);\n })\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.d.mts
CHANGED
|
@@ -23,7 +23,8 @@ interface JunoTaskConfig {
|
|
|
23
23
|
mainTask?: string;
|
|
24
24
|
logLevel: LogLevel;
|
|
25
25
|
logFile?: string;
|
|
26
|
-
|
|
26
|
+
/** Verbosity level: 0=quiet, 1=normal+helping texts (default), 2=debug+hooks */
|
|
27
|
+
verbose: number;
|
|
27
28
|
quiet: boolean;
|
|
28
29
|
mcpTimeout: number;
|
|
29
30
|
mcpRetries: number;
|
|
@@ -35,6 +36,10 @@ interface JunoTaskConfig {
|
|
|
35
36
|
headlessMode: boolean;
|
|
36
37
|
workingDirectory: string;
|
|
37
38
|
sessionDirectory: string;
|
|
39
|
+
/** Path to project env file loaded on startup (relative to workingDirectory or absolute) */
|
|
40
|
+
envFilePath?: string;
|
|
41
|
+
/** Tracks whether the configured env file has been initialized from .env.juno */
|
|
42
|
+
envFileCopied?: boolean;
|
|
38
43
|
hooks?: Hooks;
|
|
39
44
|
skipHooks?: boolean;
|
|
40
45
|
}
|
|
@@ -89,7 +94,7 @@ declare const JunoTaskConfigSchema: z.ZodObject<{
|
|
|
89
94
|
mainTask: z.ZodOptional<z.ZodString>;
|
|
90
95
|
logLevel: z.ZodEnum<["error", "warn", "info", "debug", "trace"]>;
|
|
91
96
|
logFile: z.ZodOptional<z.ZodString>;
|
|
92
|
-
verbose: z.
|
|
97
|
+
verbose: z.ZodEffects<z.ZodNumber, number, unknown>;
|
|
93
98
|
quiet: z.ZodBoolean;
|
|
94
99
|
mcpTimeout: z.ZodNumber;
|
|
95
100
|
mcpRetries: z.ZodNumber;
|
|
@@ -101,6 +106,8 @@ declare const JunoTaskConfigSchema: z.ZodObject<{
|
|
|
101
106
|
headlessMode: z.ZodBoolean;
|
|
102
107
|
workingDirectory: z.ZodString;
|
|
103
108
|
sessionDirectory: z.ZodString;
|
|
109
|
+
envFilePath: z.ZodOptional<z.ZodString>;
|
|
110
|
+
envFileCopied: z.ZodOptional<z.ZodBoolean>;
|
|
104
111
|
hooks: z.ZodOptional<z.ZodRecord<z.ZodEnum<["START_RUN", "START_ITERATION", "END_ITERATION", "END_RUN", "ON_STALE"]>, z.ZodObject<{
|
|
105
112
|
commands: z.ZodArray<z.ZodString, "many">;
|
|
106
113
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -116,7 +123,7 @@ declare const JunoTaskConfigSchema: z.ZodObject<{
|
|
|
116
123
|
defaultModel?: string;
|
|
117
124
|
logLevel?: "error" | "warn" | "info" | "debug" | "trace";
|
|
118
125
|
logFile?: string;
|
|
119
|
-
verbose?:
|
|
126
|
+
verbose?: number;
|
|
120
127
|
quiet?: boolean;
|
|
121
128
|
mcpTimeout?: number;
|
|
122
129
|
mcpRetries?: number;
|
|
@@ -129,6 +136,8 @@ declare const JunoTaskConfigSchema: z.ZodObject<{
|
|
|
129
136
|
workingDirectory?: string;
|
|
130
137
|
sessionDirectory?: string;
|
|
131
138
|
mainTask?: string;
|
|
139
|
+
envFilePath?: string;
|
|
140
|
+
envFileCopied?: boolean;
|
|
132
141
|
hooks?: Partial<Record<"START_RUN" | "START_ITERATION" | "END_ITERATION" | "END_RUN" | "ON_STALE", {
|
|
133
142
|
commands?: string[];
|
|
134
143
|
}>>;
|
|
@@ -140,7 +149,7 @@ declare const JunoTaskConfigSchema: z.ZodObject<{
|
|
|
140
149
|
defaultModel?: string;
|
|
141
150
|
logLevel?: "error" | "warn" | "info" | "debug" | "trace";
|
|
142
151
|
logFile?: string;
|
|
143
|
-
verbose?:
|
|
152
|
+
verbose?: unknown;
|
|
144
153
|
quiet?: boolean;
|
|
145
154
|
mcpTimeout?: number;
|
|
146
155
|
mcpRetries?: number;
|
|
@@ -153,6 +162,8 @@ declare const JunoTaskConfigSchema: z.ZodObject<{
|
|
|
153
162
|
workingDirectory?: string;
|
|
154
163
|
sessionDirectory?: string;
|
|
155
164
|
mainTask?: string;
|
|
165
|
+
envFilePath?: string;
|
|
166
|
+
envFileCopied?: boolean;
|
|
156
167
|
hooks?: Partial<Record<"START_RUN" | "START_ITERATION" | "END_ITERATION" | "END_RUN" | "ON_STALE", {
|
|
157
168
|
commands?: string[];
|
|
158
169
|
}>>;
|
|
@@ -719,6 +730,8 @@ interface ExecutionRequest {
|
|
|
719
730
|
readonly resume?: string;
|
|
720
731
|
/** Continue the most recent conversation (forwarded to shell backend) */
|
|
721
732
|
readonly continueConversation?: boolean;
|
|
733
|
+
/** Extended thinking level (forwarded to shell backend --thinking flag) */
|
|
734
|
+
readonly thinking?: string;
|
|
722
735
|
}
|
|
723
736
|
/**
|
|
724
737
|
* Execution result interface for completed executions
|
|
@@ -1019,6 +1032,12 @@ declare class ExecutionEngine extends EventEmitter {
|
|
|
1019
1032
|
* Setup progress tracking for the engine
|
|
1020
1033
|
*/
|
|
1021
1034
|
private setupProgressTracking;
|
|
1035
|
+
/**
|
|
1036
|
+
* Display hook execution output to stderr at verbose level 2 (debug+hooks).
|
|
1037
|
+
* At level 2: shows hook name, command stdout/stderr output.
|
|
1038
|
+
* At level 0-1: output is suppressed (hooks still execute).
|
|
1039
|
+
*/
|
|
1040
|
+
private displayHookOutput;
|
|
1022
1041
|
/**
|
|
1023
1042
|
* Initialize backend for execution request.
|
|
1024
1043
|
* Directly creates and configures a ShellBackend (no factory indirection).
|
|
@@ -1168,6 +1187,7 @@ declare function createExecutionRequest(options: {
|
|
|
1168
1187
|
mcpServerName?: string;
|
|
1169
1188
|
resume?: string;
|
|
1170
1189
|
continueConversation?: boolean;
|
|
1190
|
+
thinking?: string;
|
|
1171
1191
|
}): ExecutionRequest;
|
|
1172
1192
|
|
|
1173
1193
|
/** Session metadata */
|
|
@@ -2009,7 +2029,7 @@ declare const ConfigValidationSchema: z.ZodObject<{
|
|
|
2009
2029
|
mainTask: z.ZodOptional<z.ZodString>;
|
|
2010
2030
|
logLevel: z.ZodEnum<["error", "warn", "info", "debug", "trace"]>;
|
|
2011
2031
|
logFile: z.ZodOptional<z.ZodString>;
|
|
2012
|
-
verbose: z.
|
|
2032
|
+
verbose: z.ZodEffects<z.ZodNumber, number, unknown>;
|
|
2013
2033
|
quiet: z.ZodBoolean;
|
|
2014
2034
|
mcpTimeout: z.ZodNumber;
|
|
2015
2035
|
mcpRetries: z.ZodNumber;
|
|
@@ -2021,6 +2041,8 @@ declare const ConfigValidationSchema: z.ZodObject<{
|
|
|
2021
2041
|
headlessMode: z.ZodBoolean;
|
|
2022
2042
|
workingDirectory: z.ZodString;
|
|
2023
2043
|
sessionDirectory: z.ZodString;
|
|
2044
|
+
envFilePath: z.ZodOptional<z.ZodString>;
|
|
2045
|
+
envFileCopied: z.ZodOptional<z.ZodBoolean>;
|
|
2024
2046
|
hooks: z.ZodOptional<z.ZodRecord<z.ZodEnum<["START_RUN", "START_ITERATION", "END_ITERATION", "END_RUN", "ON_STALE"]>, z.ZodObject<{
|
|
2025
2047
|
commands: z.ZodArray<z.ZodString, "many">;
|
|
2026
2048
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -2036,7 +2058,7 @@ declare const ConfigValidationSchema: z.ZodObject<{
|
|
|
2036
2058
|
defaultModel?: string;
|
|
2037
2059
|
logLevel?: "error" | "warn" | "info" | "debug" | "trace";
|
|
2038
2060
|
logFile?: string;
|
|
2039
|
-
verbose?:
|
|
2061
|
+
verbose?: number;
|
|
2040
2062
|
quiet?: boolean;
|
|
2041
2063
|
mcpTimeout?: number;
|
|
2042
2064
|
mcpRetries?: number;
|
|
@@ -2049,6 +2071,8 @@ declare const ConfigValidationSchema: z.ZodObject<{
|
|
|
2049
2071
|
workingDirectory?: string;
|
|
2050
2072
|
sessionDirectory?: string;
|
|
2051
2073
|
mainTask?: string;
|
|
2074
|
+
envFilePath?: string;
|
|
2075
|
+
envFileCopied?: boolean;
|
|
2052
2076
|
hooks?: Partial<Record<"START_RUN" | "START_ITERATION" | "END_ITERATION" | "END_RUN" | "ON_STALE", {
|
|
2053
2077
|
commands?: string[];
|
|
2054
2078
|
}>>;
|
|
@@ -2060,7 +2084,7 @@ declare const ConfigValidationSchema: z.ZodObject<{
|
|
|
2060
2084
|
defaultModel?: string;
|
|
2061
2085
|
logLevel?: "error" | "warn" | "info" | "debug" | "trace";
|
|
2062
2086
|
logFile?: string;
|
|
2063
|
-
verbose?:
|
|
2087
|
+
verbose?: unknown;
|
|
2064
2088
|
quiet?: boolean;
|
|
2065
2089
|
mcpTimeout?: number;
|
|
2066
2090
|
mcpRetries?: number;
|
|
@@ -2073,6 +2097,8 @@ declare const ConfigValidationSchema: z.ZodObject<{
|
|
|
2073
2097
|
workingDirectory?: string;
|
|
2074
2098
|
sessionDirectory?: string;
|
|
2075
2099
|
mainTask?: string;
|
|
2100
|
+
envFilePath?: string;
|
|
2101
|
+
envFileCopied?: boolean;
|
|
2076
2102
|
hooks?: Partial<Record<"START_RUN" | "START_ITERATION" | "END_ITERATION" | "END_RUN" | "ON_STALE", {
|
|
2077
2103
|
commands?: string[];
|
|
2078
2104
|
}>>;
|
package/dist/index.d.ts
CHANGED
|
@@ -23,7 +23,8 @@ interface JunoTaskConfig {
|
|
|
23
23
|
mainTask?: string;
|
|
24
24
|
logLevel: LogLevel;
|
|
25
25
|
logFile?: string;
|
|
26
|
-
|
|
26
|
+
/** Verbosity level: 0=quiet, 1=normal+helping texts (default), 2=debug+hooks */
|
|
27
|
+
verbose: number;
|
|
27
28
|
quiet: boolean;
|
|
28
29
|
mcpTimeout: number;
|
|
29
30
|
mcpRetries: number;
|
|
@@ -35,6 +36,10 @@ interface JunoTaskConfig {
|
|
|
35
36
|
headlessMode: boolean;
|
|
36
37
|
workingDirectory: string;
|
|
37
38
|
sessionDirectory: string;
|
|
39
|
+
/** Path to project env file loaded on startup (relative to workingDirectory or absolute) */
|
|
40
|
+
envFilePath?: string;
|
|
41
|
+
/** Tracks whether the configured env file has been initialized from .env.juno */
|
|
42
|
+
envFileCopied?: boolean;
|
|
38
43
|
hooks?: Hooks;
|
|
39
44
|
skipHooks?: boolean;
|
|
40
45
|
}
|
|
@@ -89,7 +94,7 @@ declare const JunoTaskConfigSchema: z.ZodObject<{
|
|
|
89
94
|
mainTask: z.ZodOptional<z.ZodString>;
|
|
90
95
|
logLevel: z.ZodEnum<["error", "warn", "info", "debug", "trace"]>;
|
|
91
96
|
logFile: z.ZodOptional<z.ZodString>;
|
|
92
|
-
verbose: z.
|
|
97
|
+
verbose: z.ZodEffects<z.ZodNumber, number, unknown>;
|
|
93
98
|
quiet: z.ZodBoolean;
|
|
94
99
|
mcpTimeout: z.ZodNumber;
|
|
95
100
|
mcpRetries: z.ZodNumber;
|
|
@@ -101,6 +106,8 @@ declare const JunoTaskConfigSchema: z.ZodObject<{
|
|
|
101
106
|
headlessMode: z.ZodBoolean;
|
|
102
107
|
workingDirectory: z.ZodString;
|
|
103
108
|
sessionDirectory: z.ZodString;
|
|
109
|
+
envFilePath: z.ZodOptional<z.ZodString>;
|
|
110
|
+
envFileCopied: z.ZodOptional<z.ZodBoolean>;
|
|
104
111
|
hooks: z.ZodOptional<z.ZodRecord<z.ZodEnum<["START_RUN", "START_ITERATION", "END_ITERATION", "END_RUN", "ON_STALE"]>, z.ZodObject<{
|
|
105
112
|
commands: z.ZodArray<z.ZodString, "many">;
|
|
106
113
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -116,7 +123,7 @@ declare const JunoTaskConfigSchema: z.ZodObject<{
|
|
|
116
123
|
defaultModel?: string;
|
|
117
124
|
logLevel?: "error" | "warn" | "info" | "debug" | "trace";
|
|
118
125
|
logFile?: string;
|
|
119
|
-
verbose?:
|
|
126
|
+
verbose?: number;
|
|
120
127
|
quiet?: boolean;
|
|
121
128
|
mcpTimeout?: number;
|
|
122
129
|
mcpRetries?: number;
|
|
@@ -129,6 +136,8 @@ declare const JunoTaskConfigSchema: z.ZodObject<{
|
|
|
129
136
|
workingDirectory?: string;
|
|
130
137
|
sessionDirectory?: string;
|
|
131
138
|
mainTask?: string;
|
|
139
|
+
envFilePath?: string;
|
|
140
|
+
envFileCopied?: boolean;
|
|
132
141
|
hooks?: Partial<Record<"START_RUN" | "START_ITERATION" | "END_ITERATION" | "END_RUN" | "ON_STALE", {
|
|
133
142
|
commands?: string[];
|
|
134
143
|
}>>;
|
|
@@ -140,7 +149,7 @@ declare const JunoTaskConfigSchema: z.ZodObject<{
|
|
|
140
149
|
defaultModel?: string;
|
|
141
150
|
logLevel?: "error" | "warn" | "info" | "debug" | "trace";
|
|
142
151
|
logFile?: string;
|
|
143
|
-
verbose?:
|
|
152
|
+
verbose?: unknown;
|
|
144
153
|
quiet?: boolean;
|
|
145
154
|
mcpTimeout?: number;
|
|
146
155
|
mcpRetries?: number;
|
|
@@ -153,6 +162,8 @@ declare const JunoTaskConfigSchema: z.ZodObject<{
|
|
|
153
162
|
workingDirectory?: string;
|
|
154
163
|
sessionDirectory?: string;
|
|
155
164
|
mainTask?: string;
|
|
165
|
+
envFilePath?: string;
|
|
166
|
+
envFileCopied?: boolean;
|
|
156
167
|
hooks?: Partial<Record<"START_RUN" | "START_ITERATION" | "END_ITERATION" | "END_RUN" | "ON_STALE", {
|
|
157
168
|
commands?: string[];
|
|
158
169
|
}>>;
|
|
@@ -719,6 +730,8 @@ interface ExecutionRequest {
|
|
|
719
730
|
readonly resume?: string;
|
|
720
731
|
/** Continue the most recent conversation (forwarded to shell backend) */
|
|
721
732
|
readonly continueConversation?: boolean;
|
|
733
|
+
/** Extended thinking level (forwarded to shell backend --thinking flag) */
|
|
734
|
+
readonly thinking?: string;
|
|
722
735
|
}
|
|
723
736
|
/**
|
|
724
737
|
* Execution result interface for completed executions
|
|
@@ -1019,6 +1032,12 @@ declare class ExecutionEngine extends EventEmitter {
|
|
|
1019
1032
|
* Setup progress tracking for the engine
|
|
1020
1033
|
*/
|
|
1021
1034
|
private setupProgressTracking;
|
|
1035
|
+
/**
|
|
1036
|
+
* Display hook execution output to stderr at verbose level 2 (debug+hooks).
|
|
1037
|
+
* At level 2: shows hook name, command stdout/stderr output.
|
|
1038
|
+
* At level 0-1: output is suppressed (hooks still execute).
|
|
1039
|
+
*/
|
|
1040
|
+
private displayHookOutput;
|
|
1022
1041
|
/**
|
|
1023
1042
|
* Initialize backend for execution request.
|
|
1024
1043
|
* Directly creates and configures a ShellBackend (no factory indirection).
|
|
@@ -1168,6 +1187,7 @@ declare function createExecutionRequest(options: {
|
|
|
1168
1187
|
mcpServerName?: string;
|
|
1169
1188
|
resume?: string;
|
|
1170
1189
|
continueConversation?: boolean;
|
|
1190
|
+
thinking?: string;
|
|
1171
1191
|
}): ExecutionRequest;
|
|
1172
1192
|
|
|
1173
1193
|
/** Session metadata */
|
|
@@ -2009,7 +2029,7 @@ declare const ConfigValidationSchema: z.ZodObject<{
|
|
|
2009
2029
|
mainTask: z.ZodOptional<z.ZodString>;
|
|
2010
2030
|
logLevel: z.ZodEnum<["error", "warn", "info", "debug", "trace"]>;
|
|
2011
2031
|
logFile: z.ZodOptional<z.ZodString>;
|
|
2012
|
-
verbose: z.
|
|
2032
|
+
verbose: z.ZodEffects<z.ZodNumber, number, unknown>;
|
|
2013
2033
|
quiet: z.ZodBoolean;
|
|
2014
2034
|
mcpTimeout: z.ZodNumber;
|
|
2015
2035
|
mcpRetries: z.ZodNumber;
|
|
@@ -2021,6 +2041,8 @@ declare const ConfigValidationSchema: z.ZodObject<{
|
|
|
2021
2041
|
headlessMode: z.ZodBoolean;
|
|
2022
2042
|
workingDirectory: z.ZodString;
|
|
2023
2043
|
sessionDirectory: z.ZodString;
|
|
2044
|
+
envFilePath: z.ZodOptional<z.ZodString>;
|
|
2045
|
+
envFileCopied: z.ZodOptional<z.ZodBoolean>;
|
|
2024
2046
|
hooks: z.ZodOptional<z.ZodRecord<z.ZodEnum<["START_RUN", "START_ITERATION", "END_ITERATION", "END_RUN", "ON_STALE"]>, z.ZodObject<{
|
|
2025
2047
|
commands: z.ZodArray<z.ZodString, "many">;
|
|
2026
2048
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -2036,7 +2058,7 @@ declare const ConfigValidationSchema: z.ZodObject<{
|
|
|
2036
2058
|
defaultModel?: string;
|
|
2037
2059
|
logLevel?: "error" | "warn" | "info" | "debug" | "trace";
|
|
2038
2060
|
logFile?: string;
|
|
2039
|
-
verbose?:
|
|
2061
|
+
verbose?: number;
|
|
2040
2062
|
quiet?: boolean;
|
|
2041
2063
|
mcpTimeout?: number;
|
|
2042
2064
|
mcpRetries?: number;
|
|
@@ -2049,6 +2071,8 @@ declare const ConfigValidationSchema: z.ZodObject<{
|
|
|
2049
2071
|
workingDirectory?: string;
|
|
2050
2072
|
sessionDirectory?: string;
|
|
2051
2073
|
mainTask?: string;
|
|
2074
|
+
envFilePath?: string;
|
|
2075
|
+
envFileCopied?: boolean;
|
|
2052
2076
|
hooks?: Partial<Record<"START_RUN" | "START_ITERATION" | "END_ITERATION" | "END_RUN" | "ON_STALE", {
|
|
2053
2077
|
commands?: string[];
|
|
2054
2078
|
}>>;
|
|
@@ -2060,7 +2084,7 @@ declare const ConfigValidationSchema: z.ZodObject<{
|
|
|
2060
2084
|
defaultModel?: string;
|
|
2061
2085
|
logLevel?: "error" | "warn" | "info" | "debug" | "trace";
|
|
2062
2086
|
logFile?: string;
|
|
2063
|
-
verbose?:
|
|
2087
|
+
verbose?: unknown;
|
|
2064
2088
|
quiet?: boolean;
|
|
2065
2089
|
mcpTimeout?: number;
|
|
2066
2090
|
mcpRetries?: number;
|
|
@@ -2073,6 +2097,8 @@ declare const ConfigValidationSchema: z.ZodObject<{
|
|
|
2073
2097
|
workingDirectory?: string;
|
|
2074
2098
|
sessionDirectory?: string;
|
|
2075
2099
|
mainTask?: string;
|
|
2100
|
+
envFilePath?: string;
|
|
2101
|
+
envFileCopied?: boolean;
|
|
2076
2102
|
hooks?: Partial<Record<"START_RUN" | "START_ITERATION" | "END_ITERATION" | "END_RUN" | "ON_STALE", {
|
|
2077
2103
|
commands?: string[];
|
|
2078
2104
|
}>>;
|