repoburg 1.3.201 → 1.3.202
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/agent-pane/backend/data.db-shm +0 -0
- package/agent-pane/backend/data.db-wal +0 -0
- package/agent-pane/backend/dist/index.js +478 -250
- package/agent-pane/backend/src/db/index.ts +6 -0
- package/agent-pane/backend/src/providers/runtime-provider.ts +6 -0
- package/agent-pane/backend/src/repoburg/action-mapping.test.ts +122 -0
- package/agent-pane/backend/src/repoburg/action-mapping.ts +89 -11
- package/agent-pane/backend/src/repoburg/agent-runtime-client.ts +23 -0
- package/agent-pane/backend/src/repoburg/backend-resolver.test.ts +85 -0
- package/agent-pane/backend/src/repoburg/backend-resolver.ts +28 -13
- package/agent-pane/backend/src/repoburg/repoburg-client.test.ts +21 -0
- package/agent-pane/backend/src/repoburg/repoburg-client.ts +13 -0
- package/agent-pane/backend/src/repoburg/repoburg-provider.test.ts +57 -0
- package/agent-pane/backend/src/repoburg/repoburg-provider.ts +49 -0
- package/agent-pane/backend/src/repoburg/turn-projector.test.ts +147 -1
- package/agent-pane/backend/src/repoburg/turn-projector.ts +101 -1
- package/agent-pane/backend/src/routes/sessions.test.ts +215 -1
- package/agent-pane/backend/src/routes/sessions.ts +70 -9
- package/agent-pane/frontend/dist/assets/index-CJxD4YmJ.js +370 -0
- package/agent-pane/frontend/dist/assets/{index-34WaZYsW.css → index-r-xwfOKQ.css} +1 -1
- package/agent-pane/frontend/dist/index.html +2 -2
- package/agent-pane/frontend/src/api/sessions.test.ts +1 -0
- package/agent-pane/frontend/src/api/websocket.test.ts +2 -2
- package/agent-pane/frontend/src/api/websocket.ts +3 -1
- package/agent-pane/frontend/src/components/AskUserItem.test.tsx +143 -0
- package/agent-pane/frontend/src/components/AskUserItem.tsx +207 -0
- package/agent-pane/frontend/src/components/TurnContent.test.tsx +79 -0
- package/agent-pane/frontend/src/components/TurnContent.tsx +49 -3
- package/agent-pane/frontend/src/components/panels/TurnsPanel.test.tsx +48 -0
- package/agent-pane/frontend/src/components/panels/TurnsPanel.tsx +7 -2
- package/agent-pane/frontend/src/store/store.test.ts +19 -0
- package/agent-pane/frontend/src/store/wsSlice.ts +10 -3
- package/agent-pane/frontend/src/styles/app.css +16 -0
- package/agent-pane/frontend/src/test/fixtures.ts +1 -0
- package/agent-pane/frontend/src/types/index.ts +2 -0
- package/agent-pane/frontend/src/utils/duration.test.ts +1 -0
- package/agent-pane/shared/types.ts +17 -0
- package/askuser-after-step5-postgres-selected.png +0 -0
- package/askuser-after-step7-answer-sent.png +0 -0
- package/askuser-card-visible.png +0 -0
- package/backend/dist/src/agent-runtime/agent-runtime-event-emitter.d.ts +16 -0
- package/backend/dist/src/agent-runtime/agent-runtime-event-emitter.js +87 -0
- package/backend/dist/src/agent-runtime/agent-runtime-event-emitter.js.map +1 -1
- package/backend/dist/src/agent-runtime/agent-runtime.types.d.ts +16 -1
- package/backend/dist/src/app.controller.d.ts +1 -0
- package/backend/dist/src/app.service.d.ts +1 -0
- package/backend/dist/src/app.service.js +4 -1
- package/backend/dist/src/app.service.js.map +1 -1
- package/backend/dist/src/interactive-chat/chat.service.d.ts +4 -0
- package/backend/dist/src/interactive-chat/chat.service.js +21 -1
- package/backend/dist/src/interactive-chat/chat.service.js.map +1 -1
- package/backend/dist/src/llm-orchestration/action-handlers/invoke-subagent.handler.js +12 -1
- package/backend/dist/src/llm-orchestration/action-handlers/invoke-subagent.handler.js.map +1 -1
- package/backend/dist/src/llm-orchestration/llm-orchestration.interfaces.d.ts +1 -0
- package/backend/dist/src/llm-orchestration/llm-orchestration.interfaces.js +1 -0
- package/backend/dist/src/llm-orchestration/llm-orchestration.interfaces.js.map +1 -1
- package/backend/dist/src/llm-orchestration/llm-turn-processor.service.js +2 -0
- package/backend/dist/src/llm-orchestration/llm-turn-processor.service.js.map +1 -1
- package/backend/dist/tsconfig.build.tsbuildinfo +1 -1
- package/daemon/dist/api/services.js +4 -0
- package/daemon/dist/serviceManager.js +30 -11
- package/daemon/dist/serviceManager.spec.js +26 -0
- package/daemon/dist/workspace-validation.js +63 -0
- package/daemon/dist/workspace-validation.spec.js +63 -0
- package/package.json +1 -1
- package/r2-step4-apple-banana.png +0 -0
- package/r2-step5-after-rewind-apple-last.png +0 -0
- package/r2-step7-apple-cherry.png +0 -0
- package/r2-step8-cherry-menu-no-restore.png +0 -0
- package/r3-step3-live-task-card-running.png +0 -0
- package/r3-step4-after-completion.png +0 -0
- package/r3-step5-persistence-after-reload.png +0 -0
- package/r3-step6-tasks-tab-card.png +0 -0
- package/reverify-answered-state-answer-sent.png +0 -0
- package/reverify-card-visible-after-completion.png +0 -0
- package/rewind-step3-apple-banana-turns.png +0 -0
- package/rewind-step5-ui-unchanged-after-confirmed-rewind.png +0 -0
- package/rewind-step6-apple-menu-no-restore.png +0 -0
- package/rewind-step7-final-turnlist-unchanged.png +0 -0
- package/rewind-step7-negative-error-toast.png +0 -0
- package/rewind-step7-negative-error-toast2.png +0 -0
- package/subagent-r2-step5-turn-after-reload-no-card.png +0 -0
- package/subagent-r2-step6-tasks-panel-card.png +0 -0
- package/subagent-step3-tasks-tab-done-card.png +0 -0
- package/subagent-step4-turn-stuck-no-cards.png +0 -0
- package/agent-pane/frontend/dist/assets/index-y7xlT86e.js +0 -362
|
@@ -1 +1 @@
|
|
|
1
|
-
@import"https://fonts.googleapis.com/css2?family=Inter:wght@400;450;510;590;600&family=JetBrains+Mono:wght@400;500&display=swap";:root{--canvas: #fdfdfc;--surface-0: #f8f7f5;--surface-1: #f0efed;--surface-2: #e6e4e0;--surface-3: #d6d3cd;--border: #e2e0db;--border-muted: #edebe7;--border-hover: #ccc8c0;--text: #1c1b18;--text-2: #54504a;--text-3: #78736c;--text-muted: #a8a399;--accent: #d97706;--accent-hover: #b45309;--accent-soft: rgba(217, 119, 6, .08);--accent-glow: rgba(217, 119, 6, .2);--green: #16a34a;--amber: #ca8a04;--red: #dc2626;--green-soft: rgba(22, 163, 74, .08);--amber-soft: rgba(202, 138, 4, .08);--red-soft: rgba(220, 38, 38, .08);--ic-claude: #c2410c;--ic-codex: #6366f1;--ic-repoburg: #059669;--ic-cursor: #db2777;--font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;--font-mono: "JetBrains Mono", "SF Mono", "Fira Code", monospace;--r-sm: 4px;--r-md: 6px;--r-lg: 8px;--r-xl: 12px;--r-pill: 9999px;--ease: cubic-bezier(.25, .46, .45, .94);--ease-out: cubic-bezier(.22, 1, .36, 1);--dur-fast: .1s;--dur-normal: .15s;--dur-slow: .25s;--inset-highlight: inset 0 1px 0 rgba(0, 0, 0, .03);--inset-strong: inset 0 1px 0 rgba(0, 0, 0, .05);--focus-ring: 0 0 0 3px var(--accent-glow)}*{margin:0;padding:0;box-sizing:border-box}html,body{height:100%;overflow:hidden}body{font-family:var(--font-sans);font-size:13px;font-weight:400;background:var(--canvas);color:var(--text-2);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility;font-feature-settings:"ss03","cv11";font-variant-numeric:tabular-nums;letter-spacing:-.01em}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--surface-3);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:var(--border-hover)}:focus-visible{outline:none;box-shadow:var(--focus-ring);border-radius:var(--r-md)}.ide-root{display:flex;flex-direction:column;height:100vh}.ide-layout{display:grid;grid-template-columns:240px 6px 1fr 6px 300px;flex:1;overflow:hidden}.resize-handle{width:6px;cursor:col-resize;background:transparent;flex-shrink:0;transition:background var(--dur-fast) var(--ease)}.resize-handle:hover,.resize-handle.dragging{background:var(--border-hover)}body.is-resizing{-webkit-user-select:none;user-select:none}body.is-resizing *{cursor:col-resize!important}.ide-sidebar{background:var(--surface-0);border-right:1px solid var(--border);overflow-y:auto;display:flex;flex-direction:column}.sidebar-header{padding:10px 12px 8px;display:flex;align-items:center;justify-content:space-between}.sidebar-header-title{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.08em;color:var(--text-muted)}.sidebar-add{width:20px;height:20px;border-radius:var(--r-sm);border:none;background:transparent;color:var(--text-muted);cursor:pointer;font-size:15px;display:flex;align-items:center;justify-content:center;transition:all var(--dur-normal) var(--ease)}.sidebar-add:hover{background:#0000000f;color:var(--text)}.tree-section{margin-bottom:2px}.tree-section-header{padding:5px 8px;display:flex;align-items:center;gap:6px;font-size:11px;font-weight:590;color:var(--text-2);cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:var(--r-sm);transition:background var(--dur-fast) var(--ease)}.tree-section-header:hover{background:#0000000a}.tree-chevron{font-size:9px;color:var(--text-muted);width:10px;transition:transform var(--dur-normal) var(--ease)}.tree-section.collapsed .tree-chevron{transform:rotate(-90deg)}.tree-section.collapsed .tree-children{display:none}.tree-count{margin-left:auto;font-size:10px;background:var(--surface-2);padding:1px 6px;border-radius:var(--r-pill);color:var(--text-muted);font-variant-numeric:tabular-nums}.tree-children{padding-left:4px}.tree-item{padding:4px 8px 4px 26px;border-radius:var(--r-sm);font-size:12px;cursor:pointer;display:flex;align-items:center;gap:6px;color:var(--text-2);-webkit-user-select:none;user-select:none;transition:all var(--dur-fast) var(--ease);position:relative}.tree-item:hover{background:#0000000a;color:var(--text)}.tree-item.active{background:var(--accent-soft);color:var(--text)}.tree-item.active:before{content:"";position:absolute;left:0;top:4px;bottom:4px;width:2px;background:var(--accent);border-radius:var(--r-pill)}.tree-item .ri{width:16px;height:16px;border-radius:3px;display:flex;align-items:center;justify-content:center;font-size:8px;font-weight:700;color:#fff;flex-shrink:0}.tree-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sidebar-footer{margin-top:auto;padding:8px 12px;border-top:1px solid var(--border-muted);font-size:11px;color:var(--text-muted);display:flex;align-items:center;gap:6px;cursor:pointer}.sidebar-footer:hover{color:var(--text-2)}.ide-center{display:flex;flex-direction:column;background:var(--canvas);overflow:hidden;min-height:0}.ide-tabs{display:flex;background:var(--surface-0);border-bottom:1px solid var(--border);overflow-x:auto;flex-shrink:0;scrollbar-width:none}.ide-tabs::-webkit-scrollbar{display:none}.ide-tab{padding:8px 12px;font-size:12px;color:var(--text-3);border-right:1px solid var(--border-muted);cursor:pointer;display:flex;align-items:center;gap:6px;white-space:nowrap;-webkit-user-select:none;user-select:none;transition:all var(--dur-fast) var(--ease);position:relative}.ide-tab:hover{background:#00000008;color:var(--text-2)}.ide-tab.active{color:var(--text);background:var(--canvas)}.ide-tab.active:after{content:"";position:absolute;left:0;right:0;top:0;height:2px;background:var(--accent)}.ide-tab .ri{width:14px;height:14px;font-size:7px;border-radius:3px}.ide-tab-close{margin-left:4px;color:var(--text-muted);font-size:14px;opacity:0;transition:opacity var(--dur-fast) var(--ease);display:flex;align-items:center}.ide-tab:hover .ide-tab-close{opacity:1}.ide-tab-close:hover{color:var(--red)}.ide-tab-add{padding:8px 10px;color:var(--text-muted);cursor:pointer;font-size:14px;transition:color var(--dur-fast) var(--ease);display:flex;align-items:center}.ide-tab-add:hover{color:var(--text)}.ide-render{flex:1;overflow:hidden;display:flex;flex-direction:column;position:relative;min-height:0}.render-scroll{flex:1;padding:20px 28px;overflow-y:auto;font-size:14px;line-height:1.7;color:var(--text);min-height:0}.render-content{max-width:720px}.render-content h1,.render-content h2,.render-content h3{margin:20px 0 8px;font-weight:600;color:var(--text);line-height:1.3}.render-content h1{font-size:20px}.render-content h2{font-size:17px}.render-content h3{font-size:15px}.render-content p{margin-bottom:12px;color:var(--text-2)}.render-content ul,.render-content ol{margin-bottom:12px;padding-left:24px}.render-content li{margin-bottom:4px;color:var(--text-2)}.render-content code{font-family:var(--font-mono);font-size:12px;background:var(--surface-1);padding:2px 6px;border-radius:var(--r-sm);color:var(--accent)}.render-content pre{background:var(--surface-0);border:1px solid var(--border);border-radius:var(--r-md);padding:12px 16px;overflow-x:auto;margin-bottom:12px}.render-content pre code{background:none;padding:0;color:var(--text);font-size:12.5px;line-height:1.6}.render-content a{color:var(--accent);text-decoration:none}.render-content a:hover{text-decoration:underline}.render-content blockquote{border-left:3px solid var(--border);padding-left:14px;color:var(--text-3);margin-bottom:12px}.render-content table{width:100%;border-collapse:collapse;margin-bottom:12px}.render-content th,.render-content td{border:1px solid var(--border);padding:6px 10px;font-size:13px}.render-content th{background:var(--surface-1);font-weight:510}.turn-header{display:flex;align-items:center;gap:8px;margin-bottom:14px}.turn-header-icon{width:24px;height:24px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:9px;font-weight:700;color:#fff}.turn-header-title{font-size:14px;font-weight:600;color:var(--text)}.turn-header-meta{font-size:11px;color:var(--text-muted)}.tool-calls{margin-bottom:16px}.tool-calls-header{display:flex;align-items:center;gap:8px;padding:6px 12px;background:var(--surface-1);border:1px solid var(--border);border-radius:var(--r-sm);cursor:pointer;transition:background .15s ease-out;-webkit-user-select:none;user-select:none}.tool-calls-header:hover{background:var(--surface-2)}.tool-calls-icon{display:flex;align-items:center;color:var(--text-3);flex-shrink:0}.tool-calls-summary{font-size:13px;font-weight:500;color:var(--text-2);flex:1}.tool-calls-chevron{color:var(--text-muted);transition:transform .15s ease-out;flex-shrink:0}.tool-calls-body{margin-top:8px;padding-left:16px;border-left:2px solid var(--border)}.intermediate-segment{margin-bottom:16px}.intermediate-segment:last-child{margin-bottom:0}.user-message{font-size:14px;color:var(--text);background:var(--accent-soft);padding:12px 16px;border-radius:var(--r-md);border:1px solid rgba(217,119,6,.15)}.cmd-bar{position:relative;display:flex;flex-direction:column;padding:0;background:var(--surface-0);border-top:1px solid var(--border);flex-shrink:0}.cmd-input-row{display:flex;align-items:flex-end;gap:8px;padding:8px 12px}.cmd-bar:focus-within{box-shadow:inset 0 0 0 1px #d9770666}.cmd-textarea{flex:1;border:none;background:transparent;color:var(--text);font-size:13px;font-family:var(--font-sans);outline:none;resize:none;overflow-y:auto;line-height:1.5;padding:6px 0}.cmd-textarea::placeholder{color:var(--text-muted)}.cmd-textarea:disabled{opacity:.5}.cmd-textarea:focus-visible{box-shadow:none}.cmd-send-btn{width:28px;height:28px;border:none;border-radius:var(--r-sm);background:var(--surface-2);color:var(--text-muted);cursor:default;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:all var(--dur-fast) var(--ease)}.cmd-send-btn:not(:disabled){background:var(--accent);color:#fff;cursor:pointer}.cmd-send-btn:not(:disabled):hover{background:var(--accent-hover)}.cmd-send-btn:disabled{opacity:.4}.cmd-stop-btn{width:28px;height:28px;border:none;border-radius:var(--r-sm);background:var(--red);color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:all var(--dur-fast) var(--ease)}.cmd-stop-btn:hover{background:#b91c1c}.ide-right{background:var(--surface-0);border-left:1px solid var(--border);display:flex;flex-direction:column;overflow:hidden}.right-tabs{display:flex;padding:0 8px;border-bottom:1px solid var(--border);flex-shrink:0;gap:2px}.right-tab{padding:7px 10px;font-size:11px;font-weight:510;color:var(--text-3);cursor:pointer;border-bottom:2px solid transparent;-webkit-user-select:none;user-select:none;transition:all var(--dur-fast) var(--ease);margin-bottom:-1px}.right-tab:hover{color:var(--text-2)}.right-tab.active{color:var(--text);border-bottom-color:var(--accent)}.right-content{flex:1;overflow-y:auto;padding:14px}.right-section{margin-bottom:20px}.right-section-title{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.08em;color:var(--text-muted);margin-bottom:8px}.turn-item{display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:var(--r-sm);cursor:pointer;font-size:12px;color:var(--text-3);transition:all var(--dur-fast) var(--ease);position:relative}.turn-item:hover{background:#0000000a;color:var(--text-2)}.turn-item.active{background:var(--accent-soft);color:var(--text)}.turn-item.active:before{content:"";position:absolute;left:0;top:4px;bottom:4px;width:2px;background:var(--accent);border-radius:var(--r-pill)}.turn-item-icon{width:18px;height:18px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:8px;font-weight:700;color:#fff}.turn-item-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.turn-item-status{font-size:10px;color:var(--amber);flex-shrink:0}.turn-item-meta{font-size:10px;color:var(--text-muted);flex-shrink:0}.file-change{display:flex;align-items:center;gap:8px;padding:5px 0;font-size:12px;border-bottom:1px solid var(--border-muted)}.file-change:last-child{border:none}.file-change.clickable{cursor:pointer;transition:background var(--dur-fast) var(--ease)}.file-change.clickable:hover{background:#00000008}.fc-status{width:14px;text-align:center;font-weight:700;font-size:11px;flex-shrink:0}.fc-add{color:var(--green)}.fc-mod{color:var(--amber)}.fc-del{color:var(--red)}.fc-name{flex:1;color:var(--text-2);font-family:var(--font-mono);font-size:11px}.fc-delta{font-size:10px;color:var(--text-muted);flex-shrink:0;font-variant-numeric:tabular-nums}.diff-file-header{display:flex;align-items:center;gap:10px;padding:10px 14px;background:var(--surface-0);border:1px solid var(--border);border-radius:var(--r-md) var(--r-md) 0 0;border-bottom:none}.diff-file-status{width:16px;height:16px;border-radius:3px;display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:700;flex-shrink:0}.diff-file-name{font-family:var(--font-mono);font-size:13px;font-weight:510;color:var(--text)}.diff-file-stats{display:flex;align-items:center;gap:6px;margin-left:auto;font-size:11px;font-variant-numeric:tabular-nums}.diff-file-badge{padding:1px 7px;border-radius:var(--r-pill);background:var(--surface-2);color:var(--text-3);font-size:10px}.diff-body{border:1px solid var(--border);border-radius:0 0 var(--r-md) var(--r-md);overflow:hidden;margin-bottom:20px}.diff-line{display:flex;align-items:flex-start;font-family:var(--font-mono);font-size:12px;line-height:1.6}.diff-line-num{width:42px;flex-shrink:0;text-align:right;padding:0 8px;color:var(--text-muted);background:var(--surface-0);-webkit-user-select:none;user-select:none;border-right:1px solid var(--border-muted)}.diff-sign{width:20px;flex-shrink:0;text-align:center;-webkit-user-select:none;user-select:none;font-weight:700}.diff-line-content{flex:1;padding:0 8px;white-space:pre-wrap;word-break:break-all;min-width:0}.diff-line-add{background:#16a34a0f}.diff-line-add .diff-sign{color:var(--green)}.diff-line-del{background:#dc26260f}.diff-line-del .diff-sign{color:var(--red)}.diff-line-ctx .diff-sign{color:var(--text-muted)}.diff-line-ctx .diff-line-content{color:var(--text-3)}.changes-scope-toggle{display:flex;gap:2px;margin-bottom:12px;padding:2px;background:var(--surface-1);border-radius:var(--r-md)}.scope-btn{flex:1;padding:5px 10px;border:none;background:transparent;color:var(--text-3);font-size:11px;font-weight:510;cursor:pointer;border-radius:var(--r-sm);font-family:var(--font-sans);transition:all var(--dur-fast) var(--ease)}.scope-btn:hover{color:var(--text-2)}.scope-btn.active{background:var(--surface-0);color:var(--text);box-shadow:var(--inset-highlight)}.ide-statusbar{display:flex;align-items:center;gap:12px;padding:0 12px;height:24px;background:var(--surface-0);border-top:1px solid var(--border);font-size:11px;color:var(--text-muted);flex-shrink:0;font-variant-numeric:tabular-nums}.sb-item{display:flex;align-items:center;gap:3px;cursor:pointer;transition:color var(--dur-fast) var(--ease)}.sb-item:hover{color:var(--text-2)}.sb-spacer{flex:1}.sb-divider{color:var(--border)}.sb-context{display:flex;align-items:center;gap:5px}.sb-context-text{font-size:10px;color:var(--text-muted);font-variant-numeric:tabular-nums}.model-selector{position:relative}.model-selector-btn{display:flex;align-items:center;gap:4px;background:none;border:none;cursor:pointer;color:var(--text-muted);font-size:11px;padding:2px 6px;border-radius:3px;transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}.model-selector-btn:hover{background:var(--surface-1);color:var(--text-2)}.model-selector-provider{font-weight:500;color:var(--accent)}.model-selector-sep{color:var(--border);margin:0 1px}.model-selector-model{color:var(--text-2)}.model-selector-reasoning{color:var(--text-muted);font-style:italic}.model-selector-chevron{opacity:.5;flex-shrink:0}.model-selector-popover{position:absolute;bottom:calc(100% + 4px);left:0;display:flex;gap:1px;background:var(--surface-0);border:1px solid var(--border);border-radius:6px;box-shadow:0 4px 16px #0003;z-index:100;min-width:0;overflow:hidden}.model-selector-column{min-width:140px;max-width:220px;padding:4px 0;background:var(--surface-0)}.model-selector-col-header{padding:4px 10px;font-size:9px;font-weight:600;text-transform:uppercase;color:var(--text-muted);letter-spacing:.5px}.model-selector-item{display:flex;align-items:center;gap:6px;padding:6px 10px;cursor:pointer;font-size:11px;color:var(--text-2);transition:background var(--dur-fast) var(--ease)}.model-selector-item:hover{background:var(--surface-1)}.model-selector-item.selected{color:var(--accent)}.model-selector-item.disabled{cursor:default;opacity:.5}.model-selector-item.disabled:hover{background:none}.model-selector-item-main{display:flex;flex-direction:column;gap:1px;flex:1;min-width:0}.model-selector-item-name{font-weight:500;white-space:nowrap}.model-selector-item-desc{font-size:9px;color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.model-selector-coming-soon{display:flex;align-items:center;gap:2px;font-size:9px;color:var(--text-muted);font-style:italic}.model-selector-empty{padding:8px 10px;font-size:10px;color:var(--text-muted);font-style:italic}.dialog-select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 8px center;padding-right:26px}.badge{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:var(--r-pill);font-size:11px;font-weight:510;white-space:nowrap}.badge-running{background:var(--green-soft);color:var(--green)}.badge-queued{background:var(--amber-soft);color:var(--amber)}.badge-done{background:var(--accent-soft);color:var(--accent)}.badge-failed{background:var(--red-soft);color:var(--red)}.badge-paused{background:#a8a3991f;color:var(--text-muted)}.runtime-icon{width:20px;height:20px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:700;color:#fff;flex-shrink:0;letter-spacing:0}.ic-claude{background:var(--ic-claude)}.ic-codex{background:var(--ic-codex)}.ic-repoburg{background:var(--ic-repoburg)}.ic-cursor{background:var(--ic-cursor)}.status-dot{width:6px;height:6px;border-radius:50%;display:inline-block;flex-shrink:0}.status-dot.running{background:var(--green);animation:dot-pulse 1.5s ease-in-out infinite}.status-dot.queued{background:var(--amber)}.status-dot.error{background:var(--red)}.status-dot.done{background:var(--accent)}.status-dot.paused{background:var(--text-muted)}[data-lucide],svg.lucide{width:16px;height:16px;stroke-width:1.5;flex-shrink:0}.icon-xs{width:12px!important;height:12px!important}.icon-sm{width:14px!important;height:14px!important}.icon-lg{width:20px!important;height:20px!important}.dialog-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#0000004d;display:flex;align-items:center;justify-content:center;z-index:100}.dialog{background:var(--surface-0);border:1px solid var(--border);border-radius:var(--r-lg);width:400px;max-width:90vw;box-shadow:0 8px 32px #00000029}.dialog-header{display:flex;align-items:center;justify-content:space-between;padding:14px 16px;border-bottom:1px solid var(--border-muted)}.dialog-title{font-size:14px;font-weight:600;color:var(--text)}.dialog-close{border:none;background:transparent;color:var(--text-muted);cursor:pointer;padding:4px;border-radius:var(--r-sm);display:flex;align-items:center;transition:all var(--dur-fast) var(--ease)}.dialog-close:hover{background:#0000000f;color:var(--text)}.dialog-body{padding:16px;display:flex;flex-direction:column;gap:14px}.dialog-label{display:flex;flex-direction:column;gap:4px;font-size:11px;font-weight:510;color:var(--text-muted)}.dialog-input{border:1px solid var(--border);border-radius:var(--r-sm);padding:8px 10px;font-size:13px;font-family:var(--font-sans);color:var(--text);background:var(--canvas);outline:none;transition:border-color var(--dur-fast) var(--ease)}.dialog-input:focus{border-color:var(--accent);box-shadow:var(--focus-ring)}.dialog-footer{display:flex;justify-content:flex-end;gap:8px;padding:12px 16px;border-top:1px solid var(--border-muted)}.dialog-btn-cancel{padding:6px 14px;border-radius:var(--r-sm);border:1px solid var(--border);background:transparent;color:var(--text-2);font-size:12px;cursor:pointer;font-family:var(--font-sans);transition:all var(--dur-fast) var(--ease)}.dialog-btn-cancel:hover{background:var(--surface-2);color:var(--text)}.dialog-btn-create{padding:6px 14px;border-radius:var(--r-sm);border:none;background:var(--accent);color:#fff;font-size:12px;font-weight:510;cursor:pointer;font-family:var(--font-sans);transition:all var(--dur-fast) var(--ease)}.dialog-btn-create:hover{background:var(--accent-hover)}.turn-group{margin-bottom:24px}.turn-block{margin-bottom:32px;padding-bottom:8px;border-bottom:1px solid var(--border)}.turn-block:last-child{border-bottom:none}.cmd-block{background:var(--surface-0);border:1px solid var(--border);border-radius:var(--r-md);padding:10px 14px;overflow-x:auto;margin-bottom:12px}.cmd-block code{font-family:var(--font-mono);font-size:12px;color:var(--text)}.cmd-output{background:var(--surface-0);border:1px solid var(--border-muted);border-radius:var(--r-md);padding:10px 14px;overflow-x:auto;margin-bottom:12px;max-height:200px;overflow-y:auto}.cmd-output code{font-family:var(--font-mono);font-size:12px;color:var(--text-3)}.cmd-output-toggle{border:1px solid var(--border);border-radius:var(--r-sm);background:var(--surface-1);color:var(--text-muted);font-size:11px;font-family:var(--font-sans);padding:4px 10px;cursor:pointer;margin-bottom:12px;transition:all var(--dur-fast) var(--ease)}.cmd-output-toggle:hover{background:var(--surface-2);color:var(--text-2)}.mcp-args{margin-bottom:12px}.mcp-arg{margin-bottom:6px}.mcp-arg-key{font-size:11px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.04em;display:block;margin-bottom:3px}.mcp-arg-value{font-size:12px;color:var(--text-2);white-space:pre-wrap;word-break:break-word}.file-change-list{display:flex;flex-direction:column;gap:2px}.todo-list{list-style:none;padding-left:0}.todo-done{color:var(--text-3);text-decoration:line-through}.todo-pending{color:var(--text-2)}.empty-state{padding:40px 20px;text-align:center;color:var(--text-muted);font-size:13px}.palette-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#00000040;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);display:flex;align-items:flex-start;justify-content:center;padding-top:120px;z-index:200}.palette{background:var(--surface-0);border:1px solid var(--border);border-radius:var(--r-lg);width:520px;max-width:90vw;box-shadow:0 12px 40px #0003;overflow:hidden}.palette-search{display:flex;align-items:center;gap:8px;padding:12px 16px;border-bottom:1px solid var(--border-muted)}.palette-search input{flex:1;border:none;background:transparent;color:var(--text);font-size:15px;font-family:var(--font-sans);outline:none}.palette-search input::placeholder{color:var(--text-muted)}.palette-esc{font-size:10px;font-weight:600;color:var(--text-muted);background:var(--surface-2);padding:2px 6px;border-radius:var(--r-sm)}.palette-list{max-height:360px;overflow-y:auto;padding:4px}.palette-empty{padding:24px;text-align:center;color:var(--text-muted);font-size:13px}.palette-item{display:flex;align-items:center;gap:10px;padding:8px 12px;border-radius:var(--r-sm);cursor:pointer;transition:background var(--dur-fast) var(--ease)}.palette-item.selected{background:var(--accent-soft)}.palette-item-icon{color:var(--text-muted);flex-shrink:0;display:flex;align-items:center}.palette-item.selected .palette-item-icon{color:var(--accent)}.palette-item-label{font-size:13px;color:var(--text);font-weight:510}.palette-item-hint{font-size:11px;color:var(--text-muted);margin-left:auto}.palette-item-enter{color:var(--text-muted);flex-shrink:0}.toast-container{position:fixed;bottom:36px;right:16px;display:flex;flex-direction:column-reverse;gap:8px;z-index:300;pointer-events:none}.toast{display:flex;align-items:center;gap:8px;padding:10px 14px;border-radius:var(--r-md);font-size:12px;font-weight:500;min-width:280px;max-width:400px;pointer-events:auto;animation:toast-in .2s ease-out;border:1px solid var(--border);background:var(--surface-0);box-shadow:0 4px 16px #0000001f}@keyframes toast-in{0%{opacity:0;transform:translate(20px)}to{opacity:1;transform:translate(0)}}.toast-success{border-left:3px solid var(--green)}.toast-success svg{color:var(--green)}.toast-error{border-left:3px solid var(--red)}.toast-error svg{color:var(--red)}.toast-info{border-left:3px solid var(--accent)}.toast-info svg{color:var(--accent)}.toast-warn{border-left:3px solid var(--amber)}.toast-warn svg{color:var(--amber)}.toast-message{flex:1;color:var(--text-2)}.toast-close{border:none;background:transparent;color:var(--text-muted);cursor:pointer;padding:2px;border-radius:var(--r-sm);display:flex;align-items:center;transition:color var(--dur-fast) var(--ease)}.toast-close:hover{color:var(--text)}.error-banner{display:flex;align-items:center;gap:10px;padding:10px 16px;background:#dc262614;border:1px solid rgba(220,38,38,.2);border-radius:var(--r-md);margin-bottom:16px}.banner-icon{width:20px;height:20px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;flex-shrink:0}.error-banner .banner-icon{background:var(--red);color:#fff}.error-banner .banner-text{color:var(--red);font-size:13px;font-weight:500}.aborted-banner{display:flex;align-items:center;gap:10px;padding:10px 16px;background:#d9770614;border:1px solid rgba(217,119,6,.2);border-radius:var(--r-md);margin-bottom:16px}.aborted-banner .banner-icon{background:var(--amber);color:#fff}.aborted-banner .banner-text{color:var(--amber);font-size:13px;font-weight:500}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}.skeleton-bars{width:80%;max-width:500px;margin:20px 0}.skeleton-bar{height:10px;border-radius:var(--r-sm);background:var(--surface-1);margin-bottom:8px;animation:shimmer 1.2s infinite}.skeleton-bar:nth-child(1){width:60%}.skeleton-bar:nth-child(2){width:85%}.skeleton-bar:nth-child(3){width:70%}.skeleton-bar:nth-child(4){width:90%}.skeleton-bar:nth-child(5){width:50%}@keyframes shimmer{0%{opacity:.3}50%{opacity:.6}to{opacity:.3}}@keyframes dot-pulse{0%{opacity:1}to{opacity:.4}}.diff-file-header{transition:background .3s ease-out}.diff-file-header.diff-highlight{background:var(--accent-soft)}.palette-footer{display:flex;gap:16px;padding:8px 16px;border-top:1px solid var(--border-muted);font-size:11px;color:var(--text-muted)}.palette-footer-hint{display:flex;align-items:center;gap:4px}.kbd{font-family:var(--font-mono);font-size:10px;padding:1px 5px;border-radius:var(--r-sm);background:var(--surface-2);border:1px solid var(--border)}.toast-undo{font-size:12px;font-weight:500;color:var(--accent);background:transparent;border:none;cursor:pointer;padding:2px 8px;border-radius:var(--r-sm);display:flex;align-items:center;gap:4px;transition:background var(--dur-fast) var(--ease)}.toast-undo:hover{background:var(--accent-soft)}.tree-section-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11px}.tree-section-add{width:18px;height:18px;border:none;border-radius:var(--r-sm);background:transparent;color:var(--text-muted);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all var(--dur-fast) var(--ease);flex-shrink:0}.tree-section-add:hover{background:var(--accent-soft);color:var(--accent)}.tree-empty{padding:4px 8px 4px 26px;font-size:11px;color:var(--text-muted);font-style:italic}.tree-subgroup{margin-bottom:1px}.tree-subgroup-header{padding:3px 8px 3px 18px;display:flex;align-items:center;gap:5px;font-size:10px;font-weight:590;color:var(--text-muted);cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:var(--r-sm);transition:background var(--dur-fast) var(--ease)}.tree-subgroup-header:hover{background:#0000000a;color:var(--text-2)}.tree-subgroup.collapsed .tree-chevron{transform:rotate(-90deg)}.tree-subgroup.collapsed .tree-subgroup-items{display:none}.tree-subgroup-label{text-transform:uppercase;letter-spacing:.05em}.tree-subgroup-count{margin-left:auto;font-size:9px;color:var(--text-muted);font-variant-numeric:tabular-nums}.tree-subgroup-items{padding-left:0}.tree-item-finished .tree-label{color:var(--text-muted);opacity:.6}.tree-item-finished:hover .tree-label{opacity:.85}.ctx-menu{background:var(--surface-0);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:0 4px 16px #0000001f;padding:4px;min-width:160px}.ctx-menu-item{display:flex;align-items:center;gap:8px;padding:6px 10px;border-radius:var(--r-sm);font-size:12px;color:var(--text-2);cursor:pointer;transition:background var(--dur-fast) var(--ease)}.ctx-menu-item:hover{background:var(--accent-soft);color:var(--text)}.ctx-menu-item.ctx-danger:hover{background:#dc262614;color:var(--red)}.ctx-menu-item.ctx-disabled{opacity:.4;cursor:default}.ctx-menu-item.ctx-disabled:hover{background:transparent;color:var(--text-2)}.tree-rename-input{flex:1;border:1px solid var(--accent);border-radius:var(--r-sm);padding:1px 6px;font-size:12px;font-family:var(--font-sans);color:var(--text);background:var(--canvas);outline:none;box-shadow:var(--focus-ring);min-width:0}.slash-popup{position:absolute;bottom:100%;left:12px;right:12px;margin-bottom:4px;background:var(--surface-0);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:0 4px 16px #0000001f;max-height:280px;overflow-y:auto;z-index:100}.slash-popup-header{padding:6px 10px;font-size:10px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.05em;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:4px}.slash-popup-back{background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:11px;padding:2px 4px;border-radius:var(--r-sm)}.slash-popup-back:hover{background:var(--surface-1);color:var(--text-2)}.slash-popup-empty{padding:12px 10px;font-size:12px;color:var(--text-muted);text-align:center}.slash-popup-item{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 10px;cursor:pointer;border-radius:var(--r-sm);transition:background var(--dur-fast) var(--ease)}.slash-popup-item:hover,.slash-popup-item.selected{background:var(--accent-soft)}.slash-popup-label{font-size:12px;font-weight:500;color:var(--text-2);font-family:var(--font-mono)}.slash-popup-hint{font-size:11px;color:var(--text-muted)}.slash-popup-item-main{display:flex;flex-direction:column;gap:1px}.slash-popup-check{color:var(--accent);font-size:13px}.skill-badges{display:flex;flex-wrap:wrap;gap:4px;padding:6px 12px 0}.skill-badge{display:inline-flex;align-items:center;gap:4px;padding:2px 6px;font-size:11px;font-family:var(--font-mono);color:var(--accent);background:var(--accent-soft);border-radius:var(--r-sm)}.skill-badge-remove{background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:13px;line-height:1;padding:0}.skill-badge-remove:hover{color:var(--red)}.attachment-preview-area{display:flex;flex-wrap:wrap;gap:4px;padding:6px 12px 0}.attachment-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 6px 2px 2px;border:1px solid var(--border);border-radius:var(--r-pill);background:var(--surface-1);max-width:180px;position:relative;transition:border-color var(--dur-fast) var(--ease)}.attachment-chip:hover{border-color:var(--accent)}.attachment-thumb{width:18px;height:18px;object-fit:cover;border-radius:50%;flex-shrink:0}.attachment-file-icon{width:14px;height:14px;color:var(--text-muted);flex-shrink:0}.attachment-info{display:flex;flex-direction:column;gap:0;overflow:hidden;min-width:0}.attachment-name{font-size:10px;font-family:var(--font-mono);color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100px}.attachment-size{font-size:9px;color:var(--text-muted);font-variant-numeric:tabular-nums}.attachment-remove{background:none;border:none;color:var(--text-muted);cursor:pointer;padding:1px;display:flex;align-items:center;justify-content:center;border-radius:var(--r-xs);transition:all var(--dur-fast) var(--ease);flex-shrink:0}.attachment-remove:hover{color:var(--red);background:#ef44441a}.attachment-clip-btn{width:28px;height:28px;border:none;border-radius:var(--r-sm);background:transparent;color:var(--text-muted);cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:all var(--dur-fast) var(--ease)}.attachment-clip-btn:hover{color:var(--accent);background:var(--surface-2)}.attachment-clip-btn:disabled{opacity:.3;cursor:default}.cmd-bar.drag-over{box-shadow:inset 0 0 0 2px var(--accent);background:var(--accent-soft)}.image-preview-modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:10000;background:#000c;display:flex;align-items:center;justify-content:center;padding:32px;animation:modal-fade-in .15s ease-out}@keyframes modal-fade-in{0%{opacity:0}to{opacity:1}}.image-preview-content{position:relative;max-width:90vw;max-height:90vh;display:flex;flex-direction:column;align-items:center;gap:8px}.image-preview-content img{max-width:100%;max-height:80vh;object-fit:contain;border-radius:var(--r-sm);border:1px solid var(--border)}.image-preview-info{display:flex;gap:12px;font-size:12px;color:var(--text-muted);font-family:var(--font-mono)}.image-preview-close{position:absolute;top:-12px;right:-12px;width:28px;height:28px;border:none;border-radius:50%;background:var(--surface-2);color:var(--text);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all var(--dur-fast) var(--ease)}.image-preview-close:hover{background:var(--red);color:#fff}.attachment-pills{display:flex;flex-wrap:wrap;gap:4px;margin-top:6px}.attachment-pill{display:inline-flex;align-items:center;gap:4px;padding:2px 8px 2px 2px;border:1px solid var(--border);border-radius:var(--r-pill);background:var(--surface-1);font-size:10px;font-family:var(--font-mono);color:var(--text-muted);transition:border-color var(--dur-fast) var(--ease)}.attachment-pill:hover{border-color:var(--accent)}.attachment-pill-thumb{width:16px;height:16px;object-fit:cover;border-radius:50%;flex-shrink:0}.attachment-pill-icon{color:var(--text-muted);flex-shrink:0}.attachment-pill-name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100px}.right-tab-badge{display:inline-flex;align-items:center;justify-content:center;min-width:16px;height:16px;padding:0 4px;margin-left:4px;font-size:10px;font-weight:600;color:#fff;background:var(--accent);border-radius:8px}.task-count-badge{font-size:10px;font-weight:500}.task-card{border:1px solid var(--border);border-radius:var(--r-md);padding:10px 12px;margin-bottom:10px;transition:border-color var(--dur-fast) var(--ease)}.task-card.task-running{border-color:var(--accent)}.task-card.task-failed{border-color:var(--red)}.task-card-header{display:flex;align-items:center;gap:8px}.task-card-icon{display:flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:var(--r-sm);background:var(--surface-2);color:var(--text-3);flex-shrink:0}.task-card-type{font-size:13px;font-weight:600;color:var(--text)}.task-card-status{display:flex;align-items:center;gap:3px;font-size:11px;padding:2px 6px;border-radius:var(--r-sm);flex-shrink:0}.task-status-running{color:var(--accent);background:var(--accent-soft)}.task-status-done{color:var(--green);background:var(--green-soft)}.task-status-failed{color:var(--red);background:var(--red-soft)}.task-card-chevron{color:var(--text-muted);flex-shrink:0;transition:transform var(--dur-fast) var(--ease)}.task-card-desc{font-size:12px;color:var(--text-2);margin-top:6px;font-family:var(--font-mono)}.task-card-meta{font-size:11px;color:var(--text-muted);margin-top:4px}.task-card-body{margin-top:8px}.task-output{max-height:300px}.task-card-placeholder{font-size:12px;color:var(--text-muted);font-style:italic;padding:8px 0}.task-card-context{font-size:10px;color:var(--text-muted);margin-top:6px;padding-top:6px;border-top:1px solid var(--border-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}mark[data-thread-id]{background:#d977062e;border-radius:2px;cursor:pointer;padding:0 1px;transition:background var(--dur-fast) var(--ease)}mark[data-thread-id]:hover{background:#d977064d}mark[data-thread-id].thread-mark-resolved{background:transparent;border-bottom:2px dashed var(--text-muted)}.selection-actions{position:fixed;z-index:9999;display:flex;gap:4px}.discuss-button{display:flex;align-items:center;gap:4px;padding:4px 10px;border:1px solid var(--border);border-radius:var(--r-sm);background:var(--surface-0);color:var(--accent);font-size:11px;font-weight:500;cursor:pointer;box-shadow:0 2px 8px #0000001f;transition:all var(--dur-fast) var(--ease)}.discuss-button:hover{background:var(--accent-soft);border-color:var(--accent)}.thread-create-popover{position:fixed;z-index:9999;min-width:280px;max-width:360px;background:var(--surface-0);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:0 4px 16px #00000026;padding:10px;display:flex;flex-direction:column;gap:8px;transform:translate(-100%)}.thread-create-header{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.thread-create-quote{font-size:11px;color:var(--text-muted);font-style:italic;flex:1;line-height:1.4}.thread-create-close{border:none;background:transparent;color:var(--text-muted);cursor:pointer;padding:2px;border-radius:var(--r-sm);flex-shrink:0}.thread-create-close:hover{background:var(--surface-1);color:var(--text)}.thread-create-input{border:1px solid var(--border);border-radius:var(--r-sm);padding:8px 10px;font-size:13px;font-family:var(--font-sans);color:var(--text);background:var(--canvas);outline:none;resize:none;line-height:1.5;transition:border-color var(--dur-fast) var(--ease)}.thread-create-input:focus{border-color:var(--accent);box-shadow:var(--focus-ring)}.thread-create-footer{display:flex;align-items:center;justify-content:space-between}.thread-create-hint{font-size:10px;color:var(--text-muted)}.thread-create-send{display:flex;align-items:center;gap:4px;padding:4px 10px;border:none;border-radius:var(--r-sm);background:var(--accent);color:#fff;font-size:11px;font-weight:500;cursor:pointer;transition:background var(--dur-fast) var(--ease)}.thread-create-send:disabled{opacity:.4;cursor:default}.thread-create-send:not(:disabled):hover{background:var(--accent-hover)}.thread-filter-tabs{display:flex;gap:2px;margin-bottom:12px;padding:2px;background:var(--surface-1);border-radius:var(--r-md)}.thread-filter-tab{flex:1;padding:4px 8px;border:none;background:transparent;color:var(--text-3);font-size:10px;font-weight:500;cursor:pointer;border-radius:var(--r-sm);font-family:var(--font-sans);transition:all var(--dur-fast) var(--ease)}.thread-filter-tab:hover{color:var(--text-2)}.thread-filter-tab.active{background:var(--surface-0);color:var(--text);box-shadow:var(--inset-highlight)}.thread-card{border:1px solid var(--border);border-radius:var(--r-md);padding:10px 12px;margin-bottom:10px;transition:border-color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease)}.thread-card.thread-resolved{opacity:.7}.thread-card-highlighted{border-color:var(--accent);background:var(--accent-soft)}.thread-card-header{display:flex;align-items:flex-start;justify-content:space-between;gap:8px;cursor:pointer}.thread-card-quote{font-size:11px;color:var(--text-muted);font-style:italic;line-height:1.4;flex:1}.thread-card-header-right{display:flex;align-items:center;gap:4px;flex-shrink:0}.thread-status-badge{font-size:10px;font-weight:600;padding:2px 8px;border-radius:var(--r-pill)}.thread-status-open{background:var(--accent-soft);color:var(--accent)}.thread-status-resolved{background:var(--green-soft);color:var(--green)}.thread-card-conversation{margin-top:8px;max-height:300px;overflow-y:auto}.thread-card-turn{margin-bottom:8px;padding-bottom:8px;border-bottom:1px solid var(--border-muted)}.thread-card-turn:last-child{border-bottom:none;margin-bottom:0;padding-bottom:0}.thread-card-user-message{font-size:12px;color:var(--text);background:var(--accent-soft);padding:6px 10px;border-radius:var(--r-sm);border:1px solid rgba(217,119,6,.15);margin-bottom:4px}.thread-card-ai-response{font-size:12px;color:var(--text-2);padding:4px 0;line-height:1.5}.thread-card-ai-response p{margin-bottom:6px}.thread-card-ai-response code{font-family:var(--font-mono);font-size:11px;background:var(--surface-1);padding:1px 4px;border-radius:var(--r-sm);color:var(--accent)}.thread-card-ai-response pre{background:var(--surface-0);border:1px solid var(--border);border-radius:var(--r-sm);padding:8px;overflow-x:auto;margin-bottom:6px}.thread-card-ai-response pre code{background:none;padding:0}.thread-card-pending{font-size:11px;color:var(--text-muted);font-style:italic;padding:4px 0}.thread-card-placeholder{font-size:11px;color:var(--text-muted);font-style:italic;padding:8px 0}.thread-card-followup{display:flex;gap:4px;margin-top:8px}.thread-card-followup-input{flex:1;border:1px solid var(--border);border-radius:var(--r-sm);padding:6px 8px;font-size:12px;font-family:var(--font-sans);color:var(--text);background:var(--canvas);outline:none;resize:none;line-height:1.5;transition:border-color var(--dur-fast) var(--ease)}.thread-card-followup-input:focus{border-color:var(--accent)}.thread-card-followup-input:disabled{opacity:.5}.thread-card-followup-send{width:28px;height:28px;border:none;border-radius:var(--r-sm);background:var(--accent);color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:background var(--dur-fast) var(--ease)}.thread-card-followup-send:disabled{opacity:.4;cursor:default}.thread-card-followup-send:not(:disabled):hover{background:var(--accent-hover)}.thread-locate-btn{background:none;border:none;color:var(--text-muted);cursor:pointer;padding:2px;border-radius:3px;display:flex;align-items:center;transition:all var(--dur-fast) var(--ease);flex-shrink:0}.thread-locate-btn:hover{color:var(--accent);background:var(--accent-soft)}.thread-mark-flash{animation:mark-flash 1.5s ease-out}@keyframes mark-flash{0%{background:#d9770680}to{background:#d977062e}}.thread-card-actions{display:flex;gap:6px;margin-top:8px;padding-top:8px;border-top:1px solid var(--border-muted)}.thread-action-btn{display:flex;align-items:center;gap:4px;padding:4px 8px;border:1px solid var(--border);border-radius:var(--r-sm);background:transparent;color:var(--text-3);font-size:11px;cursor:pointer;font-family:var(--font-sans);transition:all var(--dur-fast) var(--ease)}.thread-action-btn:hover{background:var(--surface-1);color:var(--text)}.thread-action-btn.thread-action-danger:hover{background:#dc262614;color:var(--red);border-color:#dc262633}.agent-call-card{display:flex;align-items:center;gap:8px;padding:8px 14px;border-left:3px solid var(--accent);background:var(--surface);border-radius:0 var(--r-sm) var(--r-sm) 0}.agent-call-icon{color:var(--text-2);display:flex;align-items:center}.agent-call-desc{font-size:13px;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}.agent-call-status{font-size:10px;font-family:var(--font-mono);padding:1px 6px;border-radius:var(--r-sm)}.agent-call-status.running{color:var(--accent);background:var(--accent-soft)}.agent-call-status.done{color:var(--green);background:#22c55e14}.agent-call-status.failed{color:var(--red);background:#ef444414}
|
|
1
|
+
@import"https://fonts.googleapis.com/css2?family=Inter:wght@400;450;510;590;600&family=JetBrains+Mono:wght@400;500&display=swap";:root{--canvas: #fdfdfc;--surface-0: #f8f7f5;--surface-1: #f0efed;--surface-2: #e6e4e0;--surface-3: #d6d3cd;--border: #e2e0db;--border-muted: #edebe7;--border-hover: #ccc8c0;--text: #1c1b18;--text-2: #54504a;--text-3: #78736c;--text-muted: #a8a399;--accent: #d97706;--accent-hover: #b45309;--accent-soft: rgba(217, 119, 6, .08);--accent-glow: rgba(217, 119, 6, .2);--green: #16a34a;--amber: #ca8a04;--red: #dc2626;--green-soft: rgba(22, 163, 74, .08);--amber-soft: rgba(202, 138, 4, .08);--red-soft: rgba(220, 38, 38, .08);--ic-claude: #c2410c;--ic-codex: #6366f1;--ic-repoburg: #059669;--ic-cursor: #db2777;--font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;--font-mono: "JetBrains Mono", "SF Mono", "Fira Code", monospace;--r-sm: 4px;--r-md: 6px;--r-lg: 8px;--r-xl: 12px;--r-pill: 9999px;--ease: cubic-bezier(.25, .46, .45, .94);--ease-out: cubic-bezier(.22, 1, .36, 1);--dur-fast: .1s;--dur-normal: .15s;--dur-slow: .25s;--inset-highlight: inset 0 1px 0 rgba(0, 0, 0, .03);--inset-strong: inset 0 1px 0 rgba(0, 0, 0, .05);--focus-ring: 0 0 0 3px var(--accent-glow)}*{margin:0;padding:0;box-sizing:border-box}html,body{height:100%;overflow:hidden}body{font-family:var(--font-sans);font-size:13px;font-weight:400;background:var(--canvas);color:var(--text-2);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility;font-feature-settings:"ss03","cv11";font-variant-numeric:tabular-nums;letter-spacing:-.01em}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--surface-3);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:var(--border-hover)}:focus-visible{outline:none;box-shadow:var(--focus-ring);border-radius:var(--r-md)}.ide-root{display:flex;flex-direction:column;height:100vh}.ide-layout{display:grid;grid-template-columns:240px 6px 1fr 6px 300px;flex:1;overflow:hidden}.resize-handle{width:6px;cursor:col-resize;background:transparent;flex-shrink:0;transition:background var(--dur-fast) var(--ease)}.resize-handle:hover,.resize-handle.dragging{background:var(--border-hover)}body.is-resizing{-webkit-user-select:none;user-select:none}body.is-resizing *{cursor:col-resize!important}.ide-sidebar{background:var(--surface-0);border-right:1px solid var(--border);overflow-y:auto;display:flex;flex-direction:column}.sidebar-header{padding:10px 12px 8px;display:flex;align-items:center;justify-content:space-between}.sidebar-header-title{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.08em;color:var(--text-muted)}.sidebar-add{width:20px;height:20px;border-radius:var(--r-sm);border:none;background:transparent;color:var(--text-muted);cursor:pointer;font-size:15px;display:flex;align-items:center;justify-content:center;transition:all var(--dur-normal) var(--ease)}.sidebar-add:hover{background:#0000000f;color:var(--text)}.tree-section{margin-bottom:2px}.tree-section-header{padding:5px 8px;display:flex;align-items:center;gap:6px;font-size:11px;font-weight:590;color:var(--text-2);cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:var(--r-sm);transition:background var(--dur-fast) var(--ease)}.tree-section-header:hover{background:#0000000a}.tree-chevron{font-size:9px;color:var(--text-muted);width:10px;transition:transform var(--dur-normal) var(--ease)}.tree-section.collapsed .tree-chevron{transform:rotate(-90deg)}.tree-section.collapsed .tree-children{display:none}.tree-count{margin-left:auto;font-size:10px;background:var(--surface-2);padding:1px 6px;border-radius:var(--r-pill);color:var(--text-muted);font-variant-numeric:tabular-nums}.tree-children{padding-left:4px}.tree-item{padding:4px 8px 4px 26px;border-radius:var(--r-sm);font-size:12px;cursor:pointer;display:flex;align-items:center;gap:6px;color:var(--text-2);-webkit-user-select:none;user-select:none;transition:all var(--dur-fast) var(--ease);position:relative}.tree-item:hover{background:#0000000a;color:var(--text)}.tree-item.active{background:var(--accent-soft);color:var(--text)}.tree-item.active:before{content:"";position:absolute;left:0;top:4px;bottom:4px;width:2px;background:var(--accent);border-radius:var(--r-pill)}.tree-item .ri{width:16px;height:16px;border-radius:3px;display:flex;align-items:center;justify-content:center;font-size:8px;font-weight:700;color:#fff;flex-shrink:0}.tree-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sidebar-footer{margin-top:auto;padding:8px 12px;border-top:1px solid var(--border-muted);font-size:11px;color:var(--text-muted);display:flex;align-items:center;gap:6px;cursor:pointer}.sidebar-footer:hover{color:var(--text-2)}.ide-center{display:flex;flex-direction:column;background:var(--canvas);overflow:hidden;min-height:0}.ide-tabs{display:flex;background:var(--surface-0);border-bottom:1px solid var(--border);overflow-x:auto;flex-shrink:0;scrollbar-width:none}.ide-tabs::-webkit-scrollbar{display:none}.ide-tab{padding:8px 12px;font-size:12px;color:var(--text-3);border-right:1px solid var(--border-muted);cursor:pointer;display:flex;align-items:center;gap:6px;white-space:nowrap;-webkit-user-select:none;user-select:none;transition:all var(--dur-fast) var(--ease);position:relative}.ide-tab:hover{background:#00000008;color:var(--text-2)}.ide-tab.active{color:var(--text);background:var(--canvas)}.ide-tab.active:after{content:"";position:absolute;left:0;right:0;top:0;height:2px;background:var(--accent)}.ide-tab .ri{width:14px;height:14px;font-size:7px;border-radius:3px}.ide-tab-close{margin-left:4px;color:var(--text-muted);font-size:14px;opacity:0;transition:opacity var(--dur-fast) var(--ease);display:flex;align-items:center}.ide-tab:hover .ide-tab-close{opacity:1}.ide-tab-close:hover{color:var(--red)}.ide-tab-add{padding:8px 10px;color:var(--text-muted);cursor:pointer;font-size:14px;transition:color var(--dur-fast) var(--ease);display:flex;align-items:center}.ide-tab-add:hover{color:var(--text)}.ide-render{flex:1;overflow:hidden;display:flex;flex-direction:column;position:relative;min-height:0}.render-scroll{flex:1;padding:20px 28px;overflow-y:auto;font-size:14px;line-height:1.7;color:var(--text);min-height:0}.render-content{max-width:720px}.render-content h1,.render-content h2,.render-content h3{margin:20px 0 8px;font-weight:600;color:var(--text);line-height:1.3}.render-content h1{font-size:20px}.render-content h2{font-size:17px}.render-content h3{font-size:15px}.render-content p{margin-bottom:12px;color:var(--text-2)}.render-content ul,.render-content ol{margin-bottom:12px;padding-left:24px}.render-content li{margin-bottom:4px;color:var(--text-2)}.render-content code{font-family:var(--font-mono);font-size:12px;background:var(--surface-1);padding:2px 6px;border-radius:var(--r-sm);color:var(--accent)}.render-content pre{background:var(--surface-0);border:1px solid var(--border);border-radius:var(--r-md);padding:12px 16px;overflow-x:auto;margin-bottom:12px}.render-content pre code{background:none;padding:0;color:var(--text);font-size:12.5px;line-height:1.6}.render-content a{color:var(--accent);text-decoration:none}.render-content a:hover{text-decoration:underline}.render-content blockquote{border-left:3px solid var(--border);padding-left:14px;color:var(--text-3);margin-bottom:12px}.render-content table{width:100%;border-collapse:collapse;margin-bottom:12px}.render-content th,.render-content td{border:1px solid var(--border);padding:6px 10px;font-size:13px}.render-content th{background:var(--surface-1);font-weight:510}.turn-header{display:flex;align-items:center;gap:8px;margin-bottom:14px}.turn-header-icon{width:24px;height:24px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:9px;font-weight:700;color:#fff}.turn-header-title{font-size:14px;font-weight:600;color:var(--text)}.turn-header-meta{font-size:11px;color:var(--text-muted)}.tool-calls{margin-bottom:16px}.tool-calls-header{display:flex;align-items:center;gap:8px;padding:6px 12px;background:var(--surface-1);border:1px solid var(--border);border-radius:var(--r-sm);cursor:pointer;transition:background .15s ease-out;-webkit-user-select:none;user-select:none}.tool-calls-header:hover{background:var(--surface-2)}.tool-calls-icon{display:flex;align-items:center;color:var(--text-3);flex-shrink:0}.tool-calls-summary{font-size:13px;font-weight:500;color:var(--text-2);flex:1}.tool-calls-chevron{color:var(--text-muted);transition:transform .15s ease-out;flex-shrink:0}.tool-calls-body{margin-top:8px;padding-left:16px;border-left:2px solid var(--border)}.intermediate-segment{margin-bottom:16px}.intermediate-segment:last-child{margin-bottom:0}.user-message{font-size:14px;color:var(--text);background:var(--accent-soft);padding:12px 16px;border-radius:var(--r-md);border:1px solid rgba(217,119,6,.15)}.cmd-bar{position:relative;display:flex;flex-direction:column;padding:0;background:var(--surface-0);border-top:1px solid var(--border);flex-shrink:0}.cmd-input-row{display:flex;align-items:flex-end;gap:8px;padding:8px 12px}.cmd-bar:focus-within{box-shadow:inset 0 0 0 1px #d9770666}.cmd-textarea{flex:1;border:none;background:transparent;color:var(--text);font-size:13px;font-family:var(--font-sans);outline:none;resize:none;overflow-y:auto;line-height:1.5;padding:6px 0}.cmd-textarea::placeholder{color:var(--text-muted)}.cmd-textarea:disabled{opacity:.5}.cmd-textarea:focus-visible{box-shadow:none}.cmd-send-btn{width:28px;height:28px;border:none;border-radius:var(--r-sm);background:var(--surface-2);color:var(--text-muted);cursor:default;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:all var(--dur-fast) var(--ease)}.cmd-send-btn:not(:disabled){background:var(--accent);color:#fff;cursor:pointer}.cmd-send-btn:not(:disabled):hover{background:var(--accent-hover)}.cmd-send-btn:disabled{opacity:.4}.cmd-stop-btn{width:28px;height:28px;border:none;border-radius:var(--r-sm);background:var(--red);color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:all var(--dur-fast) var(--ease)}.cmd-stop-btn:hover{background:#b91c1c}.ide-right{background:var(--surface-0);border-left:1px solid var(--border);display:flex;flex-direction:column;overflow:hidden}.right-tabs{display:flex;padding:0 8px;border-bottom:1px solid var(--border);flex-shrink:0;gap:2px}.right-tab{padding:7px 10px;font-size:11px;font-weight:510;color:var(--text-3);cursor:pointer;border-bottom:2px solid transparent;-webkit-user-select:none;user-select:none;transition:all var(--dur-fast) var(--ease);margin-bottom:-1px}.right-tab:hover{color:var(--text-2)}.right-tab.active{color:var(--text);border-bottom-color:var(--accent)}.right-content{flex:1;overflow-y:auto;padding:14px}.right-section{margin-bottom:20px}.right-section-title{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.08em;color:var(--text-muted);margin-bottom:8px}.turn-item{display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:var(--r-sm);cursor:pointer;font-size:12px;color:var(--text-3);transition:all var(--dur-fast) var(--ease);position:relative}.turn-item:hover{background:#0000000a;color:var(--text-2)}.turn-item.active{background:var(--accent-soft);color:var(--text)}.turn-item.active:before{content:"";position:absolute;left:0;top:4px;bottom:4px;width:2px;background:var(--accent);border-radius:var(--r-pill)}.turn-item-icon{width:18px;height:18px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:8px;font-weight:700;color:#fff}.turn-item-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.turn-item-status{font-size:10px;color:var(--amber);flex-shrink:0}.turn-item-meta{font-size:10px;color:var(--text-muted);flex-shrink:0}.file-change{display:flex;align-items:center;gap:8px;padding:5px 0;font-size:12px;border-bottom:1px solid var(--border-muted)}.file-change:last-child{border:none}.file-change.clickable{cursor:pointer;transition:background var(--dur-fast) var(--ease)}.file-change.clickable:hover{background:#00000008}.fc-status{width:14px;text-align:center;font-weight:700;font-size:11px;flex-shrink:0}.fc-add{color:var(--green)}.fc-mod{color:var(--amber)}.fc-del{color:var(--red)}.fc-name{flex:1;color:var(--text-2);font-family:var(--font-mono);font-size:11px}.fc-delta{font-size:10px;color:var(--text-muted);flex-shrink:0;font-variant-numeric:tabular-nums}.diff-file-header{display:flex;align-items:center;gap:10px;padding:10px 14px;background:var(--surface-0);border:1px solid var(--border);border-radius:var(--r-md) var(--r-md) 0 0;border-bottom:none}.diff-file-status{width:16px;height:16px;border-radius:3px;display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:700;flex-shrink:0}.diff-file-name{font-family:var(--font-mono);font-size:13px;font-weight:510;color:var(--text)}.diff-file-stats{display:flex;align-items:center;gap:6px;margin-left:auto;font-size:11px;font-variant-numeric:tabular-nums}.diff-file-badge{padding:1px 7px;border-radius:var(--r-pill);background:var(--surface-2);color:var(--text-3);font-size:10px}.diff-body{border:1px solid var(--border);border-radius:0 0 var(--r-md) var(--r-md);overflow:hidden;margin-bottom:20px}.diff-line{display:flex;align-items:flex-start;font-family:var(--font-mono);font-size:12px;line-height:1.6}.diff-line-num{width:42px;flex-shrink:0;text-align:right;padding:0 8px;color:var(--text-muted);background:var(--surface-0);-webkit-user-select:none;user-select:none;border-right:1px solid var(--border-muted)}.diff-sign{width:20px;flex-shrink:0;text-align:center;-webkit-user-select:none;user-select:none;font-weight:700}.diff-line-content{flex:1;padding:0 8px;white-space:pre-wrap;word-break:break-all;min-width:0}.diff-line-add{background:#16a34a0f}.diff-line-add .diff-sign{color:var(--green)}.diff-line-del{background:#dc26260f}.diff-line-del .diff-sign{color:var(--red)}.diff-line-ctx .diff-sign{color:var(--text-muted)}.diff-line-ctx .diff-line-content{color:var(--text-3)}.changes-scope-toggle{display:flex;gap:2px;margin-bottom:12px;padding:2px;background:var(--surface-1);border-radius:var(--r-md)}.scope-btn{flex:1;padding:5px 10px;border:none;background:transparent;color:var(--text-3);font-size:11px;font-weight:510;cursor:pointer;border-radius:var(--r-sm);font-family:var(--font-sans);transition:all var(--dur-fast) var(--ease)}.scope-btn:hover{color:var(--text-2)}.scope-btn.active{background:var(--surface-0);color:var(--text);box-shadow:var(--inset-highlight)}.ide-statusbar{display:flex;align-items:center;gap:12px;padding:0 12px;height:24px;background:var(--surface-0);border-top:1px solid var(--border);font-size:11px;color:var(--text-muted);flex-shrink:0;font-variant-numeric:tabular-nums}.sb-item{display:flex;align-items:center;gap:3px;cursor:pointer;transition:color var(--dur-fast) var(--ease)}.sb-item:hover{color:var(--text-2)}.sb-spacer{flex:1}.sb-divider{color:var(--border)}.sb-context{display:flex;align-items:center;gap:5px}.sb-context-text{font-size:10px;color:var(--text-muted);font-variant-numeric:tabular-nums}.model-selector{position:relative}.model-selector-btn{display:flex;align-items:center;gap:4px;background:none;border:none;cursor:pointer;color:var(--text-muted);font-size:11px;padding:2px 6px;border-radius:3px;transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}.model-selector-btn:hover{background:var(--surface-1);color:var(--text-2)}.model-selector-provider{font-weight:500;color:var(--accent)}.model-selector-sep{color:var(--border);margin:0 1px}.model-selector-model{color:var(--text-2)}.model-selector-reasoning{color:var(--text-muted);font-style:italic}.model-selector-chevron{opacity:.5;flex-shrink:0}.model-selector-popover{position:absolute;bottom:calc(100% + 4px);left:0;display:flex;gap:1px;background:var(--surface-0);border:1px solid var(--border);border-radius:6px;box-shadow:0 4px 16px #0003;z-index:100;min-width:0;overflow:hidden}.model-selector-column{min-width:140px;max-width:220px;padding:4px 0;background:var(--surface-0)}.model-selector-col-header{padding:4px 10px;font-size:9px;font-weight:600;text-transform:uppercase;color:var(--text-muted);letter-spacing:.5px}.model-selector-item{display:flex;align-items:center;gap:6px;padding:6px 10px;cursor:pointer;font-size:11px;color:var(--text-2);transition:background var(--dur-fast) var(--ease)}.model-selector-item:hover{background:var(--surface-1)}.model-selector-item.selected{color:var(--accent)}.model-selector-item.disabled{cursor:default;opacity:.5}.model-selector-item.disabled:hover{background:none}.model-selector-item-main{display:flex;flex-direction:column;gap:1px;flex:1;min-width:0}.model-selector-item-name{font-weight:500;white-space:nowrap}.model-selector-item-desc{font-size:9px;color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.model-selector-coming-soon{display:flex;align-items:center;gap:2px;font-size:9px;color:var(--text-muted);font-style:italic}.model-selector-empty{padding:8px 10px;font-size:10px;color:var(--text-muted);font-style:italic}.dialog-select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 8px center;padding-right:26px}.badge{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:var(--r-pill);font-size:11px;font-weight:510;white-space:nowrap}.badge-running{background:var(--green-soft);color:var(--green)}.badge-queued{background:var(--amber-soft);color:var(--amber)}.badge-done{background:var(--accent-soft);color:var(--accent)}.badge-failed{background:var(--red-soft);color:var(--red)}.badge-paused{background:#a8a3991f;color:var(--text-muted)}.runtime-icon{width:20px;height:20px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:700;color:#fff;flex-shrink:0;letter-spacing:0}.ic-claude{background:var(--ic-claude)}.ic-codex{background:var(--ic-codex)}.ic-repoburg{background:var(--ic-repoburg)}.ic-cursor{background:var(--ic-cursor)}.status-dot{width:6px;height:6px;border-radius:50%;display:inline-block;flex-shrink:0}.status-dot.running{background:var(--green);animation:dot-pulse 1.5s ease-in-out infinite}.status-dot.queued{background:var(--amber)}.status-dot.error{background:var(--red)}.status-dot.done{background:var(--accent)}.status-dot.paused{background:var(--text-muted)}[data-lucide],svg.lucide{width:16px;height:16px;stroke-width:1.5;flex-shrink:0}.icon-xs{width:12px!important;height:12px!important}.icon-sm{width:14px!important;height:14px!important}.icon-lg{width:20px!important;height:20px!important}.dialog-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#0000004d;display:flex;align-items:center;justify-content:center;z-index:100}.dialog{background:var(--surface-0);border:1px solid var(--border);border-radius:var(--r-lg);width:400px;max-width:90vw;box-shadow:0 8px 32px #00000029}.dialog-header{display:flex;align-items:center;justify-content:space-between;padding:14px 16px;border-bottom:1px solid var(--border-muted)}.dialog-title{font-size:14px;font-weight:600;color:var(--text)}.dialog-close{border:none;background:transparent;color:var(--text-muted);cursor:pointer;padding:4px;border-radius:var(--r-sm);display:flex;align-items:center;transition:all var(--dur-fast) var(--ease)}.dialog-close:hover{background:#0000000f;color:var(--text)}.dialog-body{padding:16px;display:flex;flex-direction:column;gap:14px}.dialog-label{display:flex;flex-direction:column;gap:4px;font-size:11px;font-weight:510;color:var(--text-muted)}.dialog-input{border:1px solid var(--border);border-radius:var(--r-sm);padding:8px 10px;font-size:13px;font-family:var(--font-sans);color:var(--text);background:var(--canvas);outline:none;transition:border-color var(--dur-fast) var(--ease)}.dialog-input:focus{border-color:var(--accent);box-shadow:var(--focus-ring)}.dialog-footer{display:flex;justify-content:flex-end;gap:8px;padding:12px 16px;border-top:1px solid var(--border-muted)}.dialog-btn-cancel{padding:6px 14px;border-radius:var(--r-sm);border:1px solid var(--border);background:transparent;color:var(--text-2);font-size:12px;cursor:pointer;font-family:var(--font-sans);transition:all var(--dur-fast) var(--ease)}.dialog-btn-cancel:hover{background:var(--surface-2);color:var(--text)}.dialog-btn-create{padding:6px 14px;border-radius:var(--r-sm);border:none;background:var(--accent);color:#fff;font-size:12px;font-weight:510;cursor:pointer;font-family:var(--font-sans);transition:all var(--dur-fast) var(--ease)}.dialog-btn-create:hover{background:var(--accent-hover)}.turn-group{margin-bottom:24px}.turn-block{margin-bottom:32px;padding-bottom:8px;border-bottom:1px solid var(--border)}.turn-block:last-child{border-bottom:none}.cmd-block{background:var(--surface-0);border:1px solid var(--border);border-radius:var(--r-md);padding:10px 14px;overflow-x:auto;margin-bottom:12px}.cmd-block code{font-family:var(--font-mono);font-size:12px;color:var(--text)}.cmd-output{background:var(--surface-0);border:1px solid var(--border-muted);border-radius:var(--r-md);padding:10px 14px;overflow-x:auto;margin-bottom:12px;max-height:200px;overflow-y:auto}.cmd-output code{font-family:var(--font-mono);font-size:12px;color:var(--text-3)}.cmd-output-toggle{border:1px solid var(--border);border-radius:var(--r-sm);background:var(--surface-1);color:var(--text-muted);font-size:11px;font-family:var(--font-sans);padding:4px 10px;cursor:pointer;margin-bottom:12px;transition:all var(--dur-fast) var(--ease)}.cmd-output-toggle:hover{background:var(--surface-2);color:var(--text-2)}.mcp-args{margin-bottom:12px}.mcp-arg{margin-bottom:6px}.mcp-arg-key{font-size:11px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.04em;display:block;margin-bottom:3px}.mcp-arg-value{font-size:12px;color:var(--text-2);white-space:pre-wrap;word-break:break-word}.file-change-list{display:flex;flex-direction:column;gap:2px}.todo-list{list-style:none;padding-left:0}.todo-done{color:var(--text-3);text-decoration:line-through}.todo-pending{color:var(--text-2)}.empty-state{padding:40px 20px;text-align:center;color:var(--text-muted);font-size:13px}.palette-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#00000040;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);display:flex;align-items:flex-start;justify-content:center;padding-top:120px;z-index:200}.palette{background:var(--surface-0);border:1px solid var(--border);border-radius:var(--r-lg);width:520px;max-width:90vw;box-shadow:0 12px 40px #0003;overflow:hidden}.palette-search{display:flex;align-items:center;gap:8px;padding:12px 16px;border-bottom:1px solid var(--border-muted)}.palette-search input{flex:1;border:none;background:transparent;color:var(--text);font-size:15px;font-family:var(--font-sans);outline:none}.palette-search input::placeholder{color:var(--text-muted)}.palette-esc{font-size:10px;font-weight:600;color:var(--text-muted);background:var(--surface-2);padding:2px 6px;border-radius:var(--r-sm)}.palette-list{max-height:360px;overflow-y:auto;padding:4px}.palette-empty{padding:24px;text-align:center;color:var(--text-muted);font-size:13px}.palette-item{display:flex;align-items:center;gap:10px;padding:8px 12px;border-radius:var(--r-sm);cursor:pointer;transition:background var(--dur-fast) var(--ease)}.palette-item.selected{background:var(--accent-soft)}.palette-item-icon{color:var(--text-muted);flex-shrink:0;display:flex;align-items:center}.palette-item.selected .palette-item-icon{color:var(--accent)}.palette-item-label{font-size:13px;color:var(--text);font-weight:510}.palette-item-hint{font-size:11px;color:var(--text-muted);margin-left:auto}.palette-item-enter{color:var(--text-muted);flex-shrink:0}.toast-container{position:fixed;bottom:36px;right:16px;display:flex;flex-direction:column-reverse;gap:8px;z-index:300;pointer-events:none}.toast{display:flex;align-items:center;gap:8px;padding:10px 14px;border-radius:var(--r-md);font-size:12px;font-weight:500;min-width:280px;max-width:400px;pointer-events:auto;animation:toast-in .2s ease-out;border:1px solid var(--border);background:var(--surface-0);box-shadow:0 4px 16px #0000001f}@keyframes toast-in{0%{opacity:0;transform:translate(20px)}to{opacity:1;transform:translate(0)}}.toast-success{border-left:3px solid var(--green)}.toast-success svg{color:var(--green)}.toast-error{border-left:3px solid var(--red)}.toast-error svg{color:var(--red)}.toast-info{border-left:3px solid var(--accent)}.toast-info svg{color:var(--accent)}.toast-warn{border-left:3px solid var(--amber)}.toast-warn svg{color:var(--amber)}.toast-message{flex:1;color:var(--text-2)}.toast-close{border:none;background:transparent;color:var(--text-muted);cursor:pointer;padding:2px;border-radius:var(--r-sm);display:flex;align-items:center;transition:color var(--dur-fast) var(--ease)}.toast-close:hover{color:var(--text)}.error-banner{display:flex;align-items:center;gap:10px;padding:10px 16px;background:#dc262614;border:1px solid rgba(220,38,38,.2);border-radius:var(--r-md);margin-bottom:16px}.banner-icon{width:20px;height:20px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;flex-shrink:0}.error-banner .banner-icon{background:var(--red);color:#fff}.error-banner .banner-text{color:var(--red);font-size:13px;font-weight:500}.aborted-banner{display:flex;align-items:center;gap:10px;padding:10px 16px;background:#d9770614;border:1px solid rgba(217,119,6,.2);border-radius:var(--r-md);margin-bottom:16px}.aborted-banner .banner-icon{background:var(--amber);color:#fff}.aborted-banner .banner-text{color:var(--amber);font-size:13px;font-weight:500}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}.skeleton-bars{width:80%;max-width:500px;margin:20px 0}.skeleton-bar{height:10px;border-radius:var(--r-sm);background:var(--surface-1);margin-bottom:8px;animation:shimmer 1.2s infinite}.skeleton-bar:nth-child(1){width:60%}.skeleton-bar:nth-child(2){width:85%}.skeleton-bar:nth-child(3){width:70%}.skeleton-bar:nth-child(4){width:90%}.skeleton-bar:nth-child(5){width:50%}@keyframes shimmer{0%{opacity:.3}50%{opacity:.6}to{opacity:.3}}@keyframes dot-pulse{0%{opacity:1}to{opacity:.4}}.diff-file-header{transition:background .3s ease-out}.diff-file-header.diff-highlight{background:var(--accent-soft)}.palette-footer{display:flex;gap:16px;padding:8px 16px;border-top:1px solid var(--border-muted);font-size:11px;color:var(--text-muted)}.palette-footer-hint{display:flex;align-items:center;gap:4px}.kbd{font-family:var(--font-mono);font-size:10px;padding:1px 5px;border-radius:var(--r-sm);background:var(--surface-2);border:1px solid var(--border)}.toast-undo{font-size:12px;font-weight:500;color:var(--accent);background:transparent;border:none;cursor:pointer;padding:2px 8px;border-radius:var(--r-sm);display:flex;align-items:center;gap:4px;transition:background var(--dur-fast) var(--ease)}.toast-undo:hover{background:var(--accent-soft)}.tree-section-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11px}.tree-section-add{width:18px;height:18px;border:none;border-radius:var(--r-sm);background:transparent;color:var(--text-muted);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all var(--dur-fast) var(--ease);flex-shrink:0}.tree-section-add:hover{background:var(--accent-soft);color:var(--accent)}.tree-empty{padding:4px 8px 4px 26px;font-size:11px;color:var(--text-muted);font-style:italic}.tree-subgroup{margin-bottom:1px}.tree-subgroup-header{padding:3px 8px 3px 18px;display:flex;align-items:center;gap:5px;font-size:10px;font-weight:590;color:var(--text-muted);cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:var(--r-sm);transition:background var(--dur-fast) var(--ease)}.tree-subgroup-header:hover{background:#0000000a;color:var(--text-2)}.tree-subgroup.collapsed .tree-chevron{transform:rotate(-90deg)}.tree-subgroup.collapsed .tree-subgroup-items{display:none}.tree-subgroup-label{text-transform:uppercase;letter-spacing:.05em}.tree-subgroup-count{margin-left:auto;font-size:9px;color:var(--text-muted);font-variant-numeric:tabular-nums}.tree-subgroup-items{padding-left:0}.tree-item-finished .tree-label{color:var(--text-muted);opacity:.6}.tree-item-finished:hover .tree-label{opacity:.85}.ctx-menu{background:var(--surface-0);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:0 4px 16px #0000001f;padding:4px;min-width:160px}.ctx-menu-item{display:flex;align-items:center;gap:8px;padding:6px 10px;border-radius:var(--r-sm);font-size:12px;color:var(--text-2);cursor:pointer;transition:background var(--dur-fast) var(--ease)}.ctx-menu-item:hover{background:var(--accent-soft);color:var(--text)}.ctx-menu-item.ctx-danger:hover{background:#dc262614;color:var(--red)}.ctx-menu-item.ctx-disabled{opacity:.4;cursor:default}.ctx-menu-item.ctx-disabled:hover{background:transparent;color:var(--text-2)}.tree-rename-input{flex:1;border:1px solid var(--accent);border-radius:var(--r-sm);padding:1px 6px;font-size:12px;font-family:var(--font-sans);color:var(--text);background:var(--canvas);outline:none;box-shadow:var(--focus-ring);min-width:0}.slash-popup{position:absolute;bottom:100%;left:12px;right:12px;margin-bottom:4px;background:var(--surface-0);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:0 4px 16px #0000001f;max-height:280px;overflow-y:auto;z-index:100}.slash-popup-header{padding:6px 10px;font-size:10px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.05em;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:4px}.slash-popup-back{background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:11px;padding:2px 4px;border-radius:var(--r-sm)}.slash-popup-back:hover{background:var(--surface-1);color:var(--text-2)}.slash-popup-empty{padding:12px 10px;font-size:12px;color:var(--text-muted);text-align:center}.slash-popup-item{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 10px;cursor:pointer;border-radius:var(--r-sm);transition:background var(--dur-fast) var(--ease)}.slash-popup-item:hover,.slash-popup-item.selected{background:var(--accent-soft)}.slash-popup-label{font-size:12px;font-weight:500;color:var(--text-2);font-family:var(--font-mono)}.slash-popup-hint{font-size:11px;color:var(--text-muted)}.slash-popup-item-main{display:flex;flex-direction:column;gap:1px}.slash-popup-check{color:var(--accent);font-size:13px}.skill-badges{display:flex;flex-wrap:wrap;gap:4px;padding:6px 12px 0}.skill-badge{display:inline-flex;align-items:center;gap:4px;padding:2px 6px;font-size:11px;font-family:var(--font-mono);color:var(--accent);background:var(--accent-soft);border-radius:var(--r-sm)}.skill-badge-remove{background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:13px;line-height:1;padding:0}.skill-badge-remove:hover{color:var(--red)}.attachment-preview-area{display:flex;flex-wrap:wrap;gap:4px;padding:6px 12px 0}.attachment-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 6px 2px 2px;border:1px solid var(--border);border-radius:var(--r-pill);background:var(--surface-1);max-width:180px;position:relative;transition:border-color var(--dur-fast) var(--ease)}.attachment-chip:hover{border-color:var(--accent)}.attachment-thumb{width:18px;height:18px;object-fit:cover;border-radius:50%;flex-shrink:0}.attachment-file-icon{width:14px;height:14px;color:var(--text-muted);flex-shrink:0}.attachment-info{display:flex;flex-direction:column;gap:0;overflow:hidden;min-width:0}.attachment-name{font-size:10px;font-family:var(--font-mono);color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100px}.attachment-size{font-size:9px;color:var(--text-muted);font-variant-numeric:tabular-nums}.attachment-remove{background:none;border:none;color:var(--text-muted);cursor:pointer;padding:1px;display:flex;align-items:center;justify-content:center;border-radius:var(--r-xs);transition:all var(--dur-fast) var(--ease);flex-shrink:0}.attachment-remove:hover{color:var(--red);background:#ef44441a}.attachment-clip-btn{width:28px;height:28px;border:none;border-radius:var(--r-sm);background:transparent;color:var(--text-muted);cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:all var(--dur-fast) var(--ease)}.attachment-clip-btn:hover{color:var(--accent);background:var(--surface-2)}.attachment-clip-btn:disabled{opacity:.3;cursor:default}.cmd-bar.drag-over{box-shadow:inset 0 0 0 2px var(--accent);background:var(--accent-soft)}.image-preview-modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:10000;background:#000c;display:flex;align-items:center;justify-content:center;padding:32px;animation:modal-fade-in .15s ease-out}@keyframes modal-fade-in{0%{opacity:0}to{opacity:1}}.image-preview-content{position:relative;max-width:90vw;max-height:90vh;display:flex;flex-direction:column;align-items:center;gap:8px}.image-preview-content img{max-width:100%;max-height:80vh;object-fit:contain;border-radius:var(--r-sm);border:1px solid var(--border)}.image-preview-info{display:flex;gap:12px;font-size:12px;color:var(--text-muted);font-family:var(--font-mono)}.image-preview-close{position:absolute;top:-12px;right:-12px;width:28px;height:28px;border:none;border-radius:50%;background:var(--surface-2);color:var(--text);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all var(--dur-fast) var(--ease)}.image-preview-close:hover{background:var(--red);color:#fff}.attachment-pills{display:flex;flex-wrap:wrap;gap:4px;margin-top:6px}.attachment-pill{display:inline-flex;align-items:center;gap:4px;padding:2px 8px 2px 2px;border:1px solid var(--border);border-radius:var(--r-pill);background:var(--surface-1);font-size:10px;font-family:var(--font-mono);color:var(--text-muted);transition:border-color var(--dur-fast) var(--ease)}.attachment-pill:hover{border-color:var(--accent)}.attachment-pill-thumb{width:16px;height:16px;object-fit:cover;border-radius:50%;flex-shrink:0}.attachment-pill-icon{color:var(--text-muted);flex-shrink:0}.attachment-pill-name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100px}.right-tab-badge{display:inline-flex;align-items:center;justify-content:center;min-width:16px;height:16px;padding:0 4px;margin-left:4px;font-size:10px;font-weight:600;color:#fff;background:var(--accent);border-radius:8px}.task-count-badge{font-size:10px;font-weight:500}.task-card{border:1px solid var(--border);border-radius:var(--r-md);padding:10px 12px;margin-bottom:10px;transition:border-color var(--dur-fast) var(--ease)}.task-card.task-running{border-color:var(--accent)}.task-card.task-failed{border-color:var(--red)}.task-card-header{display:flex;align-items:center;gap:8px}.task-card-icon{display:flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:var(--r-sm);background:var(--surface-2);color:var(--text-3);flex-shrink:0}.task-card-type{font-size:13px;font-weight:600;color:var(--text)}.task-card-status{display:flex;align-items:center;gap:3px;font-size:11px;padding:2px 6px;border-radius:var(--r-sm);flex-shrink:0}.task-status-running{color:var(--accent);background:var(--accent-soft)}.task-status-done{color:var(--green);background:var(--green-soft)}.task-status-failed{color:var(--red);background:var(--red-soft)}.task-card-chevron{color:var(--text-muted);flex-shrink:0;transition:transform var(--dur-fast) var(--ease)}.task-card-desc{font-size:12px;color:var(--text-2);margin-top:6px;font-family:var(--font-mono)}.task-card-meta{font-size:11px;color:var(--text-muted);margin-top:4px}.task-card-body{margin-top:8px}.task-output{max-height:300px}.task-card-placeholder{font-size:12px;color:var(--text-muted);font-style:italic;padding:8px 0}.task-card-context{font-size:10px;color:var(--text-muted);margin-top:6px;padding-top:6px;border-top:1px solid var(--border-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}mark[data-thread-id]{background:#d977062e;border-radius:2px;cursor:pointer;padding:0 1px;transition:background var(--dur-fast) var(--ease)}mark[data-thread-id]:hover{background:#d977064d}mark[data-thread-id].thread-mark-resolved{background:transparent;border-bottom:2px dashed var(--text-muted)}.selection-actions{position:fixed;z-index:9999;display:flex;gap:4px}.discuss-button{display:flex;align-items:center;gap:4px;padding:4px 10px;border:1px solid var(--border);border-radius:var(--r-sm);background:var(--surface-0);color:var(--accent);font-size:11px;font-weight:500;cursor:pointer;box-shadow:0 2px 8px #0000001f;transition:all var(--dur-fast) var(--ease)}.discuss-button:hover{background:var(--accent-soft);border-color:var(--accent)}.thread-create-popover{position:fixed;z-index:9999;min-width:280px;max-width:360px;background:var(--surface-0);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:0 4px 16px #00000026;padding:10px;display:flex;flex-direction:column;gap:8px;transform:translate(-100%)}.thread-create-header{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.thread-create-quote{font-size:11px;color:var(--text-muted);font-style:italic;flex:1;line-height:1.4}.thread-create-close{border:none;background:transparent;color:var(--text-muted);cursor:pointer;padding:2px;border-radius:var(--r-sm);flex-shrink:0}.thread-create-close:hover{background:var(--surface-1);color:var(--text)}.thread-create-input{border:1px solid var(--border);border-radius:var(--r-sm);padding:8px 10px;font-size:13px;font-family:var(--font-sans);color:var(--text);background:var(--canvas);outline:none;resize:none;line-height:1.5;transition:border-color var(--dur-fast) var(--ease)}.thread-create-input:focus{border-color:var(--accent);box-shadow:var(--focus-ring)}.thread-create-footer{display:flex;align-items:center;justify-content:space-between}.thread-create-hint{font-size:10px;color:var(--text-muted)}.thread-create-send{display:flex;align-items:center;gap:4px;padding:4px 10px;border:none;border-radius:var(--r-sm);background:var(--accent);color:#fff;font-size:11px;font-weight:500;cursor:pointer;transition:background var(--dur-fast) var(--ease)}.thread-create-send:disabled{opacity:.4;cursor:default}.thread-create-send:not(:disabled):hover{background:var(--accent-hover)}.thread-filter-tabs{display:flex;gap:2px;margin-bottom:12px;padding:2px;background:var(--surface-1);border-radius:var(--r-md)}.thread-filter-tab{flex:1;padding:4px 8px;border:none;background:transparent;color:var(--text-3);font-size:10px;font-weight:500;cursor:pointer;border-radius:var(--r-sm);font-family:var(--font-sans);transition:all var(--dur-fast) var(--ease)}.thread-filter-tab:hover{color:var(--text-2)}.thread-filter-tab.active{background:var(--surface-0);color:var(--text);box-shadow:var(--inset-highlight)}.thread-card{border:1px solid var(--border);border-radius:var(--r-md);padding:10px 12px;margin-bottom:10px;transition:border-color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease)}.thread-card.thread-resolved{opacity:.7}.thread-card-highlighted{border-color:var(--accent);background:var(--accent-soft)}.thread-card-header{display:flex;align-items:flex-start;justify-content:space-between;gap:8px;cursor:pointer}.thread-card-quote{font-size:11px;color:var(--text-muted);font-style:italic;line-height:1.4;flex:1}.thread-card-header-right{display:flex;align-items:center;gap:4px;flex-shrink:0}.thread-status-badge{font-size:10px;font-weight:600;padding:2px 8px;border-radius:var(--r-pill)}.thread-status-open{background:var(--accent-soft);color:var(--accent)}.thread-status-resolved{background:var(--green-soft);color:var(--green)}.thread-card-conversation{margin-top:8px;max-height:300px;overflow-y:auto}.thread-card-turn{margin-bottom:8px;padding-bottom:8px;border-bottom:1px solid var(--border-muted)}.thread-card-turn:last-child{border-bottom:none;margin-bottom:0;padding-bottom:0}.thread-card-user-message{font-size:12px;color:var(--text);background:var(--accent-soft);padding:6px 10px;border-radius:var(--r-sm);border:1px solid rgba(217,119,6,.15);margin-bottom:4px}.thread-card-ai-response{font-size:12px;color:var(--text-2);padding:4px 0;line-height:1.5}.thread-card-ai-response p{margin-bottom:6px}.thread-card-ai-response code{font-family:var(--font-mono);font-size:11px;background:var(--surface-1);padding:1px 4px;border-radius:var(--r-sm);color:var(--accent)}.thread-card-ai-response pre{background:var(--surface-0);border:1px solid var(--border);border-radius:var(--r-sm);padding:8px;overflow-x:auto;margin-bottom:6px}.thread-card-ai-response pre code{background:none;padding:0}.thread-card-pending{font-size:11px;color:var(--text-muted);font-style:italic;padding:4px 0}.thread-card-placeholder{font-size:11px;color:var(--text-muted);font-style:italic;padding:8px 0}.thread-card-followup{display:flex;gap:4px;margin-top:8px}.thread-card-followup-input{flex:1;border:1px solid var(--border);border-radius:var(--r-sm);padding:6px 8px;font-size:12px;font-family:var(--font-sans);color:var(--text);background:var(--canvas);outline:none;resize:none;line-height:1.5;transition:border-color var(--dur-fast) var(--ease)}.thread-card-followup-input:focus{border-color:var(--accent)}.thread-card-followup-input:disabled{opacity:.5}.thread-card-followup-send{width:28px;height:28px;border:none;border-radius:var(--r-sm);background:var(--accent);color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:background var(--dur-fast) var(--ease)}.thread-card-followup-send:disabled{opacity:.4;cursor:default}.thread-card-followup-send:not(:disabled):hover{background:var(--accent-hover)}.thread-locate-btn{background:none;border:none;color:var(--text-muted);cursor:pointer;padding:2px;border-radius:3px;display:flex;align-items:center;transition:all var(--dur-fast) var(--ease);flex-shrink:0}.thread-locate-btn:hover{color:var(--accent);background:var(--accent-soft)}.thread-mark-flash{animation:mark-flash 1.5s ease-out}@keyframes mark-flash{0%{background:#d9770680}to{background:#d977062e}}.thread-card-actions{display:flex;gap:6px;margin-top:8px;padding-top:8px;border-top:1px solid var(--border-muted)}.thread-action-btn{display:flex;align-items:center;gap:4px;padding:4px 8px;border:1px solid var(--border);border-radius:var(--r-sm);background:transparent;color:var(--text-3);font-size:11px;cursor:pointer;font-family:var(--font-sans);transition:all var(--dur-fast) var(--ease)}.thread-action-btn:hover{background:var(--surface-1);color:var(--text)}.thread-action-btn.thread-action-danger:hover{background:#dc262614;color:var(--red);border-color:#dc262633}.agent-call-card{display:flex;align-items:center;gap:8px;padding:8px 14px;border-left:3px solid var(--accent);background:var(--surface);border-radius:0 var(--r-sm) var(--r-sm) 0}.agent-call-icon{color:var(--text-2);display:flex;align-items:center}.agent-call-desc{font-size:13px;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}.agent-call-status{font-size:10px;font-family:var(--font-mono);padding:1px 6px;border-radius:var(--r-sm)}.agent-call-status.running{color:var(--accent);background:var(--accent-soft)}.agent-call-status.done{color:var(--green);background:#22c55e14}.agent-call-status.failed{color:var(--red);background:#ef444414}.ask-user-card{border-left:3px solid var(--accent)}.ask-user-groups{display:flex;flex-direction:column;gap:10px;margin-top:6px}.ask-user-group{display:flex;flex-direction:column;gap:6px}.ask-user-question{font-size:12px;font-weight:600;color:var(--text-2)}.ask-user-options{display:flex;flex-wrap:wrap;gap:6px}.ask-user-option{padding:4px 10px;font-size:12px;font-family:var(--font-sans);color:var(--text-2);background:var(--canvas);border:1px solid var(--border);border-radius:var(--r-sm);cursor:pointer;transition:all var(--dur-fast) var(--ease)}.ask-user-option:not(:disabled):hover{border-color:var(--accent);color:var(--accent)}.ask-user-option.selected{background:var(--accent);border-color:var(--accent);color:#fff}.ask-user-option:disabled{opacity:.55;cursor:default}.ask-user-option.selected:disabled{opacity:.8}.ask-user-send{display:inline-flex;align-items:center;gap:5px;padding:4px 12px;font-size:12px;font-family:var(--font-sans);color:#fff;background:var(--accent);border:none;border-radius:var(--r-sm);cursor:pointer;align-self:flex-start;transition:background var(--dur-fast) var(--ease)}.ask-user-send:disabled{opacity:.4;cursor:default}.ask-user-send:not(:disabled):hover{background:var(--accent-hover)}.ask-user-submitted{font-size:11px;color:var(--text-muted);font-style:italic}
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;450;510;590;600&family=JetBrains+Mono:wght@400;500&display=swap"
|
|
11
11
|
rel="stylesheet"
|
|
12
12
|
/>
|
|
13
|
-
<script type="module" crossorigin src="/assets/index-
|
|
14
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
13
|
+
<script type="module" crossorigin src="/assets/index-CJxD4YmJ.js"></script>
|
|
14
|
+
<link rel="stylesheet" crossorigin href="/assets/index-r-xwfOKQ.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body>
|
|
17
17
|
<div id="root"></div>
|
|
@@ -245,13 +245,13 @@ describe('WebSocket event dispatch', () => {
|
|
|
245
245
|
};
|
|
246
246
|
sendMessage({ event: 'turn:completed', data: { sessionId: 's1', turnId: 't1', usage, hasUnreviewed: true } });
|
|
247
247
|
const store = getMockStore();
|
|
248
|
-
expect(store.onTurnCompleted).toHaveBeenCalledWith('s1', 't1', usage, true);
|
|
248
|
+
expect(store.onTurnCompleted).toHaveBeenCalledWith('s1', 't1', usage, true, undefined);
|
|
249
249
|
});
|
|
250
250
|
|
|
251
251
|
it('dispatches turn:completed event without usage (real app-server)', () => {
|
|
252
252
|
sendMessage({ event: 'turn:completed', data: { sessionId: 's1', turnId: 't1', hasUnreviewed: true } });
|
|
253
253
|
const store = getMockStore();
|
|
254
|
-
expect(store.onTurnCompleted).toHaveBeenCalledWith('s1', 't1', undefined, true);
|
|
254
|
+
expect(store.onTurnCompleted).toHaveBeenCalledWith('s1', 't1', undefined, true, undefined);
|
|
255
255
|
});
|
|
256
256
|
|
|
257
257
|
it('dispatches turn:failed event with error', () => {
|
|
@@ -104,6 +104,8 @@ interface TurnCompletedPayload {
|
|
|
104
104
|
turnId: string;
|
|
105
105
|
usage?: TokenUsage;
|
|
106
106
|
hasUnreviewed?: boolean;
|
|
107
|
+
/** Final turn text (repoburg final-action rounds with no agent_message item). */
|
|
108
|
+
response?: string | null;
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
interface ItemDeltaPayload {
|
|
@@ -188,7 +190,7 @@ const HANDLERS: Record<string, WsEventHandler> = {
|
|
|
188
190
|
},
|
|
189
191
|
'turn:completed': (data) => {
|
|
190
192
|
const p = data as TurnCompletedPayload;
|
|
191
|
-
useStore.getState().onTurnCompleted(p.sessionId, p.turnId, p.usage, p.hasUnreviewed);
|
|
193
|
+
useStore.getState().onTurnCompleted(p.sessionId, p.turnId, p.usage, p.hasUnreviewed, p.response ?? undefined);
|
|
192
194
|
},
|
|
193
195
|
'turn:tokenUsage': (data) => {
|
|
194
196
|
const p = data as TokenUsageUpdatedPayload;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { describe, it, expect, afterEach, vi } from 'vitest';
|
|
2
|
+
import { render, screen, fireEvent, cleanup } from '@testing-library/react';
|
|
3
|
+
import AskUserItem, { resetAskUserStore, buildSelectionPrompt } from './AskUserItem.tsx';
|
|
4
|
+
import { useStore } from '../store/store.ts';
|
|
5
|
+
import { resetStore } from '../test/component-helpers.ts';
|
|
6
|
+
import { makeTurn, makeItem, makeDetail } from '../test/fixtures.ts';
|
|
7
|
+
import type { Item, Turn } from '@agentpane/shared';
|
|
8
|
+
|
|
9
|
+
const GROUPS = [
|
|
10
|
+
{ question: 'Which database?', selections: ['Postgres', 'SQLite'] },
|
|
11
|
+
{ question: 'Proceed?', selections: ['yes', 'no'] },
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
function askItem(id: string, turnId: string, data: Record<string, unknown> | null): Item {
|
|
15
|
+
const item = makeItem(id, turnId, 'ask_user');
|
|
16
|
+
item.data = data;
|
|
17
|
+
return item;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function setup(turn: Turn, isRunning = 0) {
|
|
21
|
+
resetStore({
|
|
22
|
+
activeSessionId: turn.session_id,
|
|
23
|
+
sessionDetails: { [turn.session_id]: { ...makeDetail(turn.session_id, [turn]), is_running: isRunning } },
|
|
24
|
+
});
|
|
25
|
+
render(<AskUserItem item={turn.items[turn.items.length - 1]} turn={turn} />);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function makeAskTurn(items: Item[]): Turn {
|
|
29
|
+
return makeTurn('t1', 's1', { items, status: 'completed' });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
describe('AskUserItem', () => {
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
cleanup();
|
|
35
|
+
resetAskUserStore();
|
|
36
|
+
resetStore();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('renders all groups with their options', () => {
|
|
40
|
+
const turn = makeAskTurn([askItem('i1', 't1', { question: '', groups: GROUPS })]);
|
|
41
|
+
setup(turn);
|
|
42
|
+
expect(screen.getByText('Which database?')).toBeInTheDocument();
|
|
43
|
+
expect(screen.getByText('Proceed?')).toBeInTheDocument();
|
|
44
|
+
expect(screen.getByText('Postgres')).toBeInTheDocument();
|
|
45
|
+
expect(screen.getByText('SQLite')).toBeInTheDocument();
|
|
46
|
+
expect(screen.getByText('yes')).toBeInTheDocument();
|
|
47
|
+
expect(screen.getByText('no')).toBeInTheDocument();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('toggles one answer per group; re-click deselects', () => {
|
|
51
|
+
const turn = makeAskTurn([askItem('i1', 't1', { question: '', groups: GROUPS })]);
|
|
52
|
+
setup(turn);
|
|
53
|
+
|
|
54
|
+
const send = screen.getByRole('button', { name: /send/i });
|
|
55
|
+
expect(send).toBeDisabled();
|
|
56
|
+
|
|
57
|
+
fireEvent.click(screen.getByText('Postgres'));
|
|
58
|
+
expect(send).toBeEnabled();
|
|
59
|
+
|
|
60
|
+
// Selecting another option in the same group replaces the answer.
|
|
61
|
+
fireEvent.click(screen.getByText('SQLite'));
|
|
62
|
+
expect(screen.getByText('SQLite').className).toContain('selected');
|
|
63
|
+
expect(screen.getByText('Postgres').className).not.toContain('selected');
|
|
64
|
+
|
|
65
|
+
// Re-click deselects.
|
|
66
|
+
fireEvent.click(screen.getByText('SQLite'));
|
|
67
|
+
expect(screen.getByText('SQLite').className).not.toContain('selected');
|
|
68
|
+
expect(send).toBeDisabled();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('submits the combined prompt for all selected groups in ONE send', () => {
|
|
72
|
+
const turn = makeAskTurn([askItem('i1', 't1', { question: '', groups: GROUPS })]);
|
|
73
|
+
setup(turn);
|
|
74
|
+
const submitPrompt = vi.fn();
|
|
75
|
+
useStore.setState({ submitPrompt });
|
|
76
|
+
|
|
77
|
+
fireEvent.click(screen.getByText('Postgres'));
|
|
78
|
+
fireEvent.click(screen.getByText('yes'));
|
|
79
|
+
fireEvent.click(screen.getByRole('button', { name: /send/i }));
|
|
80
|
+
|
|
81
|
+
expect(submitPrompt).toHaveBeenCalledTimes(1);
|
|
82
|
+
expect(submitPrompt).toHaveBeenCalledWith('> Which database?\nPostgres\n\n> Proceed?\nyes');
|
|
83
|
+
expect(screen.getByText('Answer sent')).toBeInTheDocument();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('submits answers from MULTIPLE ask_user items in one turn together, sorted by item order', () => {
|
|
87
|
+
const turn = makeAskTurn([
|
|
88
|
+
askItem('i1', 't1', { question: '', groups: [GROUPS[0]] }),
|
|
89
|
+
askItem('i2', 't1', { question: '', groups: [GROUPS[1]] }),
|
|
90
|
+
]);
|
|
91
|
+
resetStore({
|
|
92
|
+
activeSessionId: 's1',
|
|
93
|
+
sessionDetails: { s1: makeDetail('s1', [turn]) },
|
|
94
|
+
});
|
|
95
|
+
const submitPrompt = vi.fn();
|
|
96
|
+
useStore.setState({ submitPrompt });
|
|
97
|
+
|
|
98
|
+
const { rerender } = render(<AskUserItem item={turn.items[0]} turn={turn} />);
|
|
99
|
+
fireEvent.click(screen.getByText('Postgres'));
|
|
100
|
+
|
|
101
|
+
// Select on the SECOND card; its Send must carry the FIRST card's answer too.
|
|
102
|
+
rerender(<AskUserItem item={turn.items[1]} turn={turn} />);
|
|
103
|
+
fireEvent.click(screen.getByText('yes'));
|
|
104
|
+
fireEvent.click(screen.getByRole('button', { name: /send/i }));
|
|
105
|
+
|
|
106
|
+
expect(submitPrompt).toHaveBeenCalledTimes(1);
|
|
107
|
+
expect(submitPrompt).toHaveBeenCalledWith('> Which database?\nPostgres\n\n> Proceed?\nyes');
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('disables buttons while the session is running', () => {
|
|
111
|
+
const turn = makeAskTurn([askItem('i1', 't1', { question: '', groups: GROUPS })]);
|
|
112
|
+
setup(turn, 1);
|
|
113
|
+
expect(screen.getByText('Postgres')).toBeDisabled();
|
|
114
|
+
// No send affordance while disabled.
|
|
115
|
+
expect(screen.queryByRole('button', { name: /send/i })).not.toBeInTheDocument();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('renders a plain-text fallback for malformed selections payloads', () => {
|
|
119
|
+
const turn = makeAskTurn([askItem('i1', 't1', { question: 'Plain question?', groups: [] })]);
|
|
120
|
+
setup(turn);
|
|
121
|
+
expect(screen.getByText('Plain question?')).toBeInTheDocument();
|
|
122
|
+
expect(screen.queryByRole('button', { name: /send/i })).not.toBeInTheDocument();
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('renders the waiting note when there is no payload', () => {
|
|
126
|
+
const turn = makeAskTurn([askItem('i1', 't1', null)]);
|
|
127
|
+
setup(turn);
|
|
128
|
+
expect(screen.getByText(/Waiting for user response/i)).toBeInTheDocument();
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
describe('buildSelectionPrompt', () => {
|
|
133
|
+
it('sorts by item index then group index and joins with \\n\\n', () => {
|
|
134
|
+
const prompt = buildSelectionPrompt([
|
|
135
|
+
{ itemIndex: 1, groupIndex: 0, question: 'Second?', answer: 'b' },
|
|
136
|
+
{ itemIndex: 0, groupIndex: 1, question: 'First group 2?', answer: 'a2' },
|
|
137
|
+
{ itemIndex: 0, groupIndex: 0, question: 'First group 1?', answer: 'a1' },
|
|
138
|
+
]);
|
|
139
|
+
expect(prompt).toBe(
|
|
140
|
+
'> First group 1?\na1\n\n> First group 2?\na2\n\n> Second?\nb',
|
|
141
|
+
);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AskUserItem — renders the runtime's ask_user action as clickable
|
|
3
|
+
* selection buttons (platform parity: SelectionButtons in the webcoder
|
|
4
|
+
* platform frontend).
|
|
5
|
+
*
|
|
6
|
+
* Behavior:
|
|
7
|
+
* - All groups render; selection is a TOGGLE (one answer per group).
|
|
8
|
+
* - Selection state is shared PER TURN (module store keyed by turn id) —
|
|
9
|
+
* if a turn ever holds multiple ask_user items, ONE Send submits ALL
|
|
10
|
+
* selected answers together as a single user_prompt.
|
|
11
|
+
* - Combined prompt = `> ${question}\n${answer}` per selected group,
|
|
12
|
+
* sorted by item order then group index, joined with `\n\n`.
|
|
13
|
+
* - Disabled once the turn is submitted, the session is running, or a
|
|
14
|
+
* newer turn exists.
|
|
15
|
+
*/
|
|
16
|
+
import { useCallback, useMemo, useSyncExternalStore } from 'react';
|
|
17
|
+
import { CircleHelp, Send } from 'lucide-react';
|
|
18
|
+
import type { AskUserItemData, Item, Turn } from '../types/index.ts';
|
|
19
|
+
import { useStore } from '../store/store.ts';
|
|
20
|
+
|
|
21
|
+
/** One selected answer with its ordering key. */
|
|
22
|
+
interface SelectionEntry {
|
|
23
|
+
itemIndex: number;
|
|
24
|
+
groupIndex: number;
|
|
25
|
+
question: string;
|
|
26
|
+
answer: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// --- Per-turn shared selection store (module-scope, tiny pub/sub) ---
|
|
30
|
+
const turnSelections = new Map<string, Map<string, SelectionEntry>>();
|
|
31
|
+
const submittedTurns = new Set<string>();
|
|
32
|
+
const listeners = new Set<() => void>();
|
|
33
|
+
const EMPTY = new Map<string, SelectionEntry>();
|
|
34
|
+
|
|
35
|
+
function notify(): void {
|
|
36
|
+
listeners.forEach((l) => l());
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function selectionKey(itemIndex: number, groupIndex: number): string {
|
|
40
|
+
return `${itemIndex}:${groupIndex}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function toggleSelection(
|
|
44
|
+
turnId: string,
|
|
45
|
+
itemIndex: number,
|
|
46
|
+
groupIndex: number,
|
|
47
|
+
question: string,
|
|
48
|
+
answer: string,
|
|
49
|
+
): void {
|
|
50
|
+
const key = selectionKey(itemIndex, groupIndex);
|
|
51
|
+
const current = turnSelections.get(turnId) ?? new Map<string, SelectionEntry>();
|
|
52
|
+
const next = new Map(current);
|
|
53
|
+
if (next.get(key)?.answer === answer) {
|
|
54
|
+
next.delete(key); // re-click deselects
|
|
55
|
+
} else {
|
|
56
|
+
next.set(key, { itemIndex, groupIndex, question, answer });
|
|
57
|
+
}
|
|
58
|
+
turnSelections.set(turnId, next);
|
|
59
|
+
notify();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function clearTurnSelections(turnId: string): void {
|
|
63
|
+
turnSelections.delete(turnId);
|
|
64
|
+
notify();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function markSubmitted(turnId: string): void {
|
|
68
|
+
submittedTurns.add(turnId);
|
|
69
|
+
clearTurnSelections(turnId);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Reset state (used by tests). */
|
|
73
|
+
export function resetAskUserStore(): void {
|
|
74
|
+
turnSelections.clear();
|
|
75
|
+
submittedTurns.clear();
|
|
76
|
+
notify();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function useTurnSelections(turnId: string): Map<string, SelectionEntry> {
|
|
80
|
+
const subscribe = useCallback((cb: () => void) => {
|
|
81
|
+
listeners.add(cb);
|
|
82
|
+
return () => {
|
|
83
|
+
listeners.delete(cb);
|
|
84
|
+
};
|
|
85
|
+
}, []);
|
|
86
|
+
return useSyncExternalStore(
|
|
87
|
+
subscribe,
|
|
88
|
+
() => turnSelections.get(turnId) ?? EMPTY,
|
|
89
|
+
() => EMPTY,
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Build the combined prompt (platform parity: sorted, `> q\nanswer`, `\n\n` join). */
|
|
94
|
+
export function buildSelectionPrompt(entries: SelectionEntry[]): string {
|
|
95
|
+
return [...entries]
|
|
96
|
+
.sort((a, b) => a.itemIndex - b.itemIndex || a.groupIndex - b.groupIndex)
|
|
97
|
+
.map((e) => `> ${e.question}\n${e.answer}`)
|
|
98
|
+
.join('\n\n');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
interface Props {
|
|
102
|
+
item: Item;
|
|
103
|
+
turn: Turn;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export default function AskUserItem({ item, turn }: Props) {
|
|
107
|
+
const data = (item.data ?? {}) as Partial<AskUserItemData>;
|
|
108
|
+
const groups = useMemo(
|
|
109
|
+
() =>
|
|
110
|
+
Array.isArray(data.groups)
|
|
111
|
+
? data.groups.filter(
|
|
112
|
+
(g): g is { question: string; selections: string[] } =>
|
|
113
|
+
!!g && Array.isArray(g.selections) && g.selections.length > 0,
|
|
114
|
+
)
|
|
115
|
+
: [],
|
|
116
|
+
[data.groups],
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
const selections = useTurnSelections(turn.id);
|
|
120
|
+
const detail = useStore((s) =>
|
|
121
|
+
turn.session_id ? s.sessionDetails[turn.session_id] : null,
|
|
122
|
+
);
|
|
123
|
+
const activeSessionId = useStore((s) => s.activeSessionId);
|
|
124
|
+
|
|
125
|
+
const itemIndex = turn.items.findIndex((i) => i.id === item.id);
|
|
126
|
+
const isLastTurn = detail
|
|
127
|
+
? detail.turns[detail.turns.length - 1]?.id === turn.id
|
|
128
|
+
: true;
|
|
129
|
+
const submitted = submittedTurns.has(turn.id);
|
|
130
|
+
const disabled =
|
|
131
|
+
submitted ||
|
|
132
|
+
detail?.is_running === 1 ||
|
|
133
|
+
!isLastTurn ||
|
|
134
|
+
turn.session_id !== activeSessionId;
|
|
135
|
+
|
|
136
|
+
const handleToggle = (groupIndex: number, question: string, answer: string) => {
|
|
137
|
+
if (disabled) return;
|
|
138
|
+
toggleSelection(turn.id, itemIndex, groupIndex, question, answer);
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const handleSend = () => {
|
|
142
|
+
const entries = [...selections.values()];
|
|
143
|
+
if (entries.length === 0) return;
|
|
144
|
+
const prompt = buildSelectionPrompt(entries);
|
|
145
|
+
markSubmitted(turn.id);
|
|
146
|
+
void useStore.getState().submitPrompt(prompt);
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
return (
|
|
150
|
+
<div className="render-content ask-user-card">
|
|
151
|
+
<div className="turn-header">
|
|
152
|
+
<span className="turn-header-icon" style={{ background: 'var(--surface-2)', color: 'var(--text-3)' }}>
|
|
153
|
+
<CircleHelp size={14} />
|
|
154
|
+
</span>
|
|
155
|
+
<span className="turn-header-title">Question</span>
|
|
156
|
+
{submitted && <span className="turn-header-meta">answered</span>}
|
|
157
|
+
</div>
|
|
158
|
+
|
|
159
|
+
{groups.length > 0 ? (
|
|
160
|
+
<div className="ask-user-groups">
|
|
161
|
+
{groups.map((group, gi) => (
|
|
162
|
+
<div key={gi} className="ask-user-group">
|
|
163
|
+
{group.question && <div className="ask-user-question">{group.question}</div>}
|
|
164
|
+
<div className="ask-user-options">
|
|
165
|
+
{group.selections.map((option) => {
|
|
166
|
+
const selected =
|
|
167
|
+
selections.get(selectionKey(itemIndex, gi))?.answer === option;
|
|
168
|
+
return (
|
|
169
|
+
<button
|
|
170
|
+
key={option}
|
|
171
|
+
type="button"
|
|
172
|
+
className={`ask-user-option ${selected ? 'selected' : ''}`}
|
|
173
|
+
disabled={disabled}
|
|
174
|
+
onClick={() => handleToggle(gi, group.question, option)}
|
|
175
|
+
>
|
|
176
|
+
{option}
|
|
177
|
+
</button>
|
|
178
|
+
);
|
|
179
|
+
})}
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
182
|
+
))}
|
|
183
|
+
{disabled ? (
|
|
184
|
+
submitted && <div className="ask-user-submitted">Answer sent</div>
|
|
185
|
+
) : (
|
|
186
|
+
<button
|
|
187
|
+
type="button"
|
|
188
|
+
className="ask-user-send"
|
|
189
|
+
disabled={selections.size === 0}
|
|
190
|
+
onClick={handleSend}
|
|
191
|
+
>
|
|
192
|
+
<Send size={12} />
|
|
193
|
+
Send
|
|
194
|
+
</button>
|
|
195
|
+
)}
|
|
196
|
+
</div>
|
|
197
|
+
) : data.question ? (
|
|
198
|
+
// Malformed payload fallback — plain-text question.
|
|
199
|
+
<p className="user-message">{data.question}</p>
|
|
200
|
+
) : (
|
|
201
|
+
<p style={{ color: 'var(--text-muted)', fontStyle: 'italic' }}>
|
|
202
|
+
Waiting for user response
|
|
203
|
+
</p>
|
|
204
|
+
)}
|
|
205
|
+
</div>
|
|
206
|
+
);
|
|
207
|
+
}
|