@xdevops/issue-auto-finish 1.0.85 → 1.0.87
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/AIRunnerRegistry-II3WWSFN.js +31 -0
- package/dist/PtyRunner-6UGI5STW.js +22 -0
- package/dist/TerminalManager-RT2N7N5R.js +8 -0
- package/dist/ai-runner/AIRunner.d.ts +9 -1
- package/dist/ai-runner/AIRunner.d.ts.map +1 -1
- package/dist/ai-runner/AIRunnerRegistry.d.ts +37 -1
- package/dist/ai-runner/AIRunnerRegistry.d.ts.map +1 -1
- package/dist/ai-runner/PtyRunner.d.ts +114 -0
- package/dist/ai-runner/PtyRunner.d.ts.map +1 -0
- package/dist/ai-runner/index.d.ts +3 -1
- package/dist/ai-runner/index.d.ts.map +1 -1
- package/dist/{ai-runner-SVUNA3FX.js → ai-runner-HLA44WI6.js} +12 -3
- package/dist/{analyze-SXXPE5XL.js → analyze-ZIXNC5GN.js} +10 -8
- package/dist/{analyze-SXXPE5XL.js.map → analyze-ZIXNC5GN.js.map} +1 -1
- package/dist/{braindump-4E5SDMSZ.js → braindump-56WAY2RD.js} +10 -8
- package/dist/{braindump-4E5SDMSZ.js.map → braindump-56WAY2RD.js.map} +1 -1
- package/dist/{chunk-JINMYD56.js → chunk-2MESXJEZ.js} +3 -3
- package/dist/{chunk-P4O4ZXEC.js → chunk-2YQHKXLL.js} +40 -19
- package/dist/chunk-2YQHKXLL.js.map +1 -0
- package/dist/chunk-AVGZH64A.js +211 -0
- package/dist/chunk-AVGZH64A.js.map +1 -0
- package/dist/{chunk-5UPYA6KH.js → chunk-IP3QTP5A.js} +1028 -763
- package/dist/chunk-IP3QTP5A.js.map +1 -0
- package/dist/chunk-KC5S66OZ.js +177 -0
- package/dist/chunk-KC5S66OZ.js.map +1 -0
- package/dist/{chunk-4QV6D34Y.js → chunk-M5C2WILQ.js} +8 -6
- package/dist/{chunk-4QV6D34Y.js.map → chunk-M5C2WILQ.js.map} +1 -1
- package/dist/{chunk-FWEW5E3B.js → chunk-NZHKAPU6.js} +35 -5
- package/dist/chunk-NZHKAPU6.js.map +1 -0
- package/dist/{chunk-KTYPZTF4.js → chunk-O3WEV5W3.js} +10 -2
- package/dist/chunk-O3WEV5W3.js.map +1 -0
- package/dist/{chunk-K2OTLYJI.js → chunk-QZZGIZWC.js} +457 -202
- package/dist/chunk-QZZGIZWC.js.map +1 -0
- package/dist/{chunk-4LFNFRCL.js → chunk-SAMTXC4A.js} +91 -214
- package/dist/chunk-SAMTXC4A.js.map +1 -0
- package/dist/chunk-U237JSLB.js +1 -0
- package/dist/chunk-U237JSLB.js.map +1 -0
- package/dist/chunk-U6GWFTKA.js +657 -0
- package/dist/chunk-U6GWFTKA.js.map +1 -0
- package/dist/{chunk-HOFYJEJ4.js → chunk-UBQLXQ7I.js} +11 -11
- package/dist/cli/setup/env-metadata.d.ts.map +1 -1
- package/dist/cli.js +8 -7
- package/dist/cli.js.map +1 -1
- package/dist/{config-QLINHCHD.js → config-WTRSZLOC.js} +4 -3
- package/dist/config-WTRSZLOC.js.map +1 -0
- package/dist/config-schema.d.ts +17 -1
- package/dist/config-schema.d.ts.map +1 -1
- package/dist/config.d.ts +20 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/errors/PhaseAbortedError.d.ts +3 -3
- package/dist/errors/PhaseAbortedError.d.ts.map +1 -1
- package/dist/errors-S3BWYA4I.js +43 -0
- package/dist/errors-S3BWYA4I.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -11
- package/dist/{init-TDKDC6YP.js → init-QQDXGTPB.js} +7 -6
- package/dist/{init-TDKDC6YP.js.map → init-QQDXGTPB.js.map} +1 -1
- package/dist/lib.js +9 -7
- package/dist/lib.js.map +1 -1
- package/dist/orchestrator/IssueProcessingContext.d.ts +39 -21
- package/dist/orchestrator/IssueProcessingContext.d.ts.map +1 -1
- package/dist/orchestrator/PipelineOrchestrator.d.ts +10 -1
- package/dist/orchestrator/PipelineOrchestrator.d.ts.map +1 -1
- package/dist/orchestrator/steps/PhaseLoopStep.d.ts +1 -1
- package/dist/orchestrator/steps/PhaseLoopStep.d.ts.map +1 -1
- package/dist/orchestrator/steps/SetupStep.d.ts.map +1 -1
- package/dist/persistence/PlanPersistence.d.ts +7 -1
- package/dist/persistence/PlanPersistence.d.ts.map +1 -1
- package/dist/phases/BasePhase.d.ts +31 -42
- package/dist/phases/BasePhase.d.ts.map +1 -1
- package/dist/phases/BuildPhase.d.ts.map +1 -1
- package/dist/phases/PhaseFactory.d.ts +2 -3
- package/dist/phases/PhaseFactory.d.ts.map +1 -1
- package/dist/phases/PhaseOutcome.d.ts +42 -0
- package/dist/phases/PhaseOutcome.d.ts.map +1 -0
- package/dist/phases/PlanPhase.d.ts +1 -1
- package/dist/phases/PlanPhase.d.ts.map +1 -1
- package/dist/phases/ReleasePhase.d.ts +8 -18
- package/dist/phases/ReleasePhase.d.ts.map +1 -1
- package/dist/phases/UatPhase.d.ts +7 -24
- package/dist/phases/UatPhase.d.ts.map +1 -1
- package/dist/phases/VerifyPhase.d.ts +4 -4
- package/dist/phases/VerifyPhase.d.ts.map +1 -1
- package/dist/poller/IssuePoller.d.ts.map +1 -1
- package/dist/prompts/release-templates.d.ts.map +1 -1
- package/dist/prompts/templates.d.ts.map +1 -1
- package/dist/{restart-RNXGTDWZ.js → restart-BMILTP5X.js} +6 -5
- package/dist/{restart-RNXGTDWZ.js.map → restart-BMILTP5X.js.map} +1 -1
- package/dist/run.js +14 -11
- package/dist/run.js.map +1 -1
- package/dist/settings/ExperimentalSettings.d.ts +1 -1
- package/dist/settings/ExperimentalSettings.d.ts.map +1 -1
- package/dist/start-6QRW6IJI.js +15 -0
- package/dist/start-6QRW6IJI.js.map +1 -0
- package/dist/terminal/TerminalManager.d.ts +62 -0
- package/dist/terminal/TerminalManager.d.ts.map +1 -0
- package/dist/terminal/TerminalWebSocket.d.ts +9 -0
- package/dist/terminal/TerminalWebSocket.d.ts.map +1 -0
- package/dist/tracker/ExecutableTask.d.ts +4 -2
- package/dist/tracker/ExecutableTask.d.ts.map +1 -1
- package/dist/tracker/IssueState.d.ts +11 -1
- package/dist/tracker/IssueState.d.ts.map +1 -1
- package/dist/tracker/IssueTracker.d.ts +19 -1
- package/dist/tracker/IssueTracker.d.ts.map +1 -1
- package/dist/web/WebServer.d.ts +4 -0
- package/dist/web/WebServer.d.ts.map +1 -1
- package/dist/web/routes/terminal.d.ts +11 -0
- package/dist/web/routes/terminal.d.ts.map +1 -0
- package/dist/webhook/CommandExecutor.d.ts.map +1 -1
- package/package.json +7 -1
- package/src/web/frontend/dist/assets/index-COYziOhv.css +1 -0
- package/src/web/frontend/dist/assets/index-D_oTMuJU.js +151 -0
- package/src/web/frontend/dist/index.html +2 -2
- package/dist/chunk-4LFNFRCL.js.map +0 -1
- package/dist/chunk-5UPYA6KH.js.map +0 -1
- package/dist/chunk-DADQSKPL.js +0 -1
- package/dist/chunk-FWEW5E3B.js.map +0 -1
- package/dist/chunk-K2OTLYJI.js.map +0 -1
- package/dist/chunk-KTYPZTF4.js.map +0 -1
- package/dist/chunk-P4O4ZXEC.js.map +0 -1
- package/dist/start-27GRO4DP.js +0 -14
- package/src/web/frontend/dist/assets/index-C4NXoH9S.js +0 -133
- package/src/web/frontend/dist/assets/index-C7lorIa0.css +0 -1
- /package/dist/{ai-runner-SVUNA3FX.js.map → AIRunnerRegistry-II3WWSFN.js.map} +0 -0
- /package/dist/{chunk-DADQSKPL.js.map → PtyRunner-6UGI5STW.js.map} +0 -0
- /package/dist/{config-QLINHCHD.js.map → TerminalManager-RT2N7N5R.js.map} +0 -0
- /package/dist/{start-27GRO4DP.js.map → ai-runner-HLA44WI6.js.map} +0 -0
- /package/dist/{chunk-JINMYD56.js.map → chunk-2MESXJEZ.js.map} +0 -0
- /package/dist/{chunk-HOFYJEJ4.js.map → chunk-UBQLXQ7I.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ai-runner/PtyRunner.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport type { AIRunner, RunOptions, RunResult, StreamEvent } from './AIRunner.js';\nimport type { PtyProfile } from './AIRunnerRegistry.js';\nimport { getPtyProfile, getRegistryEntry } from './AIRunnerRegistry.js';\nimport { getRunnerCapabilities } from './AIRunnerRegistry.js';\nimport { resolveModelForRunner } from './ModelMapping.js';\nimport type { TerminalManager } from '../terminal/TerminalManager.js';\nimport { isShuttingDown } from '../shutdown/ShutdownSignal.js';\nimport { logger as rootLogger } from '../logger.js';\n\nconst logger = rootLogger.child('PtyRunner');\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n// eslint-disable-next-line no-control-regex\nconst ANSI_RE = /\\x1b\\[[?><=]*[0-9;]*[a-zA-Z~]|\\x1b\\][^\\x07]*\\x07|\\x1b\\(B/g;\n\nexport function stripAnsi(str: string): string {\n return str.replace(ANSI_RE, '');\n}\n\n/** Best-effort extraction of issue IID from a worktree path like `.../issue-123/...` */\nfunction extractIidFromPath(workDir: string): number | undefined {\n const match = workDir.match(/issue-(\\d+)/);\n return match ? parseInt(match[1], 10) : undefined;\n}\n\n/** Claude Code / Codebuddy shows a prompt when idle and waiting for user input.\n * - Claude Code: ❯ (U+276F) — unique character, safe to match broadly\n * - Codebuddy: > — appears between separator lines, above ⏵⏵ status bar\n */\nexport function isIdlePrompt(stripped: string): boolean {\n const lines = stripped.split('\\n').filter((l) => l.trim());\n if (lines.length === 0) return false;\n const last = lines[lines.length - 1].trim();\n // 1. Prompt character on the last non-empty line\n if (/^[❯>$%]\\s*$/.test(last) || /[❯>]\\s*$/.test(last)) return true;\n // 2. Claude Code TUI: ❯ may appear mid-line due to cursor-positioned rendering\n // (status bar appended below, cursor coordinate artifacts like \"42\" after ❯).\n // Three-step heuristic: standalone ❯ + not followed by a sentence = idle.\n if (lines.some((l) => {\n const t = l.trim();\n // ❯ must be standalone (preceded by whitespace or at start of string)\n if (!/(?:^|\\s)❯/.test(t)) return false;\n // ❯ at line end → definitely idle\n if (/❯\\s*$/.test(t)) return true;\n // ❯ followed by 3+ letter word → input echo / queued message, not idle\n return !/❯\\s+[A-Za-z]{3,}/.test(t);\n })) return true;\n // 3. Codebuddy TUI: > prompt appears above the ⏵⏵ status bar, so it's NOT\n // the last line. Use ⏵ as a Codebuddy-specific guard to distinguish from\n // random > in markdown/agent output.\n if (lines.some((l) => /^>/.test(l.trim())) && /⏵/.test(stripped)) return true;\n // 4. cursor-agent TUI: → placeholder in input box + footer with / commands,\n // and NO \"ctrl+c to stop\" (which indicates generation in progress).\n if (\n /→/.test(stripped) &&\n /\\/\\s*commands/.test(stripped) &&\n !/ctrl\\+c\\s*to\\s*stop/i.test(stripped)\n ) {\n return true;\n }\n return false;\n}\n\n// ---- Known TUI noise patterns ------------------------------------------------\n\nconst SPINNER_CHARS = '✶✻✽✢✾◆❖●◐◑◒◓○⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏⠂⠒⠐⠈⠠⠤·*…⋯⬡⬢';\nconst SPINNER_RE = new RegExp(`^[${SPINNER_CHARS}\\\\s]+$`);\nconst SPINNER_FRAGMENT_RE = new RegExp(`^[${SPINNER_CHARS}][a-zA-Z]{0,3}$`);\nconst STATUS_BAR_RE = /bypass permissions|shift\\+tab|ctrl\\+[a-z].*(?:to |edit)|to interrupt|to cycle|⏵.*(?:bypass|permission)/;\nconst THINKING_RE = /^[^\\w]*\\w[\\w-]*…\\s*$/;\nconst SEPARATOR_RE = /^[─━═-]{10,}$/;\nconst EFFORT_RE = /^[◐◑◒◓]\\s+(?:low|medium|high)\\s+·\\s+\\/effort$/;\n// Claude Code status bar: spinner + elapsed time + token count, e.g. \"✶80s · ↓ 14.2k tokens)\"\nconst CLAUDE_STATUS_BAR_RE = new RegExp(`^[${SPINNER_CHARS}]\\\\s*\\\\d+[smh]`);\n// Cursor positioning artifacts: bare 1-3 digit numbers left after ANSI stripping\nconst CURSOR_ARTIFACT_RE = /^\\d{1,3}$/;\n\n// ---- cursor-agent TUI noise patterns ----------------------------------------\nconst CURSOR_GENERATING_RE = /^[⬡⬢]\\s*Generating/;\nconst CURSOR_FOOTER_RE = /^\\/\\s*commands\\s*·\\s*@\\s*files\\s*·\\s*!\\s*shell$/;\nconst CURSOR_STATUS_RE = /^▶︎?\\s*Auto-run/;\nconst CURSOR_MODEL_RE = /^(?:Opus|Claude|GPT|Gemini|当前使用的模型)\\s*/;\nconst BOX_DRAWING_RE = /^[┌┐└┘│─┬┴├┤╭╮╰╯═║╔╗╚╝╠╣╦╩╬\\s]*$/;\n// Claude Code queued message indicator — NOT an idle prompt\nconst QUEUED_MSG_RE = /Press\\s*up\\s*to\\s*edit\\s*queued\\s*messages/;\n\n/** Workspace trust dialog — TUI strips spaces, so use \\s* between words.\n * Claude Code: \"trust this folder\" / \"I trust this\"\n * Codebuddy: \"Do you trust the files in this folder?\"\n */\nexport const TRUST_DIALOG_RE = /trust\\s*(?:the\\s*files\\s*in\\s*)?this\\s*(?:folder|workspace)|I\\s*trust\\s*this/i;\n\n/** Permission / confirmation dialog — Claude Code asks \"Do you want to proceed?\"\n * when running potentially dangerous commands in plan mode.\n * The dialog shows numbered options with \"Yes\" pre-selected (❯ 1. Yes).\n * Auto-confirm by sending Enter to select the highlighted option. */\nexport const PERMISSION_DIALOG_RE =\n /Do\\s*you\\s*want\\s*to\\s*proceed\\s*\\?|(?:❯|>)\\s*\\d+\\.\\s*Yes\\b|Allow\\s+(?:this|the)\\s+(?:action|command)\\s*\\?/i;\n\n/**\n * Check if a PTY data frame contains active work content alongside the idle\n * prompt. Claude Code TUI co-renders the ❯ prompt with tool results, file\n * listings, and thinking indicators in a single data frame. When both are\n * present, the frame is a \"mixed frame\" — the agent is still active.\n *\n * Returns true when the frame has meaningful non-noise, non-prompt content.\n */\nexport function containsActiveWork(stripped: string): boolean {\n const lines = stripped.split(/[\\r\\n]+/).filter(l => l.trim());\n let inTipBlock = false;\n\n return lines.some(line => {\n const t = line.trim();\n if (t.length === 0) return false;\n\n if (/Tip:/i.test(t)) {\n inTipBlock = true;\n return false;\n }\n if (inTipBlock) return false;\n\n if (/ctrl\\+o to expand/i.test(t)) return false;\n if (/^⎿/.test(t)) return false;\n if (/^[❯>$%]\\s*$/.test(t) || /[❯>]\\s*$/.test(t)) return false;\n if (isTuiNoise(t)) return false;\n return true;\n });\n}\n\n/** True when the line is Claude Code TUI chrome (spinners, status bar, etc.) */\nexport function isTuiNoise(line: string): boolean {\n const t = line.replace(/\\r/g, '').trim();\n if (t.length === 0) return true;\n if (SPINNER_RE.test(t)) return true;\n if (t.length <= 4 && SPINNER_FRAGMENT_RE.test(t)) return true;\n if (STATUS_BAR_RE.test(t)) return true;\n if (THINKING_RE.test(t)) return true;\n if (SEPARATOR_RE.test(t)) return true;\n if (EFFORT_RE.test(t)) return true;\n if (CLAUDE_STATUS_BAR_RE.test(t)) return true;\n if (QUEUED_MSG_RE.test(t)) return true;\n if (CURSOR_ARTIFACT_RE.test(t)) return true;\n // cursor-agent patterns\n if (CURSOR_GENERATING_RE.test(t)) return true;\n if (CURSOR_FOOTER_RE.test(t)) return true;\n if (CURSOR_STATUS_RE.test(t)) return true;\n if (CURSOR_MODEL_RE.test(t)) return true;\n if (BOX_DRAWING_RE.test(t) && t.length > 1) return true;\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// Completion detection result\n// ---------------------------------------------------------------------------\n\ninterface CompletionResult {\n output: string;\n timedOut: boolean;\n timeoutType?: 'wall-clock' | 'idle';\n}\n\n// ---------------------------------------------------------------------------\n// Session tracking\n// ---------------------------------------------------------------------------\n\ninterface PtySessionInfo {\n sessionId: string;\n agentMode: string;\n /** Current interactive mode (e.g. 'bypass', 'plan', 'accept-edits'). Tracked\n * so that mode-cycle keys are only sent when the mode actually needs to change. */\n currentMode: string;\n /** The mode this session was launched with via CLI args (undefined = agent default) */\n startedWithMode?: string;\n}\n\n// ---------------------------------------------------------------------------\n// PtyRunner\n// ---------------------------------------------------------------------------\n\n/**\n * AIRunner implementation that drives persistent interactive AI agent\n * terminal sessions (PTY) per issue.\n *\n * Supports multiple agent types (claude-internal, codebuddy, cursor-agent).\n * Each phase can use a different agent; sessions are reused when the agent\n * doesn't change between consecutive phases, and recreated when it does.\n */\nexport class PtyRunner implements AIRunner {\n /** workDir → active session info (sessionId + current agent type) */\n private sessions = new Map<string, PtySessionInfo>();\n\n /** Sessions that were forcefully killed (via killByWorkDir/killAll). Checked by\n * detectCompletion's onExit handler to report failure instead of success. */\n private killedSessions = new Set<string>();\n\n constructor(\n private readonly nvmNodeVersion: string,\n private readonly terminalManager: TerminalManager,\n private readonly defaultAgentMode: string,\n private readonly phaseAgentMap: Record<string, string>,\n private readonly globalModel?: string,\n private readonly idleDetectMs: number = 30_000,\n ) {}\n\n // ---- AIRunner interface ---------------------------------------------------\n\n async run(options: RunOptions): Promise<RunResult> {\n if (isShuttingDown()) {\n logger.warn('PtyRunner skipped — service is shutting down');\n return { success: false, output: 'Service shutting down', exitCode: null };\n }\n\n const { prompt, workDir, timeoutMs, onStreamEvent, phaseName } = options;\n const agentMode = this.resolveAgentForPhase(phaseName);\n const startMode = options.mode; // 'plan' | undefined currently; extensible for future modes\n\n logger.info('PtyRunner.run()', { workDir, timeoutMs, phaseName, agentMode });\n\n // 1. Ensure persistent PTY session (creates or reuses based on agent match)\n const { sessionId, isNew } = this.ensureSession(workDir, agentMode, startMode);\n\n // 2. Wait for Claude Code to be ready before sending commands.\n // New sessions need time to initialize (banner, config loading, etc.).\n if (isNew) {\n logger.info('Waiting for AI agent prompt (new session)', { sessionId, phaseName });\n // Custom agents (e.g. claude-internal) may show banners/notices before\n // entering interactive mode. Allow up to 5 min for first-time startup.\n await this.waitForPrompt(sessionId, 300_000);\n } else {\n // Reused session may have been interrupted (Ctrl+C) by retryFromPhase.\n // Brief wait for the agent to settle back to idle prompt.\n logger.info('Waiting for AI agent prompt (reused session)', { sessionId, phaseName });\n await this.waitForPrompt(sessionId, 10_000);\n }\n\n // 2.5 Native plan mode: two-phase execution\n // Phase 1: switch to plan mode → execute plan prompt (no artifact gate)\n // Phase 2: switch to bypass → commit plan to disk file (with artifact gate)\n if (startMode === 'plan' && this.shouldUseNativePlan(agentMode)) {\n return this.runNativePlanMode(sessionId, isNew, options, agentMode, workDir);\n }\n\n // 2.5 Toggle interactive mode if needed (Shift+Tab fallback for reused sessions)\n await this.ensurePlanMode(sessionId, agentMode, startMode === 'plan', workDir);\n\n // 3. Send /clear to reset context.\n // /clear only resets conversation history — the ❯ prompt stays on screen\n // and is NOT re-emitted by the PTY (TUI sends delta updates only).\n // A brief delay is sufficient for the command to process.\n await this.writeCommand(sessionId, '/clear', agentMode);\n await new Promise(resolve => setTimeout(resolve, 2_000));\n\n // 4. Write prompt to file\n const promptFile = this.writePromptFile(workDir, prompt);\n\n // 5. Send instruction to read the prompt file\n const instruction = `Please read and follow all instructions in ${promptFile}`;\n await this.writeCommand(sessionId, instruction, agentMode);\n\n // 5. Wait for completion\n const result = await this.detectCompletion(sessionId, options, onStreamEvent);\n\n logger.info('PtyRunner phase completed', {\n workDir,\n agentMode,\n phaseName,\n timedOut: result.timedOut,\n outputLength: result.output.length,\n });\n\n return {\n success: !result.timedOut,\n output: result.output,\n errorMessage: result.timedOut\n ? (result.timeoutType === 'idle' ? 'AI 长时间无响应,已超时终止' : '执行超时')\n : undefined,\n sessionId,\n exitCode: result.timedOut ? null : 0,\n timeoutType: result.timeoutType,\n };\n }\n\n killAll(): void {\n for (const [, info] of this.sessions) {\n this.killedSessions.add(info.sessionId);\n this.terminalManager.destroy(info.sessionId);\n }\n this.sessions.clear();\n logger.info('PtyRunner: all managed sessions destroyed');\n }\n\n killByWorkDir(targetWorkDir: string): number {\n const info = this.sessions.get(targetWorkDir);\n if (!info) return 0;\n this.killedSessions.add(info.sessionId);\n this.terminalManager.destroy(info.sessionId);\n this.sessions.delete(targetWorkDir);\n return 1;\n }\n\n interruptByWorkDir(targetWorkDir: string): boolean {\n const info = this.sessions.get(targetWorkDir);\n if (!info) return false;\n\n const session = this.terminalManager.get(info.sessionId);\n if (!session) {\n // Session died externally — clean up tracking\n this.sessions.delete(targetWorkDir);\n return false;\n }\n\n // Send Ctrl+C to interrupt any running task without destroying the session\n this.terminalManager.write(info.sessionId, '\\x03');\n logger.info('Interrupted PTY session for retry', {\n workDir: targetWorkDir,\n sessionId: info.sessionId,\n });\n return true;\n }\n\n // ---- Agent resolution ----------------------------------------------------\n\n /** Get the Enter key sequence for the given agent mode */\n private getEnterKey(agentMode: string): string {\n const profile = getPtyProfile(agentMode);\n return profile?.enterKey ?? '\\r';\n }\n\n /**\n * Write a command to the PTY and press Enter.\n *\n * Some agents (codebuddy) use input coalescing in their TUI: when text and\n * Enter arrive in the same PTY write, the Enter is treated as a newline\n * character (paste) instead of triggering message submission. For these\n * agents (PtyProfile.separateEnter=true), text and Enter are sent in\n * separate writes with a 150ms gap so the Enter key is recognized as\n * a standalone key press.\n */\n private async writeCommand(sessionId: string, text: string, agentMode: string): Promise<void> {\n const enterKey = this.getEnterKey(agentMode);\n const profile = getPtyProfile(agentMode);\n\n if (profile?.separateEnter) {\n this.terminalManager.write(sessionId, text);\n await new Promise(resolve => setTimeout(resolve, 150));\n this.terminalManager.write(sessionId, enterKey);\n } else {\n this.terminalManager.write(sessionId, text + enterKey);\n }\n }\n\n /** Resolve agent mode for a given phase (fallback to default) */\n private resolveAgentForPhase(phaseName?: string): string {\n if (phaseName && this.phaseAgentMap[phaseName]) {\n return this.phaseAgentMap[phaseName];\n }\n return this.defaultAgentMode;\n }\n\n /** Look up PtyProfile from registry + resolve agent-specific binary and model */\n private resolveProfileAndModel(agentMode: string): {\n profile: PtyProfile;\n model: string | undefined;\n binary: string;\n } {\n const profile = getPtyProfile(agentMode);\n if (!profile) {\n throw new Error(\n `Agent \"${agentMode}\" has no PtyProfile — not supported in PTY mode. ` +\n `Compatible agents: claude-internal, codebuddy, cursor-agent`,\n );\n }\n const entry = getRegistryEntry(agentMode);\n const binary = (entry && process.env[entry.binaryEnvKey]) || entry?.defaultBinary || agentMode;\n const model = this.globalModel\n ? resolveModelForRunner(agentMode, this.globalModel)\n : undefined;\n return { profile, model, binary };\n }\n\n // ---- Session management ---------------------------------------------------\n\n private ensureSession(workDir: string, agentMode: string, startMode?: string): { sessionId: string; isNew: boolean } {\n const existing = this.sessions.get(workDir);\n\n // Agent switched → destroy old session\n if (existing && existing.agentMode !== agentMode) {\n logger.info('Agent switched, destroying old PTY session', {\n workDir,\n oldAgent: existing.agentMode,\n newAgent: agentMode,\n sessionId: existing.sessionId,\n });\n this.terminalManager.destroy(existing.sessionId);\n this.sessions.delete(workDir);\n }\n\n // Same agent → reuse if alive\n if (existing && existing.agentMode === agentMode) {\n if (this.terminalManager.get(existing.sessionId)) {\n logger.info('Reusing existing PTY session (same agent)', {\n workDir,\n agentMode,\n sessionId: existing.sessionId,\n });\n return { sessionId: existing.sessionId, isNew: false };\n }\n // Session died externally, clean up tracking\n this.sessions.delete(workDir);\n }\n\n // Check for orphaned sessions (e.g. from previous run or WebSocket)\n // Cannot safely reuse — we don't know what agent spawned it\n const orphan = this.terminalManager.findByWorkDir(workDir);\n if (orphan) {\n logger.info('Destroying orphaned PTY session on workDir', {\n workDir,\n sessionId: orphan.id,\n });\n this.terminalManager.destroy(orphan.id);\n }\n\n // Create new managed session with the resolved agent's binary and args\n const { profile, model, binary } = this.resolveProfileAndModel(agentMode);\n const args = profile.buildPtyArgs({ model, startMode });\n const issueIid = extractIidFromPath(workDir);\n\n const info = this.terminalManager.create({\n workDir,\n issueIid,\n command: binary,\n args,\n managed: true,\n });\n\n this.sessions.set(workDir, {\n sessionId: info.id,\n agentMode,\n // Always set initial mode to defaultModeName — CLI args always use bypass\n // (startMode is applied at runtime via Shift+Tab in ensurePlanMode).\n currentMode: profile.defaultModeName ?? 'bypass',\n startedWithMode: startMode,\n });\n logger.info('Created new PTY session', {\n workDir,\n agentMode,\n binary,\n args,\n sessionId: info.id,\n pid: info.pid,\n issueIid,\n });\n return { sessionId: info.id, isNew: true };\n }\n\n // ---- Prompt delivery ------------------------------------------------------\n\n /**\n * Wait for the AI agent to show its idle prompt (❯ or >), indicating\n * it is ready to accept input. Used before sending /clear and instructions\n * to prevent commands from arriving before the agent is initialized.\n */\n private waitForPrompt(sessionId: string, timeoutMs: number = 60_000): Promise<void> {\n return new Promise<void>((resolve) => {\n let promptSeen = false;\n let trustDialogHandled = false;\n let stabilityTimer: ReturnType<typeof setTimeout> | undefined;\n // After a prompt is first detected, wait this long with no new output\n // to confirm the agent is truly idle (not still initialising — e.g.\n // MCP auth, IDE extension install can arrive after the ❯ prompt renders).\n const STABILITY_MS = 3_000;\n\n // Secondary: TUI status bar (e.g. \"bypass permissions on (shift+tab to cycle)\")\n // is a strong signal that the input area is fully rendered. The ❯ prompt\n // exists in the same data frame but isIdlePrompt may fail on full-screen\n // renders where ❯ is embedded among other TUI content.\n const TUI_READY_RE = /bypass\\s*permissions|shift\\+?\\s*tab\\s*to\\s*cycle/i;\n let tuiReady = false;\n\n // Fallback: Claude Code TUI may render the ❯ prompt via cursor-positioning\n // sequences that don't produce a discrete onData event. When the banner has\n // been shown and the PTY goes silent, treat the agent as ready.\n let bannerSeen = false;\n let silenceTimer: ReturnType<typeof setTimeout> | undefined;\n const SILENCE_READY_MS = 8_000;\n\n const timer = setTimeout(() => {\n if (stabilityTimer) clearTimeout(stabilityTimer);\n if (silenceTimer) clearTimeout(silenceTimer);\n subscription.dispose();\n logger.warn('Timed out waiting for AI agent prompt', { sessionId, timeoutMs });\n // Resolve instead of reject — best-effort, let the run proceed\n resolve();\n }, timeoutMs);\n\n const done = (reason: string) => {\n clearTimeout(timer);\n if (stabilityTimer) clearTimeout(stabilityTimer);\n if (silenceTimer) clearTimeout(silenceTimer);\n subscription.dispose();\n logger.info('AI agent prompt detected', { sessionId, reason });\n resolve();\n };\n\n const resetSilenceTimer = () => {\n if (!bannerSeen) return;\n if (silenceTimer) clearTimeout(silenceTimer);\n silenceTimer = setTimeout(() => {\n if (promptSeen) return; // Primary detection already succeeded\n logger.info('Banner shown and PTY silent — treating agent as ready', { sessionId });\n done('silence-after-banner');\n }, SILENCE_READY_MS);\n };\n\n const subscription = this.terminalManager.onData(sessionId, (data: string) => {\n const stripped = stripAnsi(data);\n\n // Classify TUI noise (consistent with detectCompletion)\n const nonEmptyLines = stripped.split('\\n').filter((l) => l.trim());\n const isNoise = nonEmptyLines.length === 0 || nonEmptyLines.every((l) => isTuiNoise(l));\n\n // Detect Claude Code banner to enable silence-based readiness fallback.\n if (!bannerSeen && /Claude\\s*Code/i.test(stripped)) {\n bannerSeen = true;\n }\n\n // Reset silence timer on every data event (noise or not) — we want to\n // detect true silence (no PTY output at all), not filtered silence.\n resetSilenceTimer();\n\n // Auto-confirm workspace trust dialog in new worktree directories.\n // TUI cursor positioning removes spaces after ANSI stripping, so use\n // \\s* between words to match both \"trust this folder\" and \"trustthisfolder\".\n if (!trustDialogHandled && TRUST_DIALOG_RE.test(stripped)) {\n trustDialogHandled = true;\n logger.info('Trust dialog detected, auto-confirming', { sessionId });\n setTimeout(() => this.terminalManager.write(sessionId, '\\r'), 500);\n }\n\n // Auto-approve permission/confirmation dialogs that appear during\n // startup or between phases (e.g. leftover prompt from a previous task).\n if (PERMISSION_DIALOG_RE.test(stripped)) {\n logger.info('Permission dialog detected in waitForPrompt, auto-confirming', { sessionId });\n setTimeout(() => this.terminalManager.write(sessionId, '\\r'), 500);\n }\n\n if (isIdlePrompt(stripped)) {\n promptSeen = true;\n }\n\n if (!tuiReady && TUI_READY_RE.test(stripped)) {\n tuiReady = true;\n }\n\n // Once the agent is considered ready (idle prompt detected OR TUI status\n // bar rendered), (re)start a stability timer.\n // CRITICAL: TUI noise (spinners, status bar ~100ms updates) must NOT\n // reset the timer — otherwise it can never complete. Only substantive\n // output (e.g. MCP auth dialog, extension install notice) resets it.\n if (promptSeen || tuiReady) {\n if (stabilityTimer && isNoise) {\n // Already waiting — noise-only frame, let the timer continue\n } else {\n if (stabilityTimer) clearTimeout(stabilityTimer);\n const reason = promptSeen ? 'idle-prompt-stable' : 'status-bar-ready';\n stabilityTimer = setTimeout(() => done(reason), STABILITY_MS);\n }\n }\n });\n });\n }\n\n // ---- Interactive mode switching --------------------------------------------\n\n /**\n * Switch the PTY session to (or away from) plan mode by pressing the mode\n * cycle key (Shift+Tab) until the target mode is detected in the output.\n *\n * This is a no-op when the agent has no modeCycleKey configured, or the\n * session is already in the desired mode.\n */\n private async ensurePlanMode(\n sessionId: string,\n agentMode: string,\n wantPlan: boolean,\n workDir: string,\n ): Promise<void> {\n const profile = getPtyProfile(agentMode);\n if (!profile?.modeCycleKey || !profile.detectMode || !profile.planModeName) return;\n\n const session = this.sessions.get(workDir);\n if (!session) return;\n\n const targetMode = wantPlan ? profile.planModeName : (profile.defaultModeName ?? 'bypass');\n if (session.currentMode === targetMode) {\n logger.info('PTY already in target mode', { sessionId, targetMode });\n return;\n }\n\n const MAX_ATTEMPTS = 5;\n for (let i = 0; i < MAX_ATTEMPTS; i++) {\n // Start collecting BEFORE sending the key — the mode indicator is emitted\n // within milliseconds of the key press and would be missed if we waited.\n const outputPromise = this.collectRecentOutput(sessionId, 3_000);\n this.terminalManager.write(sessionId, profile.modeCycleKey);\n const recentOutput = await outputPromise;\n\n const detected = profile.detectMode(recentOutput);\n\n if (detected) {\n session.currentMode = detected;\n if (detected === targetMode) {\n logger.info('PTY mode switched', {\n sessionId, agentMode, targetMode, attempts: i + 1,\n });\n return;\n }\n }\n }\n\n logger.warn('Failed to switch PTY mode after max attempts', {\n sessionId, agentMode, targetMode, current: session.currentMode,\n });\n }\n\n /**\n * Briefly subscribe to PTY output and collect all data emitted during a\n * window. Used by ensurePlanMode to read the mode indicator after pressing\n * the cycle key.\n */\n private collectRecentOutput(sessionId: string, durationMs: number): Promise<string> {\n return new Promise(resolve => {\n const chunks: string[] = [];\n const subscription = this.terminalManager.onData(sessionId, (data: string) => {\n chunks.push(stripAnsi(data));\n });\n setTimeout(() => {\n subscription.dispose();\n resolve(chunks.join(''));\n }, durationMs);\n });\n }\n\n // ---- Native plan mode (two-phase execution) --------------------------------\n\n /**\n * Whether the agent supports the two-phase native plan strategy:\n * bypass start → Shift+Tab to plan → execute → Shift+Tab to bypass → commit file.\n *\n * Conditions: runner does NOT natively handle plan mode on its own (nativePlanMode=false)\n * AND the PTY profile supports interactive mode switching (modeCycleKey + planModeName).\n */\n private shouldUseNativePlan(agentMode: string): boolean {\n const caps = getRunnerCapabilities(agentMode);\n const profile = getPtyProfile(agentMode);\n return !caps?.nativePlanMode && !!profile?.modeCycleKey && !!profile?.planModeName;\n }\n\n /**\n * Two-phase plan execution:\n * Phase 1 — Switch to plan mode, send plan prompt, wait for idle (no artifact gate).\n * Phase 2 — Switch to bypass, send commit prompt, wait for artifact file on disk.\n */\n private async runNativePlanMode(\n sessionId: string,\n isNew: boolean,\n options: RunOptions,\n agentMode: string,\n workDir: string,\n ): Promise<RunResult> {\n // ── Phase 1: native plan mode ──\n logger.info('Native plan mode: switching to plan', { sessionId, agentMode });\n await this.ensurePlanMode(sessionId, agentMode, true, workDir);\n\n if (!isNew) {\n await this.writeCommand(sessionId, '/clear', agentMode);\n await new Promise(resolve => setTimeout(resolve, 2_000));\n }\n\n const promptFile = this.writePromptFile(workDir, options.prompt);\n await this.writeCommand(\n sessionId,\n `Please read and follow all instructions in ${promptFile}`,\n agentMode,\n );\n\n // Wait for agent to finish planning — NO artifact check (plan mode doesn't write files)\n const planResult = await this.detectCompletion(sessionId, {\n ...options,\n artifactCheck: undefined,\n }, options.onStreamEvent);\n\n if (planResult.timedOut) {\n logger.warn('Native plan mode: plan phase timed out', { sessionId });\n return this.buildRunResult(planResult, sessionId);\n }\n\n // ── Phase 2: commit plan to disk ──\n logger.info('Native plan mode: switching to bypass for commit', { sessionId });\n await this.ensurePlanMode(sessionId, agentMode, false, workDir);\n\n // /clear resets Phase 1's long conversation context\n await this.writeCommand(sessionId, '/clear', agentMode);\n await new Promise(resolve => setTimeout(resolve, 2_000));\n\n const commitPrompt = this.buildPlanCommitPrompt(options);\n await this.writeCommand(sessionId, commitPrompt, agentMode);\n\n // skipEchoDetection=true: commit prompt is sent directly (not via .phase-prompt.md),\n // so there is no echo marker to wait for — start completion detection immediately.\n const commitResult = await this.detectCompletion(\n sessionId, options, options.onStreamEvent, true,\n );\n\n logger.info('Native plan mode completed', {\n sessionId,\n timedOut: commitResult.timedOut,\n });\n return this.buildRunResult(commitResult, sessionId);\n }\n\n /** Build the prompt that instructs the agent to write the plan to disk. */\n private buildPlanCommitPrompt(options: RunOptions): string {\n const paths = options.artifactPaths ?? [];\n if (paths.length === 0) {\n return 'Write the implementation plan you just created to the project directory.';\n }\n const pathList = paths.map(p => `- ${p}`).join('\\n');\n return (\n '你刚才在规划模式下制定了一份实施计划。现在请将完整的计划内容写入以下文件:\\n\\n' +\n pathList + '\\n\\n' +\n '要求:\\n' +\n '1. 将你刚才规划的完整内容(需求分析、系统设计、实施 Todolist)写入上述文件\\n' +\n '2. 保持 Markdown 格式\\n' +\n '3. 只写入文件,不要修改任何项目代码'\n );\n }\n\n /** Map detectCompletion result to RunResult. */\n private buildRunResult(\n detectResult: { output: string; timedOut: boolean; timeoutType?: string },\n sessionId: string,\n ): RunResult {\n return {\n success: !detectResult.timedOut,\n output: detectResult.output,\n errorMessage: detectResult.timedOut\n ? (detectResult.timeoutType === 'idle' ? 'AI 长时间无响应,已超时终止' : '执行超时')\n : undefined,\n sessionId,\n exitCode: detectResult.timedOut ? null : 0,\n timeoutType: detectResult.timeoutType as RunResult['timeoutType'],\n };\n }\n\n private writePromptFile(workDir: string, prompt: string): string {\n // Write to .claude-plan/.phase-prompt.md (leading dot = not treated as artifact)\n const dir = path.join(workDir, '.claude-plan');\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n const relPath = '.claude-plan/.phase-prompt.md';\n const absPath = path.join(workDir, relPath);\n fs.writeFileSync(absPath, prompt, 'utf-8');\n return relPath;\n }\n\n // ---- Completion detection -------------------------------------------------\n\n private detectCompletion(\n sessionId: string,\n options: RunOptions,\n onStreamEvent?: (event: StreamEvent) => void,\n skipEchoDetection?: boolean,\n ): Promise<CompletionResult> {\n return new Promise<CompletionResult>((resolve) => {\n const outputLines: string[] = [];\n let lastOutputTime = Date.now();\n let hasSubstantiveOutput = false;\n let echoConsumed = skipEchoDetection ?? false;\n let resolved = false;\n let debounceTimer: ReturnType<typeof setTimeout> | undefined;\n // Primary completion signal: isIdlePrompt() detects Claude Code's ❯ prompt.\n // The idle check below is a safety-net for truly stuck sessions — uses the\n // AI-level idle timeout (default 20 min) instead of the short PTY_IDLE_DETECT_MS.\n const idleTimeoutMs = options.idleTimeoutMs ?? 600_000;\n const timeoutMs = options.timeoutMs;\n\n const finish = (result: CompletionResult) => {\n if (resolved) return;\n resolved = true;\n cleanup();\n resolve(result);\n };\n\n // Wall-clock timeout\n const wallTimer = setTimeout(() => {\n finish({\n output: outputLines.join(''),\n timedOut: true,\n timeoutType: 'wall-clock',\n });\n }, timeoutMs);\n\n // Idle safety-net: if no output for a long time, treat as idle timeout (failure).\n // The primary \"task done\" signal is isIdlePrompt() below, not this check.\n const idleCheck = setInterval(() => {\n if (!hasSubstantiveOutput) return;\n if (Date.now() - lastOutputTime >= idleTimeoutMs) {\n finish({\n output: outputLines.join(''),\n timedOut: true,\n timeoutType: 'idle',\n });\n }\n }, 5_000);\n\n // Subscribe to PTY output\n const subscription = this.terminalManager.onData(sessionId, (data: string) => {\n if (resolved) return;\n\n const stripped = stripAnsi(data);\n\n // Classify TUI noise (spinners, status bar, separators, etc.)\n const nonEmptyLines = stripped.split('\\n').filter((l) => l.trim());\n const isNoise = nonEmptyLines.length === 0 || nonEmptyLines.every((l) => isTuiNoise(l));\n const isIdle = isIdlePrompt(stripped);\n\n // Detect \"mixed frames\": the TUI co-renders ❯ with active work content\n // (tool results, file listings, thinking indicators) in a single data\n // chunk. These are NOT truly idle — the agent is still working.\n const isMixedFrame = isIdle && containsActiveWork(stripped);\n\n // Update last-activity timestamp for real content.\n // - Pure noise (spinners) → no update (would prevent debounce)\n // - Pure idle (❯ only) → no update (debounce needs to expire)\n // - Mixed frame (❯ + work content) → DO update (agent is still active)\n // - Normal content → update\n const hasRealContent = !isNoise && stripped.trim().length > 0;\n if (hasRealContent && (!isIdle || isMixedFrame)) {\n lastOutputTime = Date.now();\n }\n\n // Skip the echo of our instruction\n if (!echoConsumed && stripped.includes('.phase-prompt.md')) {\n echoConsumed = true;\n return;\n }\n\n // Queued message indicator — the agent has pending input but is still\n // processing. This is NOT an idle state and must not trigger completion.\n if (QUEUED_MSG_RE.test(stripped)) {\n return;\n }\n\n // Auto-approve permission/confirmation dialogs (plan mode safety prompts).\n // Must be checked BEFORE isIdlePrompt — the ❯ in \"❯ 1. Yes\" would\n // otherwise trigger idle detection and start a premature debounce.\n if (PERMISSION_DIALOG_RE.test(stripped)) {\n logger.info('Permission dialog detected, auto-confirming', { sessionId });\n setTimeout(() => {\n if (!resolved) this.terminalManager.write(sessionId, '\\r');\n }, 500);\n return; // Don't count dialog frames as substantive output or idle prompts\n }\n\n // Substantive output must be non-noise (spinners don't count)\n if (echoConsumed && !hasSubstantiveOutput && !isNoise && stripped.trim().length > 0) {\n hasSubstantiveOutput = true;\n }\n\n outputLines.push(stripped);\n\n // Emit stream events for the dashboard (filter TUI noise)\n if (onStreamEvent) {\n for (const line of stripped.split('\\n').filter((l) => l.trim())) {\n if (!isTuiNoise(line)) {\n onStreamEvent({\n type: 'raw',\n content: line,\n timestamp: new Date().toISOString(),\n });\n }\n }\n }\n\n // Check for Claude Code idle prompt\n if (hasSubstantiveOutput && isIdlePrompt(stripped)) {\n // Mixed frame: ❯ co-rendered with active work (tool results, etc.)\n // This is NOT a genuine idle state — skip debounce entirely.\n if (isMixedFrame) {\n // Agent is still working — do not start debounce\n } else if (debounceTimer && isNoise) {\n // CRITICAL: If a debounce is already pending and this is a pure-noise\n // idle frame (TUI refresh with ❯), skip entirely. Otherwise the TUI's\n // continuous idle-prompt stream (every ~100ms) would clear+reschedule\n // the timer infinitely, preventing it from ever completing.\n } else {\n // Real idle prompt (first one, or after real content interrupted debounce).\n // Start or restart the debounce timer.\n if (debounceTimer) clearTimeout(debounceTimer);\n const scheduleDebounce = () => {\n debounceTimer = setTimeout(() => {\n if (resolved) return;\n const recentActivityMs = Date.now() - lastOutputTime;\n if (recentActivityMs < 5_000) {\n // Recent activity — retry rather than giving up\n scheduleDebounce();\n return;\n }\n\n // Artifact hard-gate: if artifacts are expected but not ready, keep waiting\n const artifactReady = options.artifactCheck ? options.artifactCheck() : true;\n if (!artifactReady) {\n logger.info('Idle prompt detected but artifacts not ready, continuing to wait', {\n sessionId,\n });\n scheduleDebounce();\n return;\n }\n\n finish({\n output: outputLines.join(''),\n timedOut: false,\n timeoutType: undefined,\n });\n }, 5_000);\n };\n scheduleDebounce();\n }\n }\n });\n\n // PTY exit handler — Claude process crashed or was killed\n this.terminalManager.onExit(sessionId, (exitCode: number) => {\n if (!resolved) {\n const wasKilled = this.killedSessions.delete(sessionId);\n logger.warn('PTY process exited during phase', { sessionId, exitCode, wasKilled });\n // Find and remove the workDir entry for this sessionId\n for (const [wd, info] of this.sessions) {\n if (info.sessionId === sessionId) {\n this.sessions.delete(wd);\n break;\n }\n }\n finish({\n output: outputLines.join(''),\n timedOut: wasKilled,\n timeoutType: wasKilled ? 'wall-clock' : undefined,\n });\n }\n });\n\n const cleanup = () => {\n clearTimeout(wallTimer);\n clearInterval(idleCheck);\n if (debounceTimer) clearTimeout(debounceTimer);\n subscription.dispose();\n };\n });\n }\n}\n"],"mappings":"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","names":["logger"]}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ConfigGenerator,
|
|
3
|
-
PreflightChecker
|
|
4
|
-
} from "./chunk-KTYPZTF4.js";
|
|
5
1
|
import {
|
|
6
2
|
DependencyChecker
|
|
7
3
|
} from "./chunk-HDFNMVRQ.js";
|
|
4
|
+
import {
|
|
5
|
+
ConfigGenerator,
|
|
6
|
+
PreflightChecker
|
|
7
|
+
} from "./chunk-O3WEV5W3.js";
|
|
8
8
|
import {
|
|
9
9
|
getProjectKnowledge
|
|
10
10
|
} from "./chunk-ACVOOHAR.js";
|
|
11
|
-
import {
|
|
12
|
-
resolveConfigFilePath
|
|
13
|
-
} from "./chunk-FWEW5E3B.js";
|
|
14
11
|
import {
|
|
15
12
|
analyze,
|
|
16
13
|
collectStaticInfo
|
|
17
14
|
} from "./chunk-B7TVVODN.js";
|
|
15
|
+
import {
|
|
16
|
+
resolveConfigFilePath
|
|
17
|
+
} from "./chunk-NZHKAPU6.js";
|
|
18
18
|
|
|
19
19
|
// src/web/routes/setup.ts
|
|
20
20
|
import express from "express";
|
|
@@ -172,7 +172,7 @@ var E2ESetupRunner = class {
|
|
|
172
172
|
const step = "reload";
|
|
173
173
|
yield { step, status: "running", message: "Reloading configuration..." };
|
|
174
174
|
try {
|
|
175
|
-
const { reloadConfig } = await import("./config-
|
|
175
|
+
const { reloadConfig } = await import("./config-WTRSZLOC.js");
|
|
176
176
|
reloadConfig();
|
|
177
177
|
yield { step, status: "done", message: "Configuration reloaded" };
|
|
178
178
|
} catch (err) {
|
|
@@ -468,8 +468,8 @@ function createSetupRouter(deps = {}) {
|
|
|
468
468
|
sse.write({ step: "collected", message: "Static info collected" });
|
|
469
469
|
sse.write({ step: "analyzing", message: "Running AI analysis..." });
|
|
470
470
|
try {
|
|
471
|
-
const { loadConfig } = await import("./config-
|
|
472
|
-
const { createAIRunner } = await import("./ai-runner-
|
|
471
|
+
const { loadConfig } = await import("./config-WTRSZLOC.js");
|
|
472
|
+
const { createAIRunner } = await import("./ai-runner-HLA44WI6.js");
|
|
473
473
|
const config = loadConfig();
|
|
474
474
|
const runner = createAIRunner(config.ai);
|
|
475
475
|
const knowledge = await analyze({ workDir, aiRunner: runner });
|
|
@@ -549,4 +549,4 @@ function createSetupRouter(deps = {}) {
|
|
|
549
549
|
export {
|
|
550
550
|
createSetupRouter
|
|
551
551
|
};
|
|
552
|
-
//# sourceMappingURL=chunk-
|
|
552
|
+
//# sourceMappingURL=chunk-UBQLXQ7I.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env-metadata.d.ts","sourceRoot":"","sources":["../../../src/cli/setup/env-metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,UAAU;IACzB,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"env-metadata.d.ts","sourceRoot":"","sources":["../../../src/cli/setup/env-metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,UAAU;IACzB,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CA6B5D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CA4KnD,CAAC"}
|
package/dist/cli.js
CHANGED
|
@@ -12,12 +12,13 @@ import {
|
|
|
12
12
|
} from "./chunk-B7XUZJOK.js";
|
|
13
13
|
import {
|
|
14
14
|
resolveConfigFilePath
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-NZHKAPU6.js";
|
|
16
16
|
import {
|
|
17
17
|
resolveDisplayHost
|
|
18
18
|
} from "./chunk-AKXDQH25.js";
|
|
19
19
|
import "./chunk-TN2SYADO.js";
|
|
20
|
-
import "./chunk-
|
|
20
|
+
import "./chunk-SAMTXC4A.js";
|
|
21
|
+
import "./chunk-AVGZH64A.js";
|
|
21
22
|
import "./chunk-GF2RRYHB.js";
|
|
22
23
|
|
|
23
24
|
// src/cli/index.ts
|
|
@@ -87,11 +88,11 @@ var defaults = getCliDefaults();
|
|
|
87
88
|
var program = new Command();
|
|
88
89
|
program.name("issue-auto-finish").description("Issue Auto-Finish: AI-powered issue resolution daemon").version(pkg.version, "-v, --version");
|
|
89
90
|
program.command("init").description("Launch the interactive web setup wizard").option("-p, --port <port>", "Port for the setup wizard", "3456").option("-c, --config <path>", "Config file path to generate").action(async (opts) => {
|
|
90
|
-
const { initCommand } = await import("./init-
|
|
91
|
+
const { initCommand } = await import("./init-QQDXGTPB.js");
|
|
91
92
|
await initCommand({ port: parseInt(opts.port, 10), config: opts.config });
|
|
92
93
|
});
|
|
93
94
|
program.command("start").description("Start the issue-auto-finish daemon service").option("-c, --config <path>", "Path to .env config file").option("-d, --daemon", "Run as a background daemon").action(async (opts) => {
|
|
94
|
-
const { startCommand } = await import("./start-
|
|
95
|
+
const { startCommand } = await import("./start-6QRW6IJI.js");
|
|
95
96
|
await startCommand({ config: opts.config, daemon: opts.daemon });
|
|
96
97
|
});
|
|
97
98
|
program.command("stop").description("Stop the running service").option("-p, --port <port>", "Web UI port", defaults.port).option("-H, --host <host>", "Service host", defaults.host).option("-f, --force", "Force kill via SIGKILL").action(async (opts) => {
|
|
@@ -103,7 +104,7 @@ program.command("stop").description("Stop the running service").option("-p, --po
|
|
|
103
104
|
});
|
|
104
105
|
});
|
|
105
106
|
program.command("restart").description("Restart the service (stop + start)").option("-c, --config <path>", "Path to .env config file").option("-p, --port <port>", "Web UI port", defaults.port).option("-H, --host <host>", "Service host", defaults.host).option("-d, --daemon", "Restart as a background daemon").action(async (opts) => {
|
|
106
|
-
const { restartCommand } = await import("./restart-
|
|
107
|
+
const { restartCommand } = await import("./restart-BMILTP5X.js");
|
|
107
108
|
await restartCommand({
|
|
108
109
|
config: opts.config,
|
|
109
110
|
host: opts.host,
|
|
@@ -116,7 +117,7 @@ program.command("doctor").description("Check environment dependencies").action(a
|
|
|
116
117
|
await doctorCommand();
|
|
117
118
|
});
|
|
118
119
|
program.command("analyze").description("Analyze target repository and generate knowledge.json").option("-d, --dir <path>", "Project directory to analyze (defaults to PROJECT_WORK_DIR)").option("-o, --output <path>", "Output path for knowledge.json").option("-f, --force", "Overwrite existing knowledge.json").action(async (opts) => {
|
|
119
|
-
const { analyzeCommand } = await import("./analyze-
|
|
120
|
+
const { analyzeCommand } = await import("./analyze-ZIXNC5GN.js");
|
|
120
121
|
await analyzeCommand({ dir: opts.dir, output: opts.output, force: opts.force });
|
|
121
122
|
});
|
|
122
123
|
program.command("status").description("Show service status").option("-p, --port <port>", "Web UI port to query", defaults.port).option("-H, --host <host>", "Service host to query", defaults.host).option("--json", "Output raw JSON").action(async (opts) => {
|
|
@@ -249,7 +250,7 @@ program.command("issues").description("List tracked issues").option("-p, --port
|
|
|
249
250
|
});
|
|
250
251
|
});
|
|
251
252
|
program.command("braindump").description("Batch braindump: split ideas into tasks and execute in parallel").option("-f, --file <path>", "Read input from file").option("-t, --target <branch>", "Target branch for merging").option("-c, --concurrency <n>", "Max concurrent tasks").option("--runner <mode>", "Default AI runner mode (claude-internal, cursor-agent, codebuddy)").option("--auto", "Skip confirmation and execute immediately").option("-p, --port <port>", "Service port (proxy to running daemon)", defaults.port).option("-H, --host <host>", "Service host", defaults.host).action(async (opts) => {
|
|
252
|
-
const { braindumpCommand } = await import("./braindump-
|
|
253
|
+
const { braindumpCommand } = await import("./braindump-56WAY2RD.js");
|
|
253
254
|
await braindumpCommand({
|
|
254
255
|
file: opts.file,
|
|
255
256
|
target: opts.target,
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/index.ts","../src/cli/utils/defaults.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { execFile } from 'node:child_process';\nimport { fileURLToPath } from 'node:url';\nimport path from 'node:path';\nimport {\n bold, dim, green, yellow, red, cyan,\n formatUptime, buildServiceUrl, formatConnectionError,\n} from './utils/format.js';\nimport { getCliDefaults } from './utils/defaults.js';\nimport { resolveDisplayHost } from '../utils/network.js';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nfunction findPackageJson(): string {\n for (let dir = __dirname; dir !== path.dirname(dir); dir = path.dirname(dir)) {\n const candidate = path.join(dir, 'package.json');\n if (existsSync(candidate)) {\n try {\n const content = JSON.parse(readFileSync(candidate, 'utf-8'));\n if (content.name === '@xdevops/issue-auto-finish' || content.name === 'issue-auto-finish') return candidate;\n } catch { /* skip */ }\n }\n }\n return path.resolve(__dirname, '../package.json');\n}\n\nconst pkg = JSON.parse(readFileSync(findPackageJson(), 'utf-8'));\n\n/**\n * Detect global package manager and upgrade the CLI binary.\n * Supports Volta and plain npm.\n */\nasync function upgradeGlobalCli(targetVersion: string): Promise<void> {\n const pkgSpec = `${pkg.name}@${targetVersion}`;\n\n const runCmd = (cmd: string, args: string[]): Promise<string> =>\n new Promise((resolve, reject) => {\n execFile(cmd, args, { timeout: 120_000 }, (err, stdout, stderr) => {\n if (err) {\n reject(new Error(`${cmd} ${args.join(' ')} failed: ${stderr || err.message}`));\n return;\n }\n resolve(stdout);\n });\n });\n\n // Detect whether the CLI was installed via Volta\n const cliPath = process.argv[1] ?? '';\n const isVolta = cliPath.includes('.volta') || !!process.env.VOLTA_HOME;\n\n if (isVolta) {\n console.log(` Upgrading global CLI via Volta...`);\n await runCmd('volta', ['install', pkgSpec]);\n } else {\n console.log(` Upgrading global CLI via npm...`);\n await runCmd('npm', ['install', '-g', pkgSpec]);\n }\n}\n\n// Resolve default host/port from .env config (lazy, no Zod validation)\nconst defaults = getCliDefaults();\n\nconst program = new Command();\n\nprogram\n .name('issue-auto-finish')\n .description('Issue Auto-Finish: AI-powered issue resolution daemon')\n .version(pkg.version, '-v, --version');\n\n// ------ init ------\n\nprogram\n .command('init')\n .description('Launch the interactive web setup wizard')\n .option('-p, --port <port>', 'Port for the setup wizard', '3456')\n .option('-c, --config <path>', 'Config file path to generate')\n .action(async (opts) => {\n const { initCommand } = await import('./commands/init.js');\n await initCommand({ port: parseInt(opts.port, 10), config: opts.config });\n });\n\n// ------ start ------\n\nprogram\n .command('start')\n .description('Start the issue-auto-finish daemon service')\n .option('-c, --config <path>', 'Path to .env config file')\n .option('-d, --daemon', 'Run as a background daemon')\n .action(async (opts) => {\n const { startCommand } = await import('./commands/start.js');\n await startCommand({ config: opts.config, daemon: opts.daemon });\n });\n\n// ------ stop ------\n\nprogram\n .command('stop')\n .description('Stop the running service')\n .option('-p, --port <port>', 'Web UI port', defaults.port)\n .option('-H, --host <host>', 'Service host', defaults.host)\n .option('-f, --force', 'Force kill via SIGKILL')\n .action(async (opts) => {\n const { stopCommand } = await import('./commands/stop.js');\n await stopCommand({\n host: opts.host,\n port: parseInt(opts.port, 10),\n force: !!opts.force,\n });\n });\n\n// ------ restart ------\n\nprogram\n .command('restart')\n .description('Restart the service (stop + start)')\n .option('-c, --config <path>', 'Path to .env config file')\n .option('-p, --port <port>', 'Web UI port', defaults.port)\n .option('-H, --host <host>', 'Service host', defaults.host)\n .option('-d, --daemon', 'Restart as a background daemon')\n .action(async (opts) => {\n const { restartCommand } = await import('./commands/restart.js');\n await restartCommand({\n config: opts.config,\n host: opts.host,\n port: parseInt(opts.port, 10),\n daemon: opts.daemon,\n });\n });\n\n// ------ doctor ------\n\nprogram\n .command('doctor')\n .description('Check environment dependencies')\n .action(async () => {\n const { doctorCommand } = await import('./commands/doctor.js');\n await doctorCommand();\n });\n\n// ------ analyze ------\n\nprogram\n .command('analyze')\n .description('Analyze target repository and generate knowledge.json')\n .option('-d, --dir <path>', 'Project directory to analyze (defaults to PROJECT_WORK_DIR)')\n .option('-o, --output <path>', 'Output path for knowledge.json')\n .option('-f, --force', 'Overwrite existing knowledge.json')\n .action(async (opts) => {\n const { analyzeCommand } = await import('./commands/analyze.js');\n await analyzeCommand({ dir: opts.dir, output: opts.output, force: opts.force });\n });\n\n// ------ status ------\n\ninterface StatusData {\n uptime: number;\n pid: number;\n version: string;\n config: {\n aiMode: string;\n aiModel: string;\n pipelineMode: string;\n baseBranch: string;\n projectPath: string;\n maxConcurrent: number;\n webHost: string;\n webPort: number;\n };\n issues: {\n total: number;\n active: number;\n failed: number;\n };\n}\n\nprogram\n .command('status')\n .description('Show service status')\n .option('-p, --port <port>', 'Web UI port to query', defaults.port)\n .option('-H, --host <host>', 'Service host to query', defaults.host)\n .option('--json', 'Output raw JSON')\n .action(async (opts) => {\n const host = opts.host as string;\n const port = parseInt(opts.port, 10);\n const url = buildServiceUrl(host, port);\n try {\n const resp = await fetch(`${url}/api/system/status`, {\n signal: AbortSignal.timeout(5000),\n });\n if (!resp.ok) {\n console.error(` Service returned HTTP ${resp.status}`);\n process.exitCode = 1;\n return;\n }\n const status = await resp.json() as StatusData;\n\n if (opts.json) {\n console.log(JSON.stringify(status, null, 2));\n return;\n }\n\n const cfg = status.config;\n const issues = status.issues;\n const webUrl = `http://${resolveDisplayHost(cfg.webHost)}:${cfg.webPort}`;\n\n console.log(`\\n ${bold('Issue Auto-Finish Status')}\\n`);\n console.log(` ${dim('Service:')} ${green('running')} (PID ${status.pid}) ${dim('Version:')} ${status.version}`);\n console.log(` ${dim('Uptime:')} ${formatUptime(status.uptime)} ${dim('Web UI:')} ${cyan(webUrl)}`);\n console.log('');\n console.log(` ${dim('AI Mode:')} ${cfg.aiMode} ${dim('Pipeline:')} ${cfg.pipelineMode}`);\n console.log(` ${dim('AI Model:')} ${cfg.aiModel} ${dim('Branch:')} ${cfg.baseBranch}`);\n console.log(` ${dim('Project:')} ${cfg.projectPath} ${dim('Concurrent:')} ${cfg.maxConcurrent}`);\n console.log('');\n const issuesSummary = [\n `${issues.total} total`,\n `${issues.active} active`,\n issues.failed > 0 ? red(`${issues.failed} failed`) : `${issues.failed} failed`,\n ].join(', ');\n console.log(` ${dim('Issues:')} ${issuesSummary}`);\n console.log('');\n } catch (err) {\n console.error(formatConnectionError(host, port, err));\n process.exitCode = 1;\n }\n });\n\n// ------ update ------\n\nprogram\n .command('update')\n .description('Check for updates or trigger an update')\n .option('--check', 'Only check for a new version without updating')\n .option('-p, --port <port>', 'Web UI port to query', defaults.port)\n .option('-H, --host <host>', 'Service host to query', defaults.host)\n .action(async (opts) => {\n const host = opts.host as string;\n const port = parseInt(opts.port, 10);\n const url = buildServiceUrl(host, port);\n const checkOnly = !!opts.check;\n\n try {\n if (checkOnly) {\n const resp = await fetch(`${url}/api/system/update-check`, {\n method: 'POST',\n signal: AbortSignal.timeout(20_000),\n });\n if (!resp.ok) {\n const body = await resp.json() as { error?: string };\n console.error(` Check failed: ${body.error ?? resp.statusText}`);\n process.exitCode = 1;\n return;\n }\n const result = await resp.json() as { currentVersion: string; latestVersion: string; hasUpdate: boolean };\n console.log(`\\n Current version: ${result.currentVersion}`);\n console.log(` Latest version: ${result.latestVersion}`);\n console.log(` Update available: ${result.hasUpdate ? yellow('Yes') : green('No')}\\n`);\n } else {\n const checkResp = await fetch(`${url}/api/system/update-check`, {\n method: 'POST',\n signal: AbortSignal.timeout(20_000),\n });\n if (!checkResp.ok) {\n const body = await checkResp.json() as { error?: string };\n console.error(` Check failed: ${body.error ?? checkResp.statusText}`);\n process.exitCode = 1;\n return;\n }\n const result = await checkResp.json() as { currentVersion: string; latestVersion: string; hasUpdate: boolean };\n if (!result.hasUpdate) {\n console.log(`\\n ${green('Already up to date')} (v${result.currentVersion})\\n`);\n return;\n }\n\n console.log(`\\n Updating from v${result.currentVersion} to v${result.latestVersion}...`);\n const updateResp = await fetch(`${url}/api/system/update`, {\n method: 'POST',\n signal: AbortSignal.timeout(10_000),\n });\n if (!updateResp.ok) {\n const body = await updateResp.json() as { error?: string };\n console.error(` Update trigger failed: ${body.error ?? updateResp.statusText}`);\n process.exitCode = 1;\n return;\n }\n console.log(' Update triggered. The service will restart automatically via PM2.');\n\n // Also upgrade global CLI binary\n try {\n await upgradeGlobalCli(result.latestVersion);\n console.log(` ${green('Global CLI upgraded to v' + result.latestVersion)}\\n`);\n } catch (cliErr) {\n console.warn(` ${yellow('Global CLI upgrade failed (service update still proceeding):')}`);\n console.warn(` ${dim((cliErr as Error).message)}\\n`);\n }\n }\n } catch (err) {\n console.error(formatConnectionError(host, port, err));\n process.exitCode = 1;\n }\n });\n\n// ------ logs ------\n\nprogram\n .command('logs')\n .description('View service logs')\n .option('-f, --follow', 'Follow log output in real-time')\n .option('-n, --lines <count>', 'Number of lines to show', '50')\n .option('--error', 'Show only error logs')\n .action(async (opts) => {\n const { logsCommand } = await import('./commands/logs.js');\n await logsCommand({\n follow: !!opts.follow,\n lines: parseInt(opts.lines, 10),\n errorOnly: !!opts.error,\n });\n });\n\n// ------ issues ------\n\nprogram\n .command('issues')\n .description('List tracked issues')\n .option('-p, --port <port>', 'Web UI port to query', defaults.port)\n .option('-H, --host <host>', 'Service host to query', defaults.host)\n .option('-s, --state <state>', 'Filter by state (active, failed, completed, all)', 'all')\n .option('--json', 'Output raw JSON')\n .action(async (opts) => {\n const { issuesCommand } = await import('./commands/issues.js');\n await issuesCommand({\n host: opts.host,\n port: parseInt(opts.port, 10),\n state: opts.state,\n json: !!opts.json,\n });\n });\n\n// ------ braindump ------\n\nprogram\n .command('braindump')\n .description('Batch braindump: split ideas into tasks and execute in parallel')\n .option('-f, --file <path>', 'Read input from file')\n .option('-t, --target <branch>', 'Target branch for merging')\n .option('-c, --concurrency <n>', 'Max concurrent tasks')\n .option('--runner <mode>', 'Default AI runner mode (claude-internal, cursor-agent, codebuddy)')\n .option('--auto', 'Skip confirmation and execute immediately')\n .option('-p, --port <port>', 'Service port (proxy to running daemon)', defaults.port)\n .option('-H, --host <host>', 'Service host', defaults.host)\n .action(async (opts) => {\n const { braindumpCommand } = await import('./commands/braindump.js');\n await braindumpCommand({\n file: opts.file,\n target: opts.target,\n concurrency: opts.concurrency ? parseInt(opts.concurrency, 10) : undefined,\n runner: opts.runner,\n auto: !!opts.auto,\n port: opts.port,\n host: opts.host,\n });\n });\n\n// ------ distill ------\n\nprogram\n .command('distill [action]')\n .description('Knowledge distillation management (run, status, search)')\n .argument('[query]', 'Search query (for distill search)')\n .option('-p, --port <port>', 'Web UI port to query', defaults.port)\n .option('-H, --host <host>', 'Service host to query', defaults.host)\n .option('--json', 'Output raw JSON')\n .action(async (action, query, opts) => {\n const { distillCommand } = await import('./commands/distill.js');\n await distillCommand({\n action: action || 'status',\n query,\n host: opts.host,\n port: parseInt(opts.port, 10),\n json: !!opts.json,\n });\n });\n\n// ------ knowledge ------\n\nprogram\n .command('knowledge [action]')\n .description('Knowledge sync management (publish, restore, status)')\n .option('-p, --port <port>', 'Web UI port to query', defaults.port)\n .option('-H, --host <host>', 'Service host to query', defaults.host)\n .option('--json', 'Output raw JSON')\n .action(async (action, opts) => {\n const { knowledgeSyncCommand } = await import('./commands/knowledge-sync.js');\n await knowledgeSyncCommand({\n action: action || 'status',\n host: opts.host,\n port: parseInt(opts.port, 10),\n json: !!opts.json,\n });\n });\n\n// ------ migrate ------\n\nprogram\n .command('migrate')\n .description('Migrate data from PM2 source-mode to npm package mode')\n .requiredOption('-s, --source <path>', 'Source project directory (PM2 mode)')\n .option('-f, --force', 'Overwrite existing files without asking')\n .option('--dry-run', 'Show what would be migrated without copying')\n .action(async (opts) => {\n const { migrateCommand } = await import('./commands/migrate.js');\n await migrateCommand({ source: opts.source, force: !!opts.force, dryRun: !!opts.dryRun });\n });\n\n// ------ lock-migrate ------\n\nprogram\n .command('lock-migrate')\n .description('Migrate existing active issues to use lock notes (one-time upgrade)')\n .option('-p, --port <port>', 'Web UI port', defaults.port)\n .option('-H, --host <host>', 'Service host', defaults.host)\n .action(async (opts) => {\n const { lockMigrateCommand } = await import('./commands/lock-migrate.js');\n await lockMigrateCommand({\n host: opts.host,\n port: parseInt(opts.port, 10),\n });\n });\n\n// ------ release-locks ------\n\nprogram\n .command('release-locks')\n .description('Release all lock notes held by the current node')\n .option('-p, --port <port>', 'Web UI port', defaults.port)\n .option('-H, --host <host>', 'Service host', defaults.host)\n .action(async (opts) => {\n const { releaseLocksCommand } = await import('./commands/release-locks.js');\n await releaseLocksCommand({\n host: opts.host,\n port: parseInt(opts.port, 10),\n });\n });\n\nprogram.parse();\n","/**\n * CLI defaults — resolve --host / --port defaults from .env config.\n *\n * Reads the .env file (same lookup chain as the service) to extract\n * WEB_HOST and WEB_PORT, so CLI commands automatically connect to\n * the right address without manual --host / --port flags.\n *\n * This is a lightweight, lazy-init module — it only parses .env when\n * the defaults are first accessed, and does NOT import the full config\n * stack (no Zod validation, no side effects).\n */\nimport { config as loadDotenv } from 'dotenv';\nimport { resolveConfigFilePath } from '../../config.js';\n\ninterface CliDefaults {\n host: string;\n port: string;\n}\n\nlet _cached: CliDefaults | null = null;\n\n/**\n * Return default host / port for CLI commands.\n *\n * Priority:\n * 1. .env `WEB_HOST` / `WEB_PORT` (via resolveConfigFilePath)\n * 2. Hardcoded fallbacks: `127.0.0.1` / `3000`\n */\nexport function getCliDefaults(): CliDefaults {\n if (_cached) return _cached;\n\n try {\n const envFile = resolveConfigFilePath();\n const result = loadDotenv({ path: envFile, override: false });\n const parsed = result.parsed ?? {};\n\n _cached = {\n host: parsed.WEB_HOST || '127.0.0.1',\n port: parsed.WEB_PORT || '3000',\n };\n } catch {\n _cached = { host: '127.0.0.1', port: '3000' };\n }\n\n return _cached;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/index.ts","../src/cli/utils/defaults.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { execFile } from 'node:child_process';\nimport { fileURLToPath } from 'node:url';\nimport path from 'node:path';\nimport {\n bold, dim, green, yellow, red, cyan,\n formatUptime, buildServiceUrl, formatConnectionError,\n} from './utils/format.js';\nimport { getCliDefaults } from './utils/defaults.js';\nimport { resolveDisplayHost } from '../utils/network.js';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nfunction findPackageJson(): string {\n for (let dir = __dirname; dir !== path.dirname(dir); dir = path.dirname(dir)) {\n const candidate = path.join(dir, 'package.json');\n if (existsSync(candidate)) {\n try {\n const content = JSON.parse(readFileSync(candidate, 'utf-8'));\n if (content.name === '@xdevops/issue-auto-finish' || content.name === 'issue-auto-finish') return candidate;\n } catch { /* skip */ }\n }\n }\n return path.resolve(__dirname, '../package.json');\n}\n\nconst pkg = JSON.parse(readFileSync(findPackageJson(), 'utf-8'));\n\n/**\n * Detect global package manager and upgrade the CLI binary.\n * Supports Volta and plain npm.\n */\nasync function upgradeGlobalCli(targetVersion: string): Promise<void> {\n const pkgSpec = `${pkg.name}@${targetVersion}`;\n\n const runCmd = (cmd: string, args: string[]): Promise<string> =>\n new Promise((resolve, reject) => {\n execFile(cmd, args, { timeout: 120_000 }, (err, stdout, stderr) => {\n if (err) {\n reject(new Error(`${cmd} ${args.join(' ')} failed: ${stderr || err.message}`));\n return;\n }\n resolve(stdout);\n });\n });\n\n // Detect whether the CLI was installed via Volta\n const cliPath = process.argv[1] ?? '';\n const isVolta = cliPath.includes('.volta') || !!process.env.VOLTA_HOME;\n\n if (isVolta) {\n console.log(` Upgrading global CLI via Volta...`);\n await runCmd('volta', ['install', pkgSpec]);\n } else {\n console.log(` Upgrading global CLI via npm...`);\n await runCmd('npm', ['install', '-g', pkgSpec]);\n }\n}\n\n// Resolve default host/port from .env config (lazy, no Zod validation)\nconst defaults = getCliDefaults();\n\nconst program = new Command();\n\nprogram\n .name('issue-auto-finish')\n .description('Issue Auto-Finish: AI-powered issue resolution daemon')\n .version(pkg.version, '-v, --version');\n\n// ------ init ------\n\nprogram\n .command('init')\n .description('Launch the interactive web setup wizard')\n .option('-p, --port <port>', 'Port for the setup wizard', '3456')\n .option('-c, --config <path>', 'Config file path to generate')\n .action(async (opts) => {\n const { initCommand } = await import('./commands/init.js');\n await initCommand({ port: parseInt(opts.port, 10), config: opts.config });\n });\n\n// ------ start ------\n\nprogram\n .command('start')\n .description('Start the issue-auto-finish daemon service')\n .option('-c, --config <path>', 'Path to .env config file')\n .option('-d, --daemon', 'Run as a background daemon')\n .action(async (opts) => {\n const { startCommand } = await import('./commands/start.js');\n await startCommand({ config: opts.config, daemon: opts.daemon });\n });\n\n// ------ stop ------\n\nprogram\n .command('stop')\n .description('Stop the running service')\n .option('-p, --port <port>', 'Web UI port', defaults.port)\n .option('-H, --host <host>', 'Service host', defaults.host)\n .option('-f, --force', 'Force kill via SIGKILL')\n .action(async (opts) => {\n const { stopCommand } = await import('./commands/stop.js');\n await stopCommand({\n host: opts.host,\n port: parseInt(opts.port, 10),\n force: !!opts.force,\n });\n });\n\n// ------ restart ------\n\nprogram\n .command('restart')\n .description('Restart the service (stop + start)')\n .option('-c, --config <path>', 'Path to .env config file')\n .option('-p, --port <port>', 'Web UI port', defaults.port)\n .option('-H, --host <host>', 'Service host', defaults.host)\n .option('-d, --daemon', 'Restart as a background daemon')\n .action(async (opts) => {\n const { restartCommand } = await import('./commands/restart.js');\n await restartCommand({\n config: opts.config,\n host: opts.host,\n port: parseInt(opts.port, 10),\n daemon: opts.daemon,\n });\n });\n\n// ------ doctor ------\n\nprogram\n .command('doctor')\n .description('Check environment dependencies')\n .action(async () => {\n const { doctorCommand } = await import('./commands/doctor.js');\n await doctorCommand();\n });\n\n// ------ analyze ------\n\nprogram\n .command('analyze')\n .description('Analyze target repository and generate knowledge.json')\n .option('-d, --dir <path>', 'Project directory to analyze (defaults to PROJECT_WORK_DIR)')\n .option('-o, --output <path>', 'Output path for knowledge.json')\n .option('-f, --force', 'Overwrite existing knowledge.json')\n .action(async (opts) => {\n const { analyzeCommand } = await import('./commands/analyze.js');\n await analyzeCommand({ dir: opts.dir, output: opts.output, force: opts.force });\n });\n\n// ------ status ------\n\ninterface StatusData {\n uptime: number;\n pid: number;\n version: string;\n config: {\n aiMode: string;\n aiModel: string;\n pipelineMode: string;\n baseBranch: string;\n projectPath: string;\n maxConcurrent: number;\n webHost: string;\n webPort: number;\n };\n issues: {\n total: number;\n active: number;\n failed: number;\n };\n}\n\nprogram\n .command('status')\n .description('Show service status')\n .option('-p, --port <port>', 'Web UI port to query', defaults.port)\n .option('-H, --host <host>', 'Service host to query', defaults.host)\n .option('--json', 'Output raw JSON')\n .action(async (opts) => {\n const host = opts.host as string;\n const port = parseInt(opts.port, 10);\n const url = buildServiceUrl(host, port);\n try {\n const resp = await fetch(`${url}/api/system/status`, {\n signal: AbortSignal.timeout(5000),\n });\n if (!resp.ok) {\n console.error(` Service returned HTTP ${resp.status}`);\n process.exitCode = 1;\n return;\n }\n const status = await resp.json() as StatusData;\n\n if (opts.json) {\n console.log(JSON.stringify(status, null, 2));\n return;\n }\n\n const cfg = status.config;\n const issues = status.issues;\n const webUrl = `http://${resolveDisplayHost(cfg.webHost)}:${cfg.webPort}`;\n\n console.log(`\\n ${bold('Issue Auto-Finish Status')}\\n`);\n console.log(` ${dim('Service:')} ${green('running')} (PID ${status.pid}) ${dim('Version:')} ${status.version}`);\n console.log(` ${dim('Uptime:')} ${formatUptime(status.uptime)} ${dim('Web UI:')} ${cyan(webUrl)}`);\n console.log('');\n console.log(` ${dim('AI Mode:')} ${cfg.aiMode} ${dim('Pipeline:')} ${cfg.pipelineMode}`);\n console.log(` ${dim('AI Model:')} ${cfg.aiModel} ${dim('Branch:')} ${cfg.baseBranch}`);\n console.log(` ${dim('Project:')} ${cfg.projectPath} ${dim('Concurrent:')} ${cfg.maxConcurrent}`);\n console.log('');\n const issuesSummary = [\n `${issues.total} total`,\n `${issues.active} active`,\n issues.failed > 0 ? red(`${issues.failed} failed`) : `${issues.failed} failed`,\n ].join(', ');\n console.log(` ${dim('Issues:')} ${issuesSummary}`);\n console.log('');\n } catch (err) {\n console.error(formatConnectionError(host, port, err));\n process.exitCode = 1;\n }\n });\n\n// ------ update ------\n\nprogram\n .command('update')\n .description('Check for updates or trigger an update')\n .option('--check', 'Only check for a new version without updating')\n .option('-p, --port <port>', 'Web UI port to query', defaults.port)\n .option('-H, --host <host>', 'Service host to query', defaults.host)\n .action(async (opts) => {\n const host = opts.host as string;\n const port = parseInt(opts.port, 10);\n const url = buildServiceUrl(host, port);\n const checkOnly = !!opts.check;\n\n try {\n if (checkOnly) {\n const resp = await fetch(`${url}/api/system/update-check`, {\n method: 'POST',\n signal: AbortSignal.timeout(20_000),\n });\n if (!resp.ok) {\n const body = await resp.json() as { error?: string };\n console.error(` Check failed: ${body.error ?? resp.statusText}`);\n process.exitCode = 1;\n return;\n }\n const result = await resp.json() as { currentVersion: string; latestVersion: string; hasUpdate: boolean };\n console.log(`\\n Current version: ${result.currentVersion}`);\n console.log(` Latest version: ${result.latestVersion}`);\n console.log(` Update available: ${result.hasUpdate ? yellow('Yes') : green('No')}\\n`);\n } else {\n const checkResp = await fetch(`${url}/api/system/update-check`, {\n method: 'POST',\n signal: AbortSignal.timeout(20_000),\n });\n if (!checkResp.ok) {\n const body = await checkResp.json() as { error?: string };\n console.error(` Check failed: ${body.error ?? checkResp.statusText}`);\n process.exitCode = 1;\n return;\n }\n const result = await checkResp.json() as { currentVersion: string; latestVersion: string; hasUpdate: boolean };\n if (!result.hasUpdate) {\n console.log(`\\n ${green('Already up to date')} (v${result.currentVersion})\\n`);\n return;\n }\n\n console.log(`\\n Updating from v${result.currentVersion} to v${result.latestVersion}...`);\n const updateResp = await fetch(`${url}/api/system/update`, {\n method: 'POST',\n signal: AbortSignal.timeout(10_000),\n });\n if (!updateResp.ok) {\n const body = await updateResp.json() as { error?: string };\n console.error(` Update trigger failed: ${body.error ?? updateResp.statusText}`);\n process.exitCode = 1;\n return;\n }\n console.log(' Update triggered. The service will restart automatically via PM2.');\n\n // Also upgrade global CLI binary\n try {\n await upgradeGlobalCli(result.latestVersion);\n console.log(` ${green('Global CLI upgraded to v' + result.latestVersion)}\\n`);\n } catch (cliErr) {\n console.warn(` ${yellow('Global CLI upgrade failed (service update still proceeding):')}`);\n console.warn(` ${dim((cliErr as Error).message)}\\n`);\n }\n }\n } catch (err) {\n console.error(formatConnectionError(host, port, err));\n process.exitCode = 1;\n }\n });\n\n// ------ logs ------\n\nprogram\n .command('logs')\n .description('View service logs')\n .option('-f, --follow', 'Follow log output in real-time')\n .option('-n, --lines <count>', 'Number of lines to show', '50')\n .option('--error', 'Show only error logs')\n .action(async (opts) => {\n const { logsCommand } = await import('./commands/logs.js');\n await logsCommand({\n follow: !!opts.follow,\n lines: parseInt(opts.lines, 10),\n errorOnly: !!opts.error,\n });\n });\n\n// ------ issues ------\n\nprogram\n .command('issues')\n .description('List tracked issues')\n .option('-p, --port <port>', 'Web UI port to query', defaults.port)\n .option('-H, --host <host>', 'Service host to query', defaults.host)\n .option('-s, --state <state>', 'Filter by state (active, failed, completed, all)', 'all')\n .option('--json', 'Output raw JSON')\n .action(async (opts) => {\n const { issuesCommand } = await import('./commands/issues.js');\n await issuesCommand({\n host: opts.host,\n port: parseInt(opts.port, 10),\n state: opts.state,\n json: !!opts.json,\n });\n });\n\n// ------ braindump ------\n\nprogram\n .command('braindump')\n .description('Batch braindump: split ideas into tasks and execute in parallel')\n .option('-f, --file <path>', 'Read input from file')\n .option('-t, --target <branch>', 'Target branch for merging')\n .option('-c, --concurrency <n>', 'Max concurrent tasks')\n .option('--runner <mode>', 'Default AI runner mode (claude-internal, cursor-agent, codebuddy)')\n .option('--auto', 'Skip confirmation and execute immediately')\n .option('-p, --port <port>', 'Service port (proxy to running daemon)', defaults.port)\n .option('-H, --host <host>', 'Service host', defaults.host)\n .action(async (opts) => {\n const { braindumpCommand } = await import('./commands/braindump.js');\n await braindumpCommand({\n file: opts.file,\n target: opts.target,\n concurrency: opts.concurrency ? parseInt(opts.concurrency, 10) : undefined,\n runner: opts.runner,\n auto: !!opts.auto,\n port: opts.port,\n host: opts.host,\n });\n });\n\n// ------ distill ------\n\nprogram\n .command('distill [action]')\n .description('Knowledge distillation management (run, status, search)')\n .argument('[query]', 'Search query (for distill search)')\n .option('-p, --port <port>', 'Web UI port to query', defaults.port)\n .option('-H, --host <host>', 'Service host to query', defaults.host)\n .option('--json', 'Output raw JSON')\n .action(async (action, query, opts) => {\n const { distillCommand } = await import('./commands/distill.js');\n await distillCommand({\n action: action || 'status',\n query,\n host: opts.host,\n port: parseInt(opts.port, 10),\n json: !!opts.json,\n });\n });\n\n// ------ knowledge ------\n\nprogram\n .command('knowledge [action]')\n .description('Knowledge sync management (publish, restore, status)')\n .option('-p, --port <port>', 'Web UI port to query', defaults.port)\n .option('-H, --host <host>', 'Service host to query', defaults.host)\n .option('--json', 'Output raw JSON')\n .action(async (action, opts) => {\n const { knowledgeSyncCommand } = await import('./commands/knowledge-sync.js');\n await knowledgeSyncCommand({\n action: action || 'status',\n host: opts.host,\n port: parseInt(opts.port, 10),\n json: !!opts.json,\n });\n });\n\n// ------ migrate ------\n\nprogram\n .command('migrate')\n .description('Migrate data from PM2 source-mode to npm package mode')\n .requiredOption('-s, --source <path>', 'Source project directory (PM2 mode)')\n .option('-f, --force', 'Overwrite existing files without asking')\n .option('--dry-run', 'Show what would be migrated without copying')\n .action(async (opts) => {\n const { migrateCommand } = await import('./commands/migrate.js');\n await migrateCommand({ source: opts.source, force: !!opts.force, dryRun: !!opts.dryRun });\n });\n\n// ------ lock-migrate ------\n\nprogram\n .command('lock-migrate')\n .description('Migrate existing active issues to use lock notes (one-time upgrade)')\n .option('-p, --port <port>', 'Web UI port', defaults.port)\n .option('-H, --host <host>', 'Service host', defaults.host)\n .action(async (opts) => {\n const { lockMigrateCommand } = await import('./commands/lock-migrate.js');\n await lockMigrateCommand({\n host: opts.host,\n port: parseInt(opts.port, 10),\n });\n });\n\n// ------ release-locks ------\n\nprogram\n .command('release-locks')\n .description('Release all lock notes held by the current node')\n .option('-p, --port <port>', 'Web UI port', defaults.port)\n .option('-H, --host <host>', 'Service host', defaults.host)\n .action(async (opts) => {\n const { releaseLocksCommand } = await import('./commands/release-locks.js');\n await releaseLocksCommand({\n host: opts.host,\n port: parseInt(opts.port, 10),\n });\n });\n\nprogram.parse();\n","/**\n * CLI defaults — resolve --host / --port defaults from .env config.\n *\n * Reads the .env file (same lookup chain as the service) to extract\n * WEB_HOST and WEB_PORT, so CLI commands automatically connect to\n * the right address without manual --host / --port flags.\n *\n * This is a lightweight, lazy-init module — it only parses .env when\n * the defaults are first accessed, and does NOT import the full config\n * stack (no Zod validation, no side effects).\n */\nimport { config as loadDotenv } from 'dotenv';\nimport { resolveConfigFilePath } from '../../config.js';\n\ninterface CliDefaults {\n host: string;\n port: string;\n}\n\nlet _cached: CliDefaults | null = null;\n\n/**\n * Return default host / port for CLI commands.\n *\n * Priority:\n * 1. .env `WEB_HOST` / `WEB_PORT` (via resolveConfigFilePath)\n * 2. Hardcoded fallbacks: `127.0.0.1` / `3000`\n */\nexport function getCliDefaults(): CliDefaults {\n if (_cached) return _cached;\n\n try {\n const envFile = resolveConfigFilePath();\n const result = loadDotenv({ path: envFile, override: false });\n const parsed = result.parsed ?? {};\n\n _cached = {\n host: parsed.WEB_HOST || '127.0.0.1',\n port: parsed.WEB_PORT || '3000',\n };\n } catch {\n _cached = { host: '127.0.0.1', port: '3000' };\n }\n\n return _cached;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -4,10 +4,11 @@ import {
|
|
|
4
4
|
reloadConfig,
|
|
5
5
|
resetDotenvCache,
|
|
6
6
|
resolveConfigFilePath
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-NZHKAPU6.js";
|
|
8
8
|
import "./chunk-AKXDQH25.js";
|
|
9
9
|
import "./chunk-TN2SYADO.js";
|
|
10
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-SAMTXC4A.js";
|
|
11
|
+
import "./chunk-AVGZH64A.js";
|
|
11
12
|
import "./chunk-GF2RRYHB.js";
|
|
12
13
|
export {
|
|
13
14
|
ConfigValidationError,
|
|
@@ -16,4 +17,4 @@ export {
|
|
|
16
17
|
resetDotenvCache,
|
|
17
18
|
resolveConfigFilePath
|
|
18
19
|
};
|
|
19
|
-
//# sourceMappingURL=config-
|
|
20
|
+
//# sourceMappingURL=config-WTRSZLOC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/config-schema.d.ts
CHANGED
|
@@ -57,7 +57,7 @@ export declare const envSchema: z.ZodObject<{
|
|
|
57
57
|
E2E_UAT_VENDOR_DIR: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
58
58
|
E2E_UAT_CONFIG_FILE: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
59
59
|
E2E_PYTHON_BIN: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
60
|
-
E2E_AI_RUNNER_MODE: z.
|
|
60
|
+
E2E_AI_RUNNER_MODE: z.ZodOptional<z.ZodString>;
|
|
61
61
|
E2E_AI_MODEL: z.ZodOptional<z.ZodString>;
|
|
62
62
|
PREVIEW_ENABLED: z.ZodPipe<z.ZodDefault<z.ZodOptional<z.ZodString>>, z.ZodTransform<boolean, string>>;
|
|
63
63
|
PREVIEW_HOST: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
@@ -114,6 +114,12 @@ export declare const envSchema: z.ZodObject<{
|
|
|
114
114
|
VERIFY_FIX_LOOP_ENABLED: z.ZodPipe<z.ZodDefault<z.ZodOptional<z.ZodString>>, z.ZodTransform<boolean, string>>;
|
|
115
115
|
VERIFY_FIX_MAX_ITERATIONS: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
116
116
|
VERIFY_TODOLIST_CHECK_ENABLED: z.ZodPipe<z.ZodDefault<z.ZodOptional<z.ZodString>>, z.ZodTransform<boolean, string>>;
|
|
117
|
+
TERMINAL_ENABLED: z.ZodPipe<z.ZodDefault<z.ZodOptional<z.ZodString>>, z.ZodTransform<boolean, string>>;
|
|
118
|
+
TERMINAL_IDLE_TIMEOUT_MS: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
119
|
+
TERMINAL_MAX_SESSIONS: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
120
|
+
PTY_IDLE_DETECT_MS: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
121
|
+
PTY_DEFAULT_AGENT: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
122
|
+
PTY_PHASE_AGENTS: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
117
123
|
ANALYTICS_ENABLED: z.ZodPipe<z.ZodDefault<z.ZodOptional<z.ZodString>>, z.ZodTransform<boolean, string>>;
|
|
118
124
|
ANALYTICS_TARGET_API_URL: z.ZodOptional<z.ZodString>;
|
|
119
125
|
ANALYTICS_TARGET_API_TOKEN: z.ZodOptional<z.ZodString>;
|
|
@@ -283,6 +289,16 @@ export declare function transformEnvToConfig(env: ParsedEnv, dirname: string): {
|
|
|
283
289
|
readonly cacheTtlMs: number;
|
|
284
290
|
readonly skillAutoDiscover: boolean;
|
|
285
291
|
};
|
|
292
|
+
readonly terminal: {
|
|
293
|
+
readonly enabled: boolean;
|
|
294
|
+
readonly idleTimeoutMs: number;
|
|
295
|
+
readonly maxSessions: number;
|
|
296
|
+
};
|
|
297
|
+
readonly pty: {
|
|
298
|
+
readonly idleDetectMs: number;
|
|
299
|
+
readonly defaultAgent: string;
|
|
300
|
+
readonly phaseAgents: Record<string, string>;
|
|
301
|
+
};
|
|
286
302
|
readonly workspace: {
|
|
287
303
|
readonly configPath: string | undefined;
|
|
288
304
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["../src/config-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["../src/config-schema.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -163,6 +163,16 @@ export declare function loadConfig(): {
|
|
|
163
163
|
readonly cacheTtlMs: number;
|
|
164
164
|
readonly skillAutoDiscover: boolean;
|
|
165
165
|
};
|
|
166
|
+
readonly terminal: {
|
|
167
|
+
readonly enabled: boolean;
|
|
168
|
+
readonly idleTimeoutMs: number;
|
|
169
|
+
readonly maxSessions: number;
|
|
170
|
+
};
|
|
171
|
+
readonly pty: {
|
|
172
|
+
readonly idleDetectMs: number;
|
|
173
|
+
readonly defaultAgent: string;
|
|
174
|
+
readonly phaseAgents: Record<string, string>;
|
|
175
|
+
};
|
|
166
176
|
readonly workspace: {
|
|
167
177
|
readonly configPath: string | undefined;
|
|
168
178
|
};
|
|
@@ -324,6 +334,16 @@ export declare function reloadConfig(): {
|
|
|
324
334
|
readonly cacheTtlMs: number;
|
|
325
335
|
readonly skillAutoDiscover: boolean;
|
|
326
336
|
};
|
|
337
|
+
readonly terminal: {
|
|
338
|
+
readonly enabled: boolean;
|
|
339
|
+
readonly idleTimeoutMs: number;
|
|
340
|
+
readonly maxSessions: number;
|
|
341
|
+
};
|
|
342
|
+
readonly pty: {
|
|
343
|
+
readonly idleDetectMs: number;
|
|
344
|
+
readonly defaultAgent: string;
|
|
345
|
+
readonly phaseAgents: Record<string, string>;
|
|
346
|
+
};
|
|
327
347
|
readonly workspace: {
|
|
328
348
|
readonly configPath: string | undefined;
|
|
329
349
|
};
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAaA,YAAY,EACV,MAAM,EACN,YAAY,EACZ,qBAAqB,EACrB,eAAe,EAEf,cAAc,EACd,aAAa,EACb,QAAQ,EACR,UAAU,EACV,cAAc,EACd,YAAY,EACZ,SAAS,EACT,mBAAmB,EACnB,aAAa,EACb,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,aAAa,EACb,UAAU,EACV,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAI3D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAkBjE;AASD,wBAAgB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWzB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED;;;;GAIG;AACH,wBAAgB,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQ3B"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { AppError } from './BaseError.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* 用户主动中止/重做/重启阶段时抛出,中断 PhaseLoopStep 循环。
|
|
4
4
|
*
|
|
5
5
|
* 在 PipelineOrchestrator 的 catch 块中被特殊处理,
|
|
6
6
|
* 不会进入 handleFailure 路径。
|
|
7
7
|
*/
|
|
8
8
|
export declare class PhaseAbortedError extends AppError {
|
|
9
9
|
readonly phaseName: string;
|
|
10
|
-
readonly action: 'abort' | 'redo';
|
|
11
|
-
constructor(phaseName: string, action: 'abort' | 'redo');
|
|
10
|
+
readonly action: 'abort' | 'redo' | 'restart';
|
|
11
|
+
constructor(phaseName: string, action: 'abort' | 'redo' | 'restart');
|
|
12
12
|
}
|
|
13
13
|
//# sourceMappingURL=PhaseAbortedError.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PhaseAbortedError.d.ts","sourceRoot":"","sources":["../../src/errors/PhaseAbortedError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;IAC7C,SAAgB,SAAS,EAAE,MAAM,CAAC;IAClC,SAAgB,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"PhaseAbortedError.d.ts","sourceRoot":"","sources":["../../src/errors/PhaseAbortedError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;IAC7C,SAAgB,SAAS,EAAE,MAAM,CAAC;IAClC,SAAgB,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;gBAEzC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS;CAKpE"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AIExecutionError,
|
|
3
|
+
AIOutputParseError,
|
|
4
|
+
AppError,
|
|
5
|
+
BatchNotFoundError,
|
|
6
|
+
GongfengApiError,
|
|
7
|
+
GongfengUploadError,
|
|
8
|
+
InvalidPhaseError,
|
|
9
|
+
InvalidStateError,
|
|
10
|
+
IssueNotFoundError,
|
|
11
|
+
PhaseAbortedError,
|
|
12
|
+
PhaseNotRegisteredError,
|
|
13
|
+
PipelineNotFoundError,
|
|
14
|
+
PortExhaustionError,
|
|
15
|
+
RunnerNotRegisteredError,
|
|
16
|
+
ServiceShutdownError,
|
|
17
|
+
SessionLimitError,
|
|
18
|
+
SessionNotFoundError,
|
|
19
|
+
TaskNotFoundError,
|
|
20
|
+
UnregisteredPhasesError
|
|
21
|
+
} from "./chunk-AVGZH64A.js";
|
|
22
|
+
export {
|
|
23
|
+
AIExecutionError,
|
|
24
|
+
AIOutputParseError,
|
|
25
|
+
AppError,
|
|
26
|
+
BatchNotFoundError,
|
|
27
|
+
GongfengApiError,
|
|
28
|
+
GongfengUploadError,
|
|
29
|
+
InvalidPhaseError,
|
|
30
|
+
InvalidStateError,
|
|
31
|
+
IssueNotFoundError,
|
|
32
|
+
PhaseAbortedError,
|
|
33
|
+
PhaseNotRegisteredError,
|
|
34
|
+
PipelineNotFoundError,
|
|
35
|
+
PortExhaustionError,
|
|
36
|
+
RunnerNotRegisteredError,
|
|
37
|
+
ServiceShutdownError,
|
|
38
|
+
SessionLimitError,
|
|
39
|
+
SessionNotFoundError,
|
|
40
|
+
TaskNotFoundError,
|
|
41
|
+
UnregisteredPhasesError
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=errors-S3BWYA4I.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA4CA,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA4CA,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CA4e1C"}
|