claude-code-workflow 7.2.28 → 7.2.30
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/.ccw/workflows/cli-templates/schemas/plan-overview-base-schema.json +2 -2
- package/.ccw/workflows/cli-templates/schemas/task-schema.json +14 -7
- package/.claude/agents/action-planning-agent.md +7 -4
- package/.claude/agents/cli-explore-agent.md +77 -63
- package/.claude/agents/cli-lite-planning-agent.md +11 -10
- package/.claude/agents/issue-plan-agent.md +421 -426
- package/.claude/commands/workflow/spec/setup.md +1 -1
- package/.claude/skills/ccw-chain/SKILL.md +119 -0
- package/.claude/skills/ccw-chain/chains/ccw-cycle.json +21 -0
- package/.claude/skills/ccw-chain/chains/ccw-exploration.json +47 -0
- package/.claude/skills/ccw-chain/chains/ccw-issue.json +33 -0
- package/.claude/skills/ccw-chain/chains/ccw-lightweight.json +57 -0
- package/.claude/skills/ccw-chain/chains/ccw-main.json +52 -0
- package/.claude/skills/ccw-chain/chains/ccw-standard.json +39 -0
- package/.claude/skills/ccw-chain/chains/ccw-team.json +10 -0
- package/.claude/skills/ccw-chain/chains/ccw-with-file.json +31 -0
- package/.claude/skills/ccw-chain/phases/analyze-with-file.md +788 -0
- package/.claude/skills/ccw-chain/phases/brainstorm/SKILL.md +408 -0
- package/.claude/skills/ccw-chain/phases/brainstorm/phases/01-mode-routing.md +207 -0
- package/.claude/skills/ccw-chain/phases/brainstorm/phases/02-artifacts.md +567 -0
- package/.claude/skills/ccw-chain/phases/brainstorm/phases/03-role-analysis.md +748 -0
- package/.claude/skills/ccw-chain/phases/brainstorm/phases/04-synthesis.md +827 -0
- package/.claude/skills/ccw-chain/phases/brainstorm-with-file.md +482 -0
- package/.claude/skills/ccw-chain/phases/collaborative-plan-with-file.md +639 -0
- package/.claude/skills/ccw-chain/phases/debug-with-file.md +656 -0
- package/.claude/skills/ccw-chain/phases/integration-test-cycle.md +936 -0
- package/.claude/skills/ccw-chain/phases/issue-convert-to-plan.md +720 -0
- package/.claude/skills/ccw-chain/phases/issue-discover.md +483 -0
- package/.claude/skills/ccw-chain/phases/issue-execute.md +629 -0
- package/.claude/skills/ccw-chain/phases/issue-from-brainstorm.md +382 -0
- package/.claude/skills/ccw-chain/phases/issue-plan.md +343 -0
- package/.claude/skills/ccw-chain/phases/issue-queue.md +464 -0
- package/.claude/skills/ccw-chain/phases/refactor-cycle.md +852 -0
- package/.claude/skills/ccw-chain/phases/review-cycle/SKILL.md +132 -0
- package/.claude/skills/ccw-chain/phases/review-cycle/phases/review-fix.md +760 -0
- package/.claude/skills/ccw-chain/phases/review-cycle/phases/review-module.md +764 -0
- package/.claude/skills/ccw-chain/phases/review-cycle/phases/review-session.md +775 -0
- package/.claude/skills/ccw-chain/phases/roadmap-with-file.md +544 -0
- package/.claude/skills/ccw-chain/phases/spec-generator/SKILL.md +338 -0
- package/.claude/skills/ccw-chain/phases/spec-generator/phases/01-5-requirement-clarification.md +404 -0
- package/.claude/skills/ccw-chain/phases/spec-generator/phases/01-discovery.md +257 -0
- package/.claude/skills/ccw-chain/phases/spec-generator/phases/02-product-brief.md +274 -0
- package/.claude/skills/ccw-chain/phases/spec-generator/phases/03-requirements.md +184 -0
- package/.claude/skills/ccw-chain/phases/spec-generator/phases/04-architecture.md +248 -0
- package/.claude/skills/ccw-chain/phases/spec-generator/phases/05-epics-stories.md +178 -0
- package/.claude/skills/ccw-chain/phases/spec-generator/phases/06-5-auto-fix.md +144 -0
- package/.claude/skills/ccw-chain/phases/spec-generator/phases/06-readiness-check.md +480 -0
- package/.claude/skills/ccw-chain/phases/team-planex.md +123 -0
- package/.claude/skills/ccw-chain/phases/ui-design-explore-auto.md +678 -0
- package/.claude/skills/ccw-chain/phases/unified-execute-with-file.md +870 -0
- package/.claude/skills/ccw-chain/phases/workflow-execute/SKILL.md +625 -0
- package/.claude/skills/ccw-chain/phases/workflow-execute/phases/06-review.md +215 -0
- package/.claude/skills/ccw-chain/phases/workflow-lite-plan.md +616 -0
- package/.claude/skills/ccw-chain/phases/workflow-multi-cli-plan.md +424 -0
- package/.claude/skills/ccw-chain/phases/workflow-plan/SKILL.md +466 -0
- package/.claude/skills/ccw-chain/phases/workflow-plan/phases/01-session-discovery.md +99 -0
- package/.claude/skills/ccw-chain/phases/workflow-plan/phases/02-context-gathering.md +338 -0
- package/.claude/skills/ccw-chain/phases/workflow-plan/phases/03-conflict-resolution.md +422 -0
- package/.claude/skills/ccw-chain/phases/workflow-plan/phases/04-task-generation.md +440 -0
- package/.claude/skills/ccw-chain/phases/workflow-plan/phases/05-plan-verify.md +395 -0
- package/.claude/skills/ccw-chain/phases/workflow-plan/phases/06-replan.md +594 -0
- package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/SKILL.md +527 -0
- package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/01-session-discovery.md +57 -0
- package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/02-context-gathering.md +407 -0
- package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/03-test-coverage-analysis.md +172 -0
- package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/04-conflict-resolution.md +426 -0
- package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/05-tdd-task-generation.md +473 -0
- package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/06-tdd-structure-validation.md +189 -0
- package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/07-tdd-verify.md +635 -0
- package/.claude/skills/ccw-chain/phases/workflow-test-fix/SKILL.md +482 -0
- package/.claude/skills/ccw-chain/phases/workflow-test-fix/phases/01-session-start.md +60 -0
- package/.claude/skills/ccw-chain/phases/workflow-test-fix/phases/02-test-context-gather.md +493 -0
- package/.claude/skills/ccw-chain/phases/workflow-test-fix/phases/03-test-concept-enhanced.md +150 -0
- package/.claude/skills/ccw-chain/phases/workflow-test-fix/phases/04-test-task-generate.md +346 -0
- package/.claude/skills/ccw-chain/phases/workflow-test-fix/phases/05-test-cycle-execute.md +538 -0
- package/.claude/skills/ccw-chain/specs/auto-mode.md +47 -0
- package/.claude/skills/ccw-chain/specs/intent-patterns.md +60 -0
- package/.claude/skills/chain-loader/SKILL.md +78 -0
- package/.claude/skills/chain-loader/phases/01-analyze-skill.md +53 -0
- package/.claude/skills/chain-loader/phases/02-design-graph.md +73 -0
- package/.claude/skills/chain-loader/phases/03-generate-validate.md +75 -0
- package/.claude/skills/chain-loader/specs/chain-schema.md +99 -0
- package/.claude/skills/chain-loader/specs/design-patterns.md +99 -0
- package/.claude/skills/chain-loader/templates/chain-json.md +63 -0
- package/.claude/skills/review-cycle/phases/review-module.md +764 -764
- package/.claude/skills/review-cycle/phases/review-session.md +775 -775
- package/.claude/skills/workflow-multi-cli-plan/SKILL.md +2 -2
- package/.claude/skills/workflow-plan/phases/03-conflict-resolution.md +422 -422
- package/.claude/skills/workflow-plan/phases/05-plan-verify.md +395 -395
- package/.claude/skills/workflow-tdd-plan/phases/02-context-gathering.md +407 -407
- package/.claude/skills/workflow-tdd-plan/phases/04-conflict-resolution.md +426 -426
- package/.claude/skills/workflow-test-fix/phases/02-test-context-gather.md +493 -493
- package/.codex/skills/brainstorm/SKILL.md +3 -3
- package/.codex/skills/clean/SKILL.md +3 -3
- package/.codex/skills/issue-discover/SKILL.md +13 -13
- package/.codex/skills/issue-discover/phases/02-discover.md +4 -4
- package/.codex/skills/issue-discover/phases/03-discover-by-prompt.md +3 -3
- package/.codex/skills/parallel-dev-cycle/SKILL.md +4 -4
- package/.codex/skills/parallel-dev-cycle/phases/02-agent-execution.md +6 -6
- package/.codex/skills/parallel-dev-cycle/phases/03-result-aggregation.md +10 -10
- package/.codex/skills/review-cycle/SKILL.md +10 -10
- package/.codex/skills/review-cycle/phases/02-parallel-review.md +6 -6
- package/.codex/skills/review-cycle/phases/04-iterative-deep-dive.md +4 -4
- package/.codex/skills/review-cycle/phases/07-fix-parallel-planning.md +4 -4
- package/.codex/skills/review-cycle/phases/08-fix-execution.md +2 -2
- package/.codex/skills/roadmap-with-file/SKILL.md +14 -14
- package/.codex/skills/spec-generator/README.md +1 -1
- package/.codex/skills/spec-generator/SKILL.md +184 -88
- package/.codex/skills/spec-generator/phases/01-5-requirement-clarification.md +4 -7
- package/.codex/skills/spec-generator/phases/01-discovery.md +30 -11
- package/.codex/skills/spec-generator/phases/02-product-brief.md +2 -5
- package/.codex/skills/spec-generator/phases/03-requirements.md +4 -6
- package/.codex/skills/spec-generator/phases/04-architecture.md +4 -6
- package/.codex/skills/spec-generator/phases/05-epics-stories.md +4 -6
- package/.codex/skills/spec-generator/phases/06-5-auto-fix.md +4 -5
- package/.codex/skills/spec-generator/phases/06-readiness-check.md +8 -8
- package/.codex/skills/spec-generator/phases/07-issue-export.md +2 -2
- package/.codex/skills/spec-setup/SKILL.md +4 -4
- package/.codex/skills/workflow-plan/SKILL.md +6 -6
- package/.codex/skills/workflow-tdd-plan/SKILL.md +5 -5
- package/.codex/skills/workflow-test-fix-cycle/SKILL.md +19 -19
- package/.codex/skills/workflow-test-fix-cycle/phases/01-test-fix-gen.md +5 -5
- package/.codex/skills/workflow-test-fix-cycle/phases/02-test-cycle-execute.md +5 -5
- package/README.md +14 -0
- package/ccw/dist/core/routes/litellm-api-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/litellm-api-routes.js +0 -23
- package/ccw/dist/core/routes/litellm-api-routes.js.map +1 -1
- package/ccw/dist/tools/chain-loader.d.ts +10 -0
- package/ccw/dist/tools/chain-loader.d.ts.map +1 -0
- package/ccw/dist/tools/chain-loader.js +642 -0
- package/ccw/dist/tools/chain-loader.js.map +1 -0
- package/ccw/dist/tools/index.d.ts.map +1 -1
- package/ccw/dist/tools/index.js +2 -0
- package/ccw/dist/tools/index.js.map +1 -1
- package/ccw/dist/tools/json-builder.js +20 -0
- package/ccw/dist/tools/json-builder.js.map +1 -1
- package/ccw/dist/types/chain-types.d.ts +72 -0
- package/ccw/dist/types/chain-types.d.ts.map +1 -0
- package/ccw/dist/types/chain-types.js +5 -0
- package/ccw/dist/types/chain-types.js.map +1 -0
- package/ccw/frontend/dist/assets/{AlertDialog-BjP1ydDR.js → AlertDialog-exlTDW81.js} +3 -3
- package/ccw/frontend/dist/assets/{AlertDialog-BjP1ydDR.js.map → AlertDialog-exlTDW81.js.map} +1 -1
- package/ccw/frontend/dist/assets/{AnalysisPage-CAX3xqMf.js → AnalysisPage-cgV9LfAI.js} +2 -2
- package/ccw/frontend/dist/assets/{AnalysisPage-CAX3xqMf.js.map → AnalysisPage-cgV9LfAI.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ApiSettingsPage-CtWlmztq.js → ApiSettingsPage-Dk5jJdWt.js} +2 -2
- package/ccw/frontend/dist/assets/{ApiSettingsPage-CtWlmztq.js.map → ApiSettingsPage-Dk5jJdWt.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CliModeToggle-hR4a-eLX.js → CliModeToggle-Be9xsPiv.js} +2 -2
- package/ccw/frontend/dist/assets/{CliModeToggle-hR4a-eLX.js.map → CliModeToggle-Be9xsPiv.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CliSessionSharePage-DzNPkFN9.js → CliSessionSharePage-Bh9jBtPI.js} +2 -2
- package/ccw/frontend/dist/assets/{CliSessionSharePage-DzNPkFN9.js.map → CliSessionSharePage-Bh9jBtPI.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CliViewerPage-BPEGN4TT.js → CliViewerPage-BrE-oyEq.js} +2 -2
- package/ccw/frontend/dist/assets/{CliViewerPage-BPEGN4TT.js.map → CliViewerPage-BrE-oyEq.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CodexLensPage-Cf0r2RHY.js → CodexLensPage-Cd3nrC93.js} +2 -2
- package/ccw/frontend/dist/assets/{CodexLensPage-Cf0r2RHY.js.map → CodexLensPage-Cd3nrC93.js.map} +1 -1
- package/ccw/frontend/dist/assets/{Collapsible-DEm1rJ4h.js → Collapsible-DXFl3VKF.js} +2 -2
- package/ccw/frontend/dist/assets/{Collapsible-DEm1rJ4h.js.map → Collapsible-DXFl3VKF.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CommandsManagerPage-BpeWw8HO.js → CommandsManagerPage-IV8zpjgX.js} +2 -2
- package/ccw/frontend/dist/assets/{CommandsManagerPage-BpeWw8HO.js.map → CommandsManagerPage-IV8zpjgX.js.map} +1 -1
- package/ccw/frontend/dist/assets/{DeepWikiPage-BEsmh2vF.js → DeepWikiPage-CpDxtmRX.js} +2 -2
- package/ccw/frontend/dist/assets/{DeepWikiPage-BEsmh2vF.js.map → DeepWikiPage-CpDxtmRX.js.map} +1 -1
- package/ccw/frontend/dist/assets/{EndpointsPage-B30SFdtU.js → EndpointsPage-BchjWe7s.js} +2 -2
- package/ccw/frontend/dist/assets/{EndpointsPage-B30SFdtU.js.map → EndpointsPage-BchjWe7s.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ExplorerPage-BVvMpg1O.js → ExplorerPage-CbWvaJ0y.js} +2 -2
- package/ccw/frontend/dist/assets/{ExplorerPage-BVvMpg1O.js.map → ExplorerPage-CbWvaJ0y.js.map} +1 -1
- package/ccw/frontend/dist/assets/{FixSessionPage-CL73dHbh.js → FixSessionPage-YMjVRiCk.js} +2 -2
- package/ccw/frontend/dist/assets/{FixSessionPage-CL73dHbh.js.map → FixSessionPage-YMjVRiCk.js.map} +1 -1
- package/ccw/frontend/dist/assets/{FloatingFileBrowser-BL-28lMZ.js → FloatingFileBrowser-JW2ehYY_.js} +2 -2
- package/ccw/frontend/dist/assets/{FloatingFileBrowser-BL-28lMZ.js.map → FloatingFileBrowser-JW2ehYY_.js.map} +1 -1
- package/ccw/frontend/dist/assets/{FloatingPanel-BzZDciHZ.js → FloatingPanel-BtqzqDVq.js} +2 -2
- package/ccw/frontend/dist/assets/{FloatingPanel-BzZDciHZ.js.map → FloatingPanel-BtqzqDVq.js.map} +1 -1
- package/ccw/frontend/dist/assets/{GraphExplorerPage-CDp6-d8P.js → GraphExplorerPage-BsJL_W4d.js} +3 -3
- package/ccw/frontend/dist/assets/{GraphExplorerPage-CDp6-d8P.js.map → GraphExplorerPage-BsJL_W4d.js.map} +1 -1
- package/ccw/frontend/dist/assets/{HistoryPage-fZY_7O9n.js → HistoryPage-BuWpQ7k5.js} +2 -2
- package/ccw/frontend/dist/assets/{HistoryPage-fZY_7O9n.js.map → HistoryPage-BuWpQ7k5.js.map} +1 -1
- package/ccw/frontend/dist/assets/{HookManagerPage-4LJeC9bq.js → HookManagerPage-D0BtMIWy.js} +2 -2
- package/ccw/frontend/dist/assets/{HookManagerPage-4LJeC9bq.js.map → HookManagerPage-D0BtMIWy.js.map} +1 -1
- package/ccw/frontend/dist/assets/{InstallationsPage-Bpigrbhw.js → InstallationsPage-C7dwsAKG.js} +2 -2
- package/ccw/frontend/dist/assets/{InstallationsPage-Bpigrbhw.js.map → InstallationsPage-C7dwsAKG.js.map} +1 -1
- package/ccw/frontend/dist/assets/{IssueHubPage-BP0zJc1R.js → IssueHubPage-D0nCNaeB.js} +2 -2
- package/ccw/frontend/dist/assets/{IssueHubPage-BP0zJc1R.js.map → IssueHubPage-D0nCNaeB.js.map} +1 -1
- package/ccw/frontend/dist/assets/{LiteTasksPage-CSt2oVKQ.js → LiteTasksPage-B5c2Kb9r.js} +3 -3
- package/ccw/frontend/dist/assets/{LiteTasksPage-CSt2oVKQ.js.map → LiteTasksPage-B5c2Kb9r.js.map} +1 -1
- package/ccw/frontend/dist/assets/{McpManagerPage-B-xaMA0w.js → McpManagerPage-C-S5CehM.js} +2 -2
- package/ccw/frontend/dist/assets/{McpManagerPage-B-xaMA0w.js.map → McpManagerPage-C-S5CehM.js.map} +1 -1
- package/ccw/frontend/dist/assets/{MemoryPage-CJqo_7DY.js → MemoryPage-P_B0JVUQ.js} +2 -2
- package/ccw/frontend/dist/assets/{MemoryPage-CJqo_7DY.js.map → MemoryPage-P_B0JVUQ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{NotFoundPage-ibZeQA-Y.js → NotFoundPage-S4Jn9LUE.js} +2 -2
- package/ccw/frontend/dist/assets/{NotFoundPage-ibZeQA-Y.js.map → NotFoundPage-S4Jn9LUE.js.map} +1 -1
- package/ccw/frontend/dist/assets/{OrchestratorPage-DgJ4ctPQ.js → OrchestratorPage-C2Zlr7AC.js} +2 -2
- package/ccw/frontend/dist/assets/{OrchestratorPage-DgJ4ctPQ.js.map → OrchestratorPage-C2Zlr7AC.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ProjectOverviewPage-Cit0Yq0D.js → ProjectOverviewPage-CMVfz8s5.js} +2 -2
- package/ccw/frontend/dist/assets/{ProjectOverviewPage-Cit0Yq0D.js.map → ProjectOverviewPage-CMVfz8s5.js.map} +1 -1
- package/ccw/frontend/dist/assets/{PromptHistoryPage-Ce1HDIK0.js → PromptHistoryPage-YEMjFARX.js} +3 -3
- package/ccw/frontend/dist/assets/{PromptHistoryPage-Ce1HDIK0.js.map → PromptHistoryPage-YEMjFARX.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ReviewSessionPage-J1KikNrk.js → ReviewSessionPage-DnTm55nG.js} +2 -2
- package/ccw/frontend/dist/assets/{ReviewSessionPage-J1KikNrk.js.map → ReviewSessionPage-DnTm55nG.js.map} +1 -1
- package/ccw/frontend/dist/assets/{RulesManagerPage-CdBjTmth.js → RulesManagerPage-CUwebtO2.js} +2 -2
- package/ccw/frontend/dist/assets/{RulesManagerPage-CdBjTmth.js.map → RulesManagerPage-CUwebtO2.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SessionDetailPage-B9ZK7LvX.js → SessionDetailPage-0qyH1Z5P.js} +2 -2
- package/ccw/frontend/dist/assets/{SessionDetailPage-B9ZK7LvX.js.map → SessionDetailPage-0qyH1Z5P.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SessionsPage-CW_nS5UR.js → SessionsPage-BpgP4087.js} +2 -2
- package/ccw/frontend/dist/assets/{SessionsPage-CW_nS5UR.js.map → SessionsPage-BpgP4087.js.map} +1 -1
- package/ccw/frontend/dist/assets/SettingsPage-C3SJajeT.js +150 -0
- package/ccw/frontend/dist/assets/SettingsPage-C3SJajeT.js.map +1 -0
- package/ccw/frontend/dist/assets/SkillsManagerPage-vD9PTsmy.js +7 -0
- package/ccw/frontend/dist/assets/SkillsManagerPage-vD9PTsmy.js.map +1 -0
- package/ccw/frontend/dist/assets/{SpecsSettingsPage-DJpi9XQL.js → SpecsSettingsPage-DT-yTVkD.js} +4 -4
- package/ccw/frontend/dist/assets/{SpecsSettingsPage-DJpi9XQL.js.map → SpecsSettingsPage-DT-yTVkD.js.map} +1 -1
- package/ccw/frontend/dist/assets/{Switch-Ac6Ov7uy.js → Switch-CYSPdqWk.js} +2 -2
- package/ccw/frontend/dist/assets/{Switch-Ac6Ov7uy.js.map → Switch-CYSPdqWk.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TabsNavigation-DZAAspqR.js → TabsNavigation-CPh6Zor1.js} +2 -2
- package/ccw/frontend/dist/assets/{TabsNavigation-DZAAspqR.js.map → TabsNavigation-CPh6Zor1.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TaskDrawer-BJkwfhIZ.js → TaskDrawer-Ds-8830B.js} +2 -2
- package/ccw/frontend/dist/assets/{TaskDrawer-BJkwfhIZ.js.map → TaskDrawer-Ds-8830B.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TeamPage-BJgjxBgb.js → TeamPage-CJODUxBk.js} +2 -2
- package/ccw/frontend/dist/assets/{TeamPage-BJgjxBgb.js.map → TeamPage-CJODUxBk.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TerminalDashboardPage-D1WekoOy.js → TerminalDashboardPage-Cn3fGUuO.js} +3 -3
- package/ccw/frontend/dist/assets/{TerminalDashboardPage-D1WekoOy.js.map → TerminalDashboardPage-Cn3fGUuO.js.map} +1 -1
- package/ccw/frontend/dist/assets/{archive-DxemgIhF.js → archive-CjwVpw6k.js} +2 -2
- package/ccw/frontend/dist/assets/{archive-DxemgIhF.js.map → archive-CjwVpw6k.js.map} +1 -1
- package/ccw/frontend/dist/assets/{archive-restore-CjS83f1V.js → archive-restore-2vZa9Ic3.js} +2 -2
- package/ccw/frontend/dist/assets/{archive-restore-CjS83f1V.js.map → archive-restore-2vZa9Ic3.js.map} +1 -1
- package/ccw/frontend/dist/assets/{arrow-right-B5PUcn8I.js → arrow-right-CUU5XDgT.js} +2 -2
- package/ccw/frontend/dist/assets/{arrow-right-B5PUcn8I.js.map → arrow-right-CUU5XDgT.js.map} +1 -1
- package/ccw/frontend/dist/assets/{bookmark-plus-DCc9aPbb.js → bookmark-plus-Cc3nKRZ5.js} +2 -2
- package/ccw/frontend/dist/assets/{bookmark-plus-DCc9aPbb.js.map → bookmark-plus-Cc3nKRZ5.js.map} +1 -1
- package/ccw/frontend/dist/assets/{bot-DOwFtzak.js → bot-BwpSRDUa.js} +2 -2
- package/ccw/frontend/dist/assets/{bot-DOwFtzak.js.map → bot-BwpSRDUa.js.map} +1 -1
- package/ccw/frontend/dist/assets/{braces-96qH3aFh.js → braces-DBzUW1XC.js} +2 -2
- package/ccw/frontend/dist/assets/{braces-96qH3aFh.js.map → braces-DBzUW1XC.js.map} +1 -1
- package/ccw/frontend/dist/assets/{circle-stop-CCxSuil1.js → circle-stop-CGNNsjvE.js} +2 -2
- package/ccw/frontend/dist/assets/{circle-stop-CCxSuil1.js.map → circle-stop-CGNNsjvE.js.map} +1 -1
- package/ccw/frontend/dist/assets/{cpu-CZNSJFdq.js → cpu-D27G86Ul.js} +2 -2
- package/ccw/frontend/dist/assets/{cpu-CZNSJFdq.js.map → cpu-D27G86Ul.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ellipsis-vertical-h8xtvw2_.js → ellipsis-vertical-C1Ij47Yz.js} +2 -2
- package/ccw/frontend/dist/assets/{ellipsis-vertical-h8xtvw2_.js.map → ellipsis-vertical-C1Ij47Yz.js.map} +1 -1
- package/ccw/frontend/dist/assets/{eye-D3NY0bm6.js → eye-C6MOB7Au.js} +2 -2
- package/ccw/frontend/dist/assets/{eye-D3NY0bm6.js.map → eye-C6MOB7Au.js.map} +1 -1
- package/ccw/frontend/dist/assets/{eye-off-Cy2vkc8p.js → eye-off-BxfBlZ26.js} +2 -2
- package/ccw/frontend/dist/assets/{eye-off-Cy2vkc8p.js.map → eye-off-BxfBlZ26.js.map} +1 -1
- package/ccw/frontend/dist/assets/{file-json-Bzq3U1Mx.js → file-json-NI237wA-.js} +2 -2
- package/ccw/frontend/dist/assets/{file-json-Bzq3U1Mx.js.map → file-json-NI237wA-.js.map} +1 -1
- package/ccw/frontend/dist/assets/{file-text-DwuwPDPi.js → file-text-Byn2_2v6.js} +2 -2
- package/ccw/frontend/dist/assets/{file-text-DwuwPDPi.js.map → file-text-Byn2_2v6.js.map} +1 -1
- package/ccw/frontend/dist/assets/{filter-q9g-bknU.js → filter-D-7PhZjx.js} +2 -2
- package/ccw/frontend/dist/assets/{filter-q9g-bknU.js.map → filter-D-7PhZjx.js.map} +1 -1
- package/ccw/frontend/dist/assets/{folder-CL6vb42J.js → folder-BoAsK_FL.js} +2 -2
- package/ccw/frontend/dist/assets/{folder-CL6vb42J.js.map → folder-BoAsK_FL.js.map} +1 -1
- package/ccw/frontend/dist/assets/{gauge-BkrcQBly.js → gauge-DCSxJIS4.js} +2 -2
- package/ccw/frontend/dist/assets/{gauge-BkrcQBly.js.map → gauge-DCSxJIS4.js.map} +1 -1
- package/ccw/frontend/dist/assets/{globe-BQbwyNeV.js → globe-CHS3prza.js} +2 -2
- package/ccw/frontend/dist/assets/{globe-BQbwyNeV.js.map → globe-CHS3prza.js.map} +1 -1
- package/ccw/frontend/dist/assets/{grid-3x3-x5_7DrN7.js → grid-3x3-D7K35U7S.js} +2 -2
- package/ccw/frontend/dist/assets/{grid-3x3-x5_7DrN7.js.map → grid-3x3-D7K35U7S.js.map} +1 -1
- package/ccw/frontend/dist/assets/{hard-drive-DTyWXwzf.js → hard-drive-eq9xE07G.js} +2 -2
- package/ccw/frontend/dist/assets/{hard-drive-DTyWXwzf.js.map → hard-drive-eq9xE07G.js.map} +1 -1
- package/ccw/frontend/dist/assets/{hash-80O0kJO7.js → hash-C1DMpBua.js} +2 -2
- package/ccw/frontend/dist/assets/{hash-80O0kJO7.js.map → hash-C1DMpBua.js.map} +1 -1
- package/ccw/frontend/dist/assets/{history-DDlN2Bwa.js → history-Di5SBCY-.js} +2 -2
- package/ccw/frontend/dist/assets/{history-DDlN2Bwa.js.map → history-Di5SBCY-.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-mbeo62f8.js → index--_R7COnA.js} +2 -2
- package/ccw/frontend/dist/assets/{index-mbeo62f8.js.map → index--_R7COnA.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-rLgoBCfV.js → index-BUol9HDD.js} +3 -3
- package/ccw/frontend/dist/assets/{index-rLgoBCfV.js.map → index-BUol9HDD.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-Bs80iCX0.js → index-CT9oykfw.js} +2 -2
- package/ccw/frontend/dist/assets/{index-Bs80iCX0.js.map → index-CT9oykfw.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-B9A3Hnrk.js → index-Ddwvf87H.js} +2 -2
- package/ccw/frontend/dist/assets/{index-B9A3Hnrk.js.map → index-Ddwvf87H.js.map} +1 -1
- package/ccw/frontend/dist/assets/{layout-grid-C1niOWJx.js → layout-grid-LiX0qZbN.js} +2 -2
- package/ccw/frontend/dist/assets/{layout-grid-C1niOWJx.js.map → layout-grid-LiX0qZbN.js.map} +1 -1
- package/ccw/frontend/dist/assets/{lightbulb-BTmI7SUg.js → lightbulb-CL3DVEwb.js} +2 -2
- package/ccw/frontend/dist/assets/{lightbulb-BTmI7SUg.js.map → lightbulb-CL3DVEwb.js.map} +1 -1
- package/ccw/frontend/dist/assets/{link-2-CB9HKeuZ.js → link-2-CC5cFeq6.js} +2 -2
- package/ccw/frontend/dist/assets/{link-2-CB9HKeuZ.js.map → link-2-CC5cFeq6.js.map} +1 -1
- package/ccw/frontend/dist/assets/{link-koEYiemK.js → link-ngFQ9bs0.js} +2 -2
- package/ccw/frontend/dist/assets/{link-koEYiemK.js.map → link-ngFQ9bs0.js.map} +1 -1
- package/ccw/frontend/dist/assets/{list-v2_GaLdC.js → list-BEU6I0KK.js} +2 -2
- package/ccw/frontend/dist/assets/{list-v2_GaLdC.js.map → list-BEU6I0KK.js.map} +1 -1
- package/ccw/frontend/dist/assets/{map-pin-BQNfAqG_.js → map-pin-BWZdLA6y.js} +2 -2
- package/ccw/frontend/dist/assets/{map-pin-BQNfAqG_.js.map → map-pin-BWZdLA6y.js.map} +1 -1
- package/ccw/frontend/dist/assets/{messages-square-Dzq5LGg9.js → messages-square-K6_Chm7n.js} +2 -2
- package/ccw/frontend/dist/assets/{messages-square-Dzq5LGg9.js.map → messages-square-K6_Chm7n.js.map} +1 -1
- package/ccw/frontend/dist/assets/{minimize-2-CtkoJXcz.js → minimize-2-CWkphauf.js} +2 -2
- package/ccw/frontend/dist/assets/{minimize-2-CtkoJXcz.js.map → minimize-2-CWkphauf.js.map} +1 -1
- package/ccw/frontend/dist/assets/{package-CH3smL37.js → package-DrNgkamn.js} +2 -2
- package/ccw/frontend/dist/assets/{package-CH3smL37.js.map → package-DrNgkamn.js.map} +1 -1
- package/ccw/frontend/dist/assets/{plug-CZ0aL_yF.js → plug-CMo3sw5_.js} +2 -2
- package/ccw/frontend/dist/assets/{plug-CZ0aL_yF.js.map → plug-CMo3sw5_.js.map} +1 -1
- package/ccw/frontend/dist/assets/{power-F2A_J4l6.js → power-DppNTW5e.js} +2 -2
- package/ccw/frontend/dist/assets/{power-F2A_J4l6.js.map → power-DppNTW5e.js.map} +1 -1
- package/ccw/frontend/dist/assets/{save-Byxot0YU.js → save-CD8aPMbZ.js} +2 -2
- package/ccw/frontend/dist/assets/{save-Byxot0YU.js.map → save-CD8aPMbZ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{send-JjqhUkpw.js → send-B4z90fQD.js} +2 -2
- package/ccw/frontend/dist/assets/{send-JjqhUkpw.js.map → send-B4z90fQD.js.map} +1 -1
- package/ccw/frontend/dist/assets/{settings-2--SuN9rAt.js → settings-2-CAKRU_QC.js} +2 -2
- package/ccw/frontend/dist/assets/{settings-2--SuN9rAt.js.map → settings-2-CAKRU_QC.js.map} +1 -1
- package/ccw/frontend/dist/assets/{square-check-big-BbngGB2h.js → square-check-big-KhI3HrzX.js} +2 -2
- package/ccw/frontend/dist/assets/{square-check-big-BbngGB2h.js.map → square-check-big-KhI3HrzX.js.map} +1 -1
- package/ccw/frontend/dist/assets/{square-pen-CgrHgZSl.js → square-pen-BtdGIpuq.js} +2 -2
- package/ccw/frontend/dist/assets/{square-pen-CgrHgZSl.js.map → square-pen-BtdGIpuq.js.map} +1 -1
- package/ccw/frontend/dist/assets/{star-BU3TQr7Z.js → star-ZoBUkXoD.js} +2 -2
- package/ccw/frontend/dist/assets/{star-BU3TQr7Z.js.map → star-ZoBUkXoD.js.map} +1 -1
- package/ccw/frontend/dist/assets/{style-CKs7nnn3.js → style-CltxQP-P.js} +2 -2
- package/ccw/frontend/dist/assets/{style-CKs7nnn3.js.map → style-CltxQP-P.js.map} +1 -1
- package/ccw/frontend/dist/assets/{target-DW5tsDW6.js → target-C32OUSGf.js} +2 -2
- package/ccw/frontend/dist/assets/{target-DW5tsDW6.js.map → target-C32OUSGf.js.map} +1 -1
- package/ccw/frontend/dist/assets/{test-tube-BHm7w3ON.js → test-tube-0IxoyAVZ.js} +2 -2
- package/ccw/frontend/dist/assets/{test-tube-BHm7w3ON.js.map → test-tube-0IxoyAVZ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{upload-DYR7PWwt.js → upload-4eKCkyBn.js} +2 -2
- package/ccw/frontend/dist/assets/{upload-DYR7PWwt.js.map → upload-4eKCkyBn.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useApiSettings-D0TVgQD_.js → useApiSettings-zLTUWqhi.js} +2 -2
- package/ccw/frontend/dist/assets/{useApiSettings-D0TVgQD_.js.map → useApiSettings-zLTUWqhi.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useCli-DfY8mAP8.js → useCli-BtN2vpOX.js} +2 -2
- package/ccw/frontend/dist/assets/{useCli-DfY8mAP8.js.map → useCli-BtN2vpOX.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useCommands-CGusDp0F.js → useCommands-_spj49qL.js} +2 -2
- package/ccw/frontend/dist/assets/{useCommands-CGusDp0F.js.map → useCommands-_spj49qL.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useDebounce-CIwh0fF1.js → useDebounce-Bm9KFZvd.js} +2 -2
- package/ccw/frontend/dist/assets/{useDebounce-CIwh0fF1.js.map → useDebounce-Bm9KFZvd.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useFileExplorer-FMyFv39K.js → useFileExplorer-DOmpm6v9.js} +2 -2
- package/ccw/frontend/dist/assets/{useFileExplorer-FMyFv39K.js.map → useFileExplorer-DOmpm6v9.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useLocale-B2qhsoTb.js → useLocale-D2rj4rea.js} +2 -2
- package/ccw/frontend/dist/assets/{useLocale-B2qhsoTb.js.map → useLocale-D2rj4rea.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useSkills-cxKXMBm3.js → useSkills-OskEpomF.js} +3 -3
- package/ccw/frontend/dist/assets/{useSkills-cxKXMBm3.js.map → useSkills-OskEpomF.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useSystemSettings-B-xUT_z-.js → useSystemSettings-BjMgsNSF.js} +2 -2
- package/ccw/frontend/dist/assets/{useSystemSettings-B-xUT_z-.js.map → useSystemSettings-BjMgsNSF.js.map} +1 -1
- package/ccw/frontend/dist/assets/{wand-sparkles-DZV_3lPr.js → wand-sparkles-CLhyYWa7.js} +2 -2
- package/ccw/frontend/dist/assets/{wand-sparkles-DZV_3lPr.js.map → wand-sparkles-CLhyYWa7.js.map} +1 -1
- package/ccw/frontend/dist/index.html +1 -1
- package/ccw/scripts/prepublish-clean.mjs +0 -1
- package/package.json +1 -3
- package/ccw/frontend/dist/assets/SettingsPage-B2PYzSoO.js +0 -150
- package/ccw/frontend/dist/assets/SettingsPage-B2PYzSoO.js.map +0 -1
- package/ccw/frontend/dist/assets/SkillsManagerPage-CTnWrrwp.js +0 -7
- package/ccw/frontend/dist/assets/SkillsManagerPage-CTnWrrwp.js.map +0 -1
- package/ccw-litellm/README.md +0 -180
- package/ccw-litellm/pyproject.toml +0 -35
- package/ccw-litellm/src/ccw_litellm/__init__.py +0 -47
- package/ccw-litellm/src/ccw_litellm/cli.py +0 -108
- package/ccw-litellm/src/ccw_litellm/clients/__init__.py +0 -12
- package/ccw-litellm/src/ccw_litellm/clients/litellm_embedder.py +0 -270
- package/ccw-litellm/src/ccw_litellm/clients/litellm_llm.py +0 -198
- package/ccw-litellm/src/ccw_litellm/config/__init__.py +0 -22
- package/ccw-litellm/src/ccw_litellm/config/loader.py +0 -343
- package/ccw-litellm/src/ccw_litellm/config/models.py +0 -162
- package/ccw-litellm/src/ccw_litellm/interfaces/__init__.py +0 -14
- package/ccw-litellm/src/ccw_litellm/interfaces/embedder.py +0 -52
- package/ccw-litellm/src/ccw_litellm/interfaces/llm.py +0 -45
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TerminalDashboardPage-D1WekoOy.js","sources":["../../../../node_modules/lucide-react/dist/esm/icons/circle-dot.js","../../../../node_modules/lucide-react/dist/esm/icons/eraser.js","../../../../node_modules/lucide-react/dist/esm/icons/list-plus.js","../../../../node_modules/lucide-react/dist/esm/icons/wifi-off.js","../../src/components/terminal-dashboard/AssociationHighlight.tsx","../../src/components/terminal-dashboard/CliConfigModal.tsx","../../src/components/terminal-dashboard/DashboardToolbar.tsx","../../src/lib/ccw-artifacts.ts","../../src/components/terminal-dashboard/ArtifactTag.tsx","../../src/components/terminal-dashboard/TerminalInstance.tsx","../../src/components/terminal-dashboard/TerminalPane.tsx","../../src/components/terminal-dashboard/TerminalGrid.tsx","../../src/components/terminal-dashboard/SessionGroupTree.tsx","../../src/components/terminal-dashboard/IssuePanel.tsx","../../src/components/terminal-dashboard/QueueListColumn.tsx","../../src/components/terminal-dashboard/SchedulerPanel.tsx","../../src/components/terminal-dashboard/BottomInspector.tsx","../../src/components/terminal-dashboard/ExecutionMonitorPanel.tsx","../../src/components/terminal-dashboard/FileSidebarPanel.tsx","../../src/pages/TerminalDashboardPage.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CircleDot = createLucideIcon(\"CircleDot\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"1\", key: \"41hilf\" }]\n]);\n\nexport { CircleDot as default };\n//# sourceMappingURL=circle-dot.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Eraser = createLucideIcon(\"Eraser\", [\n [\n \"path\",\n {\n d: \"m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21\",\n key: \"182aya\"\n }\n ],\n [\"path\", { d: \"M22 21H7\", key: \"t4ddhn\" }],\n [\"path\", { d: \"m5 11 9 9\", key: \"1mo9qw\" }]\n]);\n\nexport { Eraser as default };\n//# sourceMappingURL=eraser.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ListPlus = createLucideIcon(\"ListPlus\", [\n [\"path\", { d: \"M11 12H3\", key: \"51ecnj\" }],\n [\"path\", { d: \"M16 6H3\", key: \"1wxfjs\" }],\n [\"path\", { d: \"M16 18H3\", key: \"12xzn7\" }],\n [\"path\", { d: \"M18 9v6\", key: \"1twb98\" }],\n [\"path\", { d: \"M21 12h-6\", key: \"bt1uis\" }]\n]);\n\nexport { ListPlus as default };\n//# sourceMappingURL=list-plus.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst WifiOff = createLucideIcon(\"WifiOff\", [\n [\"path\", { d: \"M12 20h.01\", key: \"zekei9\" }],\n [\"path\", { d: \"M8.5 16.429a5 5 0 0 1 7 0\", key: \"1bycff\" }],\n [\"path\", { d: \"M5 12.859a10 10 0 0 1 5.17-2.69\", key: \"1dl1wf\" }],\n [\"path\", { d: \"M19 12.859a10 10 0 0 0-2.007-1.523\", key: \"4k23kn\" }],\n [\"path\", { d: \"M2 8.82a15 15 0 0 1 4.177-2.643\", key: \"1grhjp\" }],\n [\"path\", { d: \"M22 8.82a15 15 0 0 0-11.288-3.764\", key: \"z3jwby\" }],\n [\"path\", { d: \"m2 2 20 20\", key: \"1ooewy\" }]\n]);\n\nexport { WifiOff as default };\n//# sourceMappingURL=wifi-off.js.map\n","// ========================================\r\n// AssociationHighlight Context\r\n// ========================================\r\n// React context provider for cross-panel association chain highlighting.\r\n// Provides ephemeral UI state for linked-chain highlights shared across\r\n// left/middle/right panels. The highlighted chain indicates which\r\n// Issue, QueueItem, and Session are visually linked.\r\n//\r\n// Design rationale: React context chosen over Zustand store because\r\n// highlight state is ephemeral UI state that does not need persistence\r\n// or cross-page sharing.\r\n\r\nimport {\r\n createContext,\r\n useContext,\r\n useState,\r\n useCallback,\r\n useEffect,\r\n useMemo,\r\n useRef,\r\n type ReactNode,\r\n} from 'react';\r\nimport type { AssociationChain } from '@/types/terminal-dashboard';\r\n\r\n// ========== Context Type ==========\r\n\r\ninterface AssociationHighlightContextType {\r\n /** Currently highlighted association chain, or null if nothing is highlighted */\r\n chain: AssociationChain | null;\r\n /** Set the highlighted chain (pass null to clear) */\r\n setChain: (chain: AssociationChain | null) => void;\r\n /** Check if a specific entity is part of the current highlighted chain */\r\n isHighlighted: (entityId: string, entityType: 'issue' | 'queue' | 'session') => boolean;\r\n}\r\n\r\n// ========== Context ==========\r\n\r\nconst AssociationHighlightContext = createContext<AssociationHighlightContextType | null>(null);\r\n\r\n// ========== Provider ==========\r\n\r\nexport function AssociationHighlightProvider({\r\n children,\r\n scopeKey,\r\n}: {\r\n children: ReactNode;\r\n scopeKey?: string | null;\r\n}) {\r\n const [chain, setChainState] = useState<AssociationChain | null>(null);\r\n const lastScopeKeyRef = useRef(scopeKey);\r\n\r\n useEffect(() => {\r\n if (lastScopeKeyRef.current !== scopeKey) {\r\n lastScopeKeyRef.current = scopeKey;\r\n setChainState(null);\r\n }\r\n }, [scopeKey]);\r\n\r\n const setChain = useCallback((nextChain: AssociationChain | null) => {\r\n setChainState(nextChain);\r\n }, []);\r\n\r\n const isHighlighted = useCallback(\r\n (entityId: string, entityType: 'issue' | 'queue' | 'session'): boolean => {\r\n if (!chain) return false;\r\n switch (entityType) {\r\n case 'issue':\r\n return chain.issueId === entityId;\r\n case 'queue':\r\n return chain.queueItemId === entityId;\r\n case 'session':\r\n return chain.sessionId === entityId;\r\n default:\r\n return false;\r\n }\r\n },\r\n [chain]\r\n );\r\n\r\n const value = useMemo<AssociationHighlightContextType>(\r\n () => ({ chain, setChain, isHighlighted }),\r\n [chain, setChain, isHighlighted]\r\n );\r\n\r\n return (\r\n <AssociationHighlightContext.Provider value={value}>\r\n {children}\r\n </AssociationHighlightContext.Provider>\r\n );\r\n}\r\n\r\n// ========== Consumer Hook ==========\r\n\r\n/**\r\n * Hook to access the association highlight context.\r\n * Must be used within an AssociationHighlightProvider.\r\n */\r\nexport function useAssociationHighlight(): AssociationHighlightContextType {\r\n const ctx = useContext(AssociationHighlightContext);\r\n if (!ctx) {\r\n throw new Error(\r\n 'useAssociationHighlight must be used within an AssociationHighlightProvider'\r\n );\r\n }\r\n return ctx;\r\n}\r\n","// ========================================\n// CliConfigModal Component\n// ========================================\n// Config modal for creating a new CLI session in Terminal Dashboard.\n\nimport * as React from 'react';\nimport { useIntl } from 'react-intl';\nimport { ChevronDown, FolderOpen, RefreshCw } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/Button';\nimport { Input } from '@/components/ui/Input';\nimport { Label } from '@/components/ui/Label';\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n} from '@/components/ui/Dialog';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/Select';\nimport { RadioGroup, RadioGroupItem } from '@/components/ui/RadioGroup';\nimport { useConfigStore, selectCliTools } from '@/stores/configStore';\nimport { useCliSettings } from '@/hooks/useApiSettings';\n\nexport type CliTool = string;\nexport type LaunchMode = 'default' | 'yolo';\nexport type ShellKind = 'bash' | 'pwsh' | 'cmd';\n\nexport interface CliSessionConfig {\n tool: CliTool;\n model?: string;\n launchMode: LaunchMode;\n preferredShell: ShellKind;\n workingDir: string;\n /** Session tag for grouping (auto-generated if not provided) */\n tag: string;\n /** CLI Settings endpoint ID for custom API configuration */\n settingsEndpointId?: string;\n}\n\nexport interface CliConfigModalProps {\n isOpen: boolean;\n onClose: () => void;\n defaultWorkingDir?: string | null;\n onCreateSession: (config: CliSessionConfig) => Promise<void>;\n}\n\n/**\n * Generate a tag name: {tool}-{HHmmss}\n * Example: gemini-143052\n */\nfunction generateTag(tool: string): string {\n const now = new Date();\n const time = now.toTimeString().slice(0, 8).replace(/:/g, '');\n return `${tool}-${time}`;\n}\n\nexport function CliConfigModal({\n isOpen,\n onClose,\n defaultWorkingDir,\n onCreateSession,\n}: CliConfigModalProps) {\n const { formatMessage } = useIntl();\n\n // Dynamic tool data from configStore\n const cliTools = useConfigStore(selectCliTools);\n const enabledTools = React.useMemo(\n () =>\n Object.entries(cliTools)\n .filter(([, config]) => config.enabled)\n .map(([key]) => key),\n [cliTools]\n );\n\n const [tool, setTool] = React.useState<CliTool>('gemini');\n const [model, setModel] = React.useState<string | undefined>(undefined);\n const [launchMode, setLaunchMode] = React.useState<LaunchMode>('yolo');\n // Default to 'cmd' on Windows for better compatibility with npm CLI tools (.cmd files)\n const [preferredShell, setPreferredShell] = React.useState<ShellKind>(\n typeof navigator !== 'undefined' && navigator.platform.toLowerCase().includes('win') ? 'cmd' : 'bash'\n );\n const [workingDir, setWorkingDir] = React.useState<string>(defaultWorkingDir ?? '');\n const [tag, setTag] = React.useState<string>('');\n\n const [isSubmitting, setIsSubmitting] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n\n // Model combobox state\n const [modelInputValue, setModelInputValue] = React.useState('');\n const [isModelDropdownOpen, setIsModelDropdownOpen] = React.useState(false);\n const modelContainerRef = React.useRef<HTMLDivElement>(null);\n const modelInputRef = React.useRef<HTMLInputElement>(null);\n\n // CLI Settings integration (for all tools)\n const { cliSettings } = useCliSettings({ enabled: true });\n\n // Map tool names to provider types for filtering\n const toolProviderMap: Record<string, string> = {\n claude: 'claude',\n codex: 'codex',\n gemini: 'gemini',\n };\n const currentProvider = toolProviderMap[tool] || tool;\n\n const enabledCliSettings = React.useMemo(\n () => (cliSettings || []).filter((s) => s.enabled && (s.provider || 'claude') === currentProvider),\n [cliSettings, currentProvider]\n );\n const [settingsEndpointId, setSettingsEndpointId] = React.useState<string | undefined>(undefined);\n\n // Reset settingsEndpointId when tool changes\n React.useEffect(() => {\n setSettingsEndpointId(undefined);\n }, [tool]);\n\n // Derive model options from configStore + CLI Settings profile override\n const modelOptions = React.useMemo(() => {\n // If a CLI Settings profile is selected and has availableModels, use those\n if (settingsEndpointId) {\n const endpoint = enabledCliSettings.find((s) => s.id === settingsEndpointId);\n if (endpoint?.settings.availableModels?.length) {\n return endpoint.settings.availableModels;\n }\n }\n const toolConfig = cliTools[tool];\n if (!toolConfig) return [];\n if (toolConfig.availableModels?.length) return toolConfig.availableModels;\n // Build models from primaryModel/secondaryModel, filtering out undefined\n const models: string[] = [];\n if (toolConfig.primaryModel) models.push(toolConfig.primaryModel);\n if (toolConfig.secondaryModel && toolConfig.secondaryModel !== toolConfig.primaryModel) {\n models.push(toolConfig.secondaryModel);\n }\n return models;\n }, [cliTools, tool, settingsEndpointId, enabledCliSettings]);\n\n // Generate new tag when modal opens or tool changes\n const regenerateTag = React.useCallback(() => {\n setTag(generateTag(tool));\n }, [tool]);\n\n React.useEffect(() => {\n if (!isOpen) return;\n // Reset to a safe default each time the modal is opened.\n const nextWorkingDir = defaultWorkingDir ?? '';\n setWorkingDir(nextWorkingDir);\n setError(null);\n setSettingsEndpointId(undefined);\n regenerateTag();\n }, [isOpen, defaultWorkingDir, regenerateTag]);\n\n // Update tag prefix when tool changes\n React.useEffect(() => {\n if (tag) {\n const suffix = tag.split('-').pop() || '';\n setTag(`${tool}-${suffix}`);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- only re-run when tool changes, reading tag intentionally stale\n }, [tool]);\n\n // Sync model input display when model state changes (e.g., tool change)\n React.useEffect(() => {\n setModelInputValue(model ?? '');\n }, [model]);\n\n // Filter model suggestions based on typed input\n const filteredModelOptions = React.useMemo(() => {\n const query = modelInputValue.toLowerCase();\n if (!query) return modelOptions;\n return modelOptions.filter((m) => m.toLowerCase().includes(query));\n }, [modelOptions, modelInputValue]);\n\n // Close model dropdown on outside click\n React.useEffect(() => {\n function handleClickOutside(e: MouseEvent) {\n if (modelContainerRef.current && !modelContainerRef.current.contains(e.target as Node)) {\n setIsModelDropdownOpen(false);\n }\n }\n if (isModelDropdownOpen) {\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }\n }, [isModelDropdownOpen]);\n\n const handleToolChange = (nextTool: string) => {\n setTool(nextTool as CliTool);\n const nextConfig = cliTools[nextTool];\n const nextModels = nextConfig?.availableModels?.length\n ? nextConfig.availableModels\n : [nextConfig?.primaryModel, nextConfig?.secondaryModel].filter(Boolean) as string[];\n if (!model || !nextModels.includes(model)) {\n setModel(nextModels[0]);\n }\n };\n\n const handleBrowse = () => {\n // Reserved for future file-picker integration\n console.log('[CliConfigModal] browse working directory - not implemented');\n };\n\n const handleCreate = async () => {\n const dir = workingDir.trim();\n if (!dir) {\n setError(formatMessage({ id: 'terminalDashboard.cliConfig.errors.workingDirRequired' }));\n return;\n }\n\n const finalTag = tag.trim() || generateTag(tool);\n\n setIsSubmitting(true);\n setError(null);\n try {\n await onCreateSession({\n tool,\n model,\n launchMode,\n preferredShell,\n workingDir: dir,\n tag: finalTag,\n settingsEndpointId,\n });\n onClose();\n } catch (err) {\n console.error('[CliConfigModal] create session failed:', err);\n setError(formatMessage({ id: 'terminalDashboard.cliConfig.errors.createFailed' }));\n } finally {\n setIsSubmitting(false);\n }\n };\n\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>\n <DialogContent className=\"sm:max-w-[720px] max-h-[90vh] overflow-y-auto\">\n <DialogHeader>\n <DialogTitle>{formatMessage({ id: 'terminalDashboard.cliConfig.title' })}</DialogTitle>\n <DialogDescription>\n {formatMessage({ id: 'terminalDashboard.cliConfig.description' })}\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4 py-4\">\n {/* Tag / Name */}\n <div className=\"space-y-2\">\n <Label htmlFor=\"cli-config-tag\">\n {formatMessage({ id: 'terminalDashboard.cliConfig.tag', defaultMessage: 'Session Name' })}\n </Label>\n <div className=\"flex gap-2\">\n <Input\n id=\"cli-config-tag\"\n value={tag}\n onChange={(e) => setTag(e.target.value)}\n placeholder={formatMessage({ id: 'terminalDashboard.cliConfig.tagPlaceholder', defaultMessage: 'e.g., gemini-143052' })}\n disabled={isSubmitting}\n className=\"flex-1\"\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={regenerateTag}\n disabled={isSubmitting}\n title={formatMessage({ id: 'terminalDashboard.cliConfig.regenerateTag', defaultMessage: 'Regenerate name' })}\n >\n <RefreshCw className=\"w-4 h-4\" />\n </Button>\n </div>\n <p className=\"text-xs text-muted-foreground\">\n {formatMessage({ id: 'terminalDashboard.cliConfig.tagHint', defaultMessage: 'Auto-generated as {tool}-{time}. Used for grouping sessions.' })}\n </p>\n </div>\n\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n {/* Tool */}\n <div className=\"space-y-2\">\n <Label htmlFor=\"cli-config-tool\">\n {formatMessage({ id: 'terminalDashboard.cliConfig.tool' })}\n </Label>\n <Select value={tool} onValueChange={handleToolChange} disabled={isSubmitting}>\n <SelectTrigger id=\"cli-config-tool\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {enabledTools.map((t) => (\n <SelectItem key={t} value={t}>\n {t}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {/* Model - Combobox (input + dropdown suggestions) */}\n <div className=\"space-y-2\">\n <Label htmlFor=\"cli-config-model\">\n {formatMessage({ id: 'terminalDashboard.cliConfig.model' })}\n </Label>\n <div ref={modelContainerRef} className=\"relative\">\n <div className=\"flex\">\n <input\n ref={modelInputRef}\n id=\"cli-config-model\"\n value={modelInputValue}\n onChange={(e) => {\n const v = e.target.value;\n setModelInputValue(v);\n setModel(v || undefined);\n if (!isModelDropdownOpen) setIsModelDropdownOpen(true);\n }}\n onFocus={() => setIsModelDropdownOpen(true)}\n onKeyDown={(e) => {\n if (e.key === 'Escape') setIsModelDropdownOpen(false);\n if (e.key === 'Enter') setIsModelDropdownOpen(false);\n }}\n placeholder={formatMessage({ id: 'terminalDashboard.cliConfig.modelAuto', defaultMessage: 'Auto' })}\n disabled={isSubmitting}\n className=\"flex h-10 w-full rounded-l-md border border-r-0 border-input bg-background px-3 py-2 text-sm font-mono ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\"\n />\n <button\n type=\"button\"\n onClick={() => {\n setIsModelDropdownOpen(!isModelDropdownOpen);\n if (!isModelDropdownOpen) modelInputRef.current?.focus();\n }}\n disabled={isSubmitting}\n className=\"flex items-center justify-center h-10 w-9 shrink-0 rounded-r-md border border-input bg-background hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <ChevronDown className=\"h-4 w-4 opacity-50\" />\n </button>\n </div>\n {isModelDropdownOpen && (\n <div className=\"absolute z-50 mt-1 w-full rounded-md border border-border bg-card shadow-md max-h-48 overflow-y-auto\">\n <button\n type=\"button\"\n onClick={() => {\n setModel(undefined);\n setModelInputValue('');\n setIsModelDropdownOpen(false);\n }}\n className={cn(\n 'flex w-full items-center px-3 py-1.5 text-sm cursor-pointer hover:bg-accent hover:text-accent-foreground',\n !model && 'bg-accent/50'\n )}\n >\n {formatMessage({ id: 'terminalDashboard.cliConfig.modelAuto', defaultMessage: 'Auto' })}\n </button>\n {filteredModelOptions.map((m) => (\n <button\n key={m}\n type=\"button\"\n onClick={() => {\n setModel(m);\n setModelInputValue(m);\n setIsModelDropdownOpen(false);\n }}\n className={cn(\n 'flex w-full items-center px-3 py-1.5 text-sm cursor-pointer hover:bg-accent hover:text-accent-foreground font-mono',\n model === m && 'bg-accent/50'\n )}\n >\n {m}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* Config Profile (all tools with settings) */}\n {enabledCliSettings.length > 0 && (\n <div className=\"space-y-2\">\n <Label htmlFor=\"cli-config-profile\">\n {formatMessage({ id: 'terminalDashboard.cliConfig.configProfile', defaultMessage: 'Config Profile' })}\n </Label>\n <Select\n value={settingsEndpointId ?? '__default__'}\n onValueChange={(v) => {\n const id = v === '__default__' ? undefined : v;\n setSettingsEndpointId(id);\n // If profile has availableModels, use those for model dropdown\n if (id) {\n const endpoint = enabledCliSettings.find((s) => s.id === id);\n if (endpoint?.settings.availableModels?.length) {\n setModel(endpoint.settings.availableModels[0]);\n }\n }\n }}\n disabled={isSubmitting}\n >\n <SelectTrigger id=\"cli-config-profile\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__default__\">\n {formatMessage({ id: 'terminalDashboard.cliConfig.defaultProfile', defaultMessage: 'Default' })}\n </SelectItem>\n {enabledCliSettings.map((s) => (\n <SelectItem key={s.id} value={s.id}>{s.name}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n <p className=\"text-xs text-muted-foreground\">\n {formatMessage({ id: 'terminalDashboard.cliConfig.configProfileHint', defaultMessage: 'Select a CLI Settings profile for custom API configuration.' })}\n </p>\n </div>\n )}\n\n {/* Mode */}\n <div className=\"space-y-2\">\n <Label>{formatMessage({ id: 'terminalDashboard.cliConfig.mode' })}</Label>\n <RadioGroup\n value={launchMode}\n onValueChange={(v) => setLaunchMode(v as LaunchMode)}\n className=\"flex items-center gap-4\"\n >\n <label className=\"flex items-center gap-2 text-sm cursor-pointer\">\n <RadioGroupItem value=\"default\" />\n {formatMessage({ id: 'terminalDashboard.cliConfig.modeDefault' })}\n </label>\n <label className=\"flex items-center gap-2 text-sm cursor-pointer\">\n <RadioGroupItem value=\"yolo\" />\n {formatMessage({ id: 'terminalDashboard.cliConfig.modeYolo' })}\n </label>\n </RadioGroup>\n </div>\n\n {/* Shell */}\n <div className=\"space-y-2\">\n <Label htmlFor=\"cli-config-shell\">\n {formatMessage({ id: 'terminalDashboard.cliConfig.shell' })}\n </Label>\n <Select\n value={preferredShell}\n onValueChange={(v) => setPreferredShell(v as ShellKind)}\n disabled={isSubmitting}\n >\n <SelectTrigger id=\"cli-config-shell\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"cmd\">cmd (推荐 Windows)</SelectItem>\n <SelectItem value=\"bash\">bash (Git Bash/WSL)</SelectItem>\n <SelectItem value=\"pwsh\">pwsh (PowerShell)</SelectItem>\n </SelectContent>\n </Select>\n </div>\n\n {/* Working Directory */}\n <div className=\"space-y-2\">\n <Label htmlFor=\"cli-config-workingDir\">\n {formatMessage({ id: 'terminalDashboard.cliConfig.workingDir' })}\n </Label>\n <div className=\"flex gap-2\">\n <Input\n id=\"cli-config-workingDir\"\n value={workingDir}\n onChange={(e) => {\n setWorkingDir(e.target.value);\n if (error) setError(null);\n }}\n placeholder={formatMessage({ id: 'terminalDashboard.cliConfig.workingDirPlaceholder' })}\n disabled={isSubmitting}\n className={cn(error && 'border-destructive')}\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleBrowse}\n disabled={isSubmitting}\n title={formatMessage({ id: 'terminalDashboard.cliConfig.browse' })}\n >\n <FolderOpen className=\"w-4 h-4\" />\n </Button>\n </div>\n {error && <p className=\"text-xs text-destructive\">{error}</p>}\n </div>\n </div>\n\n <DialogFooter>\n <Button variant=\"outline\" onClick={onClose} disabled={isSubmitting}>\n {formatMessage({ id: 'common.actions.cancel' })}\n </Button>\n <Button onClick={handleCreate} disabled={isSubmitting}>\n {formatMessage({ id: 'common.actions.create' })}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n\nexport default CliConfigModal;\n","// ========================================\n// DashboardToolbar Component\n// ========================================\n// Top toolbar for Terminal Dashboard V2.\n// Provides toggle buttons for floating panels (Issues/Queue/Inspector)\n// and layout preset controls. Sessions sidebar is always visible.\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useIntl } from 'react-intl';\nimport {\n AlertCircle,\n ListChecks,\n Info,\n FolderOpen,\n LayoutGrid,\n Columns2,\n Rows2,\n Square,\n Loader2,\n Folder,\n Maximize2,\n Minimize2,\n Activity,\n Plus,\n Gauge,\n} from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport { Badge } from '@/components/ui/Badge';\nimport {\n useIssueQueueIntegrationStore,\n selectAssociationChain,\n} from '@/stores/issueQueueIntegrationStore';\nimport { useIssues, useIssueQueue } from '@/hooks/useIssues';\nimport { useTerminalGridStore, selectTerminalGridFocusedPaneId } from '@/stores/terminalGridStore';\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\nimport { toast } from '@/stores/notificationStore';\nimport { useExecutionMonitorStore, selectActiveExecutionCount } from '@/stores/executionMonitorStore';\nimport { useSessionManagerStore } from '@/stores/sessionManagerStore';\nimport { useConfigStore } from '@/stores/configStore';\nimport { useQueueSchedulerStore, selectQueueSchedulerStatus } from '@/stores/queueSchedulerStore';\nimport { CliConfigModal, type CliSessionConfig } from './CliConfigModal';\n\n// ========== Types ==========\n\nexport type PanelId = 'issues' | 'queue' | 'inspector' | 'execution' | 'scheduler';\n\ninterface DashboardToolbarProps {\n activePanel: PanelId | null;\n onTogglePanel: (panelId: PanelId) => void;\n /** Whether the file sidebar is open */\n isFileSidebarOpen?: boolean;\n /** Callback to toggle file sidebar */\n onToggleFileSidebar?: () => void;\n /** Whether the session sidebar is open */\n isSessionSidebarOpen?: boolean;\n /** Callback to toggle session sidebar */\n onToggleSessionSidebar?: () => void;\n /** Whether fullscreen mode is active */\n isFullscreen?: boolean;\n /** Callback to toggle fullscreen mode */\n onToggleFullscreen?: () => void;\n}\n\n// ========== Layout Presets ==========\n\nconst LAYOUT_PRESETS = [\n { id: 'single' as const, icon: Square, labelId: 'terminalDashboard.toolbar.layoutSingle' },\n { id: 'split-h' as const, icon: Columns2, labelId: 'terminalDashboard.toolbar.layoutSplitH' },\n { id: 'split-v' as const, icon: Rows2, labelId: 'terminalDashboard.toolbar.layoutSplitV' },\n { id: 'grid-2x2' as const, icon: LayoutGrid, labelId: 'terminalDashboard.toolbar.layoutGrid' },\n];\n\n// ========== Component ==========\n\nexport function DashboardToolbar({ activePanel, onTogglePanel, isFileSidebarOpen, onToggleFileSidebar, isSessionSidebarOpen, onToggleSessionSidebar, isFullscreen, onToggleFullscreen }: DashboardToolbarProps) {\n const { formatMessage } = useIntl();\n\n // Issues count\n const { openCount } = useIssues();\n\n // Queue count\n const queueQuery = useIssueQueue();\n const queueCount = useMemo(() => {\n if (!queueQuery.data) return 0;\n const grouped = queueQuery.data.grouped_items ?? {};\n let count = 0;\n for (const items of Object.values(grouped)) {\n count += items.length;\n }\n return count;\n }, [queueQuery.data]);\n\n // Inspector chain indicator\n const associationChain = useIssueQueueIntegrationStore(selectAssociationChain);\n const hasChain = associationChain !== null;\n\n // Execution monitor count\n const executionCount = useExecutionMonitorStore(selectActiveExecutionCount);\n\n // Scheduler status for badge indicator\n const schedulerStatus = useQueueSchedulerStore(selectQueueSchedulerStatus);\n const isSchedulerActive = schedulerStatus !== 'idle';\n\n // Feature flags for panel visibility\n const featureFlags = useConfigStore((s) => s.featureFlags);\n const showQueue = featureFlags.dashboardQueuePanelEnabled;\n const showInspector = featureFlags.dashboardInspectorEnabled;\n const showExecution = featureFlags.dashboardExecutionMonitorEnabled;\n\n // Layout preset handler\n const resetLayout = useTerminalGridStore((s) => s.resetLayout);\n const handlePreset = useCallback(\n (preset: 'single' | 'split-h' | 'split-v' | 'grid-2x2') => {\n resetLayout(preset);\n },\n [resetLayout]\n );\n\n // Launch CLI handlers\n const projectPath = useWorkflowStore(selectProjectPath);\n const focusedPaneId = useTerminalGridStore(selectTerminalGridFocusedPaneId);\n const createSessionAndAssign = useTerminalGridStore((s) => s.createSessionAndAssign);\n const updateTerminalMeta = useSessionManagerStore((s) => s.updateTerminalMeta);\n const [isCreating, setIsCreating] = useState(false);\n const [isConfigOpen, setIsConfigOpen] = useState(false);\n\n useEffect(() => {\n setIsCreating(false);\n setIsConfigOpen(false);\n }, [projectPath]);\n\n // Helper to get or create a focused pane\n const getOrCreateFocusedPane = useCallback(() => {\n if (focusedPaneId) return focusedPaneId;\n // No focused pane - reset layout to create a single pane\n resetLayout('single');\n // Get the new focused pane id from store\n return useTerminalGridStore.getState().focusedPaneId;\n }, [focusedPaneId]);\n\n // Open config modal\n const handleOpenConfig = useCallback(() => {\n setIsConfigOpen(true);\n }, []);\n\n // Create session from config modal\n const handleCreateConfiguredSession = useCallback(async (config: CliSessionConfig) => {\n if (!projectPath) throw new Error('No project path');\n setIsCreating(true);\n try {\n const targetPaneId = getOrCreateFocusedPane();\n if (!targetPaneId) throw new Error('Failed to create pane');\n\n const result = await createSessionAndAssign(\n targetPaneId,\n {\n workingDir: config.workingDir || projectPath,\n preferredShell: config.preferredShell,\n tool: config.tool,\n model: config.model,\n launchMode: config.launchMode,\n settingsEndpointId: config.settingsEndpointId,\n },\n projectPath\n );\n\n // Store tag in terminalMetas for grouping\n if (result?.session?.sessionKey) {\n updateTerminalMeta(result.session.sessionKey, {\n tag: config.tag,\n title: config.tag,\n });\n }\n } catch (error: unknown) {\n const message = error instanceof Error\n ? error.message\n : (error as { message?: string })?.message\n ? (error as { message: string }).message\n : String(error);\n toast.error(`CLI 会话创建失败 (${config.tool})`, message);\n throw error;\n } finally {\n setIsCreating(false);\n }\n }, [projectPath, createSessionAndAssign, getOrCreateFocusedPane, updateTerminalMeta]);\n\n return (\n <>\n <div className=\"flex items-center gap-1 px-2 h-[40px] border-b border-border bg-muted/30 shrink-0\">\n {/* Launch CLI button - opens config dialog */}\n <button\n onClick={handleOpenConfig}\n className={cn(\n 'flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-xs transition-colors',\n 'text-muted-foreground hover:text-foreground hover:bg-muted',\n isCreating && 'opacity-50 cursor-wait'\n )}\n disabled={isCreating || !projectPath}\n title={formatMessage({ id: 'terminalDashboard.toolbar.launchCliHint', defaultMessage: 'Click to configure and launch a CLI session' })}\n >\n {isCreating ? (\n <Loader2 className=\"w-3.5 h-3.5 animate-spin\" />\n ) : (\n <Plus className=\"w-3.5 h-3.5\" />\n )}\n <span>{formatMessage({ id: 'terminalDashboard.toolbar.launchCli' })}</span>\n </button>\n\n {/* Separator */}\n <div className=\"w-px h-5 bg-border mx-1\" />\n\n {/* Session sidebar toggle */}\n <ToolbarButton\n icon={Folder}\n label={formatMessage({ id: 'terminalDashboard.toolbar.sessions', defaultMessage: 'Sessions' })}\n isActive={isSessionSidebarOpen ?? true}\n onClick={() => onToggleSessionSidebar?.()}\n />\n\n {/* Separator */}\n <div className=\"w-px h-5 bg-border mx-1\" />\n\n {/* Panel toggle buttons */}\n <ToolbarButton\n icon={AlertCircle}\n label={formatMessage({ id: 'terminalDashboard.toolbar.issues' })}\n isActive={activePanel === 'issues'}\n onClick={() => onTogglePanel('issues')}\n badge={openCount > 0 ? openCount : undefined}\n />\n {showQueue && (\n <ToolbarButton\n icon={ListChecks}\n label={formatMessage({ id: 'terminalDashboard.toolbar.queue' })}\n isActive={activePanel === 'queue'}\n onClick={() => onTogglePanel('queue')}\n badge={queueCount > 0 ? queueCount : undefined}\n />\n )}\n {showInspector && (\n <ToolbarButton\n icon={Info}\n label={formatMessage({ id: 'terminalDashboard.toolbar.inspector' })}\n isActive={activePanel === 'inspector'}\n onClick={() => onTogglePanel('inspector')}\n dot={hasChain}\n />\n )}\n {showExecution && (\n <ToolbarButton\n icon={Activity}\n label={formatMessage({ id: 'terminalDashboard.toolbar.executionMonitor', defaultMessage: 'Execution Monitor' })}\n isActive={activePanel === 'execution'}\n onClick={() => onTogglePanel('execution')}\n badge={executionCount > 0 ? executionCount : undefined}\n />\n )}\n <ToolbarButton\n icon={Gauge}\n label={formatMessage({ id: 'terminalDashboard.toolbar.scheduler', defaultMessage: 'Scheduler' })}\n isActive={activePanel === 'scheduler'}\n onClick={() => onTogglePanel('scheduler')}\n dot={isSchedulerActive}\n loading={isSchedulerActive}\n />\n <ToolbarButton\n icon={FolderOpen}\n label={formatMessage({ id: 'terminalDashboard.toolbar.files', defaultMessage: 'Files' })}\n isActive={isFileSidebarOpen ?? false}\n onClick={() => onToggleFileSidebar?.()}\n />\n\n {/* Separator */}\n <div className=\"w-px h-5 bg-border mx-1\" />\n\n {/* Layout presets */}\n {LAYOUT_PRESETS.map((preset) => (\n <button\n key={preset.id}\n onClick={() => handlePreset(preset.id)}\n className={cn(\n 'p-1.5 rounded transition-colors',\n 'text-muted-foreground hover:text-foreground hover:bg-muted'\n )}\n title={formatMessage({ id: preset.labelId })}\n >\n <preset.icon className=\"w-3.5 h-3.5\" />\n </button>\n ))}\n\n {/* Separator */}\n <div className=\"w-px h-5 bg-border mx-1\" />\n\n {/* Fullscreen toggle */}\n <button\n onClick={onToggleFullscreen}\n className={cn(\n 'p-1.5 rounded transition-colors',\n isFullscreen\n ? 'bg-primary/10 text-primary'\n : 'text-muted-foreground hover:text-foreground hover:bg-muted'\n )}\n title={isFullscreen\n ? formatMessage({ id: 'terminalDashboard.toolbar.exitFullscreen', defaultMessage: 'Exit Fullscreen' })\n : formatMessage({ id: 'terminalDashboard.toolbar.fullscreen', defaultMessage: 'Fullscreen' })\n }\n >\n {isFullscreen ? (\n <Minimize2 className=\"w-3.5 h-3.5\" />\n ) : (\n <Maximize2 className=\"w-3.5 h-3.5\" />\n )}\n </button>\n\n {/* Right-aligned title */}\n <span className=\"ml-auto text-xs text-muted-foreground font-medium\">\n {formatMessage({ id: 'terminalDashboard.page.title' })}\n </span>\n </div>\n\n <CliConfigModal\n isOpen={isConfigOpen}\n onClose={() => setIsConfigOpen(false)}\n defaultWorkingDir={projectPath}\n onCreateSession={handleCreateConfiguredSession}\n />\n </>\n );\n}\n\n// ========== Toolbar Button ==========\n\nfunction ToolbarButton({\n icon: Icon,\n label,\n isActive,\n onClick,\n badge,\n dot,\n loading,\n}: {\n icon: React.ComponentType<{ className?: string }>;\n label: string;\n isActive: boolean;\n onClick: () => void;\n badge?: number;\n dot?: boolean;\n loading?: boolean;\n}) {\n return (\n <button\n onClick={onClick}\n className={cn(\n 'flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-xs transition-colors',\n isActive\n ? 'bg-primary/10 text-primary font-medium'\n : 'text-muted-foreground hover:text-foreground hover:bg-muted'\n )}\n >\n {loading ? (\n <Loader2 className=\"w-3.5 h-3.5 animate-spin\" />\n ) : (\n <Icon className=\"w-3.5 h-3.5\" />\n )}\n <span>{label}</span>\n {badge !== undefined && badge > 0 && (\n <Badge variant=\"secondary\" className=\"text-[10px] px-1.5 py-0 ml-0.5\">\n {badge}\n </Badge>\n )}\n {dot && (\n <span\n className={cn(\n 'ml-0.5 w-2 h-2 rounded-full bg-primary shrink-0',\n loading && 'animate-pulse'\n )}\n />\n )}\n </button>\n );\n}\n","// ========================================\n// CCW Artifacts - Types & Detection\n// ========================================\n\nexport type ArtifactType =\n | 'workflow-session'\n | 'lite-session'\n | 'claude-md'\n | 'ccw-config'\n | 'issue';\n\nexport interface CcArtifact {\n type: ArtifactType;\n path: string;\n}\n\nconst TRAILING_PUNCTUATION = /[)\\]}>,.;:!?]+$/g;\nconst WRAP_QUOTES = /^['\"`]+|['\"`]+$/g;\n\nfunction normalizePath(raw: string): string {\n return raw.trim().replace(WRAP_QUOTES, '').replace(TRAILING_PUNCTUATION, '');\n}\n\n/**\n * Patterns for detecting CCW-related artifacts in terminal output.\n *\n * Notes:\n * - Prefer relative paths (e.g., `.workflow/...`) so callers can resolve against a project root.\n * - Keep patterns conservative to reduce false positives in generic logs.\n */\nexport const ARTIFACT_PATTERNS: Record<ArtifactType, RegExp[]> = {\n 'workflow-session': [\n /(?:^|[^\\w.])(\\.workflow[\\\\/](?:active|archives)[\\\\/][^\\s\"'`]+[\\\\/]workflow-session\\.json)\\b/g,\n ],\n 'lite-session': [\n /(?:^|[^\\w.])(\\.workflow[\\\\/]\\.lite-plan[\\\\/][^\\s\"'`]+)\\b/g,\n ],\n 'claude-md': [\n /([^\\s\"'`]*CLAUDE\\.md)\\b/gi,\n ],\n 'ccw-config': [\n /(?:^|[^\\w.])(\\.ccw[\\\\/][^\\s\"'`]+)\\b/g,\n /(?:^|[^\\w.])(ccw\\.config\\.(?:json|ya?ml|toml))\\b/gi,\n ],\n issue: [\n /(?:^|[^\\w.])(\\.workflow[\\\\/]issues[\\\\/][^\\s\"'`]+)\\b/g,\n ],\n};\n\n/**\n * Detect CCW artifacts from an arbitrary text blob.\n *\n * Returns a de-duplicated list of `{ type, path }` in discovery order.\n */\nexport function detectCcArtifacts(text: string): CcArtifact[] {\n if (!text) return [];\n\n const candidates: Array<CcArtifact & { index: number }> = [];\n\n for (const type of Object.keys(ARTIFACT_PATTERNS) as ArtifactType[]) {\n for (const pattern of ARTIFACT_PATTERNS[type]) {\n pattern.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(text)) !== null) {\n const raw = match[1] ?? match[0];\n const path = normalizePath(raw);\n if (!path) continue;\n\n const full = match[0] ?? '';\n const group = match[1] ?? raw;\n const rel = full.indexOf(group);\n const index = (match.index ?? 0) + (rel >= 0 ? rel : 0);\n\n candidates.push({ type, path, index });\n }\n }\n }\n\n candidates.sort((a, b) => a.index - b.index);\n\n const results: CcArtifact[] = [];\n const seen = new Set<string>();\n for (const c of candidates) {\n const key = `${c.type}:${c.path}`;\n if (seen.has(key)) continue;\n seen.add(key);\n results.push({ type: c.type, path: c.path });\n }\n\n return results;\n}\n","// ========================================\n// ArtifactTag Component\n// ========================================\n// Colored, clickable tag for detected CCW artifacts in terminal output.\n\nimport { useIntl } from 'react-intl';\nimport { cn } from '@/lib/utils';\nimport { badgeVariants } from '@/components/ui/Badge';\nimport type { ArtifactType } from '@/lib/ccw-artifacts';\n\nexport interface ArtifactTagProps {\n type: ArtifactType;\n path: string;\n onClick?: (path: string) => void;\n className?: string;\n}\n\nfunction getVariant(type: ArtifactType) {\n switch (type) {\n case 'workflow-session':\n return 'info';\n case 'lite-session':\n return 'success';\n case 'claude-md':\n return 'review';\n case 'ccw-config':\n return 'warning';\n case 'issue':\n return 'destructive';\n default:\n return 'secondary';\n }\n}\n\nfunction getLabelId(type: ArtifactType): string {\n switch (type) {\n case 'workflow-session':\n return 'terminalDashboard.artifacts.types.workflowSession';\n case 'lite-session':\n return 'terminalDashboard.artifacts.types.liteSession';\n case 'claude-md':\n return 'terminalDashboard.artifacts.types.claudeMd';\n case 'ccw-config':\n return 'terminalDashboard.artifacts.types.ccwConfig';\n case 'issue':\n return 'terminalDashboard.artifacts.types.issue';\n }\n}\n\nfunction basename(p: string): string {\n const parts = p.split(/[\\\\/]/g);\n return parts[parts.length - 1] || p;\n}\n\nexport function ArtifactTag({ type, path, onClick, className }: ArtifactTagProps) {\n const { formatMessage } = useIntl();\n const label = formatMessage({ id: getLabelId(type) });\n const display = basename(path);\n\n return (\n <button\n type=\"button\"\n className={cn(\n badgeVariants({ variant: getVariant(type) as any }),\n 'gap-1 cursor-pointer hover:opacity-90 active:opacity-100',\n 'px-2 py-0.5 text-[11px] font-semibold',\n className\n )}\n onClick={() => onClick?.(path)}\n title={path}\n >\n <span>{label}</span>\n <span className=\"opacity-80 font-mono\">{display}</span>\n </button>\n );\n}\n\nexport default ArtifactTag;\n","// ========================================\n// TerminalInstance Component\n// ========================================\n// xterm.js terminal wrapper for the Terminal Dashboard.\n// Reuses exact integration pattern from TerminalMainArea:\n// XTerm instance in ref, FitAddon, ResizeObserver, batched PTY input (30ms),\n// output chunk streaming from cliSessionStore.\n\nimport { useEffect, useRef, useCallback, useState } from 'react';\nimport { Terminal as XTerm } from 'xterm';\nimport { FitAddon } from 'xterm-addon-fit';\nimport { useCliSessionStore } from '@/stores/cliSessionStore';\nimport { useSessionManagerStore } from '@/stores/sessionManagerStore';\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\nimport {\n fetchCliSessionBuffer,\n sendCliSessionText,\n resizeCliSession,\n} from '@/lib/api';\nimport { cn } from '@/lib/utils';\nimport { detectCcArtifacts, type CcArtifact } from '@/lib/ccw-artifacts';\nimport { ArtifactTag } from './ArtifactTag';\n\n// ========== Types ==========\n\ninterface TerminalInstanceProps {\n /** Session key to render terminal for */\n sessionId: string;\n /** Additional CSS classes */\n className?: string;\n /** Optional callback to reveal a detected artifact path (e.g. open file browser) */\n onRevealPath?: (path: string) => void;\n}\n\n// ========== Component ==========\n\nconst ARTIFACT_DEBOUNCE_MS = 250;\nconst MAX_ARTIFACT_TAGS = 12;\n\nfunction isAbsolutePath(p: string): boolean {\n if (!p) return false;\n if (p.startsWith('/') || p.startsWith('\\\\')) return true;\n if (/^[A-Za-z]:[\\\\/]/.test(p)) return true;\n if (p.startsWith('~')) return true;\n return false;\n}\n\nfunction joinPath(base: string, relative: string): string {\n const sep = base.includes('\\\\') ? '\\\\' : '/';\n const b = base.replace(/[\\\\/]+$/, '');\n const r = relative.replace(/^[\\\\/]+/, '');\n return `${b}${sep}${r}`;\n}\n\nfunction resolveArtifactPath(path: string, projectPath: string | null): string {\n if (!path) return path;\n if (isAbsolutePath(path)) return path;\n if (!projectPath) return path;\n return joinPath(projectPath, path);\n}\n\nfunction mergeArtifacts(prev: CcArtifact[], next: CcArtifact[]): CcArtifact[] {\n if (next.length === 0) return prev;\n const map = new Map<string, CcArtifact>();\n for (const a of prev) map.set(`${a.type}:${a.path}`, a);\n let changed = false;\n for (const a of next) {\n const key = `${a.type}:${a.path}`;\n if (map.has(key)) continue;\n map.set(key, a);\n changed = true;\n }\n if (!changed) return prev;\n const merged = Array.from(map.values());\n return merged.length > MAX_ARTIFACT_TAGS ? merged.slice(merged.length - MAX_ARTIFACT_TAGS) : merged;\n}\n\nexport function TerminalInstance({ sessionId, className, onRevealPath }: TerminalInstanceProps) {\n const projectPath = useWorkflowStore(selectProjectPath);\n\n // cliSessionStore selectors\n const outputChunks = useCliSessionStore((s) => s.outputChunks);\n const setBuffer = useCliSessionStore((s) => s.setBuffer);\n const clearOutput = useCliSessionStore((s) => s.clearOutput);\n\n const [artifacts, setArtifacts] = useState<CcArtifact[]>([]);\n\n // ========== xterm Refs ==========\n\n const terminalHostRef = useRef<HTMLDivElement | null>(null);\n const xtermRef = useRef<XTerm | null>(null);\n const fitAddonRef = useRef<FitAddon | null>(null);\n const lastChunkIndexRef = useRef<number>(0);\n\n // Debounced artifact detection\n const pendingArtifactTextRef = useRef<string>('');\n const artifactTimerRef = useRef<number | null>(null);\n\n // PTY input batching (30ms, matching TerminalMainArea)\n const pendingInputRef = useRef<string>('');\n const flushTimerRef = useRef<number | null>(null);\n\n // Track sessionId in a ref so xterm onData callback always has latest value\n const sessionIdRef = useRef<string>(sessionId);\n sessionIdRef.current = sessionId;\n\n const projectPathRef = useRef<string | null>(projectPath);\n projectPathRef.current = projectPath;\n\n // Focus terminal when clicked\n const handleTerminalClick = useCallback(() => {\n xtermRef.current?.focus();\n }, []);\n\n const handleArtifactClick = useCallback((path: string) => {\n const resolved = resolveArtifactPath(path, projectPathRef.current);\n navigator.clipboard.writeText(resolved).catch((err) => {\n console.error('[TerminalInstance] copy artifact path failed:', err);\n });\n onRevealPath?.(resolved);\n }, [onRevealPath]);\n\n const scheduleArtifactParse = useCallback((text: string) => {\n if (!text) return;\n pendingArtifactTextRef.current += text;\n if (artifactTimerRef.current !== null) return;\n artifactTimerRef.current = window.setTimeout(() => {\n artifactTimerRef.current = null;\n const pending = pendingArtifactTextRef.current;\n pendingArtifactTextRef.current = '';\n const detected = detectCcArtifacts(pending);\n if (detected.length === 0) return;\n setArtifacts((prev) => mergeArtifacts(prev, detected));\n }, ARTIFACT_DEBOUNCE_MS);\n }, []);\n\n useEffect(() => {\n return () => {\n if (artifactTimerRef.current !== null) {\n window.clearTimeout(artifactTimerRef.current);\n artifactTimerRef.current = null;\n }\n };\n }, []);\n\n // ========== PTY Input Batching ==========\n\n const flushInput = useCallback(async () => {\n const key = sessionIdRef.current;\n if (!key) return;\n const pending = pendingInputRef.current;\n pendingInputRef.current = '';\n if (!pending) return;\n try {\n await sendCliSessionText(\n key,\n { text: pending, appendNewline: false },\n projectPathRef.current || undefined\n );\n } catch {\n // Ignore transient failures\n }\n }, []);\n\n const scheduleFlush = useCallback(() => {\n if (flushTimerRef.current !== null) return;\n flushTimerRef.current = window.setTimeout(async () => {\n flushTimerRef.current = null;\n await flushInput();\n }, 30);\n }, [flushInput]);\n\n // ========== xterm Lifecycle ==========\n\n // Initialize xterm instance (once per mount)\n useEffect(() => {\n if (!terminalHostRef.current) return;\n if (xtermRef.current) return;\n\n const term = new XTerm({\n convertEol: true,\n cursorBlink: true,\n fontFamily:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n fontSize: 12,\n scrollback: 5000,\n });\n const fitAddon = new FitAddon();\n term.loadAddon(fitAddon);\n term.open(terminalHostRef.current);\n fitAddon.fit();\n\n // Forward keystrokes to backend (batched 30ms)\n term.onData((data) => {\n if (!sessionIdRef.current) return;\n pendingInputRef.current += data;\n scheduleFlush();\n });\n\n xtermRef.current = term;\n fitAddonRef.current = fitAddon;\n\n return () => {\n // Flush any pending input before cleanup\n if (flushTimerRef.current !== null) {\n window.clearTimeout(flushTimerRef.current);\n flushTimerRef.current = null;\n }\n try {\n term.dispose();\n } finally {\n xtermRef.current = null;\n fitAddonRef.current = null;\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Attach to session: clear terminal and load buffer\n useEffect(() => {\n const term = xtermRef.current;\n const fitAddon = fitAddonRef.current;\n if (!term || !fitAddon) return;\n\n lastChunkIndexRef.current = 0;\n term.reset();\n term.clear();\n\n // Reset artifact detection state per session\n setArtifacts([]);\n pendingArtifactTextRef.current = '';\n if (artifactTimerRef.current !== null) {\n window.clearTimeout(artifactTimerRef.current);\n artifactTimerRef.current = null;\n }\n\n if (!sessionId) return;\n clearOutput(sessionId);\n\n fetchCliSessionBuffer(sessionId, projectPath || undefined)\n .then(({ buffer }) => {\n setBuffer(sessionId, buffer || '');\n })\n .catch(() => {\n // ignore\n })\n .finally(() => {\n fitAddon.fit();\n });\n }, [sessionId, projectPath, setBuffer, clearOutput]);\n\n // Stream new output chunks into xterm and forward to monitor worker\n useEffect(() => {\n const term = xtermRef.current;\n if (!term || !sessionId) return;\n\n const chunks = outputChunks[sessionId] ?? [];\n const start = lastChunkIndexRef.current;\n if (start >= chunks.length) return;\n\n const { feedMonitor } = useSessionManagerStore.getState();\n const newTextParts: string[] = [];\n for (let i = start; i < chunks.length; i++) {\n term.write(chunks[i].data);\n feedMonitor(sessionId, chunks[i].data);\n newTextParts.push(chunks[i].data);\n }\n lastChunkIndexRef.current = chunks.length;\n\n if (newTextParts.length > 0) {\n scheduleArtifactParse(newTextParts.join(''));\n }\n }, [outputChunks, sessionId, scheduleArtifactParse]);\n\n // ResizeObserver -> fit + resize backend\n useEffect(() => {\n const host = terminalHostRef.current;\n const term = xtermRef.current;\n const fitAddon = fitAddonRef.current;\n if (!host || !term || !fitAddon) return;\n\n const resize = () => {\n fitAddon.fit();\n if (sessionIdRef.current) {\n void (async () => {\n try {\n await resizeCliSession(\n sessionIdRef.current,\n { cols: term.cols, rows: term.rows },\n projectPathRef.current || undefined\n );\n } catch {\n // ignore\n }\n })();\n }\n };\n\n const ro = new ResizeObserver(resize);\n ro.observe(host);\n return () => ro.disconnect();\n }, [sessionId, projectPath]);\n\n // ========== Render ==========\n\n return (\n <div className={cn('relative h-full w-full', className)}>\n {artifacts.length > 0 && (\n <div className=\"absolute top-2 left-2 right-2 z-10 flex flex-wrap gap-1 pointer-events-none\">\n {artifacts.map((a) => (\n <ArtifactTag\n key={`${a.type}:${a.path}`}\n type={a.type}\n path={a.path}\n onClick={handleArtifactClick}\n className=\"pointer-events-auto\"\n />\n ))}\n </div>\n )}\n <div ref={terminalHostRef} className=\"h-full w-full bg-black/90\" onClick={handleTerminalClick} />\n </div>\n );\n}\n","// ========================================\n// TerminalPane Component\n// ========================================\n// Single terminal pane = PaneToolbar + content area.\n// Content can be terminal output or file preview based on displayMode.\n// Renders within the TerminalGrid recursive layout.\n// File preview is triggered from right sidebar FileSidebarPanel.\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useIntl } from 'react-intl';\nimport {\n SplitSquareHorizontal,\n SplitSquareVertical,\n Eraser,\n AlertTriangle,\n X,\n Terminal,\n ChevronDown,\n RotateCcw,\n Pause,\n Play,\n Loader2,\n FileText,\n ArrowLeft,\n LogOut,\n WifiOff,\n} from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport { TerminalInstance } from './TerminalInstance';\nimport { FilePreview } from '@/components/shared/FilePreview';\nimport {\n AlertDialog,\n AlertDialogContent,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogAction,\n AlertDialogCancel,\n} from '@/components/ui/AlertDialog';\nimport {\n useTerminalGridStore,\n selectTerminalGridPanes,\n selectTerminalGridFocusedPaneId,\n} from '@/stores/terminalGridStore';\nimport {\n useSessionManagerStore,\n selectTerminalMetas,\n} from '@/stores/sessionManagerStore';\nimport {\n useIssueQueueIntegrationStore,\n selectAssociationChain,\n} from '@/stores/issueQueueIntegrationStore';\nimport { useCliSessionStore } from '@/stores/cliSessionStore';\nimport { getAllPaneIds } from '@/lib/layout-utils';\nimport { useFileContent } from '@/hooks/useFileExplorer';\nimport type { PaneId } from '@/stores/viewerStore';\nimport type { TerminalStatus } from '@/types/terminal-dashboard';\n\n// ========== Status Styles ==========\n\nconst statusDotStyles: Record<TerminalStatus, string> = {\n active: 'bg-green-500',\n idle: 'bg-gray-400',\n error: 'bg-red-500',\n paused: 'bg-yellow-500',\n resuming: 'bg-blue-400 animate-pulse',\n locked: 'bg-amber-500 animate-pulse',\n};\n\n// ========== Props ==========\n\ninterface TerminalPaneProps {\n paneId: PaneId;\n}\n\n// ========== Component ==========\n\nexport function TerminalPane({ paneId }: TerminalPaneProps) {\n const { formatMessage } = useIntl();\n\n // Grid store\n const panes = useTerminalGridStore(selectTerminalGridPanes);\n const focusedPaneId = useTerminalGridStore(selectTerminalGridFocusedPaneId);\n const layout = useTerminalGridStore((s) => s.layout);\n const splitPane = useTerminalGridStore((s) => s.splitPane);\n const closePane = useTerminalGridStore((s) => s.closePane);\n const assignSession = useTerminalGridStore((s) => s.assignSession);\n const setFocused = useTerminalGridStore((s) => s.setFocused);\n const setPaneDisplayMode = useTerminalGridStore((s) => s.setPaneDisplayMode);\n\n const pane = panes[paneId];\n const sessionId = pane?.sessionId ?? null;\n const displayMode = pane?.displayMode ?? 'terminal';\n const filePath = pane?.filePath ?? null;\n const isFocused = focusedPaneId === paneId;\n const canClose = getAllPaneIds(layout).length > 1;\n const isFileMode = displayMode === 'file' && filePath;\n\n // Session data\n const terminalMetas = useSessionManagerStore(selectTerminalMetas);\n const sessions = useCliSessionStore((s) => s.sessions);\n\n // Session lifecycle actions\n const pauseSession = useSessionManagerStore((s) => s.pauseSession);\n const resumeSession = useSessionManagerStore((s) => s.resumeSession);\n const restartSession = useSessionManagerStore((s) => s.restartSession);\n const closeSession = useSessionManagerStore((s) => s.closeSession);\n\n // Action loading states\n const [isRestarting, setIsRestarting] = useState(false);\n const [isTogglingPause, setIsTogglingPause] = useState(false);\n const [isClosingSession, setIsClosingSession] = useState(false);\n const [isCloseConfirmOpen, setIsCloseConfirmOpen] = useState(false);\n\n // File content for preview mode\n const { content: fileContent, isLoading: isFileLoading, error: fileError } = useFileContent(filePath, {\n enabled: displayMode === 'file' && !!filePath,\n });\n\n // Association chain for linked issue badge\n const associationChain = useIssueQueueIntegrationStore(selectAssociationChain);\n const linkedIssueId = useMemo(() => {\n if (!sessionId || !associationChain) return null;\n if (associationChain.sessionId === sessionId) return associationChain.issueId;\n return null;\n }, [sessionId, associationChain]);\n\n // Terminal metadata\n const meta = sessionId ? terminalMetas[sessionId] : null;\n const status: TerminalStatus = meta?.status ?? 'idle';\n const alertCount = meta?.alertCount ?? 0;\n\n // Check if session exists - handles case where pane references a sessionId\n // that no longer exists in cliSessionStore (e.g., after page refresh if backend restarted)\n const isSessionNotFound = sessionId && !sessions[sessionId];\n\n // Clear invalid sessionId after showing the message\n useEffect(() => {\n if (isSessionNotFound) {\n const timer = setTimeout(() => {\n assignSession(paneId, null);\n }, 3000); // Clear after 3 seconds to let user see the message\n return () => clearTimeout(timer);\n }\n }, [isSessionNotFound, paneId, assignSession]);\n\n // Build session options for dropdown\n // Use sessions from cliSessionStore directly (all sessions, not just grouped ones)\n const sessionOptions = useMemo(() => {\n const allSessionIds = Object.keys(sessions);\n return allSessionIds.map((sid) => {\n const s = sessions[sid];\n const name = s ? (s.tool ? `${s.tool} - ${s.shellKind}` : s.shellKind) : sid;\n return { id: sid, name };\n });\n }, [sessions]);\n\n // Handlers\n const handleFocus = useCallback(() => {\n setFocused(paneId);\n }, [paneId, setFocused]);\n\n const handleSplitH = useCallback(() => {\n splitPane(paneId, 'horizontal');\n }, [paneId, splitPane]);\n\n const handleSplitV = useCallback(() => {\n splitPane(paneId, 'vertical');\n }, [paneId, splitPane]);\n\n const handleClose = useCallback(() => {\n // If pane has an active session, show confirmation dialog\n if (sessionId) {\n setIsCloseConfirmOpen(true);\n } else {\n closePane(paneId);\n }\n }, [paneId, sessionId, closePane]);\n\n const handleCloseConfirm = useCallback(() => {\n closePane(paneId);\n setIsCloseConfirmOpen(false);\n }, [paneId, closePane]);\n\n const handleSessionChange = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n const value = e.target.value;\n const session = value ? sessions[value] : null;\n assignSession(paneId, value || null, session?.cliTool ?? session?.tool ?? null);\n },\n [paneId, assignSession, sessions]\n );\n\n const handleClear = useCallback(() => {\n // Clear is handled by re-assigning the same session (triggers reset in TerminalInstance)\n if (sessionId) {\n assignSession(paneId, null);\n // Use microtask to re-assign after clearing\n queueMicrotask(() => assignSession(paneId, sessionId));\n }\n }, [paneId, sessionId, assignSession]);\n\n const handleRestart = useCallback(async () => {\n if (!sessionId || isRestarting) return;\n setIsRestarting(true);\n try {\n await restartSession(sessionId);\n } catch (error) {\n console.error('[TerminalPane] Restart failed:', error);\n } finally {\n setIsRestarting(false);\n }\n }, [sessionId, isRestarting, restartSession]);\n\n const handleTogglePause = useCallback(async () => {\n if (!sessionId || isTogglingPause) return;\n setIsTogglingPause(true);\n try {\n if (status === 'paused') {\n await resumeSession(sessionId);\n } else if (status === 'active' || status === 'idle') {\n await pauseSession(sessionId);\n }\n } catch (error) {\n console.error('[TerminalPane] Toggle pause failed:', error);\n } finally {\n setIsTogglingPause(false);\n }\n }, [sessionId, isTogglingPause, status, pauseSession, resumeSession]);\n\n const handleCloseSession = useCallback(async () => {\n if (!sessionId || isClosingSession) return;\n setIsClosingSession(true);\n try {\n await closeSession(sessionId);\n // Clear the pane's session after closing\n assignSession(paneId, null);\n } catch (error) {\n console.error('[TerminalPane] Close session failed:', error);\n } finally {\n setIsClosingSession(false);\n }\n }, [sessionId, isClosingSession, closeSession, paneId, assignSession]);\n\n // Handle back to terminal from file preview\n const handleBackToTerminal = useCallback(() => {\n setPaneDisplayMode(paneId, 'terminal');\n }, [paneId, setPaneDisplayMode]);\n\n return (\n <div\n className={cn(\n 'flex flex-col h-full border border-border/50 rounded-sm overflow-hidden',\n isFocused && 'ring-1 ring-primary/40'\n )}\n onClick={handleFocus}\n >\n {/* PaneToolbar */}\n <div className=\"flex items-center justify-between gap-1 px-2 py-1 border-b border-border bg-muted/30 shrink-0 overflow-hidden\">\n {/* Left: Session selector + status (or file path in file mode) */}\n <div className=\"flex items-center gap-1.5 min-w-0 overflow-hidden\">\n {isFileMode ? (\n // File mode header\n <>\n <button\n onClick={handleBackToTerminal}\n className=\"p-0.5 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-foreground shrink-0\"\n title={formatMessage({ id: 'terminalDashboard.pane.backToTerminal', defaultMessage: 'Back to terminal' })}\n >\n <ArrowLeft className=\"w-3.5 h-3.5\" />\n </button>\n <FileText className=\"w-3.5 h-3.5 text-muted-foreground shrink-0\" />\n <span className=\"text-xs truncate\" title={filePath ?? undefined}>\n {filePath?.split('/').pop() ?? 'File'}\n </span>\n </>\n ) : (\n // Terminal mode header\n <>\n {isSessionNotFound ? (\n <WifiOff className=\"w-3.5 h-3.5 text-yellow-500 shrink-0\" />\n ) : sessionId && (\n <span\n className={cn('w-2 h-2 rounded-full shrink-0', statusDotStyles[status])}\n />\n )}\n <div className=\"relative min-w-0 overflow-hidden\">\n <select\n value={sessionId ?? ''}\n onChange={handleSessionChange}\n className={cn(\n 'text-xs bg-transparent border-none outline-none cursor-pointer',\n 'appearance-none pr-4 max-w-[140px] truncate',\n !sessionId && 'text-muted-foreground'\n )}\n >\n <option value=\"\">\n {formatMessage({ id: 'terminalDashboard.pane.selectSession' })}\n </option>\n {sessionOptions.map((opt) => (\n <option key={opt.id} value={opt.id}>\n {opt.name}\n </option>\n ))}\n </select>\n <ChevronDown className=\"absolute right-0 top-1/2 -translate-y-1/2 w-3 h-3 text-muted-foreground pointer-events-none\" />\n </div>\n </>\n )}\n </div>\n\n {/* Center: Linked issue badge */}\n {linkedIssueId && !isFileMode && (\n <span className=\"text-[10px] font-mono px-1.5 py-0.5 rounded bg-primary/10 text-primary shrink-0 hidden sm:inline-flex\">\n {linkedIssueId}\n </span>\n )}\n\n {/* Right: Action buttons */}\n <div className=\"flex items-center gap-0.5 shrink-0\">\n <button\n onClick={handleSplitH}\n className=\"p-1 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-foreground\"\n title={formatMessage({ id: 'terminalDashboard.pane.splitHorizontal' })}\n >\n <SplitSquareHorizontal className=\"w-3.5 h-3.5\" />\n </button>\n <button\n onClick={handleSplitV}\n className=\"p-1 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-foreground\"\n title={formatMessage({ id: 'terminalDashboard.pane.splitVertical' })}\n >\n <SplitSquareVertical className=\"w-3.5 h-3.5\" />\n </button>\n {!isFileMode && sessionId && !isSessionNotFound && (\n <>\n {/* Restart button */}\n <button\n onClick={handleRestart}\n disabled={isRestarting}\n className={cn(\n 'p-1 rounded hover:bg-muted transition-colors',\n isRestarting ? 'text-muted-foreground/50' : 'text-muted-foreground hover:text-foreground'\n )}\n title={formatMessage({ id: 'terminalDashboard.pane.restart' })}\n >\n {isRestarting ? (\n <Loader2 className=\"w-3.5 h-3.5 animate-spin\" />\n ) : (\n <RotateCcw className=\"w-3.5 h-3.5\" />\n )}\n </button>\n {/* Pause/Resume toggle button */}\n <button\n onClick={handleTogglePause}\n disabled={isTogglingPause || status === 'resuming'}\n className={cn(\n 'p-1 rounded hover:bg-muted transition-colors',\n isTogglingPause || status === 'resuming'\n ? 'text-muted-foreground/50'\n : status === 'paused'\n ? 'text-yellow-500 hover:text-yellow-600'\n : 'text-muted-foreground hover:text-foreground'\n )}\n title={formatMessage({\n id: status === 'paused'\n ? 'terminalDashboard.pane.resume'\n : 'terminalDashboard.pane.pause',\n })}\n >\n {isTogglingPause || status === 'resuming' ? (\n <Loader2 className=\"w-3.5 h-3.5 animate-spin\" />\n ) : status === 'paused' ? (\n <Play className=\"w-3.5 h-3.5\" />\n ) : (\n <Pause className=\"w-3.5 h-3.5\" />\n )}\n </button>\n {/* Clear terminal button */}\n <button\n onClick={handleClear}\n className=\"p-1 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-foreground\"\n title={formatMessage({ id: 'terminalDashboard.pane.clearTerminal' })}\n >\n <Eraser className=\"w-3.5 h-3.5\" />\n </button>\n {/* Close session button */}\n <button\n onClick={handleCloseSession}\n disabled={isClosingSession}\n className={cn(\n 'p-1 rounded hover:bg-muted transition-colors',\n isClosingSession\n ? 'text-muted-foreground/50'\n : 'text-muted-foreground hover:text-destructive'\n )}\n title={formatMessage({ id: 'terminalDashboard.pane.closeSession' })}\n >\n {isClosingSession ? (\n <Loader2 className=\"w-3.5 h-3.5 animate-spin\" />\n ) : (\n <LogOut className=\"w-3.5 h-3.5\" />\n )}\n </button>\n </>\n )}\n {alertCount > 0 && !isFileMode && (\n <span className=\"flex items-center gap-0.5 px-1 text-destructive\">\n <AlertTriangle className=\"w-3 h-3\" />\n <span className=\"text-[10px] font-semibold tabular-nums\">\n {alertCount > 99 ? '99+' : alertCount}\n </span>\n </span>\n )}\n {canClose && (\n <button\n onClick={handleClose}\n className=\"p-1 rounded hover:bg-destructive/10 transition-colors text-muted-foreground hover:text-destructive\"\n title={formatMessage({ id: 'terminalDashboard.pane.closePane' })}\n >\n <X className=\"w-3.5 h-3.5\" />\n </button>\n )}\n </div>\n </div>\n\n {/* Content area */}\n {isFileMode ? (\n // File preview mode\n <div className=\"flex-1 min-h-0\">\n <FilePreview\n fileContent={fileContent}\n isLoading={isFileLoading}\n error={fileError?.message ?? null}\n className=\"h-full\"\n />\n </div>\n ) : isSessionNotFound ? (\n // Session not found state - pane references a sessionId that no longer exists\n <div className=\"flex-1 flex items-center justify-center text-muted-foreground\">\n <div className=\"text-center px-4\">\n <WifiOff className=\"h-6 w-6 mx-auto mb-1.5 text-yellow-500\" />\n <p className=\"text-sm font-medium text-foreground\">\n {formatMessage({ id: 'terminalDashboard.pane.sessionNotFound' })}\n </p>\n <p className=\"text-xs mt-1 opacity-70 max-w-[200px]\">\n {formatMessage({ id: 'terminalDashboard.pane.sessionNotFoundHint' })}\n </p>\n </div>\n </div>\n ) : sessionId ? (\n // Terminal mode with session\n <div className=\"flex-1 min-h-0\">\n <TerminalInstance sessionId={sessionId} />\n </div>\n ) : (\n // Empty terminal state\n <div className=\"flex-1 flex items-center justify-center text-muted-foreground\">\n <div className=\"text-center\">\n <Terminal className=\"h-6 w-6 mx-auto mb-1.5 opacity-30\" />\n <p className=\"text-sm\">\n {formatMessage({ id: 'terminalDashboard.pane.selectSession' })}\n </p>\n <p className=\"text-xs mt-1 opacity-70\">\n {formatMessage({ id: 'terminalDashboard.pane.selectSessionHint' })}\n </p>\n </div>\n </div>\n )}\n\n {/* Close Pane Confirmation Dialog */}\n <AlertDialog open={isCloseConfirmOpen} onOpenChange={setIsCloseConfirmOpen}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n {formatMessage({ id: 'terminalDashboard.pane.closeConfirmTitle' })}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {formatMessage({ id: 'terminalDashboard.pane.closeConfirmMessage' })}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>\n {formatMessage({ id: 'common.actions.cancel' })}\n </AlertDialogCancel>\n <AlertDialogAction onClick={handleCloseConfirm}>\n {formatMessage({ id: 'terminalDashboard.pane.closeConfirmAction' })}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n","// ========================================\r\n// TerminalGrid Component\r\n// ========================================\r\n// Recursive Allotment renderer for the terminal split pane layout.\r\n// Mirrors the LayoutContainer pattern from cli-viewer but renders\r\n// TerminalPane components as leaf nodes.\r\n\r\nimport { useCallback, useMemo } from 'react';\r\nimport { Allotment } from 'allotment';\r\nimport 'allotment/dist/style.css';\r\nimport { cn } from '@/lib/utils';\r\nimport { isPaneId } from '@/lib/layout-utils';\r\nimport {\r\n useTerminalGridStore,\r\n selectTerminalGridLayout,\r\n selectTerminalGridPanes,\r\n} from '@/stores/terminalGridStore';\r\nimport type { AllotmentLayoutGroup } from '@/stores/viewerStore';\r\nimport { TerminalPane } from './TerminalPane';\r\n\r\n// ========== Types ==========\r\n\r\ninterface GridGroupRendererProps {\r\n group: AllotmentLayoutGroup;\r\n minSize: number;\r\n depth?: number;\r\n}\r\n\r\n// ========== Recursive Group Renderer ==========\r\n\r\nfunction GridGroupRenderer({ group, minSize, depth = 0 }: GridGroupRendererProps) {\r\n const panes = useTerminalGridStore(selectTerminalGridPanes);\r\n const updateLayoutSizes = useTerminalGridStore((s) => s.updateLayoutSizes);\r\n\r\n const handleChange = useCallback(\r\n (sizes: number[]) => {\r\n updateLayoutSizes(sizes);\r\n },\r\n [updateLayoutSizes]\r\n );\r\n\r\n const validChildren = useMemo(() => {\r\n return group.children.filter((child) => {\r\n if (isPaneId(child)) {\r\n return panes[child] !== undefined;\r\n }\r\n return true;\r\n });\r\n }, [group.children, panes]);\r\n\r\n if (validChildren.length === 0) {\r\n return null;\r\n }\r\n\r\n // Generate stable key based on children\r\n const groupKey = useMemo(() => {\r\n return validChildren.map(c => isPaneId(c) ? c : 'group').join('-');\r\n }, [validChildren]);\r\n\r\n return (\r\n <Allotment\r\n key={groupKey}\r\n vertical={group.direction === 'vertical'}\r\n defaultSizes={group.sizes}\r\n onChange={handleChange}\r\n >\r\n {validChildren.map((child, index) => (\r\n <Allotment.Pane key={isPaneId(child) ? child : `group-${depth}-${index}`} minSize={minSize}>\r\n {isPaneId(child) ? (\r\n <TerminalPane paneId={child} />\r\n ) : (\r\n <GridGroupRenderer\r\n group={child}\r\n minSize={minSize}\r\n depth={depth + 1}\r\n />\r\n )}\r\n </Allotment.Pane>\r\n ))}\r\n </Allotment>\r\n );\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\nexport function TerminalGrid({ className }: { className?: string }) {\r\n const layout = useTerminalGridStore(selectTerminalGridLayout);\r\n const panes = useTerminalGridStore(selectTerminalGridPanes);\r\n\r\n const content = useMemo(() => {\r\n if (!layout.children || layout.children.length === 0) {\r\n return null;\r\n }\r\n\r\n // Single pane: render directly without Allotment wrapper\r\n if (layout.children.length === 1 && isPaneId(layout.children[0])) {\r\n const paneId = layout.children[0];\r\n if (!panes[paneId]) return null;\r\n return <TerminalPane paneId={paneId} />;\r\n }\r\n\r\n return (\r\n <GridGroupRenderer\r\n group={layout}\r\n minSize={150}\r\n depth={0}\r\n />\r\n );\r\n }, [layout, panes]);\r\n\r\n return (\r\n <div className={cn('h-full w-full overflow-hidden bg-background', className)}>\r\n {content}\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// SessionGroupTree Component\r\n// ========================================\r\n// Tree view for CLI sessions grouped by tag.\r\n// Sessions are automatically grouped by their tag (e.g., \"gemini-143052\").\r\n\r\nimport { useState, useCallback, useEffect, useMemo } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n ChevronRight,\r\n Terminal,\r\n Tag,\r\n} from 'lucide-react';\r\nimport { cn } from '@/lib/utils';\r\nimport { useSessionManagerStore, selectSessionManagerActiveTerminalId, selectTerminalMetas } from '@/stores';\r\nimport { useCliSessionStore } from '@/stores/cliSessionStore';\r\nimport { useTerminalGridStore, selectTerminalGridPanes } from '@/stores/terminalGridStore';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport type { TerminalStatus } from '@/types/terminal-dashboard';\r\n\r\n// ========== Status Dot Styles ==========\r\n\r\nconst statusDotStyles: Record<TerminalStatus, string> = {\r\n active: 'bg-green-500',\r\n idle: 'bg-gray-400',\r\n error: 'bg-red-500',\r\n paused: 'bg-yellow-500',\r\n resuming: 'bg-blue-400 animate-pulse',\r\n locked: 'bg-purple-500',\r\n};\r\n\r\n// ========== SessionGroupTree Component ==========\r\n\r\nexport function SessionGroupTree() {\r\n const { formatMessage } = useIntl();\r\n const activeTerminalId = useSessionManagerStore(selectSessionManagerActiveTerminalId);\r\n const terminalMetas = useSessionManagerStore(selectTerminalMetas);\r\n const setActiveTerminal = useSessionManagerStore((s) => s.setActiveTerminal);\r\n const sessions = useCliSessionStore((s) => s.sessions);\r\n\r\n // Grid store for pane management\r\n const panes = useTerminalGridStore(selectTerminalGridPanes);\r\n const assignSession = useTerminalGridStore((s) => s.assignSession);\r\n const setFocused = useTerminalGridStore((s) => s.setFocused);\r\n\r\n const [expandedTags, setExpandedTags] = useState<Set<string>>(new Set());\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n useEffect(() => {\r\n setExpandedTags(new Set());\r\n }, [projectPath]);\r\n\r\n const toggleTag = useCallback((tag: string) => {\r\n setExpandedTags((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(tag)) {\r\n next.delete(tag);\r\n } else {\r\n next.add(tag);\r\n }\r\n return next;\r\n });\r\n }, []);\r\n\r\n const handleSessionClick = useCallback(\r\n (sessionId: string) => {\r\n // Set active terminal in session manager\r\n setActiveTerminal(sessionId);\r\n\r\n // Find pane that already has this session, or switch focused pane\r\n const paneWithSession = Object.entries(panes).find(\r\n ([, pane]) => pane.sessionId === sessionId\r\n );\r\n\r\n if (paneWithSession) {\r\n // Focus the pane that has this session\r\n setFocused(paneWithSession[0]);\r\n } else {\r\n // Find focused pane or first pane, and assign session to it\r\n const focusedPaneId = useTerminalGridStore.getState().focusedPaneId;\r\n const targetPaneId = focusedPaneId || Object.keys(panes)[0];\r\n if (targetPaneId) {\r\n const session = sessions[sessionId];\r\n assignSession(targetPaneId, sessionId, session?.cliTool ?? session?.tool ?? null);\r\n setFocused(targetPaneId);\r\n }\r\n }\r\n },\r\n [setActiveTerminal, panes, setFocused, assignSession]\r\n );\r\n\r\n // Group sessions by tag\r\n const sessionsByTag = useMemo(() => {\r\n const groups: Record<string, { tag: string; sessionIds: string[] }> = {};\r\n const untagged: string[] = [];\r\n\r\n for (const sessionKey of Object.keys(sessions)) {\r\n const meta = terminalMetas[sessionKey];\r\n const tag = meta?.tag;\r\n if (tag) {\r\n if (!groups[tag]) {\r\n groups[tag] = { tag, sessionIds: [] };\r\n }\r\n groups[tag].sessionIds.push(sessionKey);\r\n } else {\r\n untagged.push(sessionKey);\r\n }\r\n }\r\n\r\n // Convert to array and sort by tag name (newest first by time suffix)\r\n const result = Object.values(groups).sort((a, b) => b.tag.localeCompare(a.tag));\r\n\r\n // Add untagged sessions at the end\r\n if (untagged.length > 0) {\r\n result.push({ tag: '__untagged__', sessionIds: untagged });\r\n }\r\n\r\n return result;\r\n }, [sessions, terminalMetas]);\r\n\r\n // Build a lookup for session display names\r\n const sessionNames = useMemo(() => {\r\n const map: Record<string, string> = {};\r\n for (const [key, meta] of Object.entries(sessions)) {\r\n map[key] = meta.tool ?? meta.shellKind;\r\n }\r\n return map;\r\n }, [sessions]);\r\n\r\n if (Object.keys(sessions).length === 0) {\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n <div className=\"flex-1 flex flex-col items-center justify-center gap-1.5 text-muted-foreground p-4\">\r\n <Terminal className=\"w-6 h-6 opacity-30\" />\r\n <p className=\"text-xs text-center\">\r\n {formatMessage({ id: 'terminalDashboard.sessionTree.noGroups' })}\r\n </p>\r\n <p className=\"text-[10px] text-muted-foreground/70\">\r\n Click \"New Session\" to create one\r\n </p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n {/* Session list grouped by tag */}\r\n <div className=\"flex-1 overflow-y-auto\">\r\n {sessionsByTag.map((group) => {\r\n const isExpanded = expandedTags.has(group.tag);\r\n const isUntagged = group.tag === '__untagged__';\r\n const displayName = isUntagged ? 'Other Sessions' : group.tag;\r\n\r\n return (\r\n <div key={group.tag} className=\"border-b border-border/50 last:border-b-0\">\r\n {/* Tag header */}\r\n <button\r\n onClick={() => toggleTag(group.tag)}\r\n className={cn(\r\n 'flex items-center gap-1.5 w-full px-3 py-2 text-left',\r\n 'hover:bg-muted/50 transition-colors text-sm'\r\n )}\r\n >\r\n <ChevronRight\r\n className={cn(\r\n 'w-3.5 h-3.5 text-muted-foreground transition-transform shrink-0',\r\n isExpanded && 'rotate-90'\r\n )}\r\n />\r\n <Tag className=\"w-3.5 h-3.5 text-muted-foreground shrink-0\" />\r\n <span className=\"flex-1 truncate font-medium text-xs\">{displayName}</span>\r\n <Badge variant=\"secondary\" className=\"text-[10px] px-1.5 py-0\">\r\n {group.sessionIds.length}\r\n </Badge>\r\n </button>\r\n\r\n {/* Expanded: session list */}\r\n {isExpanded && (\r\n <div className=\"pb-1\">\r\n {group.sessionIds.map((sessionId) => {\r\n const meta = terminalMetas[sessionId];\r\n const sessionStatus: TerminalStatus = meta?.status ?? 'idle';\r\n return (\r\n <div\r\n key={sessionId}\r\n className={cn(\r\n 'flex items-center gap-1.5 mx-1 px-2 py-1.5 rounded-sm cursor-pointer',\r\n 'hover:bg-muted/50 transition-colors text-sm',\r\n activeTerminalId === sessionId && 'bg-primary/10 text-primary'\r\n )}\r\n onClick={() => handleSessionClick(sessionId)}\r\n >\r\n {/* Status indicator dot */}\r\n <span\r\n className={cn('w-2 h-2 rounded-full shrink-0', statusDotStyles[sessionStatus])}\r\n title={sessionStatus}\r\n />\r\n <Terminal className=\"w-3.5 h-3.5 text-muted-foreground shrink-0\" />\r\n <span className=\"flex-1 truncate text-xs\">\r\n {sessionNames[sessionId] ?? sessionId}\r\n </span>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport default SessionGroupTree;\r\n","// ========================================\n// IssuePanel Component\n// ========================================\n// Issue list panel for the terminal dashboard middle column.\n// Consumes existing useIssues() React Query hook for data fetching.\n// Integrates with issueQueueIntegrationStore for selection state\n// and association chain highlighting.\n\nimport { useState, useMemo, useCallback, useEffect, useRef } from 'react';\nimport { useIntl } from 'react-intl';\nimport {\n AlertCircle,\n Loader2,\n AlertTriangle,\n CircleDot,\n Terminal,\n Check,\n Send,\n X,\n ListPlus,\n} from 'lucide-react';\nimport { Badge } from '@/components/ui/Badge';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/Select';\nimport { cn } from '@/lib/utils';\nimport { useIssues } from '@/hooks/useIssues';\nimport {\n useIssueQueueIntegrationStore,\n selectSelectedIssueId,\n selectAssociationChain,\n} from '@/stores/issueQueueIntegrationStore';\nimport { executeInCliSession } from '@/lib/api';\nimport type { Issue } from '@/lib/api';\nimport { useTerminalGridStore, selectTerminalGridFocusedPaneId, selectTerminalGridPanes } from '@/stores/terminalGridStore';\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\nimport { useQueueSchedulerStore } from '@/stores/queueSchedulerStore';\nimport { toast } from '@/stores/notificationStore';\n\n// ========== Execution Method Type ==========\n\ntype ExecutionMethod = 'skill-team-issue' | 'ccw-cli' | 'direct-send';\n\n// ========== Prompt Templates ==========\n\nconst PROMPT_TEMPLATES: Record<ExecutionMethod, (idStr: string) => string> = {\n 'skill-team-issue': (idStr) => `完成 ${idStr} issue`,\n 'ccw-cli': (idStr) => `完成.issue.jsonl中 ${idStr} issue`,\n 'direct-send': (idStr) => `根据@.workflow/issues/issues.jsonl中的 ${idStr} 需求,进行开发`,\n};\n\n// ========== Queue Prompt Builder ==========\n\nfunction buildQueuePrompt(issues: Issue[]): string {\n const ids = issues.map((i) => i.id).join(' ');\n return `根据@.workflow/issues/issues.jsonl中的 ${ids} 需求,进行开发`;\n}\n\n// ========== Priority Badge ==========\n\nconst PRIORITY_STYLES: Record<Issue['priority'], { variant: 'destructive' | 'warning' | 'info' | 'secondary'; label: string }> = {\n critical: { variant: 'destructive', label: 'Critical' },\n high: { variant: 'warning', label: 'High' },\n medium: { variant: 'info', label: 'Medium' },\n low: { variant: 'secondary', label: 'Low' },\n};\n\nfunction PriorityBadge({ priority }: { priority: Issue['priority'] }) {\n const style = PRIORITY_STYLES[priority] ?? PRIORITY_STYLES.medium;\n return (\n <Badge variant={style.variant} className=\"text-[10px] px-1.5 py-0 shrink-0\">\n {style.label}\n </Badge>\n );\n}\n\n// ========== Status Indicator ==========\n\nfunction StatusDot({ status }: { status: Issue['status'] }) {\n const colorMap: Record<Issue['status'], string> = {\n registered: 'text-info',\n planning: 'text-blue-500',\n planned: 'text-blue-600',\n queued: 'text-yellow-500',\n executing: 'text-warning',\n completed: 'text-success',\n failed: 'text-destructive',\n paused: 'text-muted-foreground',\n };\n return <CircleDot className={cn('w-3 h-3 shrink-0', colorMap[status] ?? 'text-muted-foreground')} />;\n}\n\n// ========== Issue Item ==========\n\nfunction IssueItem({\n issue,\n isSelected,\n isHighlighted,\n isChecked,\n onSelect,\n onToggleCheck,\n}: {\n issue: Issue;\n isSelected: boolean;\n isHighlighted: boolean;\n isChecked: boolean;\n onSelect: () => void;\n onToggleCheck: () => void;\n}) {\n return (\n <div\n role=\"button\"\n tabIndex={0}\n className={cn(\n 'w-full text-left px-2.5 py-1.5 rounded-md transition-colors',\n 'hover:bg-muted/60 focus:outline-none focus:ring-1 focus:ring-primary/30',\n isSelected && 'bg-primary/10 ring-1 ring-primary/30',\n isHighlighted && !isSelected && 'bg-accent/50'\n )}\n onClick={onSelect}\n onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onSelect(); } }}\n >\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <input\n type=\"checkbox\"\n checked={isChecked}\n onChange={(e) => { e.stopPropagation(); onToggleCheck(); }}\n onClick={(e) => e.stopPropagation()}\n className=\"w-3.5 h-3.5 rounded border-border accent-primary shrink-0\"\n />\n <StatusDot status={issue.status} />\n <span className=\"text-sm font-medium text-foreground truncate\">\n {issue.title}\n </span>\n </div>\n <div className=\"flex items-center gap-1.5 shrink-0\">\n <PriorityBadge priority={issue.priority} />\n </div>\n </div>\n {issue.context && (\n <p className=\"mt-0.5 text-xs text-muted-foreground truncate pl-7\">\n {issue.context}\n </p>\n )}\n <div className=\"mt-0.5 flex items-center gap-2 text-[10px] text-muted-foreground pl-7\">\n <span className=\"font-mono\">{issue.id}</span>\n {issue.labels && issue.labels.length > 0 && (\n <>\n <span className=\"text-border\">|</span>\n <span className=\"truncate\">{issue.labels.slice(0, 2).join(', ')}</span>\n </>\n )}\n </div>\n </div>\n );\n}\n\n// ========== Empty State ==========\n\nfunction IssueEmptyState() {\n const { formatMessage } = useIntl();\n return (\n <div className=\"flex-1 flex items-center justify-center text-muted-foreground p-4\">\n <div className=\"text-center\">\n <AlertCircle className=\"h-6 w-6 mx-auto mb-1.5 opacity-30\" />\n <p className=\"text-sm\">{formatMessage({ id: 'terminalDashboard.issuePanel.noIssues' })}</p>\n <p className=\"text-xs mt-1 opacity-70\">\n {formatMessage({ id: 'terminalDashboard.issuePanel.noIssuesDesc' })}\n </p>\n </div>\n </div>\n );\n}\n\n// ========== Error State ==========\n\nfunction IssueErrorState({ error }: { error: Error }) {\n const { formatMessage } = useIntl();\n return (\n <div className=\"flex-1 flex items-center justify-center text-destructive p-4\">\n <div className=\"text-center\">\n <AlertTriangle className=\"h-6 w-6 mx-auto mb-1.5 opacity-30\" />\n <p className=\"text-sm\">{formatMessage({ id: 'terminalDashboard.issuePanel.error' })}</p>\n <p className=\"text-xs mt-1 opacity-70\">{error.message}</p>\n </div>\n </div>\n );\n}\n\n// ========== Main Component ==========\n\nexport function IssuePanel() {\n const { formatMessage } = useIntl();\n const { issues, isLoading, error, openCount } = useIssues();\n\n const selectedIssueId = useIssueQueueIntegrationStore(selectSelectedIssueId);\n const associationChain = useIssueQueueIntegrationStore(selectAssociationChain);\n const setSelectedIssue = useIssueQueueIntegrationStore((s) => s.setSelectedIssue);\n const buildAssociationChain = useIssueQueueIntegrationStore((s) => s.buildAssociationChain);\n\n // Multi-select state\n const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());\n const [isSending, setIsSending] = useState(false);\n const [justSent, setJustSent] = useState(false);\n const [executionMethod, setExecutionMethod] = useState<ExecutionMethod>('skill-team-issue');\n const [isSendConfigOpen, setIsSendConfigOpen] = useState(false);\n const [customPrompt, setCustomPrompt] = useState('');\n const sentTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Queue state\n const [isAddingToQueue, setIsAddingToQueue] = useState(false);\n const [justQueued, setJustQueued] = useState(false);\n const [queueMode, setQueueMode] = useState<'write' | 'analysis' | 'auto'>('write');\n const queuedTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const submitItems = useQueueSchedulerStore((s) => s.submitItems);\n\n // Terminal refs\n const focusedPaneId = useTerminalGridStore(selectTerminalGridFocusedPaneId);\n const panes = useTerminalGridStore(selectTerminalGridPanes);\n const projectPath = useWorkflowStore(selectProjectPath);\n const focusedPane = focusedPaneId ? panes[focusedPaneId] : null;\n const sessionKey = focusedPane?.sessionId ?? null;\n const sessionCliTool = focusedPane?.cliTool ?? null;\n\n // Compute available methods based on the focused session's CLI tool\n const availableMethods = useMemo(() => {\n // Only offer skill methods when the session is claude (supports / slash commands)\n if (sessionCliTool === 'claude') {\n return [\n { value: 'skill-team-issue' as const, label: 'team-issue' },\n { value: 'ccw-cli' as const, label: 'ccw' },\n { value: 'direct-send' as const, label: 'Direct send' },\n ];\n }\n // For unknown/null cliTool or non-claude tools, only offer direct send\n return [\n { value: 'direct-send' as const, label: 'Direct send' },\n ];\n }, [sessionCliTool]);\n\n // Auto-switch method when the current selection is unavailable for this tool\n useEffect(() => {\n if (!availableMethods.find(m => m.value === executionMethod)) {\n setExecutionMethod(availableMethods[0].value);\n }\n }, [availableMethods, executionMethod]);\n\n // Cleanup feedback timers on unmount\n useEffect(() => {\n return () => {\n if (sentTimerRef.current) clearTimeout(sentTimerRef.current);\n if (queuedTimerRef.current) clearTimeout(queuedTimerRef.current);\n };\n }, []);\n\n useEffect(() => {\n if (sentTimerRef.current) clearTimeout(sentTimerRef.current);\n if (queuedTimerRef.current) clearTimeout(queuedTimerRef.current);\n setSelectedIds(new Set());\n setIsSending(false);\n setJustSent(false);\n setExecutionMethod('skill-team-issue');\n setIsSendConfigOpen(false);\n setCustomPrompt('');\n setIsAddingToQueue(false);\n setJustQueued(false);\n setQueueMode('write');\n }, [projectPath]);\n\n // Sort: open/in_progress first, then by priority (critical > high > medium > low)\n const sortedIssues = useMemo(() => {\n const priorityOrder: Record<string, number> = {\n critical: 0,\n high: 1,\n medium: 2,\n low: 3,\n };\n const statusOrder: Record<string, number> = {\n in_progress: 0,\n open: 1,\n resolved: 2,\n completed: 3,\n closed: 4,\n };\n return [...issues].sort((a, b) => {\n const sa = statusOrder[a.status] ?? 5;\n const sb = statusOrder[b.status] ?? 5;\n if (sa !== sb) return sa - sb;\n const pa = priorityOrder[a.priority] ?? 3;\n const pb = priorityOrder[b.priority] ?? 3;\n return pa - pb;\n });\n }, [issues]);\n\n const handleSelect = useCallback(\n (issueId: string) => {\n if (selectedIssueId === issueId) {\n setSelectedIssue(null);\n } else {\n buildAssociationChain(issueId, 'issue');\n }\n },\n [selectedIssueId, setSelectedIssue, buildAssociationChain]\n );\n\n const handleToggleSelect = useCallback((issueId: string) => {\n setSelectedIds(prev => {\n const next = new Set(prev);\n if (next.has(issueId)) next.delete(issueId);\n else next.add(issueId);\n return next;\n });\n }, []);\n\n const handleSelectAll = useCallback(() => {\n setSelectedIds(new Set(sortedIssues.map(i => i.id)));\n }, [sortedIssues]);\n\n const handleDeselectAll = useCallback(() => {\n setSelectedIds(new Set());\n }, []);\n\n const handleOpenSendConfig = useCallback(() => {\n const idStr = Array.from(selectedIds).join(' ');\n setCustomPrompt(PROMPT_TEMPLATES[executionMethod](idStr));\n setIsSendConfigOpen(true);\n }, [selectedIds, executionMethod]);\n\n const handleSendToTerminal = useCallback(async () => {\n if (!sessionKey || selectedIds.size === 0) return;\n const effectiveTool = sessionCliTool || 'claude';\n setIsSending(true);\n try {\n const prompt = customPrompt.trim();\n\n let executeInput: Parameters<typeof executeInCliSession>[1];\n\n switch (executionMethod) {\n case 'skill-team-issue':\n executeInput = {\n tool: effectiveTool,\n prompt,\n instructionType: 'skill',\n skillName: 'team-issue',\n };\n break;\n case 'ccw-cli':\n executeInput = {\n tool: effectiveTool,\n prompt,\n instructionType: 'skill',\n skillName: 'ccw',\n };\n break;\n case 'direct-send':\n executeInput = {\n tool: effectiveTool,\n prompt,\n instructionType: 'prompt',\n };\n break;\n }\n\n await executeInCliSession(sessionKey, executeInput, projectPath || undefined);\n\n toast.success('Sent to terminal', prompt.length > 60 ? prompt.slice(0, 60) + '...' : prompt);\n setJustSent(true);\n setIsSendConfigOpen(false);\n if (sentTimerRef.current) clearTimeout(sentTimerRef.current);\n sentTimerRef.current = setTimeout(() => setJustSent(false), 2000);\n } catch (err) {\n toast.error('Failed to send', err instanceof Error ? err.message : String(err));\n } finally {\n setIsSending(false);\n }\n }, [sessionKey, selectedIds, projectPath, executionMethod, sessionCliTool, customPrompt]);\n\n const handleAddToQueue = useCallback(async () => {\n if (selectedIds.size === 0) return;\n setIsAddingToQueue(true);\n try {\n const selectedIssues = sortedIssues.filter((i) => selectedIds.has(i.id));\n const now = new Date().toISOString();\n const items = selectedIssues.map((issue, index) => ({\n item_id: `Q-${issue.id}-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,\n issue_id: issue.id,\n status: 'pending' as const,\n tool: sessionCliTool || 'gemini',\n prompt: buildQueuePrompt([issue]),\n mode: queueMode,\n depends_on: [] as string[],\n execution_order: index + 1,\n execution_group: 'default',\n createdAt: now,\n metadata: { issueTitle: issue.title, issuePriority: issue.priority },\n }));\n await submitItems(items);\n toast.success(\n formatMessage({ id: 'terminalDashboard.issuePanel.addedToQueue', defaultMessage: 'Added to queue' }),\n `${items.length} item(s)`\n );\n setJustQueued(true);\n if (queuedTimerRef.current) clearTimeout(queuedTimerRef.current);\n queuedTimerRef.current = setTimeout(() => setJustQueued(false), 2000);\n } catch (err) {\n toast.error(\n formatMessage({ id: 'terminalDashboard.issuePanel.addToQueueFailed', defaultMessage: 'Failed to add to queue' }),\n err instanceof Error ? err.message : String(err)\n );\n } finally {\n setIsAddingToQueue(false);\n }\n }, [selectedIds, sortedIssues, sessionCliTool, submitItems, formatMessage]);\n\n // Loading state\n if (isLoading) {\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"px-3 py-2 border-b border-border shrink-0\">\n <h3 className=\"text-sm font-semibold flex items-center gap-2\">\n <AlertCircle className=\"w-4 h-4\" />\n {formatMessage({ id: 'terminalDashboard.issuePanel.title' })}\n </h3>\n </div>\n <div className=\"flex-1 flex items-center justify-center\">\n <Loader2 className=\"w-5 h-5 animate-spin text-muted-foreground\" />\n </div>\n </div>\n );\n }\n\n // Error state\n if (error) {\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"px-3 py-2 border-b border-border shrink-0\">\n <h3 className=\"text-sm font-semibold flex items-center gap-2\">\n <AlertCircle className=\"w-4 h-4\" />\n {formatMessage({ id: 'terminalDashboard.issuePanel.title' })}\n </h3>\n </div>\n <IssueErrorState error={error} />\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col h-full\">\n {/* Header */}\n <div className=\"px-3 py-2 border-b border-border shrink-0 flex items-center justify-between\">\n <h3 className=\"text-sm font-semibold flex items-center gap-2\">\n <AlertCircle className=\"w-4 h-4\" />\n {formatMessage({ id: 'terminalDashboard.issuePanel.title' })}\n </h3>\n <div className=\"flex items-center gap-1.5\">\n {sortedIssues.length > 0 && (\n <button\n type=\"button\"\n className=\"text-[10px] text-muted-foreground hover:text-foreground px-1\"\n onClick={selectedIds.size === sortedIssues.length ? handleDeselectAll : handleSelectAll}\n >\n {selectedIds.size === sortedIssues.length ? 'Deselect all' : 'Select all'}\n </button>\n )}\n {openCount > 0 && (\n <Badge variant=\"secondary\" className=\"text-[10px] px-1.5 py-0\">\n {openCount}\n </Badge>\n )}\n </div>\n </div>\n\n {/* Issue List */}\n {sortedIssues.length === 0 ? (\n <IssueEmptyState />\n ) : (\n <div className=\"flex-1 min-h-0 overflow-y-auto p-1.5 space-y-0.5\">\n {sortedIssues.map((issue) => (\n <IssueItem\n key={issue.id}\n issue={issue}\n isSelected={selectedIssueId === issue.id}\n isHighlighted={associationChain?.issueId === issue.id}\n isChecked={selectedIds.has(issue.id)}\n onSelect={() => handleSelect(issue.id)}\n onToggleCheck={() => handleToggleSelect(issue.id)}\n />\n ))}\n </div>\n )}\n\n {/* Send to Terminal bar */}\n {selectedIds.size > 0 && (\n <div className=\"border-t border-border shrink-0\">\n {/* Send Config Panel (expandable) */}\n {isSendConfigOpen && (\n <div className=\"px-3 py-2 space-y-2 border-b border-border bg-muted/20\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs font-medium text-foreground\">Send Configuration</span>\n <button\n type=\"button\"\n className=\"p-0.5 rounded hover:bg-muted text-muted-foreground hover:text-foreground\"\n onClick={() => setIsSendConfigOpen(false)}\n >\n <X className=\"w-3.5 h-3.5\" />\n </button>\n </div>\n {/* Method selector */}\n {availableMethods.length > 1 && (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-[10px] text-muted-foreground shrink-0\">Method</span>\n <Select\n value={executionMethod}\n onValueChange={(v) => {\n const method = v as ExecutionMethod;\n setExecutionMethod(method);\n const idStr = Array.from(selectedIds).join(' ');\n setCustomPrompt(PROMPT_TEMPLATES[method](idStr));\n }}\n >\n <SelectTrigger className=\"h-6 w-full text-xs\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {availableMethods.map((m) => (\n <SelectItem key={m.value} value={m.value} className=\"text-xs\">\n {m.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n {/* Prompt preview label */}\n {executionMethod !== 'direct-send' && (\n <div className=\"text-[10px] text-muted-foreground\">\n Prefix: <span className=\"font-mono text-foreground\">/{executionMethod === 'skill-team-issue' ? 'team-issue' : 'ccw'}</span>\n </div>\n )}\n {/* Editable prompt */}\n <textarea\n className=\"w-full text-xs bg-background border border-border rounded-md px-2 py-1.5 resize-none focus:outline-none focus:ring-1 focus:ring-primary/40 text-foreground\"\n rows={3}\n value={customPrompt}\n onChange={(e) => setCustomPrompt(e.target.value)}\n placeholder=\"Enter prompt...\"\n />\n {/* Send button */}\n <button\n type=\"button\"\n className={cn(\n 'w-full flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium transition-colors',\n 'bg-primary text-primary-foreground hover:bg-primary/90',\n 'disabled:opacity-50 disabled:cursor-not-allowed'\n )}\n disabled={!sessionKey || isSending || !customPrompt.trim()}\n onClick={handleSendToTerminal}\n >\n {isSending ? <Loader2 className=\"w-3.5 h-3.5 animate-spin\" /> : <Send className=\"w-3.5 h-3.5\" />}\n Confirm Send\n </button>\n </div>\n )}\n {/* Bottom bar */}\n <div className=\"px-3 py-2 flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-muted-foreground\">\n {selectedIds.size} selected\n </span>\n <button\n type=\"button\"\n className=\"text-xs text-muted-foreground hover:text-foreground\"\n onClick={handleDeselectAll}\n >\n Clear\n </button>\n </div>\n <div className=\"flex items-center gap-1.5\">\n {/* Queue mode selector */}\n <select\n className=\"h-6 text-[10px] rounded border border-border bg-background px-1 text-muted-foreground\"\n value={queueMode}\n onChange={(e) => setQueueMode(e.target.value as 'write' | 'analysis' | 'auto')}\n title={formatMessage({ id: 'terminalDashboard.issuePanel.queueModeHint', defaultMessage: 'Execution mode for queued items' })}\n >\n <option value=\"write\">write</option>\n <option value=\"analysis\">analysis</option>\n <option value=\"auto\">auto</option>\n </select>\n {/* Add to Queue button */}\n <button\n type=\"button\"\n className={cn(\n 'flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-xs font-medium transition-colors',\n justQueued\n ? 'bg-green-600 text-white'\n : 'bg-muted text-foreground hover:bg-muted/80',\n 'disabled:opacity-50 disabled:cursor-not-allowed'\n )}\n disabled={isAddingToQueue}\n onClick={handleAddToQueue}\n title={formatMessage({ id: 'terminalDashboard.issuePanel.addToQueueHint', defaultMessage: 'Add selected issues to the execution queue' })}\n >\n {isAddingToQueue ? <Loader2 className=\"w-3.5 h-3.5 animate-spin\" /> : justQueued ? <Check className=\"w-3.5 h-3.5\" /> : <ListPlus className=\"w-3.5 h-3.5\" />}\n {justQueued\n ? formatMessage({ id: 'terminalDashboard.issuePanel.addedToQueue', defaultMessage: 'Queued!' })\n : formatMessage({ id: 'terminalDashboard.issuePanel.addToQueue', defaultMessage: 'Queue' })}\n </button>\n {/* Send to Terminal button */}\n <button\n type=\"button\"\n className={cn(\n 'flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-xs font-medium transition-colors',\n justSent\n ? 'bg-green-600 text-white'\n : 'bg-primary text-primary-foreground hover:bg-primary/90',\n 'disabled:opacity-50 disabled:cursor-not-allowed'\n )}\n disabled={!sessionKey || isSending}\n onClick={isSendConfigOpen ? handleSendToTerminal : handleOpenSendConfig}\n title={!sessionKey ? 'No terminal session focused' : `Send via ${executionMethod}`}\n >\n {isSending ? <Loader2 className=\"w-3.5 h-3.5 animate-spin\" /> : justSent ? <Check className=\"w-3.5 h-3.5\" /> : <Terminal className=\"w-3.5 h-3.5\" />}\n {justSent ? 'Sent!' : `Send (${selectedIds.size})`}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n","// ========================================\r\n// QueueListColumn Component\r\n// ========================================\r\n// Queue items list for embedding in the Issues dual-column panel.\r\n// Unified data source: queueSchedulerStore only.\r\n// Includes inline scheduler controls at the bottom.\r\n\r\nimport { useMemo, useCallback, useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n ListChecks,\r\n Loader2,\r\n CheckCircle,\r\n XCircle,\r\n Zap,\r\n Ban,\r\n Square,\r\n Terminal,\r\n Timer,\r\n Clock,\r\n Play,\r\n Pause,\r\n StopCircle,\r\n} from 'lucide-react';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport {\r\n AlertDialog,\r\n AlertDialogContent,\r\n AlertDialogHeader,\r\n AlertDialogTitle,\r\n AlertDialogDescription,\r\n AlertDialogFooter,\r\n AlertDialogAction,\r\n AlertDialogCancel,\r\n} from '@/components/ui/AlertDialog';\r\nimport { cn } from '@/lib/utils';\r\nimport {\r\n useIssueQueueIntegrationStore,\r\n selectAssociationChain,\r\n} from '@/stores/issueQueueIntegrationStore';\r\nimport {\r\n useQueueExecutionStore,\r\n selectByQueueItem,\r\n} from '@/stores/queueExecutionStore';\r\nimport {\r\n useQueueSchedulerStore,\r\n selectQueueSchedulerStatus,\r\n selectQueueItems,\r\n selectSchedulerProgress,\r\n selectCurrentConcurrency,\r\n selectSchedulerConfig,\r\n} from '@/stores/queueSchedulerStore';\r\nimport type { QueueItem, QueueItemStatus } from '@/types/queue-frontend-types';\r\n\r\n// ========== Status Config ==========\r\n\r\nconst STATUS_CONFIG: Record<QueueItemStatus, {\r\n variant: 'info' | 'success' | 'destructive' | 'secondary' | 'warning' | 'outline';\r\n icon: typeof Clock;\r\n label: string;\r\n}> = {\r\n pending: { variant: 'secondary', icon: Clock, label: 'Pending' },\r\n queued: { variant: 'info', icon: Timer, label: 'Queued' },\r\n ready: { variant: 'info', icon: Zap, label: 'Ready' },\r\n blocked: { variant: 'outline', icon: Ban, label: 'Blocked' },\r\n executing: { variant: 'warning', icon: Loader2, label: 'Executing' },\r\n completed: { variant: 'success', icon: CheckCircle, label: 'Completed' },\r\n failed: { variant: 'destructive', icon: XCircle, label: 'Failed' },\r\n cancelled: { variant: 'secondary', icon: Square, label: 'Cancelled' },\r\n};\r\n\r\n// ========== Scheduler Status Styles ==========\r\n\r\nconst SCHEDULER_STATUS_STYLE: Record<string, string> = {\r\n idle: 'bg-muted text-muted-foreground',\r\n running: 'bg-blue-500/15 text-blue-600',\r\n paused: 'bg-yellow-500/15 text-yellow-600',\r\n stopping: 'bg-orange-500/15 text-orange-600',\r\n completed: 'bg-green-500/15 text-green-600',\r\n failed: 'bg-red-500/15 text-red-600',\r\n};\r\n\r\n// ========== Item Row ==========\r\n\r\nfunction QueueItemRow({\r\n item,\r\n isHighlighted,\r\n onSelect,\r\n}: {\r\n item: QueueItem;\r\n isHighlighted: boolean;\r\n onSelect: () => void;\r\n}) {\r\n const { formatMessage } = useIntl();\r\n const config = STATUS_CONFIG[item.status] ?? STATUS_CONFIG.pending;\r\n const StatusIcon = config.icon;\r\n\r\n const executions = useQueueExecutionStore(selectByQueueItem(item.item_id));\r\n const activeExec = executions.find((e) => e.status === 'running') ?? executions[0];\r\n const sessionKey = item.sessionKey ?? activeExec?.sessionKey;\r\n\r\n const isExecuting = item.status === 'executing';\r\n const isBlocked = item.status === 'blocked';\r\n\r\n // Show issue_id if available (for items added from IssuePanel)\r\n const displayId = item.issue_id ? `${item.issue_id}` : item.item_id;\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n className={cn(\r\n 'w-full text-left px-2.5 py-1.5 rounded-md transition-colors',\r\n 'hover:bg-muted/60 focus:outline-none focus:ring-1 focus:ring-primary/30',\r\n isHighlighted && 'bg-accent/50 ring-1 ring-accent/30',\r\n isExecuting && 'border-l-2 border-l-blue-500'\r\n )}\r\n onClick={onSelect}\r\n >\r\n <div className=\"flex items-center justify-between gap-1.5\">\r\n <div className=\"flex items-center gap-1.5 min-w-0\">\r\n <StatusIcon\r\n className={cn(\r\n 'w-3 h-3 shrink-0',\r\n isExecuting && 'animate-spin'\r\n )}\r\n />\r\n <span className=\"text-xs font-medium text-foreground truncate font-mono\">\r\n {displayId}\r\n </span>\r\n </div>\r\n <Badge variant={config.variant} className=\"text-[10px] px-1 py-0 shrink-0\">\r\n {formatMessage({ id: `terminalDashboard.queuePanel.status.${item.status}`, defaultMessage: config.label })}\r\n </Badge>\r\n </div>\r\n <div className=\"mt-0.5 flex items-center gap-1.5 text-[10px] text-muted-foreground pl-4\">\r\n {item.execution_group && <span>{item.execution_group}</span>}\r\n {sessionKey && (\r\n <>\r\n <span className=\"text-border\">|</span>\r\n <span className=\"flex items-center gap-0.5\">\r\n <Terminal className=\"w-2.5 h-2.5\" />\r\n {sessionKey}\r\n </span>\r\n </>\r\n )}\r\n </div>\r\n {isBlocked && item.depends_on.length > 0 && (\r\n <div className=\"mt-0.5 text-[10px] text-orange-500/80 pl-4 truncate\">\r\n {formatMessage(\r\n { id: 'terminalDashboard.queuePanel.blockedBy', defaultMessage: 'Blocked by: {deps}' },\r\n { deps: item.depends_on.join(', ') }\r\n )}\r\n </div>\r\n )}\r\n </button>\r\n );\r\n}\r\n\r\n// ========== Inline Scheduler Controls ==========\r\n\r\nfunction SchedulerBar() {\r\n const { formatMessage } = useIntl();\r\n const status = useQueueSchedulerStore(selectQueueSchedulerStatus);\r\n const progress = useQueueSchedulerStore(selectSchedulerProgress);\r\n const concurrency = useQueueSchedulerStore(selectCurrentConcurrency);\r\n const config = useQueueSchedulerStore(selectSchedulerConfig);\r\n const startQueue = useQueueSchedulerStore((s) => s.startQueue);\r\n const pauseQueue = useQueueSchedulerStore((s) => s.pauseQueue);\r\n const stopQueue = useQueueSchedulerStore((s) => s.stopQueue);\r\n const items = useQueueSchedulerStore(selectQueueItems);\r\n\r\n const canStart = status === 'idle' && items.length > 0;\r\n const canPause = status === 'running';\r\n const canResume = status === 'paused';\r\n const canStop = status === 'running' || status === 'paused';\r\n const isActive = status !== 'idle';\r\n\r\n const [isStopConfirmOpen, setIsStopConfirmOpen] = useState(false);\r\n\r\n const handleStart = useCallback(() => {\r\n if (canResume) {\r\n startQueue();\r\n } else if (canStart) {\r\n startQueue(items);\r\n }\r\n }, [canResume, canStart, startQueue, items]);\r\n\r\n return (\r\n <div className=\"border-t border-border px-2.5 py-1.5 shrink-0\">\r\n <div className=\"flex items-center justify-between gap-2\">\r\n {/* Status badge */}\r\n <Badge\r\n variant=\"outline\"\r\n className={cn('text-[10px] px-1.5 py-0', SCHEDULER_STATUS_STYLE[status])}\r\n >\r\n {formatMessage({ id: `terminalDashboard.queuePanel.scheduler.status.${status}`, defaultMessage: status })}\r\n </Badge>\r\n\r\n {/* Progress + Concurrency */}\r\n {isActive && (\r\n <span className=\"text-[10px] text-muted-foreground\">\r\n {progress}% | {concurrency}/{config?.maxConcurrentSessions ?? 2}\r\n </span>\r\n )}\r\n\r\n {/* Controls */}\r\n <div className=\"flex items-center gap-0.5\">\r\n {(canStart || canResume) && (\r\n <button\r\n type=\"button\"\r\n className=\"p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground\"\r\n onClick={handleStart}\r\n title={formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.start', defaultMessage: 'Start' })}\r\n >\r\n <Play className=\"w-3 h-3\" />\r\n </button>\r\n )}\r\n {canPause && (\r\n <button\r\n type=\"button\"\r\n className=\"p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground\"\r\n onClick={pauseQueue}\r\n title={formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.pause', defaultMessage: 'Pause' })}\r\n >\r\n <Pause className=\"w-3 h-3\" />\r\n </button>\r\n )}\r\n {canStop && (\r\n <button\r\n type=\"button\"\r\n className=\"p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground\"\r\n onClick={() => setIsStopConfirmOpen(true)}\r\n title={formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.stop', defaultMessage: 'Stop' })}\r\n >\r\n <StopCircle className=\"w-3 h-3\" />\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Progress bar */}\r\n {isActive && (\r\n <div className=\"mt-1 h-1 bg-muted rounded-full overflow-hidden\">\r\n <div\r\n className=\"h-full bg-primary rounded-full transition-all duration-300\"\r\n style={{ width: `${progress}%` }}\r\n />\r\n </div>\r\n )}\r\n\r\n {/* Stop confirmation dialog */}\r\n <AlertDialog open={isStopConfirmOpen} onOpenChange={setIsStopConfirmOpen}>\r\n <AlertDialogContent className=\"max-w-sm\">\r\n <AlertDialogHeader>\r\n <AlertDialogTitle className=\"text-base\">\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.stopConfirmTitle', defaultMessage: 'Stop Queue?' })}\r\n </AlertDialogTitle>\r\n <AlertDialogDescription>\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.stopConfirmMessage', defaultMessage: 'Executing tasks will finish, but no new tasks will be started.' })}\r\n </AlertDialogDescription>\r\n </AlertDialogHeader>\r\n <AlertDialogFooter>\r\n <AlertDialogCancel className=\"h-8 text-xs\">\r\n {formatMessage({ id: 'common.cancel', defaultMessage: 'Cancel' })}\r\n </AlertDialogCancel>\r\n <AlertDialogAction\r\n className=\"h-8 text-xs bg-destructive text-destructive-foreground hover:bg-destructive/90\"\r\n onClick={() => { stopQueue(); setIsStopConfirmOpen(false); }}\r\n >\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.stop', defaultMessage: 'Stop' })}\r\n </AlertDialogAction>\r\n </AlertDialogFooter>\r\n </AlertDialogContent>\r\n </AlertDialog>\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\nexport function QueueListColumn() {\r\n const { formatMessage } = useIntl();\r\n\r\n const items = useQueueSchedulerStore(selectQueueItems);\r\n const associationChain = useIssueQueueIntegrationStore(selectAssociationChain);\r\n const buildAssociationChain = useIssueQueueIntegrationStore((s) => s.buildAssociationChain);\r\n\r\n // NOTE: loadInitialState is called from a parent component or app initialization\r\n // to avoid infinite loop issues with Zustand selectors\r\n\r\n const sortedItems = useMemo(\r\n () => [...items].sort((a, b) => a.execution_order - b.execution_order),\r\n [items]\r\n );\r\n\r\n const handleSelect = useCallback(\r\n (queueItemId: string) => {\r\n buildAssociationChain(queueItemId, 'queue');\r\n },\r\n [buildAssociationChain]\r\n );\r\n\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n {/* Item list */}\r\n {sortedItems.length === 0 ? (\r\n <div className=\"flex-1 flex items-center justify-center text-muted-foreground p-3\">\r\n <div className=\"text-center\">\r\n <ListChecks className=\"h-5 w-5 mx-auto mb-1 opacity-30\" />\r\n <p className=\"text-xs\">{formatMessage({ id: 'terminalDashboard.queuePanel.noItems' })}</p>\r\n <p className=\"text-[10px] mt-0.5 opacity-70\">\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.noItemsDesc', defaultMessage: 'Select issues and click Queue to add items' })}\r\n </p>\r\n </div>\r\n </div>\r\n ) : (\r\n <div className=\"flex-1 min-h-0 overflow-y-auto p-1 space-y-0.5\">\r\n {sortedItems.map((item) => (\r\n <QueueItemRow\r\n key={item.item_id}\r\n item={item}\r\n isHighlighted={associationChain?.queueItemId === item.item_id}\r\n onSelect={() => handleSelect(item.item_id)}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Inline scheduler controls */}\r\n <SchedulerBar />\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// SchedulerPanel Component\r\n// ========================================\r\n// Standalone queue scheduler control panel.\r\n// Shows scheduler status, start/pause/stop controls, concurrency config,\r\n// progress bar, and session pool overview.\r\n\r\nimport { useCallback, useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Play,\r\n Pause,\r\n Square,\r\n Loader2,\r\n} from 'lucide-react';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Progress } from '@/components/ui/Progress';\r\nimport {\r\n AlertDialog,\r\n AlertDialogContent,\r\n AlertDialogHeader,\r\n AlertDialogTitle,\r\n AlertDialogDescription,\r\n AlertDialogFooter,\r\n AlertDialogAction,\r\n AlertDialogCancel,\r\n} from '@/components/ui/AlertDialog';\r\nimport { cn } from '@/lib/utils';\r\nimport {\r\n useQueueSchedulerStore,\r\n selectQueueSchedulerStatus,\r\n selectSchedulerProgress,\r\n selectSchedulerConfig,\r\n selectSessionPool,\r\n selectCurrentConcurrency,\r\n selectSchedulerError,\r\n} from '@/stores/queueSchedulerStore';\r\nimport type { QueueSchedulerStatus } from '@/types/queue-frontend-types';\r\n\r\n// ========== Status Badge Config ==========\r\n\r\nconst SCHEDULER_STATUS_CLASS: Record<QueueSchedulerStatus, string> = {\r\n idle: 'bg-muted text-muted-foreground border-border',\r\n running: 'bg-primary/10 text-primary border-primary/50',\r\n paused: 'bg-amber-500/10 text-amber-500 border-amber-500/50',\r\n stopping: 'bg-orange-500/10 text-orange-500 border-orange-500/50',\r\n completed: 'bg-green-500/10 text-green-500 border-green-500/50',\r\n failed: 'bg-destructive/10 text-destructive border-destructive/50',\r\n};\r\n\r\n// ========== Component ==========\r\n\r\nexport function SchedulerPanel() {\r\n const { formatMessage } = useIntl();\r\n\r\n const schedulerStatus = useQueueSchedulerStore(selectQueueSchedulerStatus);\r\n const progress = useQueueSchedulerStore(selectSchedulerProgress);\r\n const config = useQueueSchedulerStore(selectSchedulerConfig);\r\n const sessionPool = useQueueSchedulerStore(selectSessionPool);\r\n const concurrency = useQueueSchedulerStore(selectCurrentConcurrency);\r\n const error = useQueueSchedulerStore(selectSchedulerError);\r\n const startQueue = useQueueSchedulerStore((s) => s.startQueue);\r\n const pauseQueue = useQueueSchedulerStore((s) => s.pauseQueue);\r\n const stopQueue = useQueueSchedulerStore((s) => s.stopQueue);\r\n const updateConfig = useQueueSchedulerStore((s) => s.updateConfig);\r\n\r\n const isIdle = schedulerStatus === 'idle';\r\n const isRunning = schedulerStatus === 'running';\r\n const isPaused = schedulerStatus === 'paused';\r\n const isStopping = schedulerStatus === 'stopping';\r\n const isTerminal = schedulerStatus === 'completed' || schedulerStatus === 'failed';\r\n\r\n const [isStopConfirmOpen, setIsStopConfirmOpen] = useState(false);\r\n\r\n const handleConcurrencyChange = useCallback(\r\n (e: React.ChangeEvent<HTMLInputElement>) => {\r\n const value = parseInt(e.target.value, 10);\r\n if (!isNaN(value) && value >= 1 && value <= 10) {\r\n updateConfig({ maxConcurrentSessions: value });\r\n }\r\n },\r\n [updateConfig]\r\n );\r\n\r\n const sessionEntries = Object.entries(sessionPool ?? {});\r\n\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n {/* Status + Controls */}\r\n <div className=\"px-3 py-3 border-b border-border space-y-3 shrink-0\">\r\n {/* Status badge */}\r\n <div className=\"flex items-center gap-2\">\r\n <span\r\n className={cn(\r\n 'px-2.5 py-1 rounded text-xs font-medium border',\r\n SCHEDULER_STATUS_CLASS[schedulerStatus]\r\n )}\r\n >\r\n {formatMessage({\r\n id: `terminalDashboard.queuePanel.scheduler.status.${schedulerStatus}`,\r\n defaultMessage: schedulerStatus,\r\n })}\r\n </span>\r\n <span className=\"text-xs text-muted-foreground ml-auto tabular-nums\">\r\n {concurrency}/{config?.maxConcurrentSessions ?? 2}\r\n </span>\r\n </div>\r\n\r\n {/* Control buttons */}\r\n <div className=\"flex items-center gap-2\">\r\n {(isIdle || isTerminal) && (\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n className=\"h-7 text-xs gap-1.5 flex-1\"\r\n onClick={() => startQueue()}\r\n >\r\n <Play className=\"w-3.5 h-3.5\" />\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.start', defaultMessage: 'Start' })}\r\n </Button>\r\n )}\r\n {isPaused && (\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n className=\"h-7 text-xs gap-1.5 flex-1\"\r\n onClick={() => startQueue()}\r\n >\r\n <Play className=\"w-3.5 h-3.5\" />\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.start', defaultMessage: 'Resume' })}\r\n </Button>\r\n )}\r\n {isRunning && (\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n className=\"h-7 text-xs gap-1.5 flex-1\"\r\n onClick={pauseQueue}\r\n >\r\n <Pause className=\"w-3.5 h-3.5\" />\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.pause', defaultMessage: 'Pause' })}\r\n </Button>\r\n )}\r\n {(isRunning || isPaused) && (\r\n <Button\r\n variant=\"destructive\"\r\n size=\"sm\"\r\n className=\"h-7 text-xs gap-1.5\"\r\n disabled={isStopping}\r\n onClick={() => setIsStopConfirmOpen(true)}\r\n >\r\n {isStopping ? <Loader2 className=\"w-3.5 h-3.5 animate-spin\" /> : <Square className=\"w-3.5 h-3.5\" />}\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.stop', defaultMessage: 'Stop' })}\r\n </Button>\r\n )}\r\n </div>\r\n\r\n {/* Progress bar (visible when not idle) */}\r\n {!isIdle && (\r\n <div className=\"flex items-center gap-2\">\r\n <Progress\r\n value={progress}\r\n className=\"h-1.5 flex-1\"\r\n indicatorClassName={cn(\r\n schedulerStatus === 'failed' && 'bg-destructive',\r\n schedulerStatus === 'completed' && 'bg-green-500',\r\n schedulerStatus === 'paused' && 'bg-amber-500',\r\n (schedulerStatus === 'running' || schedulerStatus === 'stopping') && 'bg-primary',\r\n )}\r\n />\r\n <span className=\"text-[10px] text-muted-foreground tabular-nums shrink-0\">\r\n {formatMessage(\r\n { id: 'terminalDashboard.queuePanel.scheduler.progress', defaultMessage: '{percent}%' },\r\n { percent: progress }\r\n )}\r\n </span>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Concurrency Config */}\r\n <div className=\"px-3 py-2.5 border-b border-border shrink-0\">\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.concurrency', defaultMessage: 'Concurrency' })}\r\n </span>\r\n <input\r\n type=\"number\"\r\n min={1}\r\n max={10}\r\n value={config?.maxConcurrentSessions ?? 2}\r\n onChange={handleConcurrencyChange}\r\n className=\"w-14 h-6 text-xs text-center rounded border border-border bg-background px-1\"\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* Session Pool */}\r\n <div className=\"flex-1 min-h-0 overflow-y-auto\">\r\n <div className=\"px-3 py-2\">\r\n <h4 className=\"text-[10px] font-medium text-muted-foreground uppercase tracking-wider mb-2\">\r\n {formatMessage({ id: 'terminalDashboard.schedulerPanel.sessionPool', defaultMessage: 'Session Pool' })}\r\n </h4>\r\n {sessionEntries.length === 0 ? (\r\n <p className=\"text-xs text-muted-foreground/60 py-2\">\r\n {formatMessage({ id: 'terminalDashboard.schedulerPanel.noSessions', defaultMessage: 'No active sessions' })}\r\n </p>\r\n ) : (\r\n <div className=\"space-y-1\">\r\n {sessionEntries.map(([resumeKey, binding]) => (\r\n <div\r\n key={resumeKey}\r\n className=\"flex items-center justify-between px-2 py-1.5 rounded bg-muted/30 text-xs\"\r\n >\r\n <div className=\"min-w-0\">\r\n <span className=\"font-mono text-foreground truncate block\">{binding.sessionKey}</span>\r\n <span className=\"text-[10px] text-muted-foreground truncate block\">{resumeKey}</span>\r\n </div>\r\n <span className=\"text-[10px] text-muted-foreground shrink-0 ml-2 tabular-nums\">\r\n {new Date(binding.lastUsed).toLocaleTimeString()}\r\n </span>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Error display */}\r\n {error && (\r\n <div className=\"px-3 py-2 border-t border-destructive/30 bg-destructive/5 shrink-0\">\r\n <p className=\"text-xs text-destructive break-words\">{error}</p>\r\n </div>\r\n )}\r\n\r\n {/* Stop confirmation dialog */}\r\n <AlertDialog open={isStopConfirmOpen} onOpenChange={setIsStopConfirmOpen}>\r\n <AlertDialogContent className=\"max-w-sm\">\r\n <AlertDialogHeader>\r\n <AlertDialogTitle className=\"text-base\">\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.stopConfirmTitle', defaultMessage: 'Stop Queue?' })}\r\n </AlertDialogTitle>\r\n <AlertDialogDescription>\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.stopConfirmMessage', defaultMessage: 'Executing tasks will finish, but no new tasks will be started. Pending items will remain in the queue.' })}\r\n </AlertDialogDescription>\r\n </AlertDialogHeader>\r\n <AlertDialogFooter>\r\n <AlertDialogCancel className=\"h-8 text-xs\">\r\n {formatMessage({ id: 'common.cancel', defaultMessage: 'Cancel' })}\r\n </AlertDialogCancel>\r\n <AlertDialogAction\r\n className=\"h-8 text-xs bg-destructive text-destructive-foreground hover:bg-destructive/90\"\r\n onClick={() => { stopQueue(); setIsStopConfirmOpen(false); }}\r\n >\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.stop', defaultMessage: 'Stop' })}\r\n </AlertDialogAction>\r\n </AlertDialogFooter>\r\n </AlertDialogContent>\r\n </AlertDialog>\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// BottomInspector Component\r\n// ========================================\r\n// Association chain visualization (Issue -> Queue -> Session).\r\n// Exports InspectorContent (pure content) for embedding in BottomPanel,\r\n// and BottomInspector (legacy standalone collapsible wrapper).\r\n\r\nimport { useState, useCallback, useMemo } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n ChevronDown,\r\n ChevronUp,\r\n Info,\r\n AlertCircle,\r\n ListChecks,\r\n Terminal,\r\n ArrowRight,\r\n} from 'lucide-react';\r\nimport { cn } from '@/lib/utils';\r\nimport {\r\n useIssueQueueIntegrationStore,\r\n selectAssociationChain,\r\n} from '@/stores/issueQueueIntegrationStore';\r\nimport { useQueueExecutionStore } from '@/stores/queueExecutionStore';\r\nimport { useCliSessionStore } from '@/stores/cliSessionStore';\r\nimport { useAssociationHighlight } from './AssociationHighlight';\r\n\r\n// ========== Chain Node ==========\r\n\r\nfunction ChainNode({\r\n icon: Icon,\r\n label,\r\n entityId,\r\n status,\r\n timestamp,\r\n isLast = false,\r\n}: {\r\n icon: React.ComponentType<{ className?: string }>;\r\n label: string;\r\n entityId: string | null;\r\n status?: string;\r\n timestamp?: string;\r\n isLast?: boolean;\r\n}) {\r\n if (!entityId) {\r\n return (\r\n <div className=\"flex items-center gap-2 opacity-40\">\r\n <Icon className=\"w-3.5 h-3.5 text-muted-foreground\" />\r\n <span className=\"text-xs text-muted-foreground\">{label}</span>\r\n <span className=\"text-xs text-muted-foreground italic\">--</span>\r\n {!isLast && <ArrowRight className=\"w-3 h-3 text-muted-foreground mx-1\" />}\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"flex items-center gap-2\">\r\n <Icon className=\"w-3.5 h-3.5 text-foreground\" />\r\n <span className=\"text-xs text-muted-foreground\">{label}</span>\r\n <span className=\"text-xs font-mono font-semibold text-foreground px-1.5 py-0.5 rounded bg-muted\">\r\n {entityId}\r\n </span>\r\n {status && (\r\n <span className=\"text-[10px] text-muted-foreground px-1 py-0.5 rounded border border-border\">\r\n {status}\r\n </span>\r\n )}\r\n {timestamp && (\r\n <span className=\"text-[10px] text-muted-foreground\">\r\n {formatTimestamp(timestamp)}\r\n </span>\r\n )}\r\n {!isLast && <ArrowRight className=\"w-3 h-3 text-muted-foreground mx-1\" />}\r\n </div>\r\n );\r\n}\r\n\r\n/** Format ISO timestamp to short readable form */\r\nfunction formatTimestamp(ts: string): string {\r\n try {\r\n const date = new Date(ts);\r\n return date.toLocaleTimeString(undefined, {\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n second: '2-digit',\r\n });\r\n } catch {\r\n return ts;\r\n }\r\n}\r\n\r\n// ========== InspectorContent (Pure content, no collapsible wrapper) ==========\r\n\r\nexport function InspectorContent() {\r\n const { formatMessage } = useIntl();\r\n const associationChain = useIssueQueueIntegrationStore(selectAssociationChain);\r\n const { chain: highlightedChain } = useAssociationHighlight();\r\n\r\n const activeChain = highlightedChain ?? associationChain;\r\n\r\n const chainDetails = useMemo(() => {\r\n if (!activeChain) return null;\r\n\r\n const executions = Object.values(useQueueExecutionStore.getState().executions);\r\n const sessions = useCliSessionStore.getState().sessions;\r\n\r\n let queueStatus: string | undefined;\r\n let executionTimestamp: string | undefined;\r\n if (activeChain.queueItemId) {\r\n const exec = executions.find((e) => e.queueItemId === activeChain.queueItemId);\r\n if (exec) {\r\n queueStatus = exec.status;\r\n executionTimestamp = exec.startedAt;\r\n }\r\n }\r\n\r\n let sessionStatus: string | undefined;\r\n let sessionTimestamp: string | undefined;\r\n if (activeChain.sessionId) {\r\n const session = sessions[activeChain.sessionId];\r\n if (session) {\r\n sessionStatus = 'active';\r\n sessionTimestamp = session.createdAt;\r\n }\r\n }\r\n\r\n return { queueStatus, executionTimestamp, sessionStatus, sessionTimestamp };\r\n }, [activeChain]);\r\n\r\n const hasChain = activeChain !== null;\r\n\r\n return (\r\n <div className=\"h-full overflow-y-auto px-4 py-3\">\r\n {hasChain ? (\r\n <div className=\"space-y-2\">\r\n <p className=\"text-xs font-medium text-muted-foreground\">\r\n {formatMessage({ id: 'terminalDashboard.inspector.associationChain' })}\r\n </p>\r\n <div className=\"flex items-center gap-1 flex-wrap\">\r\n <ChainNode\r\n icon={AlertCircle}\r\n label=\"Issue\"\r\n entityId={activeChain.issueId}\r\n />\r\n <ChainNode\r\n icon={ListChecks}\r\n label=\"Queue\"\r\n entityId={activeChain.queueItemId}\r\n status={chainDetails?.queueStatus}\r\n timestamp={chainDetails?.executionTimestamp}\r\n />\r\n <ChainNode\r\n icon={Terminal}\r\n label=\"Session\"\r\n entityId={activeChain.sessionId}\r\n status={chainDetails?.sessionStatus}\r\n timestamp={chainDetails?.sessionTimestamp}\r\n isLast\r\n />\r\n </div>\r\n </div>\r\n ) : (\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'terminalDashboard.inspector.noSelection' })}\r\n </p>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Legacy Standalone Component ==========\r\n\r\nexport function BottomInspector() {\r\n const { formatMessage } = useIntl();\r\n const [isOpen, setIsOpen] = useState(false);\r\n\r\n const associationChain = useIssueQueueIntegrationStore(selectAssociationChain);\r\n const { chain: highlightedChain } = useAssociationHighlight();\r\n\r\n // Use highlighted chain from context, fall back to store association chain\r\n const activeChain = highlightedChain ?? associationChain;\r\n\r\n const toggle = useCallback(() => {\r\n setIsOpen((prev) => !prev);\r\n }, []);\r\n\r\n // Resolve additional details from stores\r\n const chainDetails = useMemo(() => {\r\n if (!activeChain) return null;\r\n\r\n const executions = Object.values(useQueueExecutionStore.getState().executions);\r\n const sessions = useCliSessionStore.getState().sessions;\r\n\r\n // Find matching execution for queue status\r\n let queueStatus: string | undefined;\r\n let executionTimestamp: string | undefined;\r\n if (activeChain.queueItemId) {\r\n const exec = executions.find((e) => e.queueItemId === activeChain.queueItemId);\r\n if (exec) {\r\n queueStatus = exec.status;\r\n executionTimestamp = exec.startedAt;\r\n }\r\n }\r\n\r\n // Find session metadata\r\n let sessionStatus: string | undefined;\r\n let sessionTimestamp: string | undefined;\r\n if (activeChain.sessionId) {\r\n const session = sessions[activeChain.sessionId];\r\n if (session) {\r\n sessionStatus = 'active';\r\n sessionTimestamp = session.createdAt;\r\n }\r\n }\r\n\r\n return {\r\n queueStatus,\r\n executionTimestamp,\r\n sessionStatus,\r\n sessionTimestamp,\r\n };\r\n }, [activeChain]);\r\n\r\n const hasChain = activeChain !== null;\r\n\r\n return (\r\n <div className={cn('border-t border-border bg-muted/30 shrink-0 transition-all duration-200')}>\r\n {/* Toggle button */}\r\n <button\r\n onClick={toggle}\r\n className=\"flex items-center gap-2 w-full px-4 py-1.5 text-sm text-muted-foreground hover:text-foreground transition-colors\"\r\n >\r\n <Info className=\"w-4 h-4\" />\r\n <span className=\"font-medium\">\r\n {formatMessage({ id: 'terminalDashboard.inspector.title' })}\r\n </span>\r\n {hasChain && (\r\n <span className=\"ml-1 w-2 h-2 rounded-full bg-primary shrink-0\" />\r\n )}\r\n {isOpen ? (\r\n <ChevronDown className=\"w-4 h-4 ml-auto\" />\r\n ) : (\r\n <ChevronUp className=\"w-4 h-4 ml-auto\" />\r\n )}\r\n </button>\r\n\r\n {/* Collapsible content */}\r\n <div\r\n className={cn(\r\n 'overflow-hidden transition-all duration-200',\r\n isOpen ? 'max-h-40 opacity-100' : 'max-h-0 opacity-0'\r\n )}\r\n >\r\n <div className=\"px-4 pb-3\">\r\n {hasChain ? (\r\n <div className=\"space-y-2\">\r\n {/* Chain label */}\r\n <p className=\"text-xs font-medium text-muted-foreground\">\r\n {formatMessage({ id: 'terminalDashboard.inspector.associationChain' })}\r\n </p>\r\n {/* Chain visualization: Issue -> Queue -> Session */}\r\n <div className=\"flex items-center gap-1 flex-wrap\">\r\n <ChainNode\r\n icon={AlertCircle}\r\n label=\"Issue\"\r\n entityId={activeChain.issueId}\r\n />\r\n <ChainNode\r\n icon={ListChecks}\r\n label=\"Queue\"\r\n entityId={activeChain.queueItemId}\r\n status={chainDetails?.queueStatus}\r\n timestamp={chainDetails?.executionTimestamp}\r\n />\r\n <ChainNode\r\n icon={Terminal}\r\n label=\"Session\"\r\n entityId={activeChain.sessionId}\r\n status={chainDetails?.sessionStatus}\r\n timestamp={chainDetails?.sessionTimestamp}\r\n isLast\r\n />\r\n </div>\r\n </div>\r\n ) : (\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'terminalDashboard.inspector.noSelection' })}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// Execution Monitor Panel\r\n// ========================================\r\n// Panel for monitoring workflow executions and orchestration plans in Terminal Dashboard.\r\n// Displays execution progress, step list, control buttons, and active orchestration plans.\r\n\r\nimport { useMemo } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Play,\r\n Pause,\r\n Square,\r\n CheckCircle2,\r\n XCircle,\r\n Circle,\r\n Loader2,\r\n Clock,\r\n Terminal,\r\n Bot,\r\n} from 'lucide-react';\r\nimport { cn } from '@/lib/utils';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { Progress } from '@/components/ui/Progress';\r\nimport {\r\n useExecutionMonitorStore,\r\n selectCurrentExecution,\r\n selectActiveExecutions,\r\n} from '@/stores/executionMonitorStore';\r\nimport { useOrchestratorStore, selectActivePlans } from '@/stores';\r\nimport type { ExecutionStatus, StepInfo } from '@/stores/executionMonitorStore';\r\nimport type { OrchestrationRunState } from '@/stores/orchestratorStore';\r\nimport type { OrchestrationStatus } from '@/types/orchestrator';\r\n\r\n// ========== Status Config ==========\r\n\r\nconst statusConfig: Record<ExecutionStatus, { label: string; color: string; bgColor: string }> = {\r\n pending: { label: 'Pending', color: 'text-muted-foreground', bgColor: 'bg-muted' },\r\n running: { label: 'Running', color: 'text-primary', bgColor: 'bg-primary/10' },\r\n paused: { label: 'Paused', color: 'text-amber-500', bgColor: 'bg-amber-500/10' },\r\n completed: { label: 'Completed', color: 'text-green-500', bgColor: 'bg-green-500/10' },\r\n failed: { label: 'Failed', color: 'text-destructive', bgColor: 'bg-destructive/10' },\r\n cancelled: { label: 'Cancelled', color: 'text-muted-foreground', bgColor: 'bg-muted' },\r\n};\r\n\r\nconst ORCHESTRATION_STATUS_CONFIG: Record<\r\n OrchestrationStatus,\r\n { variant: 'default' | 'info' | 'success' | 'destructive' | 'secondary' | 'warning'; messageId: string }\r\n> = {\r\n running: { variant: 'info', messageId: 'terminalDashboard.agentList.statusRunning' },\r\n completed: { variant: 'success', messageId: 'terminalDashboard.agentList.statusCompleted' },\r\n failed: { variant: 'destructive', messageId: 'terminalDashboard.agentList.statusFailed' },\r\n paused: { variant: 'warning', messageId: 'terminalDashboard.agentList.statusPaused' },\r\n pending: { variant: 'secondary', messageId: 'terminalDashboard.agentList.statusPending' },\r\n cancelled: { variant: 'secondary', messageId: 'terminalDashboard.agentList.statusPending' },\r\n};\r\n\r\n// ========== Step Status Icon ==========\r\n\r\nfunction StepStatusIcon({ status }: { status: ExecutionStatus }) {\r\n switch (status) {\r\n case 'pending':\r\n return <Circle className=\"w-4 h-4 text-muted-foreground\" />;\r\n case 'running':\r\n return <Loader2 className=\"w-4 h-4 text-primary animate-spin\" />;\r\n case 'completed':\r\n return <CheckCircle2 className=\"w-4 h-4 text-green-500\" />;\r\n case 'failed':\r\n return <XCircle className=\"w-4 h-4 text-destructive\" />;\r\n case 'paused':\r\n return <Pause className=\"w-4 h-4 text-amber-500\" />;\r\n case 'cancelled':\r\n return <Square className=\"w-4 h-4 text-muted-foreground\" />;\r\n default:\r\n return <Circle className=\"w-4 h-4 text-muted-foreground opacity-50\" />;\r\n }\r\n}\r\n\r\n// ========== Step List Item ==========\r\n\r\ninterface StepListItemProps {\r\n step: StepInfo;\r\n isCurrent: boolean;\r\n}\r\n\r\nfunction StepListItem({ step, isCurrent }: StepListItemProps) {\r\n return (\r\n <div\r\n className={cn(\r\n 'flex items-start gap-3 px-3 py-2 rounded-md transition-colors',\r\n isCurrent && step.status === 'running' && 'bg-primary/5 border border-primary/20',\r\n step.status === 'failed' && 'bg-destructive/5'\r\n )}\r\n >\r\n <div className=\"pt-0.5 shrink-0\">\r\n <StepStatusIcon status={step.status} />\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <span\r\n className={cn(\r\n 'text-sm font-medium truncate block',\r\n step.status === 'completed' && 'text-muted-foreground',\r\n step.status === 'running' && 'text-foreground',\r\n step.status === 'failed' && 'text-destructive'\r\n )}\r\n >\r\n {step.name}\r\n </span>\r\n {step.error && (\r\n <p className=\"text-xs text-destructive mt-1 truncate\">{step.error}</p>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Orchestration Plan Item ==========\r\n\r\nfunction OrchestrationPlanItem({\r\n runState,\r\n}: {\r\n runState: OrchestrationRunState;\r\n}) {\r\n const { formatMessage } = useIntl();\r\n const { plan, status, stepStatuses } = runState;\r\n\r\n const totalSteps = plan.steps.length;\r\n const completedSteps = useMemo(\r\n () =>\r\n Object.values(stepStatuses).filter(\r\n (s) => s.status === 'completed' || s.status === 'skipped'\r\n ).length,\r\n [stepStatuses]\r\n );\r\n\r\n const config = ORCHESTRATION_STATUS_CONFIG[status] ?? ORCHESTRATION_STATUS_CONFIG.pending;\r\n const isRunning = status === 'running';\r\n\r\n return (\r\n <div\r\n className={cn(\r\n 'flex items-center gap-2 px-3 py-2 rounded-md',\r\n 'hover:bg-muted/30 transition-colors'\r\n )}\r\n >\r\n <div className=\"shrink-0\">\r\n {isRunning ? (\r\n <Loader2 className=\"w-4 h-4 text-primary animate-spin\" />\r\n ) : (\r\n <Bot className=\"w-4 h-4 text-muted-foreground\" />\r\n )}\r\n </div>\r\n\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"text-sm font-medium truncate\">{plan.name}</p>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage(\r\n { id: 'terminalDashboard.agentList.stepLabel' },\r\n { current: completedSteps, total: totalSteps }\r\n )}\r\n </p>\r\n </div>\r\n\r\n <Badge variant={config.variant} className=\"text-xs px-2 py-0 shrink-0\">\r\n {formatMessage({ id: config.messageId })}\r\n </Badge>\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\nexport function ExecutionMonitorPanel() {\r\n const { formatMessage } = useIntl();\r\n\r\n const currentExecution = useExecutionMonitorStore(selectCurrentExecution);\r\n const activeExecutions = useExecutionMonitorStore(selectActiveExecutions);\r\n const selectExecution = useExecutionMonitorStore((s) => s.selectExecution);\r\n const pauseExecution = useExecutionMonitorStore((s) => s.pauseExecution);\r\n const resumeExecution = useExecutionMonitorStore((s) => s.resumeExecution);\r\n const stopExecution = useExecutionMonitorStore((s) => s.stopExecution);\r\n const clearExecution = useExecutionMonitorStore((s) => s.clearExecution);\r\n\r\n // Orchestration plans\r\n const activePlans = useOrchestratorStore(selectActivePlans);\r\n const planEntries = useMemo(\r\n () => Object.entries(activePlans),\r\n [activePlans]\r\n );\r\n\r\n const executions = Object.values(activeExecutions);\r\n const hasContent = executions.length > 0 || planEntries.length > 0;\r\n\r\n if (!hasContent) {\r\n return (\r\n <div className=\"flex flex-col items-center justify-center h-full text-muted-foreground p-8\">\r\n <Terminal className=\"w-10 h-10 mb-3 opacity-30\" />\r\n <p className=\"text-sm font-medium\">\r\n {formatMessage({ id: 'executionMonitor.noExecutions', defaultMessage: 'No active executions' })}\r\n </p>\r\n <p className=\"text-xs mt-1 opacity-70\">\r\n {formatMessage({ id: 'executionMonitor.sendToTerminal', defaultMessage: 'Send a workflow to terminal to start' })}\r\n </p>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n {/* Orchestration Plans Section */}\r\n {planEntries.length > 0 && (\r\n <div className=\"border-b border-border shrink-0\">\r\n <div className=\"flex items-center gap-2 px-4 py-2 bg-muted/20\">\r\n <Bot className=\"w-4 h-4 text-muted-foreground\" />\r\n <h3 className=\"text-xs font-semibold text-muted-foreground uppercase tracking-wide\">\r\n {formatMessage({ id: 'terminalDashboard.agentList.title' })}\r\n </h3>\r\n <Badge variant=\"secondary\" className=\"text-[10px] px-1.5 py-0 ml-auto\">\r\n {planEntries.length}\r\n </Badge>\r\n </div>\r\n <div className=\"divide-y divide-border/50\">\r\n {planEntries.map(([planId, runState]) => (\r\n <OrchestrationPlanItem key={planId} runState={runState} />\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Workflow Executions Section */}\r\n {executions.length > 0 && (\r\n <>\r\n {/* Execution selector (if multiple) */}\r\n {executions.length > 1 && (\r\n <div className=\"border-b border-border p-2 shrink-0\">\r\n <div className=\"flex flex-wrap gap-1\">\r\n {executions.map((exec) => (\r\n <button\r\n key={exec.executionId}\r\n onClick={() => selectExecution(exec.executionId)}\r\n className={cn(\r\n 'px-2 py-1 text-xs rounded-md transition-colors truncate max-w-[120px]',\r\n currentExecution?.executionId === exec.executionId\r\n ? 'bg-primary text-primary-foreground'\r\n : 'bg-muted hover:bg-muted/80 text-muted-foreground'\r\n )}\r\n >\r\n {exec.flowName}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {currentExecution && (\r\n <>\r\n {/* Header */}\r\n <div className=\"p-4 border-b border-border space-y-3 shrink-0\">\r\n <div className=\"flex items-center gap-3\">\r\n <h3 className=\"text-sm font-semibold text-foreground truncate flex-1\">\r\n {currentExecution.flowName}\r\n </h3>\r\n <Badge\r\n variant=\"secondary\"\r\n className={cn('shrink-0', statusConfig[currentExecution.status].bgColor)}\r\n >\r\n {statusConfig[currentExecution.status].label}\r\n </Badge>\r\n </div>\r\n\r\n {/* Progress */}\r\n <div className=\"space-y-1\">\r\n <div className=\"flex justify-between text-xs text-muted-foreground\">\r\n <span>\r\n {formatMessage(\r\n { id: 'executionMonitor.progress', defaultMessage: '{completed}/{total} steps' },\r\n { completed: currentExecution.completedSteps, total: currentExecution.totalSteps || currentExecution.steps.length }\r\n )}\r\n </span>\r\n <span>\r\n {Math.round(\r\n (currentExecution.completedSteps / (currentExecution.totalSteps || currentExecution.steps.length || 1)) * 100\r\n )}%\r\n </span>\r\n </div>\r\n <Progress\r\n value={\r\n (currentExecution.completedSteps / (currentExecution.totalSteps || currentExecution.steps.length || 1)) * 100\r\n }\r\n className=\"h-2\"\r\n />\r\n </div>\r\n\r\n {/* Meta info */}\r\n <div className=\"flex items-center gap-3 text-xs text-muted-foreground\">\r\n <span className=\"flex items-center gap-1\">\r\n <Clock className=\"w-3 h-3\" />\r\n {new Date(currentExecution.startedAt).toLocaleTimeString()}\r\n </span>\r\n <span className=\"flex items-center gap-1\">\r\n <Terminal className=\"w-3 h-3\" />\r\n <span className=\"truncate max-w-[100px]\">{currentExecution.sessionKey.slice(0, 20)}...</span>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n {/* Step list */}\r\n <div className=\"flex-1 overflow-y-auto p-2 space-y-1\">\r\n {currentExecution.steps.map((step) => (\r\n <StepListItem\r\n key={step.id}\r\n step={step}\r\n isCurrent={step.id === currentExecution.currentStepId}\r\n />\r\n ))}\r\n </div>\r\n\r\n {/* Control bar */}\r\n <div className=\"p-3 border-t border-border flex items-center gap-2 shrink-0\">\r\n {currentExecution.status === 'running' && (\r\n <>\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => pauseExecution(currentExecution.executionId)}\r\n className=\"gap-1.5\"\r\n >\r\n <Pause className=\"w-3.5 h-3.5\" />\r\n {formatMessage({ id: 'executionMonitor.pause', defaultMessage: 'Pause' })}\r\n </Button>\r\n <Button\r\n variant=\"destructive\"\r\n size=\"sm\"\r\n onClick={() => stopExecution(currentExecution.executionId)}\r\n className=\"gap-1.5\"\r\n >\r\n <Square className=\"w-3.5 h-3.5\" />\r\n {formatMessage({ id: 'executionMonitor.stop', defaultMessage: 'Stop' })}\r\n </Button>\r\n </>\r\n )}\r\n\r\n {currentExecution.status === 'paused' && (\r\n <>\r\n <Button\r\n variant=\"default\"\r\n size=\"sm\"\r\n onClick={() => resumeExecution(currentExecution.executionId)}\r\n className=\"gap-1.5\"\r\n >\r\n <Play className=\"w-3.5 h-3.5\" />\r\n {formatMessage({ id: 'executionMonitor.resume', defaultMessage: 'Resume' })}\r\n </Button>\r\n <Button\r\n variant=\"destructive\"\r\n size=\"sm\"\r\n onClick={() => stopExecution(currentExecution.executionId)}\r\n className=\"gap-1.5\"\r\n >\r\n <Square className=\"w-3.5 h-3.5\" />\r\n {formatMessage({ id: 'executionMonitor.stop', defaultMessage: 'Stop' })}\r\n </Button>\r\n </>\r\n )}\r\n\r\n {(currentExecution.status === 'completed' ||\r\n currentExecution.status === 'failed' ||\r\n currentExecution.status === 'cancelled') && (\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => clearExecution(currentExecution.executionId)}\r\n className=\"gap-1.5 ml-auto\"\r\n >\r\n {formatMessage({ id: 'executionMonitor.clear', defaultMessage: 'Clear' })}\r\n </Button>\r\n )}\r\n </div>\r\n </>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default ExecutionMonitorPanel;\r\n","// ========================================\n// FileSidebarPanel Component\n// ========================================\n// Right sidebar file browser for Terminal Dashboard.\n// Displays file tree and allows showing files in focused terminal pane.\n\nimport * as React from 'react';\nimport { useIntl } from 'react-intl';\nimport { FolderOpen, RefreshCw, Loader2, ChevronLeft, FileText, Eye, EyeOff } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/Button';\nimport { TreeView } from '@/components/shared/TreeView';\nimport { useFileExplorer } from '@/hooks/useFileExplorer';\nimport { useTerminalGridStore, selectTerminalGridFocusedPaneId } from '@/stores/terminalGridStore';\nimport type { FileSystemNode } from '@/types/file-explorer';\n\nexport interface FileSidebarPanelProps {\n /** Root path for file explorer */\n rootPath: string;\n /** Whether the panel is enabled (has project path) */\n enabled?: boolean;\n /** Optional class name */\n className?: string;\n /** Callback when panel collapse is requested */\n onCollapse?: () => void;\n /** Initial width of the panel */\n width?: number;\n}\n\nexport function FileSidebarPanel({\n rootPath,\n enabled = true,\n className,\n onCollapse,\n width = 280,\n}: FileSidebarPanelProps) {\n const { formatMessage } = useIntl();\n\n // Store\n const focusedPaneId = useTerminalGridStore(selectTerminalGridFocusedPaneId);\n const showFileInPane = useTerminalGridStore((s) => s.showFileInPane);\n\n // File explorer hook\n const {\n rootNodes,\n state,\n isLoading,\n isFetching,\n error,\n refetch,\n setSelectedFile,\n toggleExpanded,\n toggleShowHidden,\n } = useFileExplorer({\n rootPath,\n maxDepth: 6,\n enabled,\n });\n\n // Handle node click\n const handleNodeClick = React.useCallback(\n (node: FileSystemNode) => {\n // Only files can be shown in pane\n if (node.type === 'file') {\n setSelectedFile(node.path);\n // Show file in focused pane if one exists\n if (focusedPaneId) {\n showFileInPane(focusedPaneId, node.path);\n }\n }\n },\n [focusedPaneId, setSelectedFile, showFileInPane]\n );\n\n // Handle refresh\n const handleRefresh = React.useCallback(() => {\n refetch();\n }, [refetch]);\n\n // Handle collapse\n const handleCollapse = React.useCallback(() => {\n onCollapse?.();\n }, [onCollapse]);\n\n // Disabled state (no project path)\n if (!enabled) {\n return (\n <div\n className={cn(\n 'flex flex-col h-full border-l border-border bg-background',\n className\n )}\n style={{ width }}\n >\n <div className=\"flex items-center justify-between px-3 py-2 border-b border-border bg-muted/30\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n {formatMessage({ id: 'terminalDashboard.fileSidebar.title', defaultMessage: 'Files' })}\n </span>\n {onCollapse && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 w-6 p-0\"\n onClick={handleCollapse}\n >\n <ChevronLeft className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n </div>\n <div className=\"flex-1 flex flex-col items-center justify-center px-4 text-center text-muted-foreground\">\n <FolderOpen className=\"h-10 w-10 mb-3 opacity-40\" />\n <p className=\"text-xs\">\n {formatMessage({ id: 'terminalDashboard.fileSidebar.noProject', defaultMessage: 'No project open' })}\n </p>\n <p className=\"text-[10px] mt-1 opacity-70\">\n {formatMessage({ id: 'terminalDashboard.fileSidebar.openProjectHint', defaultMessage: 'Open a project to browse files' })}\n </p>\n </div>\n </div>\n );\n }\n\n return (\n <div\n className={cn(\n 'flex flex-col h-full border-l border-border bg-background',\n className\n )}\n style={{ width }}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between gap-2 px-3 py-2 border-b border-border bg-muted/30 shrink-0\">\n <div className=\"flex items-center gap-2 min-w-0 flex-1\">\n <FolderOpen className=\"h-3.5 w-3.5 text-muted-foreground shrink-0\" />\n <span className=\"text-xs font-medium truncate\">\n {formatMessage({ id: 'terminalDashboard.fileSidebar.title', defaultMessage: 'Files' })}\n </span>\n {isFetching && !isLoading && (\n <Loader2 className=\"h-3 w-3 animate-spin text-muted-foreground\" />\n )}\n </div>\n <div className=\"flex items-center gap-1 shrink-0\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 w-6 p-0\"\n onClick={toggleShowHidden}\n title={formatMessage({ id: 'terminalDashboard.fileBrowser.showHidden' })}\n >\n {state.showHiddenFiles ? <EyeOff className=\"h-3.5 w-3.5\" /> : <Eye className=\"h-3.5 w-3.5\" />}\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 w-6 p-0\"\n onClick={handleRefresh}\n disabled={isFetching}\n title={formatMessage({ id: 'terminalDashboard.fileSidebar.refresh', defaultMessage: 'Refresh' })}\n >\n <RefreshCw className={cn('h-3.5 w-3.5', isFetching && 'animate-spin')} />\n </Button>\n {onCollapse && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 w-6 p-0\"\n onClick={handleCollapse}\n title={formatMessage({ id: 'terminalDashboard.fileSidebar.collapse', defaultMessage: 'Collapse' })}\n >\n <ChevronLeft className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n </div>\n </div>\n\n {/* Current path indicator */}\n <div className=\"px-3 py-1.5 border-b border-border/50 bg-muted/10 shrink-0\">\n <div className=\"text-[10px] text-muted-foreground truncate font-mono\" title={rootPath}>\n {rootPath}\n </div>\n </div>\n\n {/* Tree view */}\n <div className=\"flex-1 min-h-0 overflow-y-auto\">\n {isLoading ? (\n <div className=\"flex items-center justify-center py-8 text-muted-foreground\">\n <Loader2 className=\"w-5 h-5 animate-spin\" />\n <span className=\"ml-2 text-xs\">\n {formatMessage({ id: 'terminalDashboard.fileBrowser.loading', defaultMessage: 'Loading...' })}\n </span>\n </div>\n ) : error ? (\n <div className=\"p-3 text-xs text-destructive\">\n {formatMessage({ id: 'terminalDashboard.fileBrowser.loadFailed', defaultMessage: 'Failed to load files' })}\n </div>\n ) : rootNodes.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-8 px-4 text-center text-muted-foreground\">\n <FileText className=\"h-10 w-10 mb-3 opacity-40\" />\n <p className=\"text-xs\">\n {formatMessage({ id: 'terminalDashboard.fileSidebar.empty', defaultMessage: 'No files found' })}\n </p>\n </div>\n ) : (\n <TreeView\n nodes={rootNodes}\n expandedPaths={state.expandedPaths}\n selectedPath={state.selectedFile}\n onNodeClick={handleNodeClick}\n onToggle={toggleExpanded}\n maxDepth={0}\n className=\"py-1\"\n />\n )}\n </div>\n\n {/* Footer hint */}\n {!focusedPaneId && (\n <div className=\"px-3 py-2 border-t border-border bg-muted/10 shrink-0\">\n <p className=\"text-[10px] text-muted-foreground text-center\">\n {formatMessage({ id: 'terminalDashboard.fileSidebar.selectPaneHint', defaultMessage: 'Click a pane to show file preview' })}\n </p>\n </div>\n )}\n </div>\n );\n}\n\nexport default FileSidebarPanel;\n","// ========================================\n// Terminal Dashboard Page (V2)\n// ========================================\n// Terminal-first layout with fixed session sidebar + floating panels + right file sidebar.\n// Left sidebar: SessionGroupTree (always visible)\n// Main area: TerminalGrid (tmux-style split panes)\n// Right sidebar: FileSidebarPanel (file tree, resizable)\n// Top: DashboardToolbar with panel toggles and layout presets\n// Floating panels: Issues, Queue, Inspector, Execution Monitor (overlay, mutually exclusive)\n// Fullscreen mode: Uses global isImmersiveMode to hide app chrome (Header + Sidebar)\n\nimport { useState, useCallback, useEffect } from 'react';\nimport { useIntl } from 'react-intl';\nimport { Allotment } from 'allotment';\nimport 'allotment/dist/style.css';\nimport { AssociationHighlightProvider } from '@/components/terminal-dashboard/AssociationHighlight';\nimport { DashboardToolbar, type PanelId } from '@/components/terminal-dashboard/DashboardToolbar';\nimport { TerminalGrid } from '@/components/terminal-dashboard/TerminalGrid';\nimport { FloatingPanel } from '@/components/terminal-dashboard/FloatingPanel';\nimport { SessionGroupTree } from '@/components/terminal-dashboard/SessionGroupTree';\nimport { IssuePanel } from '@/components/terminal-dashboard/IssuePanel';\nimport { QueuePanel } from '@/components/terminal-dashboard/QueuePanel';\nimport { QueueListColumn } from '@/components/terminal-dashboard/QueueListColumn';\nimport { SchedulerPanel } from '@/components/terminal-dashboard/SchedulerPanel';\nimport { InspectorContent } from '@/components/terminal-dashboard/BottomInspector';\nimport { ExecutionMonitorPanel } from '@/components/terminal-dashboard/ExecutionMonitorPanel';\nimport { FileSidebarPanel } from '@/components/terminal-dashboard/FileSidebarPanel';\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\nimport { useAppStore, selectIsImmersiveMode } from '@/stores/appStore';\nimport { useConfigStore } from '@/stores/configStore';\n\n// ========== Main Page Component ==========\n\nexport function TerminalDashboardPage() {\n const { formatMessage } = useIntl();\n const [activePanel, setActivePanel] = useState<PanelId | null>(null);\n const [isFileSidebarOpen, setIsFileSidebarOpen] = useState(true);\n const [isSessionSidebarOpen, setIsSessionSidebarOpen] = useState(true);\n\n const projectPath = useWorkflowStore(selectProjectPath);\n\n // Feature flags for panel visibility\n const featureFlags = useConfigStore((s) => s.featureFlags);\n\n // Use global immersive mode state (only affects AppShell chrome)\n const isImmersiveMode = useAppStore(selectIsImmersiveMode);\n const toggleImmersiveMode = useAppStore((s) => s.toggleImmersiveMode);\n\n const togglePanel = useCallback((panelId: PanelId) => {\n setActivePanel((prev) => (prev === panelId ? null : panelId));\n }, []);\n\n const closePanel = useCallback(() => {\n setActivePanel(null);\n }, []);\n\n useEffect(() => {\n setActivePanel(null);\n }, [projectPath]);\n\n return (\n <div className={`flex flex-col overflow-hidden ${isImmersiveMode ? 'h-screen' : 'h-[calc(100vh-56px)]'}`}>\n <AssociationHighlightProvider scopeKey={projectPath ?? 'default'}>\n {/* Global toolbar */}\n <DashboardToolbar\n activePanel={activePanel}\n onTogglePanel={togglePanel}\n isFileSidebarOpen={isFileSidebarOpen}\n onToggleFileSidebar={() => setIsFileSidebarOpen((prev) => !prev)}\n isSessionSidebarOpen={isSessionSidebarOpen}\n onToggleSessionSidebar={() => setIsSessionSidebarOpen((prev) => !prev)}\n isFullscreen={isImmersiveMode}\n onToggleFullscreen={toggleImmersiveMode}\n />\n\n {/* Main content with three-column layout */}\n <div className=\"flex-1 min-h-0\">\n <Allotment className=\"h-full\">\n {/* Session sidebar (controlled by local state, not immersive mode) */}\n {isSessionSidebarOpen && (\n <Allotment.Pane preferredSize={240} minSize={180} maxSize={320}>\n <div className=\"h-full flex flex-col border-r border-border\">\n <div className=\"flex-1 min-h-0 overflow-y-auto\">\n <SessionGroupTree />\n </div>\n </div>\n </Allotment.Pane>\n )}\n\n {/* Terminal grid (flexible) */}\n <Allotment.Pane preferredSize={-1} minSize={300}>\n <TerminalGrid />\n </Allotment.Pane>\n\n {/* File sidebar (controlled by local state, not immersive mode) */}\n {isFileSidebarOpen && (\n <Allotment.Pane preferredSize={280} minSize={200} maxSize={400}>\n <FileSidebarPanel\n rootPath={projectPath ?? '/'}\n enabled={!!projectPath}\n onCollapse={() => setIsFileSidebarOpen(false)}\n />\n </Allotment.Pane>\n )}\n </Allotment>\n </div>\n\n {/* Floating panels (always available) */}\n <FloatingPanel\n isOpen={activePanel === 'issues'}\n onClose={closePanel}\n title={formatMessage({ id: 'terminalDashboard.toolbar.issues' })}\n side=\"left\"\n width={700}\n >\n <div className=\"flex h-full\">\n <div className=\"flex-1 min-w-0 border-r border-border\">\n <IssuePanel />\n </div>\n <div className=\"flex-1 min-w-0 flex flex-col\">\n <div className=\"px-3 py-2 border-b border-border shrink-0\">\n <h3 className=\"text-sm font-semibold\">{formatMessage({ id: 'terminalDashboard.toolbar.queue' })}</h3>\n </div>\n <QueueListColumn />\n </div>\n </div>\n </FloatingPanel>\n\n {featureFlags.dashboardQueuePanelEnabled && (\n <FloatingPanel\n isOpen={activePanel === 'queue'}\n onClose={closePanel}\n title={formatMessage({ id: 'terminalDashboard.toolbar.queue' })}\n side=\"right\"\n width={400}\n >\n <QueuePanel />\n </FloatingPanel>\n )}\n\n {featureFlags.dashboardInspectorEnabled && (\n <FloatingPanel\n isOpen={activePanel === 'inspector'}\n onClose={closePanel}\n title={formatMessage({ id: 'terminalDashboard.toolbar.inspector' })}\n side=\"right\"\n width={360}\n >\n <InspectorContent />\n </FloatingPanel>\n )}\n\n {featureFlags.dashboardExecutionMonitorEnabled && (\n <FloatingPanel\n isOpen={activePanel === 'execution'}\n onClose={closePanel}\n title={formatMessage({ id: 'terminalDashboard.toolbar.executionMonitor', defaultMessage: 'Execution Monitor' })}\n side=\"right\"\n width={380}\n >\n <ExecutionMonitorPanel />\n </FloatingPanel>\n )}\n\n <FloatingPanel\n isOpen={activePanel === 'scheduler'}\n onClose={closePanel}\n title={formatMessage({ id: 'terminalDashboard.toolbar.scheduler', defaultMessage: 'Scheduler' })}\n side=\"right\"\n width={340}\n >\n <SchedulerPanel />\n </FloatingPanel>\n </AssociationHighlightProvider>\n </div>\n );\n}\n\nexport default TerminalDashboardPage;\n"],"names":["CircleDot","createLucideIcon","Eraser","ListPlus","WifiOff","AssociationHighlightContext","createContext","AssociationHighlightProvider","children","scopeKey","chain","setChainState","useState","lastScopeKeyRef","useRef","useEffect","setChain","useCallback","nextChain","isHighlighted","entityId","entityType","value","useMemo","jsx","useAssociationHighlight","ctx","useContext","generateTag","tool","time","CliConfigModal","isOpen","onClose","defaultWorkingDir","onCreateSession","formatMessage","useIntl","cliTools","useConfigStore","selectCliTools","enabledTools","React.useMemo","config","key","setTool","React.useState","model","setModel","launchMode","setLaunchMode","preferredShell","setPreferredShell","workingDir","setWorkingDir","tag","setTag","isSubmitting","setIsSubmitting","error","setError","modelInputValue","setModelInputValue","isModelDropdownOpen","setIsModelDropdownOpen","modelContainerRef","React.useRef","modelInputRef","cliSettings","useCliSettings","currentProvider","enabledCliSettings","s","settingsEndpointId","setSettingsEndpointId","React.useEffect","modelOptions","endpoint","_a","toolConfig","_b","models","regenerateTag","React.useCallback","suffix","filteredModelOptions","query","m","handleClickOutside","e","handleToolChange","nextTool","nextConfig","nextModels","handleBrowse","handleCreate","dir","finalTag","err","Dialog","open","jsxs","DialogContent","DialogHeader","DialogTitle","DialogDescription","Label","Input","Button","RefreshCw","Select","SelectTrigger","SelectValue","SelectContent","t","SelectItem","v","ChevronDown","cn","id","RadioGroup","RadioGroupItem","FolderOpen","DialogFooter","LAYOUT_PRESETS","Square","Columns2","Rows2","LayoutGrid","DashboardToolbar","activePanel","onTogglePanel","isFileSidebarOpen","onToggleFileSidebar","isSessionSidebarOpen","onToggleSessionSidebar","isFullscreen","onToggleFullscreen","openCount","useIssues","queueQuery","useIssueQueue","queueCount","grouped","count","items","hasChain","useIssueQueueIntegrationStore","selectAssociationChain","executionCount","useExecutionMonitorStore","selectActiveExecutionCount","isSchedulerActive","useQueueSchedulerStore","selectQueueSchedulerStatus","featureFlags","showQueue","showInspector","showExecution","resetLayout","useTerminalGridStore","handlePreset","preset","projectPath","useWorkflowStore","selectProjectPath","focusedPaneId","selectTerminalGridFocusedPaneId","createSessionAndAssign","updateTerminalMeta","useSessionManagerStore","isCreating","setIsCreating","isConfigOpen","setIsConfigOpen","getOrCreateFocusedPane","handleOpenConfig","handleCreateConfiguredSession","targetPaneId","result","message","toast","Fragment","Loader2","Plus","ToolbarButton","Folder","AlertCircle","ListChecks","Info","Activity","Gauge","Minimize2","Maximize2","Icon","label","isActive","onClick","badge","dot","loading","Badge","TRAILING_PUNCTUATION","WRAP_QUOTES","normalizePath","raw","ARTIFACT_PATTERNS","detectCcArtifacts","text","candidates","type","pattern","match","path","full","group","rel","index","a","b","results","seen","c","getVariant","getLabelId","basename","p","parts","ArtifactTag","className","display","badgeVariants","ARTIFACT_DEBOUNCE_MS","MAX_ARTIFACT_TAGS","isAbsolutePath","joinPath","base","relative","sep","r","resolveArtifactPath","mergeArtifacts","prev","next","map","changed","merged","TerminalInstance","sessionId","onRevealPath","outputChunks","useCliSessionStore","setBuffer","clearOutput","artifacts","setArtifacts","terminalHostRef","xtermRef","fitAddonRef","lastChunkIndexRef","pendingArtifactTextRef","artifactTimerRef","pendingInputRef","flushTimerRef","sessionIdRef","projectPathRef","handleTerminalClick","handleArtifactClick","resolved","scheduleArtifactParse","pending","detected","flushInput","sendCliSessionText","scheduleFlush","term","XTerm","fitAddon","FitAddon","data","fetchCliSessionBuffer","buffer","chunks","start","feedMonitor","newTextParts","i","host","resize","resizeCliSession","ro","statusDotStyles","TerminalPane","paneId","panes","selectTerminalGridPanes","layout","splitPane","closePane","assignSession","setFocused","setPaneDisplayMode","pane","displayMode","filePath","isFocused","canClose","getAllPaneIds","isFileMode","terminalMetas","selectTerminalMetas","sessions","pauseSession","resumeSession","restartSession","closeSession","isRestarting","setIsRestarting","isTogglingPause","setIsTogglingPause","isClosingSession","setIsClosingSession","isCloseConfirmOpen","setIsCloseConfirmOpen","fileContent","isFileLoading","fileError","useFileContent","associationChain","linkedIssueId","meta","status","alertCount","isSessionNotFound","timer","sessionOptions","sid","name","handleFocus","handleSplitH","handleSplitV","handleClose","handleCloseConfirm","handleSessionChange","session","handleClear","handleRestart","handleTogglePause","handleCloseSession","handleBackToTerminal","ArrowLeft","FileText","opt","SplitSquareHorizontal","SplitSquareVertical","RotateCcw","Play","Pause","LogOut","AlertTriangle","X","FilePreview","Terminal","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","GridGroupRenderer","minSize","depth","updateLayoutSizes","handleChange","sizes","validChildren","child","isPaneId","groupKey","Allotment","TerminalGrid","selectTerminalGridLayout","content","SessionGroupTree","activeTerminalId","selectSessionManagerActiveTerminalId","setActiveTerminal","expandedTags","setExpandedTags","toggleTag","handleSessionClick","paneWithSession","sessionsByTag","groups","untagged","sessionKey","sessionNames","isExpanded","displayName","ChevronRight","Tag","sessionStatus","PROMPT_TEMPLATES","idStr","buildQueuePrompt","issues","PRIORITY_STYLES","PriorityBadge","priority","style","StatusDot","colorMap","IssueItem","issue","isSelected","isChecked","onSelect","onToggleCheck","IssueEmptyState","IssueErrorState","IssuePanel","isLoading","selectedIssueId","selectSelectedIssueId","setSelectedIssue","buildAssociationChain","selectedIds","setSelectedIds","isSending","setIsSending","justSent","setJustSent","executionMethod","setExecutionMethod","isSendConfigOpen","setIsSendConfigOpen","customPrompt","setCustomPrompt","sentTimerRef","isAddingToQueue","setIsAddingToQueue","justQueued","setJustQueued","queueMode","setQueueMode","queuedTimerRef","submitItems","focusedPane","sessionCliTool","availableMethods","sortedIssues","priorityOrder","statusOrder","sa","sb","pa","pb","handleSelect","issueId","handleToggleSelect","handleSelectAll","handleDeselectAll","handleOpenSendConfig","handleSendToTerminal","effectiveTool","prompt","executeInput","executeInCliSession","handleAddToQueue","selectedIssues","now","method","Send","Check","STATUS_CONFIG","Clock","Timer","Zap","Ban","CheckCircle","XCircle","SCHEDULER_STATUS_STYLE","QueueItemRow","item","StatusIcon","executions","useQueueExecutionStore","selectByQueueItem","activeExec","isExecuting","isBlocked","displayId","SchedulerBar","progress","selectSchedulerProgress","concurrency","selectCurrentConcurrency","selectSchedulerConfig","startQueue","pauseQueue","stopQueue","selectQueueItems","canStart","canPause","canResume","canStop","isStopConfirmOpen","setIsStopConfirmOpen","handleStart","StopCircle","QueueListColumn","sortedItems","queueItemId","SCHEDULER_STATUS_CLASS","SchedulerPanel","schedulerStatus","sessionPool","selectSessionPool","selectSchedulerError","updateConfig","isIdle","isRunning","isPaused","isStopping","isTerminal","handleConcurrencyChange","sessionEntries","Progress","resumeKey","binding","ChainNode","timestamp","isLast","formatTimestamp","ArrowRight","ts","InspectorContent","highlightedChain","activeChain","chainDetails","queueStatus","executionTimestamp","exec","sessionTimestamp","statusConfig","ORCHESTRATION_STATUS_CONFIG","StepStatusIcon","Circle","CheckCircle2","StepListItem","step","isCurrent","OrchestrationPlanItem","runState","plan","stepStatuses","totalSteps","completedSteps","Bot","ExecutionMonitorPanel","currentExecution","selectCurrentExecution","activeExecutions","selectActiveExecutions","selectExecution","pauseExecution","resumeExecution","stopExecution","clearExecution","activePlans","useOrchestratorStore","selectActivePlans","planEntries","planId","FileSidebarPanel","rootPath","enabled","onCollapse","width","showFileInPane","rootNodes","state","isFetching","refetch","setSelectedFile","toggleExpanded","toggleShowHidden","useFileExplorer","handleNodeClick","node","handleRefresh","handleCollapse","EyeOff","Eye","ChevronLeft","TreeView","TerminalDashboardPage","setActivePanel","setIsFileSidebarOpen","setIsSessionSidebarOpen","isImmersiveMode","useAppStore","selectIsImmersiveMode","toggleImmersiveMode","togglePanel","panelId","closePanel","FloatingPanel","QueuePanel"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}
|
|
1
|
+
{"version":3,"file":"TerminalDashboardPage-Cn3fGUuO.js","sources":["../../../../node_modules/lucide-react/dist/esm/icons/circle-dot.js","../../../../node_modules/lucide-react/dist/esm/icons/eraser.js","../../../../node_modules/lucide-react/dist/esm/icons/list-plus.js","../../../../node_modules/lucide-react/dist/esm/icons/wifi-off.js","../../src/components/terminal-dashboard/AssociationHighlight.tsx","../../src/components/terminal-dashboard/CliConfigModal.tsx","../../src/components/terminal-dashboard/DashboardToolbar.tsx","../../src/lib/ccw-artifacts.ts","../../src/components/terminal-dashboard/ArtifactTag.tsx","../../src/components/terminal-dashboard/TerminalInstance.tsx","../../src/components/terminal-dashboard/TerminalPane.tsx","../../src/components/terminal-dashboard/TerminalGrid.tsx","../../src/components/terminal-dashboard/SessionGroupTree.tsx","../../src/components/terminal-dashboard/IssuePanel.tsx","../../src/components/terminal-dashboard/QueueListColumn.tsx","../../src/components/terminal-dashboard/SchedulerPanel.tsx","../../src/components/terminal-dashboard/BottomInspector.tsx","../../src/components/terminal-dashboard/ExecutionMonitorPanel.tsx","../../src/components/terminal-dashboard/FileSidebarPanel.tsx","../../src/pages/TerminalDashboardPage.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CircleDot = createLucideIcon(\"CircleDot\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"1\", key: \"41hilf\" }]\n]);\n\nexport { CircleDot as default };\n//# sourceMappingURL=circle-dot.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Eraser = createLucideIcon(\"Eraser\", [\n [\n \"path\",\n {\n d: \"m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21\",\n key: \"182aya\"\n }\n ],\n [\"path\", { d: \"M22 21H7\", key: \"t4ddhn\" }],\n [\"path\", { d: \"m5 11 9 9\", key: \"1mo9qw\" }]\n]);\n\nexport { Eraser as default };\n//# sourceMappingURL=eraser.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ListPlus = createLucideIcon(\"ListPlus\", [\n [\"path\", { d: \"M11 12H3\", key: \"51ecnj\" }],\n [\"path\", { d: \"M16 6H3\", key: \"1wxfjs\" }],\n [\"path\", { d: \"M16 18H3\", key: \"12xzn7\" }],\n [\"path\", { d: \"M18 9v6\", key: \"1twb98\" }],\n [\"path\", { d: \"M21 12h-6\", key: \"bt1uis\" }]\n]);\n\nexport { ListPlus as default };\n//# sourceMappingURL=list-plus.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst WifiOff = createLucideIcon(\"WifiOff\", [\n [\"path\", { d: \"M12 20h.01\", key: \"zekei9\" }],\n [\"path\", { d: \"M8.5 16.429a5 5 0 0 1 7 0\", key: \"1bycff\" }],\n [\"path\", { d: \"M5 12.859a10 10 0 0 1 5.17-2.69\", key: \"1dl1wf\" }],\n [\"path\", { d: \"M19 12.859a10 10 0 0 0-2.007-1.523\", key: \"4k23kn\" }],\n [\"path\", { d: \"M2 8.82a15 15 0 0 1 4.177-2.643\", key: \"1grhjp\" }],\n [\"path\", { d: \"M22 8.82a15 15 0 0 0-11.288-3.764\", key: \"z3jwby\" }],\n [\"path\", { d: \"m2 2 20 20\", key: \"1ooewy\" }]\n]);\n\nexport { WifiOff as default };\n//# sourceMappingURL=wifi-off.js.map\n","// ========================================\r\n// AssociationHighlight Context\r\n// ========================================\r\n// React context provider for cross-panel association chain highlighting.\r\n// Provides ephemeral UI state for linked-chain highlights shared across\r\n// left/middle/right panels. The highlighted chain indicates which\r\n// Issue, QueueItem, and Session are visually linked.\r\n//\r\n// Design rationale: React context chosen over Zustand store because\r\n// highlight state is ephemeral UI state that does not need persistence\r\n// or cross-page sharing.\r\n\r\nimport {\r\n createContext,\r\n useContext,\r\n useState,\r\n useCallback,\r\n useEffect,\r\n useMemo,\r\n useRef,\r\n type ReactNode,\r\n} from 'react';\r\nimport type { AssociationChain } from '@/types/terminal-dashboard';\r\n\r\n// ========== Context Type ==========\r\n\r\ninterface AssociationHighlightContextType {\r\n /** Currently highlighted association chain, or null if nothing is highlighted */\r\n chain: AssociationChain | null;\r\n /** Set the highlighted chain (pass null to clear) */\r\n setChain: (chain: AssociationChain | null) => void;\r\n /** Check if a specific entity is part of the current highlighted chain */\r\n isHighlighted: (entityId: string, entityType: 'issue' | 'queue' | 'session') => boolean;\r\n}\r\n\r\n// ========== Context ==========\r\n\r\nconst AssociationHighlightContext = createContext<AssociationHighlightContextType | null>(null);\r\n\r\n// ========== Provider ==========\r\n\r\nexport function AssociationHighlightProvider({\r\n children,\r\n scopeKey,\r\n}: {\r\n children: ReactNode;\r\n scopeKey?: string | null;\r\n}) {\r\n const [chain, setChainState] = useState<AssociationChain | null>(null);\r\n const lastScopeKeyRef = useRef(scopeKey);\r\n\r\n useEffect(() => {\r\n if (lastScopeKeyRef.current !== scopeKey) {\r\n lastScopeKeyRef.current = scopeKey;\r\n setChainState(null);\r\n }\r\n }, [scopeKey]);\r\n\r\n const setChain = useCallback((nextChain: AssociationChain | null) => {\r\n setChainState(nextChain);\r\n }, []);\r\n\r\n const isHighlighted = useCallback(\r\n (entityId: string, entityType: 'issue' | 'queue' | 'session'): boolean => {\r\n if (!chain) return false;\r\n switch (entityType) {\r\n case 'issue':\r\n return chain.issueId === entityId;\r\n case 'queue':\r\n return chain.queueItemId === entityId;\r\n case 'session':\r\n return chain.sessionId === entityId;\r\n default:\r\n return false;\r\n }\r\n },\r\n [chain]\r\n );\r\n\r\n const value = useMemo<AssociationHighlightContextType>(\r\n () => ({ chain, setChain, isHighlighted }),\r\n [chain, setChain, isHighlighted]\r\n );\r\n\r\n return (\r\n <AssociationHighlightContext.Provider value={value}>\r\n {children}\r\n </AssociationHighlightContext.Provider>\r\n );\r\n}\r\n\r\n// ========== Consumer Hook ==========\r\n\r\n/**\r\n * Hook to access the association highlight context.\r\n * Must be used within an AssociationHighlightProvider.\r\n */\r\nexport function useAssociationHighlight(): AssociationHighlightContextType {\r\n const ctx = useContext(AssociationHighlightContext);\r\n if (!ctx) {\r\n throw new Error(\r\n 'useAssociationHighlight must be used within an AssociationHighlightProvider'\r\n );\r\n }\r\n return ctx;\r\n}\r\n","// ========================================\n// CliConfigModal Component\n// ========================================\n// Config modal for creating a new CLI session in Terminal Dashboard.\n\nimport * as React from 'react';\nimport { useIntl } from 'react-intl';\nimport { ChevronDown, FolderOpen, RefreshCw } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/Button';\nimport { Input } from '@/components/ui/Input';\nimport { Label } from '@/components/ui/Label';\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n} from '@/components/ui/Dialog';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/Select';\nimport { RadioGroup, RadioGroupItem } from '@/components/ui/RadioGroup';\nimport { useConfigStore, selectCliTools } from '@/stores/configStore';\nimport { useCliSettings } from '@/hooks/useApiSettings';\n\nexport type CliTool = string;\nexport type LaunchMode = 'default' | 'yolo';\nexport type ShellKind = 'bash' | 'pwsh' | 'cmd';\n\nexport interface CliSessionConfig {\n tool: CliTool;\n model?: string;\n launchMode: LaunchMode;\n preferredShell: ShellKind;\n workingDir: string;\n /** Session tag for grouping (auto-generated if not provided) */\n tag: string;\n /** CLI Settings endpoint ID for custom API configuration */\n settingsEndpointId?: string;\n}\n\nexport interface CliConfigModalProps {\n isOpen: boolean;\n onClose: () => void;\n defaultWorkingDir?: string | null;\n onCreateSession: (config: CliSessionConfig) => Promise<void>;\n}\n\n/**\n * Generate a tag name: {tool}-{HHmmss}\n * Example: gemini-143052\n */\nfunction generateTag(tool: string): string {\n const now = new Date();\n const time = now.toTimeString().slice(0, 8).replace(/:/g, '');\n return `${tool}-${time}`;\n}\n\nexport function CliConfigModal({\n isOpen,\n onClose,\n defaultWorkingDir,\n onCreateSession,\n}: CliConfigModalProps) {\n const { formatMessage } = useIntl();\n\n // Dynamic tool data from configStore\n const cliTools = useConfigStore(selectCliTools);\n const enabledTools = React.useMemo(\n () =>\n Object.entries(cliTools)\n .filter(([, config]) => config.enabled)\n .map(([key]) => key),\n [cliTools]\n );\n\n const [tool, setTool] = React.useState<CliTool>('gemini');\n const [model, setModel] = React.useState<string | undefined>(undefined);\n const [launchMode, setLaunchMode] = React.useState<LaunchMode>('yolo');\n // Default to 'cmd' on Windows for better compatibility with npm CLI tools (.cmd files)\n const [preferredShell, setPreferredShell] = React.useState<ShellKind>(\n typeof navigator !== 'undefined' && navigator.platform.toLowerCase().includes('win') ? 'cmd' : 'bash'\n );\n const [workingDir, setWorkingDir] = React.useState<string>(defaultWorkingDir ?? '');\n const [tag, setTag] = React.useState<string>('');\n\n const [isSubmitting, setIsSubmitting] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n\n // Model combobox state\n const [modelInputValue, setModelInputValue] = React.useState('');\n const [isModelDropdownOpen, setIsModelDropdownOpen] = React.useState(false);\n const modelContainerRef = React.useRef<HTMLDivElement>(null);\n const modelInputRef = React.useRef<HTMLInputElement>(null);\n\n // CLI Settings integration (for all tools)\n const { cliSettings } = useCliSettings({ enabled: true });\n\n // Map tool names to provider types for filtering\n const toolProviderMap: Record<string, string> = {\n claude: 'claude',\n codex: 'codex',\n gemini: 'gemini',\n };\n const currentProvider = toolProviderMap[tool] || tool;\n\n const enabledCliSettings = React.useMemo(\n () => (cliSettings || []).filter((s) => s.enabled && (s.provider || 'claude') === currentProvider),\n [cliSettings, currentProvider]\n );\n const [settingsEndpointId, setSettingsEndpointId] = React.useState<string | undefined>(undefined);\n\n // Reset settingsEndpointId when tool changes\n React.useEffect(() => {\n setSettingsEndpointId(undefined);\n }, [tool]);\n\n // Derive model options from configStore + CLI Settings profile override\n const modelOptions = React.useMemo(() => {\n // If a CLI Settings profile is selected and has availableModels, use those\n if (settingsEndpointId) {\n const endpoint = enabledCliSettings.find((s) => s.id === settingsEndpointId);\n if (endpoint?.settings.availableModels?.length) {\n return endpoint.settings.availableModels;\n }\n }\n const toolConfig = cliTools[tool];\n if (!toolConfig) return [];\n if (toolConfig.availableModels?.length) return toolConfig.availableModels;\n // Build models from primaryModel/secondaryModel, filtering out undefined\n const models: string[] = [];\n if (toolConfig.primaryModel) models.push(toolConfig.primaryModel);\n if (toolConfig.secondaryModel && toolConfig.secondaryModel !== toolConfig.primaryModel) {\n models.push(toolConfig.secondaryModel);\n }\n return models;\n }, [cliTools, tool, settingsEndpointId, enabledCliSettings]);\n\n // Generate new tag when modal opens or tool changes\n const regenerateTag = React.useCallback(() => {\n setTag(generateTag(tool));\n }, [tool]);\n\n React.useEffect(() => {\n if (!isOpen) return;\n // Reset to a safe default each time the modal is opened.\n const nextWorkingDir = defaultWorkingDir ?? '';\n setWorkingDir(nextWorkingDir);\n setError(null);\n setSettingsEndpointId(undefined);\n regenerateTag();\n }, [isOpen, defaultWorkingDir, regenerateTag]);\n\n // Update tag prefix when tool changes\n React.useEffect(() => {\n if (tag) {\n const suffix = tag.split('-').pop() || '';\n setTag(`${tool}-${suffix}`);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- only re-run when tool changes, reading tag intentionally stale\n }, [tool]);\n\n // Sync model input display when model state changes (e.g., tool change)\n React.useEffect(() => {\n setModelInputValue(model ?? '');\n }, [model]);\n\n // Filter model suggestions based on typed input\n const filteredModelOptions = React.useMemo(() => {\n const query = modelInputValue.toLowerCase();\n if (!query) return modelOptions;\n return modelOptions.filter((m) => m.toLowerCase().includes(query));\n }, [modelOptions, modelInputValue]);\n\n // Close model dropdown on outside click\n React.useEffect(() => {\n function handleClickOutside(e: MouseEvent) {\n if (modelContainerRef.current && !modelContainerRef.current.contains(e.target as Node)) {\n setIsModelDropdownOpen(false);\n }\n }\n if (isModelDropdownOpen) {\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }\n }, [isModelDropdownOpen]);\n\n const handleToolChange = (nextTool: string) => {\n setTool(nextTool as CliTool);\n const nextConfig = cliTools[nextTool];\n const nextModels = nextConfig?.availableModels?.length\n ? nextConfig.availableModels\n : [nextConfig?.primaryModel, nextConfig?.secondaryModel].filter(Boolean) as string[];\n if (!model || !nextModels.includes(model)) {\n setModel(nextModels[0]);\n }\n };\n\n const handleBrowse = () => {\n // Reserved for future file-picker integration\n console.log('[CliConfigModal] browse working directory - not implemented');\n };\n\n const handleCreate = async () => {\n const dir = workingDir.trim();\n if (!dir) {\n setError(formatMessage({ id: 'terminalDashboard.cliConfig.errors.workingDirRequired' }));\n return;\n }\n\n const finalTag = tag.trim() || generateTag(tool);\n\n setIsSubmitting(true);\n setError(null);\n try {\n await onCreateSession({\n tool,\n model,\n launchMode,\n preferredShell,\n workingDir: dir,\n tag: finalTag,\n settingsEndpointId,\n });\n onClose();\n } catch (err) {\n console.error('[CliConfigModal] create session failed:', err);\n setError(formatMessage({ id: 'terminalDashboard.cliConfig.errors.createFailed' }));\n } finally {\n setIsSubmitting(false);\n }\n };\n\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>\n <DialogContent className=\"sm:max-w-[720px] max-h-[90vh] overflow-y-auto\">\n <DialogHeader>\n <DialogTitle>{formatMessage({ id: 'terminalDashboard.cliConfig.title' })}</DialogTitle>\n <DialogDescription>\n {formatMessage({ id: 'terminalDashboard.cliConfig.description' })}\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4 py-4\">\n {/* Tag / Name */}\n <div className=\"space-y-2\">\n <Label htmlFor=\"cli-config-tag\">\n {formatMessage({ id: 'terminalDashboard.cliConfig.tag', defaultMessage: 'Session Name' })}\n </Label>\n <div className=\"flex gap-2\">\n <Input\n id=\"cli-config-tag\"\n value={tag}\n onChange={(e) => setTag(e.target.value)}\n placeholder={formatMessage({ id: 'terminalDashboard.cliConfig.tagPlaceholder', defaultMessage: 'e.g., gemini-143052' })}\n disabled={isSubmitting}\n className=\"flex-1\"\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={regenerateTag}\n disabled={isSubmitting}\n title={formatMessage({ id: 'terminalDashboard.cliConfig.regenerateTag', defaultMessage: 'Regenerate name' })}\n >\n <RefreshCw className=\"w-4 h-4\" />\n </Button>\n </div>\n <p className=\"text-xs text-muted-foreground\">\n {formatMessage({ id: 'terminalDashboard.cliConfig.tagHint', defaultMessage: 'Auto-generated as {tool}-{time}. Used for grouping sessions.' })}\n </p>\n </div>\n\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n {/* Tool */}\n <div className=\"space-y-2\">\n <Label htmlFor=\"cli-config-tool\">\n {formatMessage({ id: 'terminalDashboard.cliConfig.tool' })}\n </Label>\n <Select value={tool} onValueChange={handleToolChange} disabled={isSubmitting}>\n <SelectTrigger id=\"cli-config-tool\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {enabledTools.map((t) => (\n <SelectItem key={t} value={t}>\n {t}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {/* Model - Combobox (input + dropdown suggestions) */}\n <div className=\"space-y-2\">\n <Label htmlFor=\"cli-config-model\">\n {formatMessage({ id: 'terminalDashboard.cliConfig.model' })}\n </Label>\n <div ref={modelContainerRef} className=\"relative\">\n <div className=\"flex\">\n <input\n ref={modelInputRef}\n id=\"cli-config-model\"\n value={modelInputValue}\n onChange={(e) => {\n const v = e.target.value;\n setModelInputValue(v);\n setModel(v || undefined);\n if (!isModelDropdownOpen) setIsModelDropdownOpen(true);\n }}\n onFocus={() => setIsModelDropdownOpen(true)}\n onKeyDown={(e) => {\n if (e.key === 'Escape') setIsModelDropdownOpen(false);\n if (e.key === 'Enter') setIsModelDropdownOpen(false);\n }}\n placeholder={formatMessage({ id: 'terminalDashboard.cliConfig.modelAuto', defaultMessage: 'Auto' })}\n disabled={isSubmitting}\n className=\"flex h-10 w-full rounded-l-md border border-r-0 border-input bg-background px-3 py-2 text-sm font-mono ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\"\n />\n <button\n type=\"button\"\n onClick={() => {\n setIsModelDropdownOpen(!isModelDropdownOpen);\n if (!isModelDropdownOpen) modelInputRef.current?.focus();\n }}\n disabled={isSubmitting}\n className=\"flex items-center justify-center h-10 w-9 shrink-0 rounded-r-md border border-input bg-background hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <ChevronDown className=\"h-4 w-4 opacity-50\" />\n </button>\n </div>\n {isModelDropdownOpen && (\n <div className=\"absolute z-50 mt-1 w-full rounded-md border border-border bg-card shadow-md max-h-48 overflow-y-auto\">\n <button\n type=\"button\"\n onClick={() => {\n setModel(undefined);\n setModelInputValue('');\n setIsModelDropdownOpen(false);\n }}\n className={cn(\n 'flex w-full items-center px-3 py-1.5 text-sm cursor-pointer hover:bg-accent hover:text-accent-foreground',\n !model && 'bg-accent/50'\n )}\n >\n {formatMessage({ id: 'terminalDashboard.cliConfig.modelAuto', defaultMessage: 'Auto' })}\n </button>\n {filteredModelOptions.map((m) => (\n <button\n key={m}\n type=\"button\"\n onClick={() => {\n setModel(m);\n setModelInputValue(m);\n setIsModelDropdownOpen(false);\n }}\n className={cn(\n 'flex w-full items-center px-3 py-1.5 text-sm cursor-pointer hover:bg-accent hover:text-accent-foreground font-mono',\n model === m && 'bg-accent/50'\n )}\n >\n {m}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* Config Profile (all tools with settings) */}\n {enabledCliSettings.length > 0 && (\n <div className=\"space-y-2\">\n <Label htmlFor=\"cli-config-profile\">\n {formatMessage({ id: 'terminalDashboard.cliConfig.configProfile', defaultMessage: 'Config Profile' })}\n </Label>\n <Select\n value={settingsEndpointId ?? '__default__'}\n onValueChange={(v) => {\n const id = v === '__default__' ? undefined : v;\n setSettingsEndpointId(id);\n // If profile has availableModels, use those for model dropdown\n if (id) {\n const endpoint = enabledCliSettings.find((s) => s.id === id);\n if (endpoint?.settings.availableModels?.length) {\n setModel(endpoint.settings.availableModels[0]);\n }\n }\n }}\n disabled={isSubmitting}\n >\n <SelectTrigger id=\"cli-config-profile\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__default__\">\n {formatMessage({ id: 'terminalDashboard.cliConfig.defaultProfile', defaultMessage: 'Default' })}\n </SelectItem>\n {enabledCliSettings.map((s) => (\n <SelectItem key={s.id} value={s.id}>{s.name}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n <p className=\"text-xs text-muted-foreground\">\n {formatMessage({ id: 'terminalDashboard.cliConfig.configProfileHint', defaultMessage: 'Select a CLI Settings profile for custom API configuration.' })}\n </p>\n </div>\n )}\n\n {/* Mode */}\n <div className=\"space-y-2\">\n <Label>{formatMessage({ id: 'terminalDashboard.cliConfig.mode' })}</Label>\n <RadioGroup\n value={launchMode}\n onValueChange={(v) => setLaunchMode(v as LaunchMode)}\n className=\"flex items-center gap-4\"\n >\n <label className=\"flex items-center gap-2 text-sm cursor-pointer\">\n <RadioGroupItem value=\"default\" />\n {formatMessage({ id: 'terminalDashboard.cliConfig.modeDefault' })}\n </label>\n <label className=\"flex items-center gap-2 text-sm cursor-pointer\">\n <RadioGroupItem value=\"yolo\" />\n {formatMessage({ id: 'terminalDashboard.cliConfig.modeYolo' })}\n </label>\n </RadioGroup>\n </div>\n\n {/* Shell */}\n <div className=\"space-y-2\">\n <Label htmlFor=\"cli-config-shell\">\n {formatMessage({ id: 'terminalDashboard.cliConfig.shell' })}\n </Label>\n <Select\n value={preferredShell}\n onValueChange={(v) => setPreferredShell(v as ShellKind)}\n disabled={isSubmitting}\n >\n <SelectTrigger id=\"cli-config-shell\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"cmd\">cmd (推荐 Windows)</SelectItem>\n <SelectItem value=\"bash\">bash (Git Bash/WSL)</SelectItem>\n <SelectItem value=\"pwsh\">pwsh (PowerShell)</SelectItem>\n </SelectContent>\n </Select>\n </div>\n\n {/* Working Directory */}\n <div className=\"space-y-2\">\n <Label htmlFor=\"cli-config-workingDir\">\n {formatMessage({ id: 'terminalDashboard.cliConfig.workingDir' })}\n </Label>\n <div className=\"flex gap-2\">\n <Input\n id=\"cli-config-workingDir\"\n value={workingDir}\n onChange={(e) => {\n setWorkingDir(e.target.value);\n if (error) setError(null);\n }}\n placeholder={formatMessage({ id: 'terminalDashboard.cliConfig.workingDirPlaceholder' })}\n disabled={isSubmitting}\n className={cn(error && 'border-destructive')}\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleBrowse}\n disabled={isSubmitting}\n title={formatMessage({ id: 'terminalDashboard.cliConfig.browse' })}\n >\n <FolderOpen className=\"w-4 h-4\" />\n </Button>\n </div>\n {error && <p className=\"text-xs text-destructive\">{error}</p>}\n </div>\n </div>\n\n <DialogFooter>\n <Button variant=\"outline\" onClick={onClose} disabled={isSubmitting}>\n {formatMessage({ id: 'common.actions.cancel' })}\n </Button>\n <Button onClick={handleCreate} disabled={isSubmitting}>\n {formatMessage({ id: 'common.actions.create' })}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n\nexport default CliConfigModal;\n","// ========================================\n// DashboardToolbar Component\n// ========================================\n// Top toolbar for Terminal Dashboard V2.\n// Provides toggle buttons for floating panels (Issues/Queue/Inspector)\n// and layout preset controls. Sessions sidebar is always visible.\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useIntl } from 'react-intl';\nimport {\n AlertCircle,\n ListChecks,\n Info,\n FolderOpen,\n LayoutGrid,\n Columns2,\n Rows2,\n Square,\n Loader2,\n Folder,\n Maximize2,\n Minimize2,\n Activity,\n Plus,\n Gauge,\n} from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport { Badge } from '@/components/ui/Badge';\nimport {\n useIssueQueueIntegrationStore,\n selectAssociationChain,\n} from '@/stores/issueQueueIntegrationStore';\nimport { useIssues, useIssueQueue } from '@/hooks/useIssues';\nimport { useTerminalGridStore, selectTerminalGridFocusedPaneId } from '@/stores/terminalGridStore';\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\nimport { toast } from '@/stores/notificationStore';\nimport { useExecutionMonitorStore, selectActiveExecutionCount } from '@/stores/executionMonitorStore';\nimport { useSessionManagerStore } from '@/stores/sessionManagerStore';\nimport { useConfigStore } from '@/stores/configStore';\nimport { useQueueSchedulerStore, selectQueueSchedulerStatus } from '@/stores/queueSchedulerStore';\nimport { CliConfigModal, type CliSessionConfig } from './CliConfigModal';\n\n// ========== Types ==========\n\nexport type PanelId = 'issues' | 'queue' | 'inspector' | 'execution' | 'scheduler';\n\ninterface DashboardToolbarProps {\n activePanel: PanelId | null;\n onTogglePanel: (panelId: PanelId) => void;\n /** Whether the file sidebar is open */\n isFileSidebarOpen?: boolean;\n /** Callback to toggle file sidebar */\n onToggleFileSidebar?: () => void;\n /** Whether the session sidebar is open */\n isSessionSidebarOpen?: boolean;\n /** Callback to toggle session sidebar */\n onToggleSessionSidebar?: () => void;\n /** Whether fullscreen mode is active */\n isFullscreen?: boolean;\n /** Callback to toggle fullscreen mode */\n onToggleFullscreen?: () => void;\n}\n\n// ========== Layout Presets ==========\n\nconst LAYOUT_PRESETS = [\n { id: 'single' as const, icon: Square, labelId: 'terminalDashboard.toolbar.layoutSingle' },\n { id: 'split-h' as const, icon: Columns2, labelId: 'terminalDashboard.toolbar.layoutSplitH' },\n { id: 'split-v' as const, icon: Rows2, labelId: 'terminalDashboard.toolbar.layoutSplitV' },\n { id: 'grid-2x2' as const, icon: LayoutGrid, labelId: 'terminalDashboard.toolbar.layoutGrid' },\n];\n\n// ========== Component ==========\n\nexport function DashboardToolbar({ activePanel, onTogglePanel, isFileSidebarOpen, onToggleFileSidebar, isSessionSidebarOpen, onToggleSessionSidebar, isFullscreen, onToggleFullscreen }: DashboardToolbarProps) {\n const { formatMessage } = useIntl();\n\n // Issues count\n const { openCount } = useIssues();\n\n // Queue count\n const queueQuery = useIssueQueue();\n const queueCount = useMemo(() => {\n if (!queueQuery.data) return 0;\n const grouped = queueQuery.data.grouped_items ?? {};\n let count = 0;\n for (const items of Object.values(grouped)) {\n count += items.length;\n }\n return count;\n }, [queueQuery.data]);\n\n // Inspector chain indicator\n const associationChain = useIssueQueueIntegrationStore(selectAssociationChain);\n const hasChain = associationChain !== null;\n\n // Execution monitor count\n const executionCount = useExecutionMonitorStore(selectActiveExecutionCount);\n\n // Scheduler status for badge indicator\n const schedulerStatus = useQueueSchedulerStore(selectQueueSchedulerStatus);\n const isSchedulerActive = schedulerStatus !== 'idle';\n\n // Feature flags for panel visibility\n const featureFlags = useConfigStore((s) => s.featureFlags);\n const showQueue = featureFlags.dashboardQueuePanelEnabled;\n const showInspector = featureFlags.dashboardInspectorEnabled;\n const showExecution = featureFlags.dashboardExecutionMonitorEnabled;\n\n // Layout preset handler\n const resetLayout = useTerminalGridStore((s) => s.resetLayout);\n const handlePreset = useCallback(\n (preset: 'single' | 'split-h' | 'split-v' | 'grid-2x2') => {\n resetLayout(preset);\n },\n [resetLayout]\n );\n\n // Launch CLI handlers\n const projectPath = useWorkflowStore(selectProjectPath);\n const focusedPaneId = useTerminalGridStore(selectTerminalGridFocusedPaneId);\n const createSessionAndAssign = useTerminalGridStore((s) => s.createSessionAndAssign);\n const updateTerminalMeta = useSessionManagerStore((s) => s.updateTerminalMeta);\n const [isCreating, setIsCreating] = useState(false);\n const [isConfigOpen, setIsConfigOpen] = useState(false);\n\n useEffect(() => {\n setIsCreating(false);\n setIsConfigOpen(false);\n }, [projectPath]);\n\n // Helper to get or create a focused pane\n const getOrCreateFocusedPane = useCallback(() => {\n if (focusedPaneId) return focusedPaneId;\n // No focused pane - reset layout to create a single pane\n resetLayout('single');\n // Get the new focused pane id from store\n return useTerminalGridStore.getState().focusedPaneId;\n }, [focusedPaneId]);\n\n // Open config modal\n const handleOpenConfig = useCallback(() => {\n setIsConfigOpen(true);\n }, []);\n\n // Create session from config modal\n const handleCreateConfiguredSession = useCallback(async (config: CliSessionConfig) => {\n if (!projectPath) throw new Error('No project path');\n setIsCreating(true);\n try {\n const targetPaneId = getOrCreateFocusedPane();\n if (!targetPaneId) throw new Error('Failed to create pane');\n\n const result = await createSessionAndAssign(\n targetPaneId,\n {\n workingDir: config.workingDir || projectPath,\n preferredShell: config.preferredShell,\n tool: config.tool,\n model: config.model,\n launchMode: config.launchMode,\n settingsEndpointId: config.settingsEndpointId,\n },\n projectPath\n );\n\n // Store tag in terminalMetas for grouping\n if (result?.session?.sessionKey) {\n updateTerminalMeta(result.session.sessionKey, {\n tag: config.tag,\n title: config.tag,\n });\n }\n } catch (error: unknown) {\n const message = error instanceof Error\n ? error.message\n : (error as { message?: string })?.message\n ? (error as { message: string }).message\n : String(error);\n toast.error(`CLI 会话创建失败 (${config.tool})`, message);\n throw error;\n } finally {\n setIsCreating(false);\n }\n }, [projectPath, createSessionAndAssign, getOrCreateFocusedPane, updateTerminalMeta]);\n\n return (\n <>\n <div className=\"flex items-center gap-1 px-2 h-[40px] border-b border-border bg-muted/30 shrink-0\">\n {/* Launch CLI button - opens config dialog */}\n <button\n onClick={handleOpenConfig}\n className={cn(\n 'flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-xs transition-colors',\n 'text-muted-foreground hover:text-foreground hover:bg-muted',\n isCreating && 'opacity-50 cursor-wait'\n )}\n disabled={isCreating || !projectPath}\n title={formatMessage({ id: 'terminalDashboard.toolbar.launchCliHint', defaultMessage: 'Click to configure and launch a CLI session' })}\n >\n {isCreating ? (\n <Loader2 className=\"w-3.5 h-3.5 animate-spin\" />\n ) : (\n <Plus className=\"w-3.5 h-3.5\" />\n )}\n <span>{formatMessage({ id: 'terminalDashboard.toolbar.launchCli' })}</span>\n </button>\n\n {/* Separator */}\n <div className=\"w-px h-5 bg-border mx-1\" />\n\n {/* Session sidebar toggle */}\n <ToolbarButton\n icon={Folder}\n label={formatMessage({ id: 'terminalDashboard.toolbar.sessions', defaultMessage: 'Sessions' })}\n isActive={isSessionSidebarOpen ?? true}\n onClick={() => onToggleSessionSidebar?.()}\n />\n\n {/* Separator */}\n <div className=\"w-px h-5 bg-border mx-1\" />\n\n {/* Panel toggle buttons */}\n <ToolbarButton\n icon={AlertCircle}\n label={formatMessage({ id: 'terminalDashboard.toolbar.issues' })}\n isActive={activePanel === 'issues'}\n onClick={() => onTogglePanel('issues')}\n badge={openCount > 0 ? openCount : undefined}\n />\n {showQueue && (\n <ToolbarButton\n icon={ListChecks}\n label={formatMessage({ id: 'terminalDashboard.toolbar.queue' })}\n isActive={activePanel === 'queue'}\n onClick={() => onTogglePanel('queue')}\n badge={queueCount > 0 ? queueCount : undefined}\n />\n )}\n {showInspector && (\n <ToolbarButton\n icon={Info}\n label={formatMessage({ id: 'terminalDashboard.toolbar.inspector' })}\n isActive={activePanel === 'inspector'}\n onClick={() => onTogglePanel('inspector')}\n dot={hasChain}\n />\n )}\n {showExecution && (\n <ToolbarButton\n icon={Activity}\n label={formatMessage({ id: 'terminalDashboard.toolbar.executionMonitor', defaultMessage: 'Execution Monitor' })}\n isActive={activePanel === 'execution'}\n onClick={() => onTogglePanel('execution')}\n badge={executionCount > 0 ? executionCount : undefined}\n />\n )}\n <ToolbarButton\n icon={Gauge}\n label={formatMessage({ id: 'terminalDashboard.toolbar.scheduler', defaultMessage: 'Scheduler' })}\n isActive={activePanel === 'scheduler'}\n onClick={() => onTogglePanel('scheduler')}\n dot={isSchedulerActive}\n loading={isSchedulerActive}\n />\n <ToolbarButton\n icon={FolderOpen}\n label={formatMessage({ id: 'terminalDashboard.toolbar.files', defaultMessage: 'Files' })}\n isActive={isFileSidebarOpen ?? false}\n onClick={() => onToggleFileSidebar?.()}\n />\n\n {/* Separator */}\n <div className=\"w-px h-5 bg-border mx-1\" />\n\n {/* Layout presets */}\n {LAYOUT_PRESETS.map((preset) => (\n <button\n key={preset.id}\n onClick={() => handlePreset(preset.id)}\n className={cn(\n 'p-1.5 rounded transition-colors',\n 'text-muted-foreground hover:text-foreground hover:bg-muted'\n )}\n title={formatMessage({ id: preset.labelId })}\n >\n <preset.icon className=\"w-3.5 h-3.5\" />\n </button>\n ))}\n\n {/* Separator */}\n <div className=\"w-px h-5 bg-border mx-1\" />\n\n {/* Fullscreen toggle */}\n <button\n onClick={onToggleFullscreen}\n className={cn(\n 'p-1.5 rounded transition-colors',\n isFullscreen\n ? 'bg-primary/10 text-primary'\n : 'text-muted-foreground hover:text-foreground hover:bg-muted'\n )}\n title={isFullscreen\n ? formatMessage({ id: 'terminalDashboard.toolbar.exitFullscreen', defaultMessage: 'Exit Fullscreen' })\n : formatMessage({ id: 'terminalDashboard.toolbar.fullscreen', defaultMessage: 'Fullscreen' })\n }\n >\n {isFullscreen ? (\n <Minimize2 className=\"w-3.5 h-3.5\" />\n ) : (\n <Maximize2 className=\"w-3.5 h-3.5\" />\n )}\n </button>\n\n {/* Right-aligned title */}\n <span className=\"ml-auto text-xs text-muted-foreground font-medium\">\n {formatMessage({ id: 'terminalDashboard.page.title' })}\n </span>\n </div>\n\n <CliConfigModal\n isOpen={isConfigOpen}\n onClose={() => setIsConfigOpen(false)}\n defaultWorkingDir={projectPath}\n onCreateSession={handleCreateConfiguredSession}\n />\n </>\n );\n}\n\n// ========== Toolbar Button ==========\n\nfunction ToolbarButton({\n icon: Icon,\n label,\n isActive,\n onClick,\n badge,\n dot,\n loading,\n}: {\n icon: React.ComponentType<{ className?: string }>;\n label: string;\n isActive: boolean;\n onClick: () => void;\n badge?: number;\n dot?: boolean;\n loading?: boolean;\n}) {\n return (\n <button\n onClick={onClick}\n className={cn(\n 'flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-xs transition-colors',\n isActive\n ? 'bg-primary/10 text-primary font-medium'\n : 'text-muted-foreground hover:text-foreground hover:bg-muted'\n )}\n >\n {loading ? (\n <Loader2 className=\"w-3.5 h-3.5 animate-spin\" />\n ) : (\n <Icon className=\"w-3.5 h-3.5\" />\n )}\n <span>{label}</span>\n {badge !== undefined && badge > 0 && (\n <Badge variant=\"secondary\" className=\"text-[10px] px-1.5 py-0 ml-0.5\">\n {badge}\n </Badge>\n )}\n {dot && (\n <span\n className={cn(\n 'ml-0.5 w-2 h-2 rounded-full bg-primary shrink-0',\n loading && 'animate-pulse'\n )}\n />\n )}\n </button>\n );\n}\n","// ========================================\n// CCW Artifacts - Types & Detection\n// ========================================\n\nexport type ArtifactType =\n | 'workflow-session'\n | 'lite-session'\n | 'claude-md'\n | 'ccw-config'\n | 'issue';\n\nexport interface CcArtifact {\n type: ArtifactType;\n path: string;\n}\n\nconst TRAILING_PUNCTUATION = /[)\\]}>,.;:!?]+$/g;\nconst WRAP_QUOTES = /^['\"`]+|['\"`]+$/g;\n\nfunction normalizePath(raw: string): string {\n return raw.trim().replace(WRAP_QUOTES, '').replace(TRAILING_PUNCTUATION, '');\n}\n\n/**\n * Patterns for detecting CCW-related artifacts in terminal output.\n *\n * Notes:\n * - Prefer relative paths (e.g., `.workflow/...`) so callers can resolve against a project root.\n * - Keep patterns conservative to reduce false positives in generic logs.\n */\nexport const ARTIFACT_PATTERNS: Record<ArtifactType, RegExp[]> = {\n 'workflow-session': [\n /(?:^|[^\\w.])(\\.workflow[\\\\/](?:active|archives)[\\\\/][^\\s\"'`]+[\\\\/]workflow-session\\.json)\\b/g,\n ],\n 'lite-session': [\n /(?:^|[^\\w.])(\\.workflow[\\\\/]\\.lite-plan[\\\\/][^\\s\"'`]+)\\b/g,\n ],\n 'claude-md': [\n /([^\\s\"'`]*CLAUDE\\.md)\\b/gi,\n ],\n 'ccw-config': [\n /(?:^|[^\\w.])(\\.ccw[\\\\/][^\\s\"'`]+)\\b/g,\n /(?:^|[^\\w.])(ccw\\.config\\.(?:json|ya?ml|toml))\\b/gi,\n ],\n issue: [\n /(?:^|[^\\w.])(\\.workflow[\\\\/]issues[\\\\/][^\\s\"'`]+)\\b/g,\n ],\n};\n\n/**\n * Detect CCW artifacts from an arbitrary text blob.\n *\n * Returns a de-duplicated list of `{ type, path }` in discovery order.\n */\nexport function detectCcArtifacts(text: string): CcArtifact[] {\n if (!text) return [];\n\n const candidates: Array<CcArtifact & { index: number }> = [];\n\n for (const type of Object.keys(ARTIFACT_PATTERNS) as ArtifactType[]) {\n for (const pattern of ARTIFACT_PATTERNS[type]) {\n pattern.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(text)) !== null) {\n const raw = match[1] ?? match[0];\n const path = normalizePath(raw);\n if (!path) continue;\n\n const full = match[0] ?? '';\n const group = match[1] ?? raw;\n const rel = full.indexOf(group);\n const index = (match.index ?? 0) + (rel >= 0 ? rel : 0);\n\n candidates.push({ type, path, index });\n }\n }\n }\n\n candidates.sort((a, b) => a.index - b.index);\n\n const results: CcArtifact[] = [];\n const seen = new Set<string>();\n for (const c of candidates) {\n const key = `${c.type}:${c.path}`;\n if (seen.has(key)) continue;\n seen.add(key);\n results.push({ type: c.type, path: c.path });\n }\n\n return results;\n}\n","// ========================================\n// ArtifactTag Component\n// ========================================\n// Colored, clickable tag for detected CCW artifacts in terminal output.\n\nimport { useIntl } from 'react-intl';\nimport { cn } from '@/lib/utils';\nimport { badgeVariants } from '@/components/ui/Badge';\nimport type { ArtifactType } from '@/lib/ccw-artifacts';\n\nexport interface ArtifactTagProps {\n type: ArtifactType;\n path: string;\n onClick?: (path: string) => void;\n className?: string;\n}\n\nfunction getVariant(type: ArtifactType) {\n switch (type) {\n case 'workflow-session':\n return 'info';\n case 'lite-session':\n return 'success';\n case 'claude-md':\n return 'review';\n case 'ccw-config':\n return 'warning';\n case 'issue':\n return 'destructive';\n default:\n return 'secondary';\n }\n}\n\nfunction getLabelId(type: ArtifactType): string {\n switch (type) {\n case 'workflow-session':\n return 'terminalDashboard.artifacts.types.workflowSession';\n case 'lite-session':\n return 'terminalDashboard.artifacts.types.liteSession';\n case 'claude-md':\n return 'terminalDashboard.artifacts.types.claudeMd';\n case 'ccw-config':\n return 'terminalDashboard.artifacts.types.ccwConfig';\n case 'issue':\n return 'terminalDashboard.artifacts.types.issue';\n }\n}\n\nfunction basename(p: string): string {\n const parts = p.split(/[\\\\/]/g);\n return parts[parts.length - 1] || p;\n}\n\nexport function ArtifactTag({ type, path, onClick, className }: ArtifactTagProps) {\n const { formatMessage } = useIntl();\n const label = formatMessage({ id: getLabelId(type) });\n const display = basename(path);\n\n return (\n <button\n type=\"button\"\n className={cn(\n badgeVariants({ variant: getVariant(type) as any }),\n 'gap-1 cursor-pointer hover:opacity-90 active:opacity-100',\n 'px-2 py-0.5 text-[11px] font-semibold',\n className\n )}\n onClick={() => onClick?.(path)}\n title={path}\n >\n <span>{label}</span>\n <span className=\"opacity-80 font-mono\">{display}</span>\n </button>\n );\n}\n\nexport default ArtifactTag;\n","// ========================================\n// TerminalInstance Component\n// ========================================\n// xterm.js terminal wrapper for the Terminal Dashboard.\n// Reuses exact integration pattern from TerminalMainArea:\n// XTerm instance in ref, FitAddon, ResizeObserver, batched PTY input (30ms),\n// output chunk streaming from cliSessionStore.\n\nimport { useEffect, useRef, useCallback, useState } from 'react';\nimport { Terminal as XTerm } from 'xterm';\nimport { FitAddon } from 'xterm-addon-fit';\nimport { useCliSessionStore } from '@/stores/cliSessionStore';\nimport { useSessionManagerStore } from '@/stores/sessionManagerStore';\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\nimport {\n fetchCliSessionBuffer,\n sendCliSessionText,\n resizeCliSession,\n} from '@/lib/api';\nimport { cn } from '@/lib/utils';\nimport { detectCcArtifacts, type CcArtifact } from '@/lib/ccw-artifacts';\nimport { ArtifactTag } from './ArtifactTag';\n\n// ========== Types ==========\n\ninterface TerminalInstanceProps {\n /** Session key to render terminal for */\n sessionId: string;\n /** Additional CSS classes */\n className?: string;\n /** Optional callback to reveal a detected artifact path (e.g. open file browser) */\n onRevealPath?: (path: string) => void;\n}\n\n// ========== Component ==========\n\nconst ARTIFACT_DEBOUNCE_MS = 250;\nconst MAX_ARTIFACT_TAGS = 12;\n\nfunction isAbsolutePath(p: string): boolean {\n if (!p) return false;\n if (p.startsWith('/') || p.startsWith('\\\\')) return true;\n if (/^[A-Za-z]:[\\\\/]/.test(p)) return true;\n if (p.startsWith('~')) return true;\n return false;\n}\n\nfunction joinPath(base: string, relative: string): string {\n const sep = base.includes('\\\\') ? '\\\\' : '/';\n const b = base.replace(/[\\\\/]+$/, '');\n const r = relative.replace(/^[\\\\/]+/, '');\n return `${b}${sep}${r}`;\n}\n\nfunction resolveArtifactPath(path: string, projectPath: string | null): string {\n if (!path) return path;\n if (isAbsolutePath(path)) return path;\n if (!projectPath) return path;\n return joinPath(projectPath, path);\n}\n\nfunction mergeArtifacts(prev: CcArtifact[], next: CcArtifact[]): CcArtifact[] {\n if (next.length === 0) return prev;\n const map = new Map<string, CcArtifact>();\n for (const a of prev) map.set(`${a.type}:${a.path}`, a);\n let changed = false;\n for (const a of next) {\n const key = `${a.type}:${a.path}`;\n if (map.has(key)) continue;\n map.set(key, a);\n changed = true;\n }\n if (!changed) return prev;\n const merged = Array.from(map.values());\n return merged.length > MAX_ARTIFACT_TAGS ? merged.slice(merged.length - MAX_ARTIFACT_TAGS) : merged;\n}\n\nexport function TerminalInstance({ sessionId, className, onRevealPath }: TerminalInstanceProps) {\n const projectPath = useWorkflowStore(selectProjectPath);\n\n // cliSessionStore selectors\n const outputChunks = useCliSessionStore((s) => s.outputChunks);\n const setBuffer = useCliSessionStore((s) => s.setBuffer);\n const clearOutput = useCliSessionStore((s) => s.clearOutput);\n\n const [artifacts, setArtifacts] = useState<CcArtifact[]>([]);\n\n // ========== xterm Refs ==========\n\n const terminalHostRef = useRef<HTMLDivElement | null>(null);\n const xtermRef = useRef<XTerm | null>(null);\n const fitAddonRef = useRef<FitAddon | null>(null);\n const lastChunkIndexRef = useRef<number>(0);\n\n // Debounced artifact detection\n const pendingArtifactTextRef = useRef<string>('');\n const artifactTimerRef = useRef<number | null>(null);\n\n // PTY input batching (30ms, matching TerminalMainArea)\n const pendingInputRef = useRef<string>('');\n const flushTimerRef = useRef<number | null>(null);\n\n // Track sessionId in a ref so xterm onData callback always has latest value\n const sessionIdRef = useRef<string>(sessionId);\n sessionIdRef.current = sessionId;\n\n const projectPathRef = useRef<string | null>(projectPath);\n projectPathRef.current = projectPath;\n\n // Focus terminal when clicked\n const handleTerminalClick = useCallback(() => {\n xtermRef.current?.focus();\n }, []);\n\n const handleArtifactClick = useCallback((path: string) => {\n const resolved = resolveArtifactPath(path, projectPathRef.current);\n navigator.clipboard.writeText(resolved).catch((err) => {\n console.error('[TerminalInstance] copy artifact path failed:', err);\n });\n onRevealPath?.(resolved);\n }, [onRevealPath]);\n\n const scheduleArtifactParse = useCallback((text: string) => {\n if (!text) return;\n pendingArtifactTextRef.current += text;\n if (artifactTimerRef.current !== null) return;\n artifactTimerRef.current = window.setTimeout(() => {\n artifactTimerRef.current = null;\n const pending = pendingArtifactTextRef.current;\n pendingArtifactTextRef.current = '';\n const detected = detectCcArtifacts(pending);\n if (detected.length === 0) return;\n setArtifacts((prev) => mergeArtifacts(prev, detected));\n }, ARTIFACT_DEBOUNCE_MS);\n }, []);\n\n useEffect(() => {\n return () => {\n if (artifactTimerRef.current !== null) {\n window.clearTimeout(artifactTimerRef.current);\n artifactTimerRef.current = null;\n }\n };\n }, []);\n\n // ========== PTY Input Batching ==========\n\n const flushInput = useCallback(async () => {\n const key = sessionIdRef.current;\n if (!key) return;\n const pending = pendingInputRef.current;\n pendingInputRef.current = '';\n if (!pending) return;\n try {\n await sendCliSessionText(\n key,\n { text: pending, appendNewline: false },\n projectPathRef.current || undefined\n );\n } catch {\n // Ignore transient failures\n }\n }, []);\n\n const scheduleFlush = useCallback(() => {\n if (flushTimerRef.current !== null) return;\n flushTimerRef.current = window.setTimeout(async () => {\n flushTimerRef.current = null;\n await flushInput();\n }, 30);\n }, [flushInput]);\n\n // ========== xterm Lifecycle ==========\n\n // Initialize xterm instance (once per mount)\n useEffect(() => {\n if (!terminalHostRef.current) return;\n if (xtermRef.current) return;\n\n const term = new XTerm({\n convertEol: true,\n cursorBlink: true,\n fontFamily:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n fontSize: 12,\n scrollback: 5000,\n });\n const fitAddon = new FitAddon();\n term.loadAddon(fitAddon);\n term.open(terminalHostRef.current);\n fitAddon.fit();\n\n // Forward keystrokes to backend (batched 30ms)\n term.onData((data) => {\n if (!sessionIdRef.current) return;\n pendingInputRef.current += data;\n scheduleFlush();\n });\n\n xtermRef.current = term;\n fitAddonRef.current = fitAddon;\n\n return () => {\n // Flush any pending input before cleanup\n if (flushTimerRef.current !== null) {\n window.clearTimeout(flushTimerRef.current);\n flushTimerRef.current = null;\n }\n try {\n term.dispose();\n } finally {\n xtermRef.current = null;\n fitAddonRef.current = null;\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Attach to session: clear terminal and load buffer\n useEffect(() => {\n const term = xtermRef.current;\n const fitAddon = fitAddonRef.current;\n if (!term || !fitAddon) return;\n\n lastChunkIndexRef.current = 0;\n term.reset();\n term.clear();\n\n // Reset artifact detection state per session\n setArtifacts([]);\n pendingArtifactTextRef.current = '';\n if (artifactTimerRef.current !== null) {\n window.clearTimeout(artifactTimerRef.current);\n artifactTimerRef.current = null;\n }\n\n if (!sessionId) return;\n clearOutput(sessionId);\n\n fetchCliSessionBuffer(sessionId, projectPath || undefined)\n .then(({ buffer }) => {\n setBuffer(sessionId, buffer || '');\n })\n .catch(() => {\n // ignore\n })\n .finally(() => {\n fitAddon.fit();\n });\n }, [sessionId, projectPath, setBuffer, clearOutput]);\n\n // Stream new output chunks into xterm and forward to monitor worker\n useEffect(() => {\n const term = xtermRef.current;\n if (!term || !sessionId) return;\n\n const chunks = outputChunks[sessionId] ?? [];\n const start = lastChunkIndexRef.current;\n if (start >= chunks.length) return;\n\n const { feedMonitor } = useSessionManagerStore.getState();\n const newTextParts: string[] = [];\n for (let i = start; i < chunks.length; i++) {\n term.write(chunks[i].data);\n feedMonitor(sessionId, chunks[i].data);\n newTextParts.push(chunks[i].data);\n }\n lastChunkIndexRef.current = chunks.length;\n\n if (newTextParts.length > 0) {\n scheduleArtifactParse(newTextParts.join(''));\n }\n }, [outputChunks, sessionId, scheduleArtifactParse]);\n\n // ResizeObserver -> fit + resize backend\n useEffect(() => {\n const host = terminalHostRef.current;\n const term = xtermRef.current;\n const fitAddon = fitAddonRef.current;\n if (!host || !term || !fitAddon) return;\n\n const resize = () => {\n fitAddon.fit();\n if (sessionIdRef.current) {\n void (async () => {\n try {\n await resizeCliSession(\n sessionIdRef.current,\n { cols: term.cols, rows: term.rows },\n projectPathRef.current || undefined\n );\n } catch {\n // ignore\n }\n })();\n }\n };\n\n const ro = new ResizeObserver(resize);\n ro.observe(host);\n return () => ro.disconnect();\n }, [sessionId, projectPath]);\n\n // ========== Render ==========\n\n return (\n <div className={cn('relative h-full w-full', className)}>\n {artifacts.length > 0 && (\n <div className=\"absolute top-2 left-2 right-2 z-10 flex flex-wrap gap-1 pointer-events-none\">\n {artifacts.map((a) => (\n <ArtifactTag\n key={`${a.type}:${a.path}`}\n type={a.type}\n path={a.path}\n onClick={handleArtifactClick}\n className=\"pointer-events-auto\"\n />\n ))}\n </div>\n )}\n <div ref={terminalHostRef} className=\"h-full w-full bg-black/90\" onClick={handleTerminalClick} />\n </div>\n );\n}\n","// ========================================\n// TerminalPane Component\n// ========================================\n// Single terminal pane = PaneToolbar + content area.\n// Content can be terminal output or file preview based on displayMode.\n// Renders within the TerminalGrid recursive layout.\n// File preview is triggered from right sidebar FileSidebarPanel.\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useIntl } from 'react-intl';\nimport {\n SplitSquareHorizontal,\n SplitSquareVertical,\n Eraser,\n AlertTriangle,\n X,\n Terminal,\n ChevronDown,\n RotateCcw,\n Pause,\n Play,\n Loader2,\n FileText,\n ArrowLeft,\n LogOut,\n WifiOff,\n} from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport { TerminalInstance } from './TerminalInstance';\nimport { FilePreview } from '@/components/shared/FilePreview';\nimport {\n AlertDialog,\n AlertDialogContent,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogAction,\n AlertDialogCancel,\n} from '@/components/ui/AlertDialog';\nimport {\n useTerminalGridStore,\n selectTerminalGridPanes,\n selectTerminalGridFocusedPaneId,\n} from '@/stores/terminalGridStore';\nimport {\n useSessionManagerStore,\n selectTerminalMetas,\n} from '@/stores/sessionManagerStore';\nimport {\n useIssueQueueIntegrationStore,\n selectAssociationChain,\n} from '@/stores/issueQueueIntegrationStore';\nimport { useCliSessionStore } from '@/stores/cliSessionStore';\nimport { getAllPaneIds } from '@/lib/layout-utils';\nimport { useFileContent } from '@/hooks/useFileExplorer';\nimport type { PaneId } from '@/stores/viewerStore';\nimport type { TerminalStatus } from '@/types/terminal-dashboard';\n\n// ========== Status Styles ==========\n\nconst statusDotStyles: Record<TerminalStatus, string> = {\n active: 'bg-green-500',\n idle: 'bg-gray-400',\n error: 'bg-red-500',\n paused: 'bg-yellow-500',\n resuming: 'bg-blue-400 animate-pulse',\n locked: 'bg-amber-500 animate-pulse',\n};\n\n// ========== Props ==========\n\ninterface TerminalPaneProps {\n paneId: PaneId;\n}\n\n// ========== Component ==========\n\nexport function TerminalPane({ paneId }: TerminalPaneProps) {\n const { formatMessage } = useIntl();\n\n // Grid store\n const panes = useTerminalGridStore(selectTerminalGridPanes);\n const focusedPaneId = useTerminalGridStore(selectTerminalGridFocusedPaneId);\n const layout = useTerminalGridStore((s) => s.layout);\n const splitPane = useTerminalGridStore((s) => s.splitPane);\n const closePane = useTerminalGridStore((s) => s.closePane);\n const assignSession = useTerminalGridStore((s) => s.assignSession);\n const setFocused = useTerminalGridStore((s) => s.setFocused);\n const setPaneDisplayMode = useTerminalGridStore((s) => s.setPaneDisplayMode);\n\n const pane = panes[paneId];\n const sessionId = pane?.sessionId ?? null;\n const displayMode = pane?.displayMode ?? 'terminal';\n const filePath = pane?.filePath ?? null;\n const isFocused = focusedPaneId === paneId;\n const canClose = getAllPaneIds(layout).length > 1;\n const isFileMode = displayMode === 'file' && filePath;\n\n // Session data\n const terminalMetas = useSessionManagerStore(selectTerminalMetas);\n const sessions = useCliSessionStore((s) => s.sessions);\n\n // Session lifecycle actions\n const pauseSession = useSessionManagerStore((s) => s.pauseSession);\n const resumeSession = useSessionManagerStore((s) => s.resumeSession);\n const restartSession = useSessionManagerStore((s) => s.restartSession);\n const closeSession = useSessionManagerStore((s) => s.closeSession);\n\n // Action loading states\n const [isRestarting, setIsRestarting] = useState(false);\n const [isTogglingPause, setIsTogglingPause] = useState(false);\n const [isClosingSession, setIsClosingSession] = useState(false);\n const [isCloseConfirmOpen, setIsCloseConfirmOpen] = useState(false);\n\n // File content for preview mode\n const { content: fileContent, isLoading: isFileLoading, error: fileError } = useFileContent(filePath, {\n enabled: displayMode === 'file' && !!filePath,\n });\n\n // Association chain for linked issue badge\n const associationChain = useIssueQueueIntegrationStore(selectAssociationChain);\n const linkedIssueId = useMemo(() => {\n if (!sessionId || !associationChain) return null;\n if (associationChain.sessionId === sessionId) return associationChain.issueId;\n return null;\n }, [sessionId, associationChain]);\n\n // Terminal metadata\n const meta = sessionId ? terminalMetas[sessionId] : null;\n const status: TerminalStatus = meta?.status ?? 'idle';\n const alertCount = meta?.alertCount ?? 0;\n\n // Check if session exists - handles case where pane references a sessionId\n // that no longer exists in cliSessionStore (e.g., after page refresh if backend restarted)\n const isSessionNotFound = sessionId && !sessions[sessionId];\n\n // Clear invalid sessionId after showing the message\n useEffect(() => {\n if (isSessionNotFound) {\n const timer = setTimeout(() => {\n assignSession(paneId, null);\n }, 3000); // Clear after 3 seconds to let user see the message\n return () => clearTimeout(timer);\n }\n }, [isSessionNotFound, paneId, assignSession]);\n\n // Build session options for dropdown\n // Use sessions from cliSessionStore directly (all sessions, not just grouped ones)\n const sessionOptions = useMemo(() => {\n const allSessionIds = Object.keys(sessions);\n return allSessionIds.map((sid) => {\n const s = sessions[sid];\n const name = s ? (s.tool ? `${s.tool} - ${s.shellKind}` : s.shellKind) : sid;\n return { id: sid, name };\n });\n }, [sessions]);\n\n // Handlers\n const handleFocus = useCallback(() => {\n setFocused(paneId);\n }, [paneId, setFocused]);\n\n const handleSplitH = useCallback(() => {\n splitPane(paneId, 'horizontal');\n }, [paneId, splitPane]);\n\n const handleSplitV = useCallback(() => {\n splitPane(paneId, 'vertical');\n }, [paneId, splitPane]);\n\n const handleClose = useCallback(() => {\n // If pane has an active session, show confirmation dialog\n if (sessionId) {\n setIsCloseConfirmOpen(true);\n } else {\n closePane(paneId);\n }\n }, [paneId, sessionId, closePane]);\n\n const handleCloseConfirm = useCallback(() => {\n closePane(paneId);\n setIsCloseConfirmOpen(false);\n }, [paneId, closePane]);\n\n const handleSessionChange = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n const value = e.target.value;\n const session = value ? sessions[value] : null;\n assignSession(paneId, value || null, session?.cliTool ?? session?.tool ?? null);\n },\n [paneId, assignSession, sessions]\n );\n\n const handleClear = useCallback(() => {\n // Clear is handled by re-assigning the same session (triggers reset in TerminalInstance)\n if (sessionId) {\n assignSession(paneId, null);\n // Use microtask to re-assign after clearing\n queueMicrotask(() => assignSession(paneId, sessionId));\n }\n }, [paneId, sessionId, assignSession]);\n\n const handleRestart = useCallback(async () => {\n if (!sessionId || isRestarting) return;\n setIsRestarting(true);\n try {\n await restartSession(sessionId);\n } catch (error) {\n console.error('[TerminalPane] Restart failed:', error);\n } finally {\n setIsRestarting(false);\n }\n }, [sessionId, isRestarting, restartSession]);\n\n const handleTogglePause = useCallback(async () => {\n if (!sessionId || isTogglingPause) return;\n setIsTogglingPause(true);\n try {\n if (status === 'paused') {\n await resumeSession(sessionId);\n } else if (status === 'active' || status === 'idle') {\n await pauseSession(sessionId);\n }\n } catch (error) {\n console.error('[TerminalPane] Toggle pause failed:', error);\n } finally {\n setIsTogglingPause(false);\n }\n }, [sessionId, isTogglingPause, status, pauseSession, resumeSession]);\n\n const handleCloseSession = useCallback(async () => {\n if (!sessionId || isClosingSession) return;\n setIsClosingSession(true);\n try {\n await closeSession(sessionId);\n // Clear the pane's session after closing\n assignSession(paneId, null);\n } catch (error) {\n console.error('[TerminalPane] Close session failed:', error);\n } finally {\n setIsClosingSession(false);\n }\n }, [sessionId, isClosingSession, closeSession, paneId, assignSession]);\n\n // Handle back to terminal from file preview\n const handleBackToTerminal = useCallback(() => {\n setPaneDisplayMode(paneId, 'terminal');\n }, [paneId, setPaneDisplayMode]);\n\n return (\n <div\n className={cn(\n 'flex flex-col h-full border border-border/50 rounded-sm overflow-hidden',\n isFocused && 'ring-1 ring-primary/40'\n )}\n onClick={handleFocus}\n >\n {/* PaneToolbar */}\n <div className=\"flex items-center justify-between gap-1 px-2 py-1 border-b border-border bg-muted/30 shrink-0 overflow-hidden\">\n {/* Left: Session selector + status (or file path in file mode) */}\n <div className=\"flex items-center gap-1.5 min-w-0 overflow-hidden\">\n {isFileMode ? (\n // File mode header\n <>\n <button\n onClick={handleBackToTerminal}\n className=\"p-0.5 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-foreground shrink-0\"\n title={formatMessage({ id: 'terminalDashboard.pane.backToTerminal', defaultMessage: 'Back to terminal' })}\n >\n <ArrowLeft className=\"w-3.5 h-3.5\" />\n </button>\n <FileText className=\"w-3.5 h-3.5 text-muted-foreground shrink-0\" />\n <span className=\"text-xs truncate\" title={filePath ?? undefined}>\n {filePath?.split('/').pop() ?? 'File'}\n </span>\n </>\n ) : (\n // Terminal mode header\n <>\n {isSessionNotFound ? (\n <WifiOff className=\"w-3.5 h-3.5 text-yellow-500 shrink-0\" />\n ) : sessionId && (\n <span\n className={cn('w-2 h-2 rounded-full shrink-0', statusDotStyles[status])}\n />\n )}\n <div className=\"relative min-w-0 overflow-hidden\">\n <select\n value={sessionId ?? ''}\n onChange={handleSessionChange}\n className={cn(\n 'text-xs bg-transparent border-none outline-none cursor-pointer',\n 'appearance-none pr-4 max-w-[140px] truncate',\n !sessionId && 'text-muted-foreground'\n )}\n >\n <option value=\"\">\n {formatMessage({ id: 'terminalDashboard.pane.selectSession' })}\n </option>\n {sessionOptions.map((opt) => (\n <option key={opt.id} value={opt.id}>\n {opt.name}\n </option>\n ))}\n </select>\n <ChevronDown className=\"absolute right-0 top-1/2 -translate-y-1/2 w-3 h-3 text-muted-foreground pointer-events-none\" />\n </div>\n </>\n )}\n </div>\n\n {/* Center: Linked issue badge */}\n {linkedIssueId && !isFileMode && (\n <span className=\"text-[10px] font-mono px-1.5 py-0.5 rounded bg-primary/10 text-primary shrink-0 hidden sm:inline-flex\">\n {linkedIssueId}\n </span>\n )}\n\n {/* Right: Action buttons */}\n <div className=\"flex items-center gap-0.5 shrink-0\">\n <button\n onClick={handleSplitH}\n className=\"p-1 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-foreground\"\n title={formatMessage({ id: 'terminalDashboard.pane.splitHorizontal' })}\n >\n <SplitSquareHorizontal className=\"w-3.5 h-3.5\" />\n </button>\n <button\n onClick={handleSplitV}\n className=\"p-1 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-foreground\"\n title={formatMessage({ id: 'terminalDashboard.pane.splitVertical' })}\n >\n <SplitSquareVertical className=\"w-3.5 h-3.5\" />\n </button>\n {!isFileMode && sessionId && !isSessionNotFound && (\n <>\n {/* Restart button */}\n <button\n onClick={handleRestart}\n disabled={isRestarting}\n className={cn(\n 'p-1 rounded hover:bg-muted transition-colors',\n isRestarting ? 'text-muted-foreground/50' : 'text-muted-foreground hover:text-foreground'\n )}\n title={formatMessage({ id: 'terminalDashboard.pane.restart' })}\n >\n {isRestarting ? (\n <Loader2 className=\"w-3.5 h-3.5 animate-spin\" />\n ) : (\n <RotateCcw className=\"w-3.5 h-3.5\" />\n )}\n </button>\n {/* Pause/Resume toggle button */}\n <button\n onClick={handleTogglePause}\n disabled={isTogglingPause || status === 'resuming'}\n className={cn(\n 'p-1 rounded hover:bg-muted transition-colors',\n isTogglingPause || status === 'resuming'\n ? 'text-muted-foreground/50'\n : status === 'paused'\n ? 'text-yellow-500 hover:text-yellow-600'\n : 'text-muted-foreground hover:text-foreground'\n )}\n title={formatMessage({\n id: status === 'paused'\n ? 'terminalDashboard.pane.resume'\n : 'terminalDashboard.pane.pause',\n })}\n >\n {isTogglingPause || status === 'resuming' ? (\n <Loader2 className=\"w-3.5 h-3.5 animate-spin\" />\n ) : status === 'paused' ? (\n <Play className=\"w-3.5 h-3.5\" />\n ) : (\n <Pause className=\"w-3.5 h-3.5\" />\n )}\n </button>\n {/* Clear terminal button */}\n <button\n onClick={handleClear}\n className=\"p-1 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-foreground\"\n title={formatMessage({ id: 'terminalDashboard.pane.clearTerminal' })}\n >\n <Eraser className=\"w-3.5 h-3.5\" />\n </button>\n {/* Close session button */}\n <button\n onClick={handleCloseSession}\n disabled={isClosingSession}\n className={cn(\n 'p-1 rounded hover:bg-muted transition-colors',\n isClosingSession\n ? 'text-muted-foreground/50'\n : 'text-muted-foreground hover:text-destructive'\n )}\n title={formatMessage({ id: 'terminalDashboard.pane.closeSession' })}\n >\n {isClosingSession ? (\n <Loader2 className=\"w-3.5 h-3.5 animate-spin\" />\n ) : (\n <LogOut className=\"w-3.5 h-3.5\" />\n )}\n </button>\n </>\n )}\n {alertCount > 0 && !isFileMode && (\n <span className=\"flex items-center gap-0.5 px-1 text-destructive\">\n <AlertTriangle className=\"w-3 h-3\" />\n <span className=\"text-[10px] font-semibold tabular-nums\">\n {alertCount > 99 ? '99+' : alertCount}\n </span>\n </span>\n )}\n {canClose && (\n <button\n onClick={handleClose}\n className=\"p-1 rounded hover:bg-destructive/10 transition-colors text-muted-foreground hover:text-destructive\"\n title={formatMessage({ id: 'terminalDashboard.pane.closePane' })}\n >\n <X className=\"w-3.5 h-3.5\" />\n </button>\n )}\n </div>\n </div>\n\n {/* Content area */}\n {isFileMode ? (\n // File preview mode\n <div className=\"flex-1 min-h-0\">\n <FilePreview\n fileContent={fileContent}\n isLoading={isFileLoading}\n error={fileError?.message ?? null}\n className=\"h-full\"\n />\n </div>\n ) : isSessionNotFound ? (\n // Session not found state - pane references a sessionId that no longer exists\n <div className=\"flex-1 flex items-center justify-center text-muted-foreground\">\n <div className=\"text-center px-4\">\n <WifiOff className=\"h-6 w-6 mx-auto mb-1.5 text-yellow-500\" />\n <p className=\"text-sm font-medium text-foreground\">\n {formatMessage({ id: 'terminalDashboard.pane.sessionNotFound' })}\n </p>\n <p className=\"text-xs mt-1 opacity-70 max-w-[200px]\">\n {formatMessage({ id: 'terminalDashboard.pane.sessionNotFoundHint' })}\n </p>\n </div>\n </div>\n ) : sessionId ? (\n // Terminal mode with session\n <div className=\"flex-1 min-h-0\">\n <TerminalInstance sessionId={sessionId} />\n </div>\n ) : (\n // Empty terminal state\n <div className=\"flex-1 flex items-center justify-center text-muted-foreground\">\n <div className=\"text-center\">\n <Terminal className=\"h-6 w-6 mx-auto mb-1.5 opacity-30\" />\n <p className=\"text-sm\">\n {formatMessage({ id: 'terminalDashboard.pane.selectSession' })}\n </p>\n <p className=\"text-xs mt-1 opacity-70\">\n {formatMessage({ id: 'terminalDashboard.pane.selectSessionHint' })}\n </p>\n </div>\n </div>\n )}\n\n {/* Close Pane Confirmation Dialog */}\n <AlertDialog open={isCloseConfirmOpen} onOpenChange={setIsCloseConfirmOpen}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n {formatMessage({ id: 'terminalDashboard.pane.closeConfirmTitle' })}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {formatMessage({ id: 'terminalDashboard.pane.closeConfirmMessage' })}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>\n {formatMessage({ id: 'common.actions.cancel' })}\n </AlertDialogCancel>\n <AlertDialogAction onClick={handleCloseConfirm}>\n {formatMessage({ id: 'terminalDashboard.pane.closeConfirmAction' })}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n","// ========================================\r\n// TerminalGrid Component\r\n// ========================================\r\n// Recursive Allotment renderer for the terminal split pane layout.\r\n// Mirrors the LayoutContainer pattern from cli-viewer but renders\r\n// TerminalPane components as leaf nodes.\r\n\r\nimport { useCallback, useMemo } from 'react';\r\nimport { Allotment } from 'allotment';\r\nimport 'allotment/dist/style.css';\r\nimport { cn } from '@/lib/utils';\r\nimport { isPaneId } from '@/lib/layout-utils';\r\nimport {\r\n useTerminalGridStore,\r\n selectTerminalGridLayout,\r\n selectTerminalGridPanes,\r\n} from '@/stores/terminalGridStore';\r\nimport type { AllotmentLayoutGroup } from '@/stores/viewerStore';\r\nimport { TerminalPane } from './TerminalPane';\r\n\r\n// ========== Types ==========\r\n\r\ninterface GridGroupRendererProps {\r\n group: AllotmentLayoutGroup;\r\n minSize: number;\r\n depth?: number;\r\n}\r\n\r\n// ========== Recursive Group Renderer ==========\r\n\r\nfunction GridGroupRenderer({ group, minSize, depth = 0 }: GridGroupRendererProps) {\r\n const panes = useTerminalGridStore(selectTerminalGridPanes);\r\n const updateLayoutSizes = useTerminalGridStore((s) => s.updateLayoutSizes);\r\n\r\n const handleChange = useCallback(\r\n (sizes: number[]) => {\r\n updateLayoutSizes(sizes);\r\n },\r\n [updateLayoutSizes]\r\n );\r\n\r\n const validChildren = useMemo(() => {\r\n return group.children.filter((child) => {\r\n if (isPaneId(child)) {\r\n return panes[child] !== undefined;\r\n }\r\n return true;\r\n });\r\n }, [group.children, panes]);\r\n\r\n if (validChildren.length === 0) {\r\n return null;\r\n }\r\n\r\n // Generate stable key based on children\r\n const groupKey = useMemo(() => {\r\n return validChildren.map(c => isPaneId(c) ? c : 'group').join('-');\r\n }, [validChildren]);\r\n\r\n return (\r\n <Allotment\r\n key={groupKey}\r\n vertical={group.direction === 'vertical'}\r\n defaultSizes={group.sizes}\r\n onChange={handleChange}\r\n >\r\n {validChildren.map((child, index) => (\r\n <Allotment.Pane key={isPaneId(child) ? child : `group-${depth}-${index}`} minSize={minSize}>\r\n {isPaneId(child) ? (\r\n <TerminalPane paneId={child} />\r\n ) : (\r\n <GridGroupRenderer\r\n group={child}\r\n minSize={minSize}\r\n depth={depth + 1}\r\n />\r\n )}\r\n </Allotment.Pane>\r\n ))}\r\n </Allotment>\r\n );\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\nexport function TerminalGrid({ className }: { className?: string }) {\r\n const layout = useTerminalGridStore(selectTerminalGridLayout);\r\n const panes = useTerminalGridStore(selectTerminalGridPanes);\r\n\r\n const content = useMemo(() => {\r\n if (!layout.children || layout.children.length === 0) {\r\n return null;\r\n }\r\n\r\n // Single pane: render directly without Allotment wrapper\r\n if (layout.children.length === 1 && isPaneId(layout.children[0])) {\r\n const paneId = layout.children[0];\r\n if (!panes[paneId]) return null;\r\n return <TerminalPane paneId={paneId} />;\r\n }\r\n\r\n return (\r\n <GridGroupRenderer\r\n group={layout}\r\n minSize={150}\r\n depth={0}\r\n />\r\n );\r\n }, [layout, panes]);\r\n\r\n return (\r\n <div className={cn('h-full w-full overflow-hidden bg-background', className)}>\r\n {content}\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// SessionGroupTree Component\r\n// ========================================\r\n// Tree view for CLI sessions grouped by tag.\r\n// Sessions are automatically grouped by their tag (e.g., \"gemini-143052\").\r\n\r\nimport { useState, useCallback, useEffect, useMemo } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n ChevronRight,\r\n Terminal,\r\n Tag,\r\n} from 'lucide-react';\r\nimport { cn } from '@/lib/utils';\r\nimport { useSessionManagerStore, selectSessionManagerActiveTerminalId, selectTerminalMetas } from '@/stores';\r\nimport { useCliSessionStore } from '@/stores/cliSessionStore';\r\nimport { useTerminalGridStore, selectTerminalGridPanes } from '@/stores/terminalGridStore';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport type { TerminalStatus } from '@/types/terminal-dashboard';\r\n\r\n// ========== Status Dot Styles ==========\r\n\r\nconst statusDotStyles: Record<TerminalStatus, string> = {\r\n active: 'bg-green-500',\r\n idle: 'bg-gray-400',\r\n error: 'bg-red-500',\r\n paused: 'bg-yellow-500',\r\n resuming: 'bg-blue-400 animate-pulse',\r\n locked: 'bg-purple-500',\r\n};\r\n\r\n// ========== SessionGroupTree Component ==========\r\n\r\nexport function SessionGroupTree() {\r\n const { formatMessage } = useIntl();\r\n const activeTerminalId = useSessionManagerStore(selectSessionManagerActiveTerminalId);\r\n const terminalMetas = useSessionManagerStore(selectTerminalMetas);\r\n const setActiveTerminal = useSessionManagerStore((s) => s.setActiveTerminal);\r\n const sessions = useCliSessionStore((s) => s.sessions);\r\n\r\n // Grid store for pane management\r\n const panes = useTerminalGridStore(selectTerminalGridPanes);\r\n const assignSession = useTerminalGridStore((s) => s.assignSession);\r\n const setFocused = useTerminalGridStore((s) => s.setFocused);\r\n\r\n const [expandedTags, setExpandedTags] = useState<Set<string>>(new Set());\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n useEffect(() => {\r\n setExpandedTags(new Set());\r\n }, [projectPath]);\r\n\r\n const toggleTag = useCallback((tag: string) => {\r\n setExpandedTags((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(tag)) {\r\n next.delete(tag);\r\n } else {\r\n next.add(tag);\r\n }\r\n return next;\r\n });\r\n }, []);\r\n\r\n const handleSessionClick = useCallback(\r\n (sessionId: string) => {\r\n // Set active terminal in session manager\r\n setActiveTerminal(sessionId);\r\n\r\n // Find pane that already has this session, or switch focused pane\r\n const paneWithSession = Object.entries(panes).find(\r\n ([, pane]) => pane.sessionId === sessionId\r\n );\r\n\r\n if (paneWithSession) {\r\n // Focus the pane that has this session\r\n setFocused(paneWithSession[0]);\r\n } else {\r\n // Find focused pane or first pane, and assign session to it\r\n const focusedPaneId = useTerminalGridStore.getState().focusedPaneId;\r\n const targetPaneId = focusedPaneId || Object.keys(panes)[0];\r\n if (targetPaneId) {\r\n const session = sessions[sessionId];\r\n assignSession(targetPaneId, sessionId, session?.cliTool ?? session?.tool ?? null);\r\n setFocused(targetPaneId);\r\n }\r\n }\r\n },\r\n [setActiveTerminal, panes, setFocused, assignSession]\r\n );\r\n\r\n // Group sessions by tag\r\n const sessionsByTag = useMemo(() => {\r\n const groups: Record<string, { tag: string; sessionIds: string[] }> = {};\r\n const untagged: string[] = [];\r\n\r\n for (const sessionKey of Object.keys(sessions)) {\r\n const meta = terminalMetas[sessionKey];\r\n const tag = meta?.tag;\r\n if (tag) {\r\n if (!groups[tag]) {\r\n groups[tag] = { tag, sessionIds: [] };\r\n }\r\n groups[tag].sessionIds.push(sessionKey);\r\n } else {\r\n untagged.push(sessionKey);\r\n }\r\n }\r\n\r\n // Convert to array and sort by tag name (newest first by time suffix)\r\n const result = Object.values(groups).sort((a, b) => b.tag.localeCompare(a.tag));\r\n\r\n // Add untagged sessions at the end\r\n if (untagged.length > 0) {\r\n result.push({ tag: '__untagged__', sessionIds: untagged });\r\n }\r\n\r\n return result;\r\n }, [sessions, terminalMetas]);\r\n\r\n // Build a lookup for session display names\r\n const sessionNames = useMemo(() => {\r\n const map: Record<string, string> = {};\r\n for (const [key, meta] of Object.entries(sessions)) {\r\n map[key] = meta.tool ?? meta.shellKind;\r\n }\r\n return map;\r\n }, [sessions]);\r\n\r\n if (Object.keys(sessions).length === 0) {\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n <div className=\"flex-1 flex flex-col items-center justify-center gap-1.5 text-muted-foreground p-4\">\r\n <Terminal className=\"w-6 h-6 opacity-30\" />\r\n <p className=\"text-xs text-center\">\r\n {formatMessage({ id: 'terminalDashboard.sessionTree.noGroups' })}\r\n </p>\r\n <p className=\"text-[10px] text-muted-foreground/70\">\r\n Click \"New Session\" to create one\r\n </p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n {/* Session list grouped by tag */}\r\n <div className=\"flex-1 overflow-y-auto\">\r\n {sessionsByTag.map((group) => {\r\n const isExpanded = expandedTags.has(group.tag);\r\n const isUntagged = group.tag === '__untagged__';\r\n const displayName = isUntagged ? 'Other Sessions' : group.tag;\r\n\r\n return (\r\n <div key={group.tag} className=\"border-b border-border/50 last:border-b-0\">\r\n {/* Tag header */}\r\n <button\r\n onClick={() => toggleTag(group.tag)}\r\n className={cn(\r\n 'flex items-center gap-1.5 w-full px-3 py-2 text-left',\r\n 'hover:bg-muted/50 transition-colors text-sm'\r\n )}\r\n >\r\n <ChevronRight\r\n className={cn(\r\n 'w-3.5 h-3.5 text-muted-foreground transition-transform shrink-0',\r\n isExpanded && 'rotate-90'\r\n )}\r\n />\r\n <Tag className=\"w-3.5 h-3.5 text-muted-foreground shrink-0\" />\r\n <span className=\"flex-1 truncate font-medium text-xs\">{displayName}</span>\r\n <Badge variant=\"secondary\" className=\"text-[10px] px-1.5 py-0\">\r\n {group.sessionIds.length}\r\n </Badge>\r\n </button>\r\n\r\n {/* Expanded: session list */}\r\n {isExpanded && (\r\n <div className=\"pb-1\">\r\n {group.sessionIds.map((sessionId) => {\r\n const meta = terminalMetas[sessionId];\r\n const sessionStatus: TerminalStatus = meta?.status ?? 'idle';\r\n return (\r\n <div\r\n key={sessionId}\r\n className={cn(\r\n 'flex items-center gap-1.5 mx-1 px-2 py-1.5 rounded-sm cursor-pointer',\r\n 'hover:bg-muted/50 transition-colors text-sm',\r\n activeTerminalId === sessionId && 'bg-primary/10 text-primary'\r\n )}\r\n onClick={() => handleSessionClick(sessionId)}\r\n >\r\n {/* Status indicator dot */}\r\n <span\r\n className={cn('w-2 h-2 rounded-full shrink-0', statusDotStyles[sessionStatus])}\r\n title={sessionStatus}\r\n />\r\n <Terminal className=\"w-3.5 h-3.5 text-muted-foreground shrink-0\" />\r\n <span className=\"flex-1 truncate text-xs\">\r\n {sessionNames[sessionId] ?? sessionId}\r\n </span>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport default SessionGroupTree;\r\n","// ========================================\n// IssuePanel Component\n// ========================================\n// Issue list panel for the terminal dashboard middle column.\n// Consumes existing useIssues() React Query hook for data fetching.\n// Integrates with issueQueueIntegrationStore for selection state\n// and association chain highlighting.\n\nimport { useState, useMemo, useCallback, useEffect, useRef } from 'react';\nimport { useIntl } from 'react-intl';\nimport {\n AlertCircle,\n Loader2,\n AlertTriangle,\n CircleDot,\n Terminal,\n Check,\n Send,\n X,\n ListPlus,\n} from 'lucide-react';\nimport { Badge } from '@/components/ui/Badge';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/Select';\nimport { cn } from '@/lib/utils';\nimport { useIssues } from '@/hooks/useIssues';\nimport {\n useIssueQueueIntegrationStore,\n selectSelectedIssueId,\n selectAssociationChain,\n} from '@/stores/issueQueueIntegrationStore';\nimport { executeInCliSession } from '@/lib/api';\nimport type { Issue } from '@/lib/api';\nimport { useTerminalGridStore, selectTerminalGridFocusedPaneId, selectTerminalGridPanes } from '@/stores/terminalGridStore';\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\nimport { useQueueSchedulerStore } from '@/stores/queueSchedulerStore';\nimport { toast } from '@/stores/notificationStore';\n\n// ========== Execution Method Type ==========\n\ntype ExecutionMethod = 'skill-team-issue' | 'ccw-cli' | 'direct-send';\n\n// ========== Prompt Templates ==========\n\nconst PROMPT_TEMPLATES: Record<ExecutionMethod, (idStr: string) => string> = {\n 'skill-team-issue': (idStr) => `完成 ${idStr} issue`,\n 'ccw-cli': (idStr) => `完成.issue.jsonl中 ${idStr} issue`,\n 'direct-send': (idStr) => `根据@.workflow/issues/issues.jsonl中的 ${idStr} 需求,进行开发`,\n};\n\n// ========== Queue Prompt Builder ==========\n\nfunction buildQueuePrompt(issues: Issue[]): string {\n const ids = issues.map((i) => i.id).join(' ');\n return `根据@.workflow/issues/issues.jsonl中的 ${ids} 需求,进行开发`;\n}\n\n// ========== Priority Badge ==========\n\nconst PRIORITY_STYLES: Record<Issue['priority'], { variant: 'destructive' | 'warning' | 'info' | 'secondary'; label: string }> = {\n critical: { variant: 'destructive', label: 'Critical' },\n high: { variant: 'warning', label: 'High' },\n medium: { variant: 'info', label: 'Medium' },\n low: { variant: 'secondary', label: 'Low' },\n};\n\nfunction PriorityBadge({ priority }: { priority: Issue['priority'] }) {\n const style = PRIORITY_STYLES[priority] ?? PRIORITY_STYLES.medium;\n return (\n <Badge variant={style.variant} className=\"text-[10px] px-1.5 py-0 shrink-0\">\n {style.label}\n </Badge>\n );\n}\n\n// ========== Status Indicator ==========\n\nfunction StatusDot({ status }: { status: Issue['status'] }) {\n const colorMap: Record<Issue['status'], string> = {\n registered: 'text-info',\n planning: 'text-blue-500',\n planned: 'text-blue-600',\n queued: 'text-yellow-500',\n executing: 'text-warning',\n completed: 'text-success',\n failed: 'text-destructive',\n paused: 'text-muted-foreground',\n };\n return <CircleDot className={cn('w-3 h-3 shrink-0', colorMap[status] ?? 'text-muted-foreground')} />;\n}\n\n// ========== Issue Item ==========\n\nfunction IssueItem({\n issue,\n isSelected,\n isHighlighted,\n isChecked,\n onSelect,\n onToggleCheck,\n}: {\n issue: Issue;\n isSelected: boolean;\n isHighlighted: boolean;\n isChecked: boolean;\n onSelect: () => void;\n onToggleCheck: () => void;\n}) {\n return (\n <div\n role=\"button\"\n tabIndex={0}\n className={cn(\n 'w-full text-left px-2.5 py-1.5 rounded-md transition-colors',\n 'hover:bg-muted/60 focus:outline-none focus:ring-1 focus:ring-primary/30',\n isSelected && 'bg-primary/10 ring-1 ring-primary/30',\n isHighlighted && !isSelected && 'bg-accent/50'\n )}\n onClick={onSelect}\n onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onSelect(); } }}\n >\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <input\n type=\"checkbox\"\n checked={isChecked}\n onChange={(e) => { e.stopPropagation(); onToggleCheck(); }}\n onClick={(e) => e.stopPropagation()}\n className=\"w-3.5 h-3.5 rounded border-border accent-primary shrink-0\"\n />\n <StatusDot status={issue.status} />\n <span className=\"text-sm font-medium text-foreground truncate\">\n {issue.title}\n </span>\n </div>\n <div className=\"flex items-center gap-1.5 shrink-0\">\n <PriorityBadge priority={issue.priority} />\n </div>\n </div>\n {issue.context && (\n <p className=\"mt-0.5 text-xs text-muted-foreground truncate pl-7\">\n {issue.context}\n </p>\n )}\n <div className=\"mt-0.5 flex items-center gap-2 text-[10px] text-muted-foreground pl-7\">\n <span className=\"font-mono\">{issue.id}</span>\n {issue.labels && issue.labels.length > 0 && (\n <>\n <span className=\"text-border\">|</span>\n <span className=\"truncate\">{issue.labels.slice(0, 2).join(', ')}</span>\n </>\n )}\n </div>\n </div>\n );\n}\n\n// ========== Empty State ==========\n\nfunction IssueEmptyState() {\n const { formatMessage } = useIntl();\n return (\n <div className=\"flex-1 flex items-center justify-center text-muted-foreground p-4\">\n <div className=\"text-center\">\n <AlertCircle className=\"h-6 w-6 mx-auto mb-1.5 opacity-30\" />\n <p className=\"text-sm\">{formatMessage({ id: 'terminalDashboard.issuePanel.noIssues' })}</p>\n <p className=\"text-xs mt-1 opacity-70\">\n {formatMessage({ id: 'terminalDashboard.issuePanel.noIssuesDesc' })}\n </p>\n </div>\n </div>\n );\n}\n\n// ========== Error State ==========\n\nfunction IssueErrorState({ error }: { error: Error }) {\n const { formatMessage } = useIntl();\n return (\n <div className=\"flex-1 flex items-center justify-center text-destructive p-4\">\n <div className=\"text-center\">\n <AlertTriangle className=\"h-6 w-6 mx-auto mb-1.5 opacity-30\" />\n <p className=\"text-sm\">{formatMessage({ id: 'terminalDashboard.issuePanel.error' })}</p>\n <p className=\"text-xs mt-1 opacity-70\">{error.message}</p>\n </div>\n </div>\n );\n}\n\n// ========== Main Component ==========\n\nexport function IssuePanel() {\n const { formatMessage } = useIntl();\n const { issues, isLoading, error, openCount } = useIssues();\n\n const selectedIssueId = useIssueQueueIntegrationStore(selectSelectedIssueId);\n const associationChain = useIssueQueueIntegrationStore(selectAssociationChain);\n const setSelectedIssue = useIssueQueueIntegrationStore((s) => s.setSelectedIssue);\n const buildAssociationChain = useIssueQueueIntegrationStore((s) => s.buildAssociationChain);\n\n // Multi-select state\n const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());\n const [isSending, setIsSending] = useState(false);\n const [justSent, setJustSent] = useState(false);\n const [executionMethod, setExecutionMethod] = useState<ExecutionMethod>('skill-team-issue');\n const [isSendConfigOpen, setIsSendConfigOpen] = useState(false);\n const [customPrompt, setCustomPrompt] = useState('');\n const sentTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Queue state\n const [isAddingToQueue, setIsAddingToQueue] = useState(false);\n const [justQueued, setJustQueued] = useState(false);\n const [queueMode, setQueueMode] = useState<'write' | 'analysis' | 'auto'>('write');\n const queuedTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const submitItems = useQueueSchedulerStore((s) => s.submitItems);\n\n // Terminal refs\n const focusedPaneId = useTerminalGridStore(selectTerminalGridFocusedPaneId);\n const panes = useTerminalGridStore(selectTerminalGridPanes);\n const projectPath = useWorkflowStore(selectProjectPath);\n const focusedPane = focusedPaneId ? panes[focusedPaneId] : null;\n const sessionKey = focusedPane?.sessionId ?? null;\n const sessionCliTool = focusedPane?.cliTool ?? null;\n\n // Compute available methods based on the focused session's CLI tool\n const availableMethods = useMemo(() => {\n // Only offer skill methods when the session is claude (supports / slash commands)\n if (sessionCliTool === 'claude') {\n return [\n { value: 'skill-team-issue' as const, label: 'team-issue' },\n { value: 'ccw-cli' as const, label: 'ccw' },\n { value: 'direct-send' as const, label: 'Direct send' },\n ];\n }\n // For unknown/null cliTool or non-claude tools, only offer direct send\n return [\n { value: 'direct-send' as const, label: 'Direct send' },\n ];\n }, [sessionCliTool]);\n\n // Auto-switch method when the current selection is unavailable for this tool\n useEffect(() => {\n if (!availableMethods.find(m => m.value === executionMethod)) {\n setExecutionMethod(availableMethods[0].value);\n }\n }, [availableMethods, executionMethod]);\n\n // Cleanup feedback timers on unmount\n useEffect(() => {\n return () => {\n if (sentTimerRef.current) clearTimeout(sentTimerRef.current);\n if (queuedTimerRef.current) clearTimeout(queuedTimerRef.current);\n };\n }, []);\n\n useEffect(() => {\n if (sentTimerRef.current) clearTimeout(sentTimerRef.current);\n if (queuedTimerRef.current) clearTimeout(queuedTimerRef.current);\n setSelectedIds(new Set());\n setIsSending(false);\n setJustSent(false);\n setExecutionMethod('skill-team-issue');\n setIsSendConfigOpen(false);\n setCustomPrompt('');\n setIsAddingToQueue(false);\n setJustQueued(false);\n setQueueMode('write');\n }, [projectPath]);\n\n // Sort: open/in_progress first, then by priority (critical > high > medium > low)\n const sortedIssues = useMemo(() => {\n const priorityOrder: Record<string, number> = {\n critical: 0,\n high: 1,\n medium: 2,\n low: 3,\n };\n const statusOrder: Record<string, number> = {\n in_progress: 0,\n open: 1,\n resolved: 2,\n completed: 3,\n closed: 4,\n };\n return [...issues].sort((a, b) => {\n const sa = statusOrder[a.status] ?? 5;\n const sb = statusOrder[b.status] ?? 5;\n if (sa !== sb) return sa - sb;\n const pa = priorityOrder[a.priority] ?? 3;\n const pb = priorityOrder[b.priority] ?? 3;\n return pa - pb;\n });\n }, [issues]);\n\n const handleSelect = useCallback(\n (issueId: string) => {\n if (selectedIssueId === issueId) {\n setSelectedIssue(null);\n } else {\n buildAssociationChain(issueId, 'issue');\n }\n },\n [selectedIssueId, setSelectedIssue, buildAssociationChain]\n );\n\n const handleToggleSelect = useCallback((issueId: string) => {\n setSelectedIds(prev => {\n const next = new Set(prev);\n if (next.has(issueId)) next.delete(issueId);\n else next.add(issueId);\n return next;\n });\n }, []);\n\n const handleSelectAll = useCallback(() => {\n setSelectedIds(new Set(sortedIssues.map(i => i.id)));\n }, [sortedIssues]);\n\n const handleDeselectAll = useCallback(() => {\n setSelectedIds(new Set());\n }, []);\n\n const handleOpenSendConfig = useCallback(() => {\n const idStr = Array.from(selectedIds).join(' ');\n setCustomPrompt(PROMPT_TEMPLATES[executionMethod](idStr));\n setIsSendConfigOpen(true);\n }, [selectedIds, executionMethod]);\n\n const handleSendToTerminal = useCallback(async () => {\n if (!sessionKey || selectedIds.size === 0) return;\n const effectiveTool = sessionCliTool || 'claude';\n setIsSending(true);\n try {\n const prompt = customPrompt.trim();\n\n let executeInput: Parameters<typeof executeInCliSession>[1];\n\n switch (executionMethod) {\n case 'skill-team-issue':\n executeInput = {\n tool: effectiveTool,\n prompt,\n instructionType: 'skill',\n skillName: 'team-issue',\n };\n break;\n case 'ccw-cli':\n executeInput = {\n tool: effectiveTool,\n prompt,\n instructionType: 'skill',\n skillName: 'ccw',\n };\n break;\n case 'direct-send':\n executeInput = {\n tool: effectiveTool,\n prompt,\n instructionType: 'prompt',\n };\n break;\n }\n\n await executeInCliSession(sessionKey, executeInput, projectPath || undefined);\n\n toast.success('Sent to terminal', prompt.length > 60 ? prompt.slice(0, 60) + '...' : prompt);\n setJustSent(true);\n setIsSendConfigOpen(false);\n if (sentTimerRef.current) clearTimeout(sentTimerRef.current);\n sentTimerRef.current = setTimeout(() => setJustSent(false), 2000);\n } catch (err) {\n toast.error('Failed to send', err instanceof Error ? err.message : String(err));\n } finally {\n setIsSending(false);\n }\n }, [sessionKey, selectedIds, projectPath, executionMethod, sessionCliTool, customPrompt]);\n\n const handleAddToQueue = useCallback(async () => {\n if (selectedIds.size === 0) return;\n setIsAddingToQueue(true);\n try {\n const selectedIssues = sortedIssues.filter((i) => selectedIds.has(i.id));\n const now = new Date().toISOString();\n const items = selectedIssues.map((issue, index) => ({\n item_id: `Q-${issue.id}-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,\n issue_id: issue.id,\n status: 'pending' as const,\n tool: sessionCliTool || 'gemini',\n prompt: buildQueuePrompt([issue]),\n mode: queueMode,\n depends_on: [] as string[],\n execution_order: index + 1,\n execution_group: 'default',\n createdAt: now,\n metadata: { issueTitle: issue.title, issuePriority: issue.priority },\n }));\n await submitItems(items);\n toast.success(\n formatMessage({ id: 'terminalDashboard.issuePanel.addedToQueue', defaultMessage: 'Added to queue' }),\n `${items.length} item(s)`\n );\n setJustQueued(true);\n if (queuedTimerRef.current) clearTimeout(queuedTimerRef.current);\n queuedTimerRef.current = setTimeout(() => setJustQueued(false), 2000);\n } catch (err) {\n toast.error(\n formatMessage({ id: 'terminalDashboard.issuePanel.addToQueueFailed', defaultMessage: 'Failed to add to queue' }),\n err instanceof Error ? err.message : String(err)\n );\n } finally {\n setIsAddingToQueue(false);\n }\n }, [selectedIds, sortedIssues, sessionCliTool, submitItems, formatMessage]);\n\n // Loading state\n if (isLoading) {\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"px-3 py-2 border-b border-border shrink-0\">\n <h3 className=\"text-sm font-semibold flex items-center gap-2\">\n <AlertCircle className=\"w-4 h-4\" />\n {formatMessage({ id: 'terminalDashboard.issuePanel.title' })}\n </h3>\n </div>\n <div className=\"flex-1 flex items-center justify-center\">\n <Loader2 className=\"w-5 h-5 animate-spin text-muted-foreground\" />\n </div>\n </div>\n );\n }\n\n // Error state\n if (error) {\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"px-3 py-2 border-b border-border shrink-0\">\n <h3 className=\"text-sm font-semibold flex items-center gap-2\">\n <AlertCircle className=\"w-4 h-4\" />\n {formatMessage({ id: 'terminalDashboard.issuePanel.title' })}\n </h3>\n </div>\n <IssueErrorState error={error} />\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col h-full\">\n {/* Header */}\n <div className=\"px-3 py-2 border-b border-border shrink-0 flex items-center justify-between\">\n <h3 className=\"text-sm font-semibold flex items-center gap-2\">\n <AlertCircle className=\"w-4 h-4\" />\n {formatMessage({ id: 'terminalDashboard.issuePanel.title' })}\n </h3>\n <div className=\"flex items-center gap-1.5\">\n {sortedIssues.length > 0 && (\n <button\n type=\"button\"\n className=\"text-[10px] text-muted-foreground hover:text-foreground px-1\"\n onClick={selectedIds.size === sortedIssues.length ? handleDeselectAll : handleSelectAll}\n >\n {selectedIds.size === sortedIssues.length ? 'Deselect all' : 'Select all'}\n </button>\n )}\n {openCount > 0 && (\n <Badge variant=\"secondary\" className=\"text-[10px] px-1.5 py-0\">\n {openCount}\n </Badge>\n )}\n </div>\n </div>\n\n {/* Issue List */}\n {sortedIssues.length === 0 ? (\n <IssueEmptyState />\n ) : (\n <div className=\"flex-1 min-h-0 overflow-y-auto p-1.5 space-y-0.5\">\n {sortedIssues.map((issue) => (\n <IssueItem\n key={issue.id}\n issue={issue}\n isSelected={selectedIssueId === issue.id}\n isHighlighted={associationChain?.issueId === issue.id}\n isChecked={selectedIds.has(issue.id)}\n onSelect={() => handleSelect(issue.id)}\n onToggleCheck={() => handleToggleSelect(issue.id)}\n />\n ))}\n </div>\n )}\n\n {/* Send to Terminal bar */}\n {selectedIds.size > 0 && (\n <div className=\"border-t border-border shrink-0\">\n {/* Send Config Panel (expandable) */}\n {isSendConfigOpen && (\n <div className=\"px-3 py-2 space-y-2 border-b border-border bg-muted/20\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs font-medium text-foreground\">Send Configuration</span>\n <button\n type=\"button\"\n className=\"p-0.5 rounded hover:bg-muted text-muted-foreground hover:text-foreground\"\n onClick={() => setIsSendConfigOpen(false)}\n >\n <X className=\"w-3.5 h-3.5\" />\n </button>\n </div>\n {/* Method selector */}\n {availableMethods.length > 1 && (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-[10px] text-muted-foreground shrink-0\">Method</span>\n <Select\n value={executionMethod}\n onValueChange={(v) => {\n const method = v as ExecutionMethod;\n setExecutionMethod(method);\n const idStr = Array.from(selectedIds).join(' ');\n setCustomPrompt(PROMPT_TEMPLATES[method](idStr));\n }}\n >\n <SelectTrigger className=\"h-6 w-full text-xs\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {availableMethods.map((m) => (\n <SelectItem key={m.value} value={m.value} className=\"text-xs\">\n {m.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n {/* Prompt preview label */}\n {executionMethod !== 'direct-send' && (\n <div className=\"text-[10px] text-muted-foreground\">\n Prefix: <span className=\"font-mono text-foreground\">/{executionMethod === 'skill-team-issue' ? 'team-issue' : 'ccw'}</span>\n </div>\n )}\n {/* Editable prompt */}\n <textarea\n className=\"w-full text-xs bg-background border border-border rounded-md px-2 py-1.5 resize-none focus:outline-none focus:ring-1 focus:ring-primary/40 text-foreground\"\n rows={3}\n value={customPrompt}\n onChange={(e) => setCustomPrompt(e.target.value)}\n placeholder=\"Enter prompt...\"\n />\n {/* Send button */}\n <button\n type=\"button\"\n className={cn(\n 'w-full flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium transition-colors',\n 'bg-primary text-primary-foreground hover:bg-primary/90',\n 'disabled:opacity-50 disabled:cursor-not-allowed'\n )}\n disabled={!sessionKey || isSending || !customPrompt.trim()}\n onClick={handleSendToTerminal}\n >\n {isSending ? <Loader2 className=\"w-3.5 h-3.5 animate-spin\" /> : <Send className=\"w-3.5 h-3.5\" />}\n Confirm Send\n </button>\n </div>\n )}\n {/* Bottom bar */}\n <div className=\"px-3 py-2 flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-muted-foreground\">\n {selectedIds.size} selected\n </span>\n <button\n type=\"button\"\n className=\"text-xs text-muted-foreground hover:text-foreground\"\n onClick={handleDeselectAll}\n >\n Clear\n </button>\n </div>\n <div className=\"flex items-center gap-1.5\">\n {/* Queue mode selector */}\n <select\n className=\"h-6 text-[10px] rounded border border-border bg-background px-1 text-muted-foreground\"\n value={queueMode}\n onChange={(e) => setQueueMode(e.target.value as 'write' | 'analysis' | 'auto')}\n title={formatMessage({ id: 'terminalDashboard.issuePanel.queueModeHint', defaultMessage: 'Execution mode for queued items' })}\n >\n <option value=\"write\">write</option>\n <option value=\"analysis\">analysis</option>\n <option value=\"auto\">auto</option>\n </select>\n {/* Add to Queue button */}\n <button\n type=\"button\"\n className={cn(\n 'flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-xs font-medium transition-colors',\n justQueued\n ? 'bg-green-600 text-white'\n : 'bg-muted text-foreground hover:bg-muted/80',\n 'disabled:opacity-50 disabled:cursor-not-allowed'\n )}\n disabled={isAddingToQueue}\n onClick={handleAddToQueue}\n title={formatMessage({ id: 'terminalDashboard.issuePanel.addToQueueHint', defaultMessage: 'Add selected issues to the execution queue' })}\n >\n {isAddingToQueue ? <Loader2 className=\"w-3.5 h-3.5 animate-spin\" /> : justQueued ? <Check className=\"w-3.5 h-3.5\" /> : <ListPlus className=\"w-3.5 h-3.5\" />}\n {justQueued\n ? formatMessage({ id: 'terminalDashboard.issuePanel.addedToQueue', defaultMessage: 'Queued!' })\n : formatMessage({ id: 'terminalDashboard.issuePanel.addToQueue', defaultMessage: 'Queue' })}\n </button>\n {/* Send to Terminal button */}\n <button\n type=\"button\"\n className={cn(\n 'flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-xs font-medium transition-colors',\n justSent\n ? 'bg-green-600 text-white'\n : 'bg-primary text-primary-foreground hover:bg-primary/90',\n 'disabled:opacity-50 disabled:cursor-not-allowed'\n )}\n disabled={!sessionKey || isSending}\n onClick={isSendConfigOpen ? handleSendToTerminal : handleOpenSendConfig}\n title={!sessionKey ? 'No terminal session focused' : `Send via ${executionMethod}`}\n >\n {isSending ? <Loader2 className=\"w-3.5 h-3.5 animate-spin\" /> : justSent ? <Check className=\"w-3.5 h-3.5\" /> : <Terminal className=\"w-3.5 h-3.5\" />}\n {justSent ? 'Sent!' : `Send (${selectedIds.size})`}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n","// ========================================\r\n// QueueListColumn Component\r\n// ========================================\r\n// Queue items list for embedding in the Issues dual-column panel.\r\n// Unified data source: queueSchedulerStore only.\r\n// Includes inline scheduler controls at the bottom.\r\n\r\nimport { useMemo, useCallback, useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n ListChecks,\r\n Loader2,\r\n CheckCircle,\r\n XCircle,\r\n Zap,\r\n Ban,\r\n Square,\r\n Terminal,\r\n Timer,\r\n Clock,\r\n Play,\r\n Pause,\r\n StopCircle,\r\n} from 'lucide-react';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport {\r\n AlertDialog,\r\n AlertDialogContent,\r\n AlertDialogHeader,\r\n AlertDialogTitle,\r\n AlertDialogDescription,\r\n AlertDialogFooter,\r\n AlertDialogAction,\r\n AlertDialogCancel,\r\n} from '@/components/ui/AlertDialog';\r\nimport { cn } from '@/lib/utils';\r\nimport {\r\n useIssueQueueIntegrationStore,\r\n selectAssociationChain,\r\n} from '@/stores/issueQueueIntegrationStore';\r\nimport {\r\n useQueueExecutionStore,\r\n selectByQueueItem,\r\n} from '@/stores/queueExecutionStore';\r\nimport {\r\n useQueueSchedulerStore,\r\n selectQueueSchedulerStatus,\r\n selectQueueItems,\r\n selectSchedulerProgress,\r\n selectCurrentConcurrency,\r\n selectSchedulerConfig,\r\n} from '@/stores/queueSchedulerStore';\r\nimport type { QueueItem, QueueItemStatus } from '@/types/queue-frontend-types';\r\n\r\n// ========== Status Config ==========\r\n\r\nconst STATUS_CONFIG: Record<QueueItemStatus, {\r\n variant: 'info' | 'success' | 'destructive' | 'secondary' | 'warning' | 'outline';\r\n icon: typeof Clock;\r\n label: string;\r\n}> = {\r\n pending: { variant: 'secondary', icon: Clock, label: 'Pending' },\r\n queued: { variant: 'info', icon: Timer, label: 'Queued' },\r\n ready: { variant: 'info', icon: Zap, label: 'Ready' },\r\n blocked: { variant: 'outline', icon: Ban, label: 'Blocked' },\r\n executing: { variant: 'warning', icon: Loader2, label: 'Executing' },\r\n completed: { variant: 'success', icon: CheckCircle, label: 'Completed' },\r\n failed: { variant: 'destructive', icon: XCircle, label: 'Failed' },\r\n cancelled: { variant: 'secondary', icon: Square, label: 'Cancelled' },\r\n};\r\n\r\n// ========== Scheduler Status Styles ==========\r\n\r\nconst SCHEDULER_STATUS_STYLE: Record<string, string> = {\r\n idle: 'bg-muted text-muted-foreground',\r\n running: 'bg-blue-500/15 text-blue-600',\r\n paused: 'bg-yellow-500/15 text-yellow-600',\r\n stopping: 'bg-orange-500/15 text-orange-600',\r\n completed: 'bg-green-500/15 text-green-600',\r\n failed: 'bg-red-500/15 text-red-600',\r\n};\r\n\r\n// ========== Item Row ==========\r\n\r\nfunction QueueItemRow({\r\n item,\r\n isHighlighted,\r\n onSelect,\r\n}: {\r\n item: QueueItem;\r\n isHighlighted: boolean;\r\n onSelect: () => void;\r\n}) {\r\n const { formatMessage } = useIntl();\r\n const config = STATUS_CONFIG[item.status] ?? STATUS_CONFIG.pending;\r\n const StatusIcon = config.icon;\r\n\r\n const executions = useQueueExecutionStore(selectByQueueItem(item.item_id));\r\n const activeExec = executions.find((e) => e.status === 'running') ?? executions[0];\r\n const sessionKey = item.sessionKey ?? activeExec?.sessionKey;\r\n\r\n const isExecuting = item.status === 'executing';\r\n const isBlocked = item.status === 'blocked';\r\n\r\n // Show issue_id if available (for items added from IssuePanel)\r\n const displayId = item.issue_id ? `${item.issue_id}` : item.item_id;\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n className={cn(\r\n 'w-full text-left px-2.5 py-1.5 rounded-md transition-colors',\r\n 'hover:bg-muted/60 focus:outline-none focus:ring-1 focus:ring-primary/30',\r\n isHighlighted && 'bg-accent/50 ring-1 ring-accent/30',\r\n isExecuting && 'border-l-2 border-l-blue-500'\r\n )}\r\n onClick={onSelect}\r\n >\r\n <div className=\"flex items-center justify-between gap-1.5\">\r\n <div className=\"flex items-center gap-1.5 min-w-0\">\r\n <StatusIcon\r\n className={cn(\r\n 'w-3 h-3 shrink-0',\r\n isExecuting && 'animate-spin'\r\n )}\r\n />\r\n <span className=\"text-xs font-medium text-foreground truncate font-mono\">\r\n {displayId}\r\n </span>\r\n </div>\r\n <Badge variant={config.variant} className=\"text-[10px] px-1 py-0 shrink-0\">\r\n {formatMessage({ id: `terminalDashboard.queuePanel.status.${item.status}`, defaultMessage: config.label })}\r\n </Badge>\r\n </div>\r\n <div className=\"mt-0.5 flex items-center gap-1.5 text-[10px] text-muted-foreground pl-4\">\r\n {item.execution_group && <span>{item.execution_group}</span>}\r\n {sessionKey && (\r\n <>\r\n <span className=\"text-border\">|</span>\r\n <span className=\"flex items-center gap-0.5\">\r\n <Terminal className=\"w-2.5 h-2.5\" />\r\n {sessionKey}\r\n </span>\r\n </>\r\n )}\r\n </div>\r\n {isBlocked && item.depends_on.length > 0 && (\r\n <div className=\"mt-0.5 text-[10px] text-orange-500/80 pl-4 truncate\">\r\n {formatMessage(\r\n { id: 'terminalDashboard.queuePanel.blockedBy', defaultMessage: 'Blocked by: {deps}' },\r\n { deps: item.depends_on.join(', ') }\r\n )}\r\n </div>\r\n )}\r\n </button>\r\n );\r\n}\r\n\r\n// ========== Inline Scheduler Controls ==========\r\n\r\nfunction SchedulerBar() {\r\n const { formatMessage } = useIntl();\r\n const status = useQueueSchedulerStore(selectQueueSchedulerStatus);\r\n const progress = useQueueSchedulerStore(selectSchedulerProgress);\r\n const concurrency = useQueueSchedulerStore(selectCurrentConcurrency);\r\n const config = useQueueSchedulerStore(selectSchedulerConfig);\r\n const startQueue = useQueueSchedulerStore((s) => s.startQueue);\r\n const pauseQueue = useQueueSchedulerStore((s) => s.pauseQueue);\r\n const stopQueue = useQueueSchedulerStore((s) => s.stopQueue);\r\n const items = useQueueSchedulerStore(selectQueueItems);\r\n\r\n const canStart = status === 'idle' && items.length > 0;\r\n const canPause = status === 'running';\r\n const canResume = status === 'paused';\r\n const canStop = status === 'running' || status === 'paused';\r\n const isActive = status !== 'idle';\r\n\r\n const [isStopConfirmOpen, setIsStopConfirmOpen] = useState(false);\r\n\r\n const handleStart = useCallback(() => {\r\n if (canResume) {\r\n startQueue();\r\n } else if (canStart) {\r\n startQueue(items);\r\n }\r\n }, [canResume, canStart, startQueue, items]);\r\n\r\n return (\r\n <div className=\"border-t border-border px-2.5 py-1.5 shrink-0\">\r\n <div className=\"flex items-center justify-between gap-2\">\r\n {/* Status badge */}\r\n <Badge\r\n variant=\"outline\"\r\n className={cn('text-[10px] px-1.5 py-0', SCHEDULER_STATUS_STYLE[status])}\r\n >\r\n {formatMessage({ id: `terminalDashboard.queuePanel.scheduler.status.${status}`, defaultMessage: status })}\r\n </Badge>\r\n\r\n {/* Progress + Concurrency */}\r\n {isActive && (\r\n <span className=\"text-[10px] text-muted-foreground\">\r\n {progress}% | {concurrency}/{config?.maxConcurrentSessions ?? 2}\r\n </span>\r\n )}\r\n\r\n {/* Controls */}\r\n <div className=\"flex items-center gap-0.5\">\r\n {(canStart || canResume) && (\r\n <button\r\n type=\"button\"\r\n className=\"p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground\"\r\n onClick={handleStart}\r\n title={formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.start', defaultMessage: 'Start' })}\r\n >\r\n <Play className=\"w-3 h-3\" />\r\n </button>\r\n )}\r\n {canPause && (\r\n <button\r\n type=\"button\"\r\n className=\"p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground\"\r\n onClick={pauseQueue}\r\n title={formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.pause', defaultMessage: 'Pause' })}\r\n >\r\n <Pause className=\"w-3 h-3\" />\r\n </button>\r\n )}\r\n {canStop && (\r\n <button\r\n type=\"button\"\r\n className=\"p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground\"\r\n onClick={() => setIsStopConfirmOpen(true)}\r\n title={formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.stop', defaultMessage: 'Stop' })}\r\n >\r\n <StopCircle className=\"w-3 h-3\" />\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Progress bar */}\r\n {isActive && (\r\n <div className=\"mt-1 h-1 bg-muted rounded-full overflow-hidden\">\r\n <div\r\n className=\"h-full bg-primary rounded-full transition-all duration-300\"\r\n style={{ width: `${progress}%` }}\r\n />\r\n </div>\r\n )}\r\n\r\n {/* Stop confirmation dialog */}\r\n <AlertDialog open={isStopConfirmOpen} onOpenChange={setIsStopConfirmOpen}>\r\n <AlertDialogContent className=\"max-w-sm\">\r\n <AlertDialogHeader>\r\n <AlertDialogTitle className=\"text-base\">\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.stopConfirmTitle', defaultMessage: 'Stop Queue?' })}\r\n </AlertDialogTitle>\r\n <AlertDialogDescription>\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.stopConfirmMessage', defaultMessage: 'Executing tasks will finish, but no new tasks will be started.' })}\r\n </AlertDialogDescription>\r\n </AlertDialogHeader>\r\n <AlertDialogFooter>\r\n <AlertDialogCancel className=\"h-8 text-xs\">\r\n {formatMessage({ id: 'common.cancel', defaultMessage: 'Cancel' })}\r\n </AlertDialogCancel>\r\n <AlertDialogAction\r\n className=\"h-8 text-xs bg-destructive text-destructive-foreground hover:bg-destructive/90\"\r\n onClick={() => { stopQueue(); setIsStopConfirmOpen(false); }}\r\n >\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.stop', defaultMessage: 'Stop' })}\r\n </AlertDialogAction>\r\n </AlertDialogFooter>\r\n </AlertDialogContent>\r\n </AlertDialog>\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\nexport function QueueListColumn() {\r\n const { formatMessage } = useIntl();\r\n\r\n const items = useQueueSchedulerStore(selectQueueItems);\r\n const associationChain = useIssueQueueIntegrationStore(selectAssociationChain);\r\n const buildAssociationChain = useIssueQueueIntegrationStore((s) => s.buildAssociationChain);\r\n\r\n // NOTE: loadInitialState is called from a parent component or app initialization\r\n // to avoid infinite loop issues with Zustand selectors\r\n\r\n const sortedItems = useMemo(\r\n () => [...items].sort((a, b) => a.execution_order - b.execution_order),\r\n [items]\r\n );\r\n\r\n const handleSelect = useCallback(\r\n (queueItemId: string) => {\r\n buildAssociationChain(queueItemId, 'queue');\r\n },\r\n [buildAssociationChain]\r\n );\r\n\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n {/* Item list */}\r\n {sortedItems.length === 0 ? (\r\n <div className=\"flex-1 flex items-center justify-center text-muted-foreground p-3\">\r\n <div className=\"text-center\">\r\n <ListChecks className=\"h-5 w-5 mx-auto mb-1 opacity-30\" />\r\n <p className=\"text-xs\">{formatMessage({ id: 'terminalDashboard.queuePanel.noItems' })}</p>\r\n <p className=\"text-[10px] mt-0.5 opacity-70\">\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.noItemsDesc', defaultMessage: 'Select issues and click Queue to add items' })}\r\n </p>\r\n </div>\r\n </div>\r\n ) : (\r\n <div className=\"flex-1 min-h-0 overflow-y-auto p-1 space-y-0.5\">\r\n {sortedItems.map((item) => (\r\n <QueueItemRow\r\n key={item.item_id}\r\n item={item}\r\n isHighlighted={associationChain?.queueItemId === item.item_id}\r\n onSelect={() => handleSelect(item.item_id)}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Inline scheduler controls */}\r\n <SchedulerBar />\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// SchedulerPanel Component\r\n// ========================================\r\n// Standalone queue scheduler control panel.\r\n// Shows scheduler status, start/pause/stop controls, concurrency config,\r\n// progress bar, and session pool overview.\r\n\r\nimport { useCallback, useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Play,\r\n Pause,\r\n Square,\r\n Loader2,\r\n} from 'lucide-react';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Progress } from '@/components/ui/Progress';\r\nimport {\r\n AlertDialog,\r\n AlertDialogContent,\r\n AlertDialogHeader,\r\n AlertDialogTitle,\r\n AlertDialogDescription,\r\n AlertDialogFooter,\r\n AlertDialogAction,\r\n AlertDialogCancel,\r\n} from '@/components/ui/AlertDialog';\r\nimport { cn } from '@/lib/utils';\r\nimport {\r\n useQueueSchedulerStore,\r\n selectQueueSchedulerStatus,\r\n selectSchedulerProgress,\r\n selectSchedulerConfig,\r\n selectSessionPool,\r\n selectCurrentConcurrency,\r\n selectSchedulerError,\r\n} from '@/stores/queueSchedulerStore';\r\nimport type { QueueSchedulerStatus } from '@/types/queue-frontend-types';\r\n\r\n// ========== Status Badge Config ==========\r\n\r\nconst SCHEDULER_STATUS_CLASS: Record<QueueSchedulerStatus, string> = {\r\n idle: 'bg-muted text-muted-foreground border-border',\r\n running: 'bg-primary/10 text-primary border-primary/50',\r\n paused: 'bg-amber-500/10 text-amber-500 border-amber-500/50',\r\n stopping: 'bg-orange-500/10 text-orange-500 border-orange-500/50',\r\n completed: 'bg-green-500/10 text-green-500 border-green-500/50',\r\n failed: 'bg-destructive/10 text-destructive border-destructive/50',\r\n};\r\n\r\n// ========== Component ==========\r\n\r\nexport function SchedulerPanel() {\r\n const { formatMessage } = useIntl();\r\n\r\n const schedulerStatus = useQueueSchedulerStore(selectQueueSchedulerStatus);\r\n const progress = useQueueSchedulerStore(selectSchedulerProgress);\r\n const config = useQueueSchedulerStore(selectSchedulerConfig);\r\n const sessionPool = useQueueSchedulerStore(selectSessionPool);\r\n const concurrency = useQueueSchedulerStore(selectCurrentConcurrency);\r\n const error = useQueueSchedulerStore(selectSchedulerError);\r\n const startQueue = useQueueSchedulerStore((s) => s.startQueue);\r\n const pauseQueue = useQueueSchedulerStore((s) => s.pauseQueue);\r\n const stopQueue = useQueueSchedulerStore((s) => s.stopQueue);\r\n const updateConfig = useQueueSchedulerStore((s) => s.updateConfig);\r\n\r\n const isIdle = schedulerStatus === 'idle';\r\n const isRunning = schedulerStatus === 'running';\r\n const isPaused = schedulerStatus === 'paused';\r\n const isStopping = schedulerStatus === 'stopping';\r\n const isTerminal = schedulerStatus === 'completed' || schedulerStatus === 'failed';\r\n\r\n const [isStopConfirmOpen, setIsStopConfirmOpen] = useState(false);\r\n\r\n const handleConcurrencyChange = useCallback(\r\n (e: React.ChangeEvent<HTMLInputElement>) => {\r\n const value = parseInt(e.target.value, 10);\r\n if (!isNaN(value) && value >= 1 && value <= 10) {\r\n updateConfig({ maxConcurrentSessions: value });\r\n }\r\n },\r\n [updateConfig]\r\n );\r\n\r\n const sessionEntries = Object.entries(sessionPool ?? {});\r\n\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n {/* Status + Controls */}\r\n <div className=\"px-3 py-3 border-b border-border space-y-3 shrink-0\">\r\n {/* Status badge */}\r\n <div className=\"flex items-center gap-2\">\r\n <span\r\n className={cn(\r\n 'px-2.5 py-1 rounded text-xs font-medium border',\r\n SCHEDULER_STATUS_CLASS[schedulerStatus]\r\n )}\r\n >\r\n {formatMessage({\r\n id: `terminalDashboard.queuePanel.scheduler.status.${schedulerStatus}`,\r\n defaultMessage: schedulerStatus,\r\n })}\r\n </span>\r\n <span className=\"text-xs text-muted-foreground ml-auto tabular-nums\">\r\n {concurrency}/{config?.maxConcurrentSessions ?? 2}\r\n </span>\r\n </div>\r\n\r\n {/* Control buttons */}\r\n <div className=\"flex items-center gap-2\">\r\n {(isIdle || isTerminal) && (\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n className=\"h-7 text-xs gap-1.5 flex-1\"\r\n onClick={() => startQueue()}\r\n >\r\n <Play className=\"w-3.5 h-3.5\" />\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.start', defaultMessage: 'Start' })}\r\n </Button>\r\n )}\r\n {isPaused && (\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n className=\"h-7 text-xs gap-1.5 flex-1\"\r\n onClick={() => startQueue()}\r\n >\r\n <Play className=\"w-3.5 h-3.5\" />\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.start', defaultMessage: 'Resume' })}\r\n </Button>\r\n )}\r\n {isRunning && (\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n className=\"h-7 text-xs gap-1.5 flex-1\"\r\n onClick={pauseQueue}\r\n >\r\n <Pause className=\"w-3.5 h-3.5\" />\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.pause', defaultMessage: 'Pause' })}\r\n </Button>\r\n )}\r\n {(isRunning || isPaused) && (\r\n <Button\r\n variant=\"destructive\"\r\n size=\"sm\"\r\n className=\"h-7 text-xs gap-1.5\"\r\n disabled={isStopping}\r\n onClick={() => setIsStopConfirmOpen(true)}\r\n >\r\n {isStopping ? <Loader2 className=\"w-3.5 h-3.5 animate-spin\" /> : <Square className=\"w-3.5 h-3.5\" />}\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.stop', defaultMessage: 'Stop' })}\r\n </Button>\r\n )}\r\n </div>\r\n\r\n {/* Progress bar (visible when not idle) */}\r\n {!isIdle && (\r\n <div className=\"flex items-center gap-2\">\r\n <Progress\r\n value={progress}\r\n className=\"h-1.5 flex-1\"\r\n indicatorClassName={cn(\r\n schedulerStatus === 'failed' && 'bg-destructive',\r\n schedulerStatus === 'completed' && 'bg-green-500',\r\n schedulerStatus === 'paused' && 'bg-amber-500',\r\n (schedulerStatus === 'running' || schedulerStatus === 'stopping') && 'bg-primary',\r\n )}\r\n />\r\n <span className=\"text-[10px] text-muted-foreground tabular-nums shrink-0\">\r\n {formatMessage(\r\n { id: 'terminalDashboard.queuePanel.scheduler.progress', defaultMessage: '{percent}%' },\r\n { percent: progress }\r\n )}\r\n </span>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Concurrency Config */}\r\n <div className=\"px-3 py-2.5 border-b border-border shrink-0\">\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.concurrency', defaultMessage: 'Concurrency' })}\r\n </span>\r\n <input\r\n type=\"number\"\r\n min={1}\r\n max={10}\r\n value={config?.maxConcurrentSessions ?? 2}\r\n onChange={handleConcurrencyChange}\r\n className=\"w-14 h-6 text-xs text-center rounded border border-border bg-background px-1\"\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* Session Pool */}\r\n <div className=\"flex-1 min-h-0 overflow-y-auto\">\r\n <div className=\"px-3 py-2\">\r\n <h4 className=\"text-[10px] font-medium text-muted-foreground uppercase tracking-wider mb-2\">\r\n {formatMessage({ id: 'terminalDashboard.schedulerPanel.sessionPool', defaultMessage: 'Session Pool' })}\r\n </h4>\r\n {sessionEntries.length === 0 ? (\r\n <p className=\"text-xs text-muted-foreground/60 py-2\">\r\n {formatMessage({ id: 'terminalDashboard.schedulerPanel.noSessions', defaultMessage: 'No active sessions' })}\r\n </p>\r\n ) : (\r\n <div className=\"space-y-1\">\r\n {sessionEntries.map(([resumeKey, binding]) => (\r\n <div\r\n key={resumeKey}\r\n className=\"flex items-center justify-between px-2 py-1.5 rounded bg-muted/30 text-xs\"\r\n >\r\n <div className=\"min-w-0\">\r\n <span className=\"font-mono text-foreground truncate block\">{binding.sessionKey}</span>\r\n <span className=\"text-[10px] text-muted-foreground truncate block\">{resumeKey}</span>\r\n </div>\r\n <span className=\"text-[10px] text-muted-foreground shrink-0 ml-2 tabular-nums\">\r\n {new Date(binding.lastUsed).toLocaleTimeString()}\r\n </span>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Error display */}\r\n {error && (\r\n <div className=\"px-3 py-2 border-t border-destructive/30 bg-destructive/5 shrink-0\">\r\n <p className=\"text-xs text-destructive break-words\">{error}</p>\r\n </div>\r\n )}\r\n\r\n {/* Stop confirmation dialog */}\r\n <AlertDialog open={isStopConfirmOpen} onOpenChange={setIsStopConfirmOpen}>\r\n <AlertDialogContent className=\"max-w-sm\">\r\n <AlertDialogHeader>\r\n <AlertDialogTitle className=\"text-base\">\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.stopConfirmTitle', defaultMessage: 'Stop Queue?' })}\r\n </AlertDialogTitle>\r\n <AlertDialogDescription>\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.stopConfirmMessage', defaultMessage: 'Executing tasks will finish, but no new tasks will be started. Pending items will remain in the queue.' })}\r\n </AlertDialogDescription>\r\n </AlertDialogHeader>\r\n <AlertDialogFooter>\r\n <AlertDialogCancel className=\"h-8 text-xs\">\r\n {formatMessage({ id: 'common.cancel', defaultMessage: 'Cancel' })}\r\n </AlertDialogCancel>\r\n <AlertDialogAction\r\n className=\"h-8 text-xs bg-destructive text-destructive-foreground hover:bg-destructive/90\"\r\n onClick={() => { stopQueue(); setIsStopConfirmOpen(false); }}\r\n >\r\n {formatMessage({ id: 'terminalDashboard.queuePanel.scheduler.stop', defaultMessage: 'Stop' })}\r\n </AlertDialogAction>\r\n </AlertDialogFooter>\r\n </AlertDialogContent>\r\n </AlertDialog>\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// BottomInspector Component\r\n// ========================================\r\n// Association chain visualization (Issue -> Queue -> Session).\r\n// Exports InspectorContent (pure content) for embedding in BottomPanel,\r\n// and BottomInspector (legacy standalone collapsible wrapper).\r\n\r\nimport { useState, useCallback, useMemo } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n ChevronDown,\r\n ChevronUp,\r\n Info,\r\n AlertCircle,\r\n ListChecks,\r\n Terminal,\r\n ArrowRight,\r\n} from 'lucide-react';\r\nimport { cn } from '@/lib/utils';\r\nimport {\r\n useIssueQueueIntegrationStore,\r\n selectAssociationChain,\r\n} from '@/stores/issueQueueIntegrationStore';\r\nimport { useQueueExecutionStore } from '@/stores/queueExecutionStore';\r\nimport { useCliSessionStore } from '@/stores/cliSessionStore';\r\nimport { useAssociationHighlight } from './AssociationHighlight';\r\n\r\n// ========== Chain Node ==========\r\n\r\nfunction ChainNode({\r\n icon: Icon,\r\n label,\r\n entityId,\r\n status,\r\n timestamp,\r\n isLast = false,\r\n}: {\r\n icon: React.ComponentType<{ className?: string }>;\r\n label: string;\r\n entityId: string | null;\r\n status?: string;\r\n timestamp?: string;\r\n isLast?: boolean;\r\n}) {\r\n if (!entityId) {\r\n return (\r\n <div className=\"flex items-center gap-2 opacity-40\">\r\n <Icon className=\"w-3.5 h-3.5 text-muted-foreground\" />\r\n <span className=\"text-xs text-muted-foreground\">{label}</span>\r\n <span className=\"text-xs text-muted-foreground italic\">--</span>\r\n {!isLast && <ArrowRight className=\"w-3 h-3 text-muted-foreground mx-1\" />}\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"flex items-center gap-2\">\r\n <Icon className=\"w-3.5 h-3.5 text-foreground\" />\r\n <span className=\"text-xs text-muted-foreground\">{label}</span>\r\n <span className=\"text-xs font-mono font-semibold text-foreground px-1.5 py-0.5 rounded bg-muted\">\r\n {entityId}\r\n </span>\r\n {status && (\r\n <span className=\"text-[10px] text-muted-foreground px-1 py-0.5 rounded border border-border\">\r\n {status}\r\n </span>\r\n )}\r\n {timestamp && (\r\n <span className=\"text-[10px] text-muted-foreground\">\r\n {formatTimestamp(timestamp)}\r\n </span>\r\n )}\r\n {!isLast && <ArrowRight className=\"w-3 h-3 text-muted-foreground mx-1\" />}\r\n </div>\r\n );\r\n}\r\n\r\n/** Format ISO timestamp to short readable form */\r\nfunction formatTimestamp(ts: string): string {\r\n try {\r\n const date = new Date(ts);\r\n return date.toLocaleTimeString(undefined, {\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n second: '2-digit',\r\n });\r\n } catch {\r\n return ts;\r\n }\r\n}\r\n\r\n// ========== InspectorContent (Pure content, no collapsible wrapper) ==========\r\n\r\nexport function InspectorContent() {\r\n const { formatMessage } = useIntl();\r\n const associationChain = useIssueQueueIntegrationStore(selectAssociationChain);\r\n const { chain: highlightedChain } = useAssociationHighlight();\r\n\r\n const activeChain = highlightedChain ?? associationChain;\r\n\r\n const chainDetails = useMemo(() => {\r\n if (!activeChain) return null;\r\n\r\n const executions = Object.values(useQueueExecutionStore.getState().executions);\r\n const sessions = useCliSessionStore.getState().sessions;\r\n\r\n let queueStatus: string | undefined;\r\n let executionTimestamp: string | undefined;\r\n if (activeChain.queueItemId) {\r\n const exec = executions.find((e) => e.queueItemId === activeChain.queueItemId);\r\n if (exec) {\r\n queueStatus = exec.status;\r\n executionTimestamp = exec.startedAt;\r\n }\r\n }\r\n\r\n let sessionStatus: string | undefined;\r\n let sessionTimestamp: string | undefined;\r\n if (activeChain.sessionId) {\r\n const session = sessions[activeChain.sessionId];\r\n if (session) {\r\n sessionStatus = 'active';\r\n sessionTimestamp = session.createdAt;\r\n }\r\n }\r\n\r\n return { queueStatus, executionTimestamp, sessionStatus, sessionTimestamp };\r\n }, [activeChain]);\r\n\r\n const hasChain = activeChain !== null;\r\n\r\n return (\r\n <div className=\"h-full overflow-y-auto px-4 py-3\">\r\n {hasChain ? (\r\n <div className=\"space-y-2\">\r\n <p className=\"text-xs font-medium text-muted-foreground\">\r\n {formatMessage({ id: 'terminalDashboard.inspector.associationChain' })}\r\n </p>\r\n <div className=\"flex items-center gap-1 flex-wrap\">\r\n <ChainNode\r\n icon={AlertCircle}\r\n label=\"Issue\"\r\n entityId={activeChain.issueId}\r\n />\r\n <ChainNode\r\n icon={ListChecks}\r\n label=\"Queue\"\r\n entityId={activeChain.queueItemId}\r\n status={chainDetails?.queueStatus}\r\n timestamp={chainDetails?.executionTimestamp}\r\n />\r\n <ChainNode\r\n icon={Terminal}\r\n label=\"Session\"\r\n entityId={activeChain.sessionId}\r\n status={chainDetails?.sessionStatus}\r\n timestamp={chainDetails?.sessionTimestamp}\r\n isLast\r\n />\r\n </div>\r\n </div>\r\n ) : (\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'terminalDashboard.inspector.noSelection' })}\r\n </p>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Legacy Standalone Component ==========\r\n\r\nexport function BottomInspector() {\r\n const { formatMessage } = useIntl();\r\n const [isOpen, setIsOpen] = useState(false);\r\n\r\n const associationChain = useIssueQueueIntegrationStore(selectAssociationChain);\r\n const { chain: highlightedChain } = useAssociationHighlight();\r\n\r\n // Use highlighted chain from context, fall back to store association chain\r\n const activeChain = highlightedChain ?? associationChain;\r\n\r\n const toggle = useCallback(() => {\r\n setIsOpen((prev) => !prev);\r\n }, []);\r\n\r\n // Resolve additional details from stores\r\n const chainDetails = useMemo(() => {\r\n if (!activeChain) return null;\r\n\r\n const executions = Object.values(useQueueExecutionStore.getState().executions);\r\n const sessions = useCliSessionStore.getState().sessions;\r\n\r\n // Find matching execution for queue status\r\n let queueStatus: string | undefined;\r\n let executionTimestamp: string | undefined;\r\n if (activeChain.queueItemId) {\r\n const exec = executions.find((e) => e.queueItemId === activeChain.queueItemId);\r\n if (exec) {\r\n queueStatus = exec.status;\r\n executionTimestamp = exec.startedAt;\r\n }\r\n }\r\n\r\n // Find session metadata\r\n let sessionStatus: string | undefined;\r\n let sessionTimestamp: string | undefined;\r\n if (activeChain.sessionId) {\r\n const session = sessions[activeChain.sessionId];\r\n if (session) {\r\n sessionStatus = 'active';\r\n sessionTimestamp = session.createdAt;\r\n }\r\n }\r\n\r\n return {\r\n queueStatus,\r\n executionTimestamp,\r\n sessionStatus,\r\n sessionTimestamp,\r\n };\r\n }, [activeChain]);\r\n\r\n const hasChain = activeChain !== null;\r\n\r\n return (\r\n <div className={cn('border-t border-border bg-muted/30 shrink-0 transition-all duration-200')}>\r\n {/* Toggle button */}\r\n <button\r\n onClick={toggle}\r\n className=\"flex items-center gap-2 w-full px-4 py-1.5 text-sm text-muted-foreground hover:text-foreground transition-colors\"\r\n >\r\n <Info className=\"w-4 h-4\" />\r\n <span className=\"font-medium\">\r\n {formatMessage({ id: 'terminalDashboard.inspector.title' })}\r\n </span>\r\n {hasChain && (\r\n <span className=\"ml-1 w-2 h-2 rounded-full bg-primary shrink-0\" />\r\n )}\r\n {isOpen ? (\r\n <ChevronDown className=\"w-4 h-4 ml-auto\" />\r\n ) : (\r\n <ChevronUp className=\"w-4 h-4 ml-auto\" />\r\n )}\r\n </button>\r\n\r\n {/* Collapsible content */}\r\n <div\r\n className={cn(\r\n 'overflow-hidden transition-all duration-200',\r\n isOpen ? 'max-h-40 opacity-100' : 'max-h-0 opacity-0'\r\n )}\r\n >\r\n <div className=\"px-4 pb-3\">\r\n {hasChain ? (\r\n <div className=\"space-y-2\">\r\n {/* Chain label */}\r\n <p className=\"text-xs font-medium text-muted-foreground\">\r\n {formatMessage({ id: 'terminalDashboard.inspector.associationChain' })}\r\n </p>\r\n {/* Chain visualization: Issue -> Queue -> Session */}\r\n <div className=\"flex items-center gap-1 flex-wrap\">\r\n <ChainNode\r\n icon={AlertCircle}\r\n label=\"Issue\"\r\n entityId={activeChain.issueId}\r\n />\r\n <ChainNode\r\n icon={ListChecks}\r\n label=\"Queue\"\r\n entityId={activeChain.queueItemId}\r\n status={chainDetails?.queueStatus}\r\n timestamp={chainDetails?.executionTimestamp}\r\n />\r\n <ChainNode\r\n icon={Terminal}\r\n label=\"Session\"\r\n entityId={activeChain.sessionId}\r\n status={chainDetails?.sessionStatus}\r\n timestamp={chainDetails?.sessionTimestamp}\r\n isLast\r\n />\r\n </div>\r\n </div>\r\n ) : (\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'terminalDashboard.inspector.noSelection' })}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// Execution Monitor Panel\r\n// ========================================\r\n// Panel for monitoring workflow executions and orchestration plans in Terminal Dashboard.\r\n// Displays execution progress, step list, control buttons, and active orchestration plans.\r\n\r\nimport { useMemo } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Play,\r\n Pause,\r\n Square,\r\n CheckCircle2,\r\n XCircle,\r\n Circle,\r\n Loader2,\r\n Clock,\r\n Terminal,\r\n Bot,\r\n} from 'lucide-react';\r\nimport { cn } from '@/lib/utils';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { Progress } from '@/components/ui/Progress';\r\nimport {\r\n useExecutionMonitorStore,\r\n selectCurrentExecution,\r\n selectActiveExecutions,\r\n} from '@/stores/executionMonitorStore';\r\nimport { useOrchestratorStore, selectActivePlans } from '@/stores';\r\nimport type { ExecutionStatus, StepInfo } from '@/stores/executionMonitorStore';\r\nimport type { OrchestrationRunState } from '@/stores/orchestratorStore';\r\nimport type { OrchestrationStatus } from '@/types/orchestrator';\r\n\r\n// ========== Status Config ==========\r\n\r\nconst statusConfig: Record<ExecutionStatus, { label: string; color: string; bgColor: string }> = {\r\n pending: { label: 'Pending', color: 'text-muted-foreground', bgColor: 'bg-muted' },\r\n running: { label: 'Running', color: 'text-primary', bgColor: 'bg-primary/10' },\r\n paused: { label: 'Paused', color: 'text-amber-500', bgColor: 'bg-amber-500/10' },\r\n completed: { label: 'Completed', color: 'text-green-500', bgColor: 'bg-green-500/10' },\r\n failed: { label: 'Failed', color: 'text-destructive', bgColor: 'bg-destructive/10' },\r\n cancelled: { label: 'Cancelled', color: 'text-muted-foreground', bgColor: 'bg-muted' },\r\n};\r\n\r\nconst ORCHESTRATION_STATUS_CONFIG: Record<\r\n OrchestrationStatus,\r\n { variant: 'default' | 'info' | 'success' | 'destructive' | 'secondary' | 'warning'; messageId: string }\r\n> = {\r\n running: { variant: 'info', messageId: 'terminalDashboard.agentList.statusRunning' },\r\n completed: { variant: 'success', messageId: 'terminalDashboard.agentList.statusCompleted' },\r\n failed: { variant: 'destructive', messageId: 'terminalDashboard.agentList.statusFailed' },\r\n paused: { variant: 'warning', messageId: 'terminalDashboard.agentList.statusPaused' },\r\n pending: { variant: 'secondary', messageId: 'terminalDashboard.agentList.statusPending' },\r\n cancelled: { variant: 'secondary', messageId: 'terminalDashboard.agentList.statusPending' },\r\n};\r\n\r\n// ========== Step Status Icon ==========\r\n\r\nfunction StepStatusIcon({ status }: { status: ExecutionStatus }) {\r\n switch (status) {\r\n case 'pending':\r\n return <Circle className=\"w-4 h-4 text-muted-foreground\" />;\r\n case 'running':\r\n return <Loader2 className=\"w-4 h-4 text-primary animate-spin\" />;\r\n case 'completed':\r\n return <CheckCircle2 className=\"w-4 h-4 text-green-500\" />;\r\n case 'failed':\r\n return <XCircle className=\"w-4 h-4 text-destructive\" />;\r\n case 'paused':\r\n return <Pause className=\"w-4 h-4 text-amber-500\" />;\r\n case 'cancelled':\r\n return <Square className=\"w-4 h-4 text-muted-foreground\" />;\r\n default:\r\n return <Circle className=\"w-4 h-4 text-muted-foreground opacity-50\" />;\r\n }\r\n}\r\n\r\n// ========== Step List Item ==========\r\n\r\ninterface StepListItemProps {\r\n step: StepInfo;\r\n isCurrent: boolean;\r\n}\r\n\r\nfunction StepListItem({ step, isCurrent }: StepListItemProps) {\r\n return (\r\n <div\r\n className={cn(\r\n 'flex items-start gap-3 px-3 py-2 rounded-md transition-colors',\r\n isCurrent && step.status === 'running' && 'bg-primary/5 border border-primary/20',\r\n step.status === 'failed' && 'bg-destructive/5'\r\n )}\r\n >\r\n <div className=\"pt-0.5 shrink-0\">\r\n <StepStatusIcon status={step.status} />\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <span\r\n className={cn(\r\n 'text-sm font-medium truncate block',\r\n step.status === 'completed' && 'text-muted-foreground',\r\n step.status === 'running' && 'text-foreground',\r\n step.status === 'failed' && 'text-destructive'\r\n )}\r\n >\r\n {step.name}\r\n </span>\r\n {step.error && (\r\n <p className=\"text-xs text-destructive mt-1 truncate\">{step.error}</p>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Orchestration Plan Item ==========\r\n\r\nfunction OrchestrationPlanItem({\r\n runState,\r\n}: {\r\n runState: OrchestrationRunState;\r\n}) {\r\n const { formatMessage } = useIntl();\r\n const { plan, status, stepStatuses } = runState;\r\n\r\n const totalSteps = plan.steps.length;\r\n const completedSteps = useMemo(\r\n () =>\r\n Object.values(stepStatuses).filter(\r\n (s) => s.status === 'completed' || s.status === 'skipped'\r\n ).length,\r\n [stepStatuses]\r\n );\r\n\r\n const config = ORCHESTRATION_STATUS_CONFIG[status] ?? ORCHESTRATION_STATUS_CONFIG.pending;\r\n const isRunning = status === 'running';\r\n\r\n return (\r\n <div\r\n className={cn(\r\n 'flex items-center gap-2 px-3 py-2 rounded-md',\r\n 'hover:bg-muted/30 transition-colors'\r\n )}\r\n >\r\n <div className=\"shrink-0\">\r\n {isRunning ? (\r\n <Loader2 className=\"w-4 h-4 text-primary animate-spin\" />\r\n ) : (\r\n <Bot className=\"w-4 h-4 text-muted-foreground\" />\r\n )}\r\n </div>\r\n\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"text-sm font-medium truncate\">{plan.name}</p>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage(\r\n { id: 'terminalDashboard.agentList.stepLabel' },\r\n { current: completedSteps, total: totalSteps }\r\n )}\r\n </p>\r\n </div>\r\n\r\n <Badge variant={config.variant} className=\"text-xs px-2 py-0 shrink-0\">\r\n {formatMessage({ id: config.messageId })}\r\n </Badge>\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\nexport function ExecutionMonitorPanel() {\r\n const { formatMessage } = useIntl();\r\n\r\n const currentExecution = useExecutionMonitorStore(selectCurrentExecution);\r\n const activeExecutions = useExecutionMonitorStore(selectActiveExecutions);\r\n const selectExecution = useExecutionMonitorStore((s) => s.selectExecution);\r\n const pauseExecution = useExecutionMonitorStore((s) => s.pauseExecution);\r\n const resumeExecution = useExecutionMonitorStore((s) => s.resumeExecution);\r\n const stopExecution = useExecutionMonitorStore((s) => s.stopExecution);\r\n const clearExecution = useExecutionMonitorStore((s) => s.clearExecution);\r\n\r\n // Orchestration plans\r\n const activePlans = useOrchestratorStore(selectActivePlans);\r\n const planEntries = useMemo(\r\n () => Object.entries(activePlans),\r\n [activePlans]\r\n );\r\n\r\n const executions = Object.values(activeExecutions);\r\n const hasContent = executions.length > 0 || planEntries.length > 0;\r\n\r\n if (!hasContent) {\r\n return (\r\n <div className=\"flex flex-col items-center justify-center h-full text-muted-foreground p-8\">\r\n <Terminal className=\"w-10 h-10 mb-3 opacity-30\" />\r\n <p className=\"text-sm font-medium\">\r\n {formatMessage({ id: 'executionMonitor.noExecutions', defaultMessage: 'No active executions' })}\r\n </p>\r\n <p className=\"text-xs mt-1 opacity-70\">\r\n {formatMessage({ id: 'executionMonitor.sendToTerminal', defaultMessage: 'Send a workflow to terminal to start' })}\r\n </p>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n {/* Orchestration Plans Section */}\r\n {planEntries.length > 0 && (\r\n <div className=\"border-b border-border shrink-0\">\r\n <div className=\"flex items-center gap-2 px-4 py-2 bg-muted/20\">\r\n <Bot className=\"w-4 h-4 text-muted-foreground\" />\r\n <h3 className=\"text-xs font-semibold text-muted-foreground uppercase tracking-wide\">\r\n {formatMessage({ id: 'terminalDashboard.agentList.title' })}\r\n </h3>\r\n <Badge variant=\"secondary\" className=\"text-[10px] px-1.5 py-0 ml-auto\">\r\n {planEntries.length}\r\n </Badge>\r\n </div>\r\n <div className=\"divide-y divide-border/50\">\r\n {planEntries.map(([planId, runState]) => (\r\n <OrchestrationPlanItem key={planId} runState={runState} />\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Workflow Executions Section */}\r\n {executions.length > 0 && (\r\n <>\r\n {/* Execution selector (if multiple) */}\r\n {executions.length > 1 && (\r\n <div className=\"border-b border-border p-2 shrink-0\">\r\n <div className=\"flex flex-wrap gap-1\">\r\n {executions.map((exec) => (\r\n <button\r\n key={exec.executionId}\r\n onClick={() => selectExecution(exec.executionId)}\r\n className={cn(\r\n 'px-2 py-1 text-xs rounded-md transition-colors truncate max-w-[120px]',\r\n currentExecution?.executionId === exec.executionId\r\n ? 'bg-primary text-primary-foreground'\r\n : 'bg-muted hover:bg-muted/80 text-muted-foreground'\r\n )}\r\n >\r\n {exec.flowName}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {currentExecution && (\r\n <>\r\n {/* Header */}\r\n <div className=\"p-4 border-b border-border space-y-3 shrink-0\">\r\n <div className=\"flex items-center gap-3\">\r\n <h3 className=\"text-sm font-semibold text-foreground truncate flex-1\">\r\n {currentExecution.flowName}\r\n </h3>\r\n <Badge\r\n variant=\"secondary\"\r\n className={cn('shrink-0', statusConfig[currentExecution.status].bgColor)}\r\n >\r\n {statusConfig[currentExecution.status].label}\r\n </Badge>\r\n </div>\r\n\r\n {/* Progress */}\r\n <div className=\"space-y-1\">\r\n <div className=\"flex justify-between text-xs text-muted-foreground\">\r\n <span>\r\n {formatMessage(\r\n { id: 'executionMonitor.progress', defaultMessage: '{completed}/{total} steps' },\r\n { completed: currentExecution.completedSteps, total: currentExecution.totalSteps || currentExecution.steps.length }\r\n )}\r\n </span>\r\n <span>\r\n {Math.round(\r\n (currentExecution.completedSteps / (currentExecution.totalSteps || currentExecution.steps.length || 1)) * 100\r\n )}%\r\n </span>\r\n </div>\r\n <Progress\r\n value={\r\n (currentExecution.completedSteps / (currentExecution.totalSteps || currentExecution.steps.length || 1)) * 100\r\n }\r\n className=\"h-2\"\r\n />\r\n </div>\r\n\r\n {/* Meta info */}\r\n <div className=\"flex items-center gap-3 text-xs text-muted-foreground\">\r\n <span className=\"flex items-center gap-1\">\r\n <Clock className=\"w-3 h-3\" />\r\n {new Date(currentExecution.startedAt).toLocaleTimeString()}\r\n </span>\r\n <span className=\"flex items-center gap-1\">\r\n <Terminal className=\"w-3 h-3\" />\r\n <span className=\"truncate max-w-[100px]\">{currentExecution.sessionKey.slice(0, 20)}...</span>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n {/* Step list */}\r\n <div className=\"flex-1 overflow-y-auto p-2 space-y-1\">\r\n {currentExecution.steps.map((step) => (\r\n <StepListItem\r\n key={step.id}\r\n step={step}\r\n isCurrent={step.id === currentExecution.currentStepId}\r\n />\r\n ))}\r\n </div>\r\n\r\n {/* Control bar */}\r\n <div className=\"p-3 border-t border-border flex items-center gap-2 shrink-0\">\r\n {currentExecution.status === 'running' && (\r\n <>\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => pauseExecution(currentExecution.executionId)}\r\n className=\"gap-1.5\"\r\n >\r\n <Pause className=\"w-3.5 h-3.5\" />\r\n {formatMessage({ id: 'executionMonitor.pause', defaultMessage: 'Pause' })}\r\n </Button>\r\n <Button\r\n variant=\"destructive\"\r\n size=\"sm\"\r\n onClick={() => stopExecution(currentExecution.executionId)}\r\n className=\"gap-1.5\"\r\n >\r\n <Square className=\"w-3.5 h-3.5\" />\r\n {formatMessage({ id: 'executionMonitor.stop', defaultMessage: 'Stop' })}\r\n </Button>\r\n </>\r\n )}\r\n\r\n {currentExecution.status === 'paused' && (\r\n <>\r\n <Button\r\n variant=\"default\"\r\n size=\"sm\"\r\n onClick={() => resumeExecution(currentExecution.executionId)}\r\n className=\"gap-1.5\"\r\n >\r\n <Play className=\"w-3.5 h-3.5\" />\r\n {formatMessage({ id: 'executionMonitor.resume', defaultMessage: 'Resume' })}\r\n </Button>\r\n <Button\r\n variant=\"destructive\"\r\n size=\"sm\"\r\n onClick={() => stopExecution(currentExecution.executionId)}\r\n className=\"gap-1.5\"\r\n >\r\n <Square className=\"w-3.5 h-3.5\" />\r\n {formatMessage({ id: 'executionMonitor.stop', defaultMessage: 'Stop' })}\r\n </Button>\r\n </>\r\n )}\r\n\r\n {(currentExecution.status === 'completed' ||\r\n currentExecution.status === 'failed' ||\r\n currentExecution.status === 'cancelled') && (\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => clearExecution(currentExecution.executionId)}\r\n className=\"gap-1.5 ml-auto\"\r\n >\r\n {formatMessage({ id: 'executionMonitor.clear', defaultMessage: 'Clear' })}\r\n </Button>\r\n )}\r\n </div>\r\n </>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default ExecutionMonitorPanel;\r\n","// ========================================\n// FileSidebarPanel Component\n// ========================================\n// Right sidebar file browser for Terminal Dashboard.\n// Displays file tree and allows showing files in focused terminal pane.\n\nimport * as React from 'react';\nimport { useIntl } from 'react-intl';\nimport { FolderOpen, RefreshCw, Loader2, ChevronLeft, FileText, Eye, EyeOff } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/Button';\nimport { TreeView } from '@/components/shared/TreeView';\nimport { useFileExplorer } from '@/hooks/useFileExplorer';\nimport { useTerminalGridStore, selectTerminalGridFocusedPaneId } from '@/stores/terminalGridStore';\nimport type { FileSystemNode } from '@/types/file-explorer';\n\nexport interface FileSidebarPanelProps {\n /** Root path for file explorer */\n rootPath: string;\n /** Whether the panel is enabled (has project path) */\n enabled?: boolean;\n /** Optional class name */\n className?: string;\n /** Callback when panel collapse is requested */\n onCollapse?: () => void;\n /** Initial width of the panel */\n width?: number;\n}\n\nexport function FileSidebarPanel({\n rootPath,\n enabled = true,\n className,\n onCollapse,\n width = 280,\n}: FileSidebarPanelProps) {\n const { formatMessage } = useIntl();\n\n // Store\n const focusedPaneId = useTerminalGridStore(selectTerminalGridFocusedPaneId);\n const showFileInPane = useTerminalGridStore((s) => s.showFileInPane);\n\n // File explorer hook\n const {\n rootNodes,\n state,\n isLoading,\n isFetching,\n error,\n refetch,\n setSelectedFile,\n toggleExpanded,\n toggleShowHidden,\n } = useFileExplorer({\n rootPath,\n maxDepth: 6,\n enabled,\n });\n\n // Handle node click\n const handleNodeClick = React.useCallback(\n (node: FileSystemNode) => {\n // Only files can be shown in pane\n if (node.type === 'file') {\n setSelectedFile(node.path);\n // Show file in focused pane if one exists\n if (focusedPaneId) {\n showFileInPane(focusedPaneId, node.path);\n }\n }\n },\n [focusedPaneId, setSelectedFile, showFileInPane]\n );\n\n // Handle refresh\n const handleRefresh = React.useCallback(() => {\n refetch();\n }, [refetch]);\n\n // Handle collapse\n const handleCollapse = React.useCallback(() => {\n onCollapse?.();\n }, [onCollapse]);\n\n // Disabled state (no project path)\n if (!enabled) {\n return (\n <div\n className={cn(\n 'flex flex-col h-full border-l border-border bg-background',\n className\n )}\n style={{ width }}\n >\n <div className=\"flex items-center justify-between px-3 py-2 border-b border-border bg-muted/30\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n {formatMessage({ id: 'terminalDashboard.fileSidebar.title', defaultMessage: 'Files' })}\n </span>\n {onCollapse && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 w-6 p-0\"\n onClick={handleCollapse}\n >\n <ChevronLeft className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n </div>\n <div className=\"flex-1 flex flex-col items-center justify-center px-4 text-center text-muted-foreground\">\n <FolderOpen className=\"h-10 w-10 mb-3 opacity-40\" />\n <p className=\"text-xs\">\n {formatMessage({ id: 'terminalDashboard.fileSidebar.noProject', defaultMessage: 'No project open' })}\n </p>\n <p className=\"text-[10px] mt-1 opacity-70\">\n {formatMessage({ id: 'terminalDashboard.fileSidebar.openProjectHint', defaultMessage: 'Open a project to browse files' })}\n </p>\n </div>\n </div>\n );\n }\n\n return (\n <div\n className={cn(\n 'flex flex-col h-full border-l border-border bg-background',\n className\n )}\n style={{ width }}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between gap-2 px-3 py-2 border-b border-border bg-muted/30 shrink-0\">\n <div className=\"flex items-center gap-2 min-w-0 flex-1\">\n <FolderOpen className=\"h-3.5 w-3.5 text-muted-foreground shrink-0\" />\n <span className=\"text-xs font-medium truncate\">\n {formatMessage({ id: 'terminalDashboard.fileSidebar.title', defaultMessage: 'Files' })}\n </span>\n {isFetching && !isLoading && (\n <Loader2 className=\"h-3 w-3 animate-spin text-muted-foreground\" />\n )}\n </div>\n <div className=\"flex items-center gap-1 shrink-0\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 w-6 p-0\"\n onClick={toggleShowHidden}\n title={formatMessage({ id: 'terminalDashboard.fileBrowser.showHidden' })}\n >\n {state.showHiddenFiles ? <EyeOff className=\"h-3.5 w-3.5\" /> : <Eye className=\"h-3.5 w-3.5\" />}\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 w-6 p-0\"\n onClick={handleRefresh}\n disabled={isFetching}\n title={formatMessage({ id: 'terminalDashboard.fileSidebar.refresh', defaultMessage: 'Refresh' })}\n >\n <RefreshCw className={cn('h-3.5 w-3.5', isFetching && 'animate-spin')} />\n </Button>\n {onCollapse && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 w-6 p-0\"\n onClick={handleCollapse}\n title={formatMessage({ id: 'terminalDashboard.fileSidebar.collapse', defaultMessage: 'Collapse' })}\n >\n <ChevronLeft className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n </div>\n </div>\n\n {/* Current path indicator */}\n <div className=\"px-3 py-1.5 border-b border-border/50 bg-muted/10 shrink-0\">\n <div className=\"text-[10px] text-muted-foreground truncate font-mono\" title={rootPath}>\n {rootPath}\n </div>\n </div>\n\n {/* Tree view */}\n <div className=\"flex-1 min-h-0 overflow-y-auto\">\n {isLoading ? (\n <div className=\"flex items-center justify-center py-8 text-muted-foreground\">\n <Loader2 className=\"w-5 h-5 animate-spin\" />\n <span className=\"ml-2 text-xs\">\n {formatMessage({ id: 'terminalDashboard.fileBrowser.loading', defaultMessage: 'Loading...' })}\n </span>\n </div>\n ) : error ? (\n <div className=\"p-3 text-xs text-destructive\">\n {formatMessage({ id: 'terminalDashboard.fileBrowser.loadFailed', defaultMessage: 'Failed to load files' })}\n </div>\n ) : rootNodes.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-8 px-4 text-center text-muted-foreground\">\n <FileText className=\"h-10 w-10 mb-3 opacity-40\" />\n <p className=\"text-xs\">\n {formatMessage({ id: 'terminalDashboard.fileSidebar.empty', defaultMessage: 'No files found' })}\n </p>\n </div>\n ) : (\n <TreeView\n nodes={rootNodes}\n expandedPaths={state.expandedPaths}\n selectedPath={state.selectedFile}\n onNodeClick={handleNodeClick}\n onToggle={toggleExpanded}\n maxDepth={0}\n className=\"py-1\"\n />\n )}\n </div>\n\n {/* Footer hint */}\n {!focusedPaneId && (\n <div className=\"px-3 py-2 border-t border-border bg-muted/10 shrink-0\">\n <p className=\"text-[10px] text-muted-foreground text-center\">\n {formatMessage({ id: 'terminalDashboard.fileSidebar.selectPaneHint', defaultMessage: 'Click a pane to show file preview' })}\n </p>\n </div>\n )}\n </div>\n );\n}\n\nexport default FileSidebarPanel;\n","// ========================================\n// Terminal Dashboard Page (V2)\n// ========================================\n// Terminal-first layout with fixed session sidebar + floating panels + right file sidebar.\n// Left sidebar: SessionGroupTree (always visible)\n// Main area: TerminalGrid (tmux-style split panes)\n// Right sidebar: FileSidebarPanel (file tree, resizable)\n// Top: DashboardToolbar with panel toggles and layout presets\n// Floating panels: Issues, Queue, Inspector, Execution Monitor (overlay, mutually exclusive)\n// Fullscreen mode: Uses global isImmersiveMode to hide app chrome (Header + Sidebar)\n\nimport { useState, useCallback, useEffect } from 'react';\nimport { useIntl } from 'react-intl';\nimport { Allotment } from 'allotment';\nimport 'allotment/dist/style.css';\nimport { AssociationHighlightProvider } from '@/components/terminal-dashboard/AssociationHighlight';\nimport { DashboardToolbar, type PanelId } from '@/components/terminal-dashboard/DashboardToolbar';\nimport { TerminalGrid } from '@/components/terminal-dashboard/TerminalGrid';\nimport { FloatingPanel } from '@/components/terminal-dashboard/FloatingPanel';\nimport { SessionGroupTree } from '@/components/terminal-dashboard/SessionGroupTree';\nimport { IssuePanel } from '@/components/terminal-dashboard/IssuePanel';\nimport { QueuePanel } from '@/components/terminal-dashboard/QueuePanel';\nimport { QueueListColumn } from '@/components/terminal-dashboard/QueueListColumn';\nimport { SchedulerPanel } from '@/components/terminal-dashboard/SchedulerPanel';\nimport { InspectorContent } from '@/components/terminal-dashboard/BottomInspector';\nimport { ExecutionMonitorPanel } from '@/components/terminal-dashboard/ExecutionMonitorPanel';\nimport { FileSidebarPanel } from '@/components/terminal-dashboard/FileSidebarPanel';\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\nimport { useAppStore, selectIsImmersiveMode } from '@/stores/appStore';\nimport { useConfigStore } from '@/stores/configStore';\n\n// ========== Main Page Component ==========\n\nexport function TerminalDashboardPage() {\n const { formatMessage } = useIntl();\n const [activePanel, setActivePanel] = useState<PanelId | null>(null);\n const [isFileSidebarOpen, setIsFileSidebarOpen] = useState(true);\n const [isSessionSidebarOpen, setIsSessionSidebarOpen] = useState(true);\n\n const projectPath = useWorkflowStore(selectProjectPath);\n\n // Feature flags for panel visibility\n const featureFlags = useConfigStore((s) => s.featureFlags);\n\n // Use global immersive mode state (only affects AppShell chrome)\n const isImmersiveMode = useAppStore(selectIsImmersiveMode);\n const toggleImmersiveMode = useAppStore((s) => s.toggleImmersiveMode);\n\n const togglePanel = useCallback((panelId: PanelId) => {\n setActivePanel((prev) => (prev === panelId ? null : panelId));\n }, []);\n\n const closePanel = useCallback(() => {\n setActivePanel(null);\n }, []);\n\n useEffect(() => {\n setActivePanel(null);\n }, [projectPath]);\n\n return (\n <div className={`flex flex-col overflow-hidden ${isImmersiveMode ? 'h-screen' : 'h-[calc(100vh-56px)]'}`}>\n <AssociationHighlightProvider scopeKey={projectPath ?? 'default'}>\n {/* Global toolbar */}\n <DashboardToolbar\n activePanel={activePanel}\n onTogglePanel={togglePanel}\n isFileSidebarOpen={isFileSidebarOpen}\n onToggleFileSidebar={() => setIsFileSidebarOpen((prev) => !prev)}\n isSessionSidebarOpen={isSessionSidebarOpen}\n onToggleSessionSidebar={() => setIsSessionSidebarOpen((prev) => !prev)}\n isFullscreen={isImmersiveMode}\n onToggleFullscreen={toggleImmersiveMode}\n />\n\n {/* Main content with three-column layout */}\n <div className=\"flex-1 min-h-0\">\n <Allotment className=\"h-full\">\n {/* Session sidebar (controlled by local state, not immersive mode) */}\n {isSessionSidebarOpen && (\n <Allotment.Pane preferredSize={240} minSize={180} maxSize={320}>\n <div className=\"h-full flex flex-col border-r border-border\">\n <div className=\"flex-1 min-h-0 overflow-y-auto\">\n <SessionGroupTree />\n </div>\n </div>\n </Allotment.Pane>\n )}\n\n {/* Terminal grid (flexible) */}\n <Allotment.Pane preferredSize={-1} minSize={300}>\n <TerminalGrid />\n </Allotment.Pane>\n\n {/* File sidebar (controlled by local state, not immersive mode) */}\n {isFileSidebarOpen && (\n <Allotment.Pane preferredSize={280} minSize={200} maxSize={400}>\n <FileSidebarPanel\n rootPath={projectPath ?? '/'}\n enabled={!!projectPath}\n onCollapse={() => setIsFileSidebarOpen(false)}\n />\n </Allotment.Pane>\n )}\n </Allotment>\n </div>\n\n {/* Floating panels (always available) */}\n <FloatingPanel\n isOpen={activePanel === 'issues'}\n onClose={closePanel}\n title={formatMessage({ id: 'terminalDashboard.toolbar.issues' })}\n side=\"left\"\n width={700}\n >\n <div className=\"flex h-full\">\n <div className=\"flex-1 min-w-0 border-r border-border\">\n <IssuePanel />\n </div>\n <div className=\"flex-1 min-w-0 flex flex-col\">\n <div className=\"px-3 py-2 border-b border-border shrink-0\">\n <h3 className=\"text-sm font-semibold\">{formatMessage({ id: 'terminalDashboard.toolbar.queue' })}</h3>\n </div>\n <QueueListColumn />\n </div>\n </div>\n </FloatingPanel>\n\n {featureFlags.dashboardQueuePanelEnabled && (\n <FloatingPanel\n isOpen={activePanel === 'queue'}\n onClose={closePanel}\n title={formatMessage({ id: 'terminalDashboard.toolbar.queue' })}\n side=\"right\"\n width={400}\n >\n <QueuePanel />\n </FloatingPanel>\n )}\n\n {featureFlags.dashboardInspectorEnabled && (\n <FloatingPanel\n isOpen={activePanel === 'inspector'}\n onClose={closePanel}\n title={formatMessage({ id: 'terminalDashboard.toolbar.inspector' })}\n side=\"right\"\n width={360}\n >\n <InspectorContent />\n </FloatingPanel>\n )}\n\n {featureFlags.dashboardExecutionMonitorEnabled && (\n <FloatingPanel\n isOpen={activePanel === 'execution'}\n onClose={closePanel}\n title={formatMessage({ id: 'terminalDashboard.toolbar.executionMonitor', defaultMessage: 'Execution Monitor' })}\n side=\"right\"\n width={380}\n >\n <ExecutionMonitorPanel />\n </FloatingPanel>\n )}\n\n <FloatingPanel\n isOpen={activePanel === 'scheduler'}\n onClose={closePanel}\n title={formatMessage({ id: 'terminalDashboard.toolbar.scheduler', defaultMessage: 'Scheduler' })}\n side=\"right\"\n width={340}\n >\n <SchedulerPanel />\n </FloatingPanel>\n </AssociationHighlightProvider>\n </div>\n );\n}\n\nexport default TerminalDashboardPage;\n"],"names":["CircleDot","createLucideIcon","Eraser","ListPlus","WifiOff","AssociationHighlightContext","createContext","AssociationHighlightProvider","children","scopeKey","chain","setChainState","useState","lastScopeKeyRef","useRef","useEffect","setChain","useCallback","nextChain","isHighlighted","entityId","entityType","value","useMemo","jsx","useAssociationHighlight","ctx","useContext","generateTag","tool","time","CliConfigModal","isOpen","onClose","defaultWorkingDir","onCreateSession","formatMessage","useIntl","cliTools","useConfigStore","selectCliTools","enabledTools","React.useMemo","config","key","setTool","React.useState","model","setModel","launchMode","setLaunchMode","preferredShell","setPreferredShell","workingDir","setWorkingDir","tag","setTag","isSubmitting","setIsSubmitting","error","setError","modelInputValue","setModelInputValue","isModelDropdownOpen","setIsModelDropdownOpen","modelContainerRef","React.useRef","modelInputRef","cliSettings","useCliSettings","currentProvider","enabledCliSettings","s","settingsEndpointId","setSettingsEndpointId","React.useEffect","modelOptions","endpoint","_a","toolConfig","_b","models","regenerateTag","React.useCallback","suffix","filteredModelOptions","query","m","handleClickOutside","e","handleToolChange","nextTool","nextConfig","nextModels","handleBrowse","handleCreate","dir","finalTag","err","Dialog","open","jsxs","DialogContent","DialogHeader","DialogTitle","DialogDescription","Label","Input","Button","RefreshCw","Select","SelectTrigger","SelectValue","SelectContent","t","SelectItem","v","ChevronDown","cn","id","RadioGroup","RadioGroupItem","FolderOpen","DialogFooter","LAYOUT_PRESETS","Square","Columns2","Rows2","LayoutGrid","DashboardToolbar","activePanel","onTogglePanel","isFileSidebarOpen","onToggleFileSidebar","isSessionSidebarOpen","onToggleSessionSidebar","isFullscreen","onToggleFullscreen","openCount","useIssues","queueQuery","useIssueQueue","queueCount","grouped","count","items","hasChain","useIssueQueueIntegrationStore","selectAssociationChain","executionCount","useExecutionMonitorStore","selectActiveExecutionCount","isSchedulerActive","useQueueSchedulerStore","selectQueueSchedulerStatus","featureFlags","showQueue","showInspector","showExecution","resetLayout","useTerminalGridStore","handlePreset","preset","projectPath","useWorkflowStore","selectProjectPath","focusedPaneId","selectTerminalGridFocusedPaneId","createSessionAndAssign","updateTerminalMeta","useSessionManagerStore","isCreating","setIsCreating","isConfigOpen","setIsConfigOpen","getOrCreateFocusedPane","handleOpenConfig","handleCreateConfiguredSession","targetPaneId","result","message","toast","Fragment","Loader2","Plus","ToolbarButton","Folder","AlertCircle","ListChecks","Info","Activity","Gauge","Minimize2","Maximize2","Icon","label","isActive","onClick","badge","dot","loading","Badge","TRAILING_PUNCTUATION","WRAP_QUOTES","normalizePath","raw","ARTIFACT_PATTERNS","detectCcArtifacts","text","candidates","type","pattern","match","path","full","group","rel","index","a","b","results","seen","c","getVariant","getLabelId","basename","p","parts","ArtifactTag","className","display","badgeVariants","ARTIFACT_DEBOUNCE_MS","MAX_ARTIFACT_TAGS","isAbsolutePath","joinPath","base","relative","sep","r","resolveArtifactPath","mergeArtifacts","prev","next","map","changed","merged","TerminalInstance","sessionId","onRevealPath","outputChunks","useCliSessionStore","setBuffer","clearOutput","artifacts","setArtifacts","terminalHostRef","xtermRef","fitAddonRef","lastChunkIndexRef","pendingArtifactTextRef","artifactTimerRef","pendingInputRef","flushTimerRef","sessionIdRef","projectPathRef","handleTerminalClick","handleArtifactClick","resolved","scheduleArtifactParse","pending","detected","flushInput","sendCliSessionText","scheduleFlush","term","XTerm","fitAddon","FitAddon","data","fetchCliSessionBuffer","buffer","chunks","start","feedMonitor","newTextParts","i","host","resize","resizeCliSession","ro","statusDotStyles","TerminalPane","paneId","panes","selectTerminalGridPanes","layout","splitPane","closePane","assignSession","setFocused","setPaneDisplayMode","pane","displayMode","filePath","isFocused","canClose","getAllPaneIds","isFileMode","terminalMetas","selectTerminalMetas","sessions","pauseSession","resumeSession","restartSession","closeSession","isRestarting","setIsRestarting","isTogglingPause","setIsTogglingPause","isClosingSession","setIsClosingSession","isCloseConfirmOpen","setIsCloseConfirmOpen","fileContent","isFileLoading","fileError","useFileContent","associationChain","linkedIssueId","meta","status","alertCount","isSessionNotFound","timer","sessionOptions","sid","name","handleFocus","handleSplitH","handleSplitV","handleClose","handleCloseConfirm","handleSessionChange","session","handleClear","handleRestart","handleTogglePause","handleCloseSession","handleBackToTerminal","ArrowLeft","FileText","opt","SplitSquareHorizontal","SplitSquareVertical","RotateCcw","Play","Pause","LogOut","AlertTriangle","X","FilePreview","Terminal","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","GridGroupRenderer","minSize","depth","updateLayoutSizes","handleChange","sizes","validChildren","child","isPaneId","groupKey","Allotment","TerminalGrid","selectTerminalGridLayout","content","SessionGroupTree","activeTerminalId","selectSessionManagerActiveTerminalId","setActiveTerminal","expandedTags","setExpandedTags","toggleTag","handleSessionClick","paneWithSession","sessionsByTag","groups","untagged","sessionKey","sessionNames","isExpanded","displayName","ChevronRight","Tag","sessionStatus","PROMPT_TEMPLATES","idStr","buildQueuePrompt","issues","PRIORITY_STYLES","PriorityBadge","priority","style","StatusDot","colorMap","IssueItem","issue","isSelected","isChecked","onSelect","onToggleCheck","IssueEmptyState","IssueErrorState","IssuePanel","isLoading","selectedIssueId","selectSelectedIssueId","setSelectedIssue","buildAssociationChain","selectedIds","setSelectedIds","isSending","setIsSending","justSent","setJustSent","executionMethod","setExecutionMethod","isSendConfigOpen","setIsSendConfigOpen","customPrompt","setCustomPrompt","sentTimerRef","isAddingToQueue","setIsAddingToQueue","justQueued","setJustQueued","queueMode","setQueueMode","queuedTimerRef","submitItems","focusedPane","sessionCliTool","availableMethods","sortedIssues","priorityOrder","statusOrder","sa","sb","pa","pb","handleSelect","issueId","handleToggleSelect","handleSelectAll","handleDeselectAll","handleOpenSendConfig","handleSendToTerminal","effectiveTool","prompt","executeInput","executeInCliSession","handleAddToQueue","selectedIssues","now","method","Send","Check","STATUS_CONFIG","Clock","Timer","Zap","Ban","CheckCircle","XCircle","SCHEDULER_STATUS_STYLE","QueueItemRow","item","StatusIcon","executions","useQueueExecutionStore","selectByQueueItem","activeExec","isExecuting","isBlocked","displayId","SchedulerBar","progress","selectSchedulerProgress","concurrency","selectCurrentConcurrency","selectSchedulerConfig","startQueue","pauseQueue","stopQueue","selectQueueItems","canStart","canPause","canResume","canStop","isStopConfirmOpen","setIsStopConfirmOpen","handleStart","StopCircle","QueueListColumn","sortedItems","queueItemId","SCHEDULER_STATUS_CLASS","SchedulerPanel","schedulerStatus","sessionPool","selectSessionPool","selectSchedulerError","updateConfig","isIdle","isRunning","isPaused","isStopping","isTerminal","handleConcurrencyChange","sessionEntries","Progress","resumeKey","binding","ChainNode","timestamp","isLast","formatTimestamp","ArrowRight","ts","InspectorContent","highlightedChain","activeChain","chainDetails","queueStatus","executionTimestamp","exec","sessionTimestamp","statusConfig","ORCHESTRATION_STATUS_CONFIG","StepStatusIcon","Circle","CheckCircle2","StepListItem","step","isCurrent","OrchestrationPlanItem","runState","plan","stepStatuses","totalSteps","completedSteps","Bot","ExecutionMonitorPanel","currentExecution","selectCurrentExecution","activeExecutions","selectActiveExecutions","selectExecution","pauseExecution","resumeExecution","stopExecution","clearExecution","activePlans","useOrchestratorStore","selectActivePlans","planEntries","planId","FileSidebarPanel","rootPath","enabled","onCollapse","width","showFileInPane","rootNodes","state","isFetching","refetch","setSelectedFile","toggleExpanded","toggleShowHidden","useFileExplorer","handleNodeClick","node","handleRefresh","handleCollapse","EyeOff","Eye","ChevronLeft","TreeView","TerminalDashboardPage","setActivePanel","setIsFileSidebarOpen","setIsSessionSidebarOpen","isImmersiveMode","useAppStore","selectIsImmersiveMode","toggleImmersiveMode","togglePanel","panelId","closePanel","FloatingPanel","QueuePanel"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}
|