clustr-ai 0.1.16 → 0.1.18

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.
@@ -29,4 +29,4 @@
29
29
  * The original design remains. The terminal itself
30
30
  * has been extended to include xterm CSI codes, among
31
31
  * other features.
32
- */.xterm{cursor:text;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm .xterm-scroll-area{visibility:hidden}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent;pointer-events:none}.xterm .xterm-accessibility-tree:not(.debug) *::selection{color:transparent}.xterm .xterm-accessibility-tree{-webkit-user-select:text;user-select:text;white-space:pre}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{text-decoration:double underline}.xterm-underline-3{text-decoration:wavy underline}.xterm-underline-4{text-decoration:dotted underline}.xterm-underline-5{text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{text-decoration:overline double underline}.xterm-overline.xterm-underline-3{text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}.xterm-decoration-top{z-index:2;position:relative}.multi-term-container{display:flex;flex-direction:row;height:100%;width:100%;background:#1a1a1a;overflow:hidden}.multi-term-pane{display:flex;flex-direction:column;background:#0a0a0a;overflow:hidden;min-width:100px;min-height:0;border:1px solid transparent;transition:border-color .15s ease;flex-shrink:0;flex-grow:0}.multi-term-divider{flex-shrink:0;background:#1a1a1a;transition:background .15s ease}.multi-term-divider.horizontal{width:4px;cursor:col-resize}.multi-term-divider.vertical{height:4px;cursor:row-resize}.multi-term-divider:hover{background:#4ade80}.multi-term-pane.focused{border-color:#333}.multi-term-pane-header{display:flex;align-items:center;gap:6px;padding:4px 10px;background:#111;border-bottom:1px solid #1a1a1a;min-height:26px;cursor:pointer;-webkit-user-select:none;user-select:none}.multi-term-pane.focused .multi-term-pane-header{background:#161616;border-bottom-color:#222}.multi-term-status-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}.multi-term-pane-name{font-size:11px;font-weight:600;color:#ccc;font-family:var(--font-mono, "JetBrains Mono", monospace);white-space:nowrap;flex-shrink:0}.multi-term-pane.focused .multi-term-pane-name{color:#fff}.multi-term-pane-task{font-size:10px;color:#555;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}.multi-term-pane-body{flex:1;overflow:hidden;min-height:0;padding:2px}.multi-term-pane-body .xterm{height:100%}.multi-term-pane-body .xterm-viewport{overflow-y:auto!important}.multi-term-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:12px;color:#333}.multi-term-empty-icon{font-size:28px;font-family:JetBrains Mono,monospace;font-weight:400;letter-spacing:.05em}.multi-term-empty-text{font-size:12px;color:#444;font-family:DM Sans,sans-serif;letter-spacing:.02em}@media(max-width:767px){.multi-term-container{flex-direction:column;overflow-y:auto;-webkit-overflow-scrolling:touch}.multi-term-pane{min-width:0;min-height:200px;flex-shrink:0;flex-grow:0;width:100%!important;height:250px!important}.multi-term-divider.horizontal{width:100%;height:4px;cursor:row-resize}.multi-term-pane-header{padding:6px 10px;min-height:32px}.multi-term-pane-name{font-size:12px}}.message-feed{display:flex;flex-direction:column;height:100%}.message-feed-header{padding:12px 20px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;border-bottom:1px solid var(--border);color:var(--text-muted);display:flex;align-items:center;justify-content:space-between}.clear-messages-btn{font-size:10px;padding:3px 10px;background:#f871711a;color:var(--red);border:1px solid rgba(248,113,113,.3);border-radius:4px;cursor:pointer;text-transform:none;letter-spacing:normal;font-weight:500}.clear-messages-btn:hover{background:#f8717133;color:var(--red);border-color:#f8717180}.message-feed-list{flex:1;overflow-y:auto;padding:4px 0}.message-feed-empty{text-align:center;color:var(--text-muted);padding:48px 24px;font-size:12px}.message-item{padding:10px 20px;border-bottom:1px solid var(--border-subtle);transition:background var(--transition)}.message-item:hover{background:var(--bg-tertiary)}.message-meta{font-size:11px;margin-bottom:4px;display:flex;align-items:center;gap:4px}.message-from{color:var(--green);font-weight:600;font-family:var(--font-mono);font-size:11px}.message-arrow{color:var(--text-secondary);font-size:10px}.message-to{color:#60a5fa;font-weight:600;font-family:var(--font-mono);font-size:11px}.message-time{color:var(--text-secondary);margin-left:auto;font-size:10px;font-family:var(--font-mono)}.message-content{font-size:13px;line-height:1.6;white-space:pre-wrap;word-break:break-word;color:var(--text);padding-left:0}@media(max-width:767px){.message-feed-header,.message-item{padding:10px 14px}.message-meta{flex-wrap:wrap;gap:4px}.message-time{width:100%;margin-left:0;margin-top:2px}}.context-viewer{height:100%;overflow-y:auto}.context-header{padding:12px 20px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;border-bottom:1px solid var(--border);color:var(--text-muted)}.context-empty{text-align:center;color:var(--text-muted);padding:48px 24px;font-size:12px}.context-table{width:100%;border-collapse:collapse;font-size:12px}.context-table th{text-align:left;padding:10px 20px;border-bottom:1px solid var(--border);color:var(--text-muted);font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.08em}.context-table td{padding:10px 20px;border-bottom:1px solid var(--border-subtle);vertical-align:top}.context-table tr{transition:background var(--transition)}.context-table tbody tr:hover{background:var(--bg-tertiary)}.context-key{color:var(--text);font-family:var(--font-mono);font-size:11px;white-space:nowrap}.context-value{max-width:400px;overflow:hidden;text-overflow:ellipsis;white-space:pre-wrap;word-break:break-word;color:var(--text-secondary);font-size:12px}.context-time{color:var(--text-muted);white-space:nowrap;font-size:11px;font-family:var(--font-mono)}.context-remove-btn{background:none;border:1px solid transparent;border-radius:var(--radius-sm);color:var(--text-muted);cursor:pointer;padding:2px 6px;font-size:10px;opacity:0;transition:all var(--transition)}.context-table tr:hover .context-remove-btn{opacity:1}.context-remove-btn:hover{background:#1a0808;color:var(--red);border-color:#3a1515}@media(max-width:767px){.context-header{padding:10px 14px}.context-table th,.context-table td{padding:8px 12px;font-size:11px}.context-value{max-width:200px;font-size:11px}.context-remove-btn{opacity:1}}.diff-viewer{background:#0a0a0a;border:1px solid var(--border);border-radius:6px;overflow:hidden}.diff-filename{padding:8px 14px;font-size:11px;font-family:var(--font-mono);color:var(--text-secondary);background:#111;border-bottom:1px solid var(--border)}.diff-content{margin:0;padding:8px 0;font-family:var(--font-mono);font-size:12px;line-height:1.5;overflow-x:auto}.diff-line{padding:0 14px;white-space:pre;min-height:18px}.diff-add{background:#4ade801a;color:#4ade80}.diff-del{background:#f871711a;color:#f87171}.diff-hunk{color:#93c5fd;padding-top:4px;padding-bottom:4px}.diff-meta{color:var(--text-muted);font-style:italic}@media(max-width:767px){.diff-content{font-size:11px}.diff-line{padding:0 10px}.diff-filename{padding:6px 10px;font-size:10px}}.file-changes{display:flex;flex-direction:column;height:100%}.file-changes-header{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;border-bottom:1px solid var(--border);color:var(--text-muted)}.file-changes-clear-btn{font-size:10px;padding:2px 8px;background:var(--bg-tertiary);color:var(--text-muted);border:1px solid var(--border);border-radius:4px;cursor:pointer;text-transform:none;letter-spacing:normal;font-weight:400}.file-changes-clear-btn:hover{background:var(--red);color:#fff;border-color:var(--red)}.file-changes-list{flex:1;overflow-y:auto;padding:4px 0}.file-changes-empty{text-align:center;color:var(--text-muted);padding:48px 24px;font-size:12px}.file-change-item{border-bottom:1px solid var(--border-subtle)}.file-change-row{display:flex;align-items:center;gap:10px;padding:8px 20px;cursor:pointer;transition:background .1s ease}.file-change-row:hover{background:var(--bg-tertiary)}.file-change-type{font-family:var(--font-mono);font-size:11px;font-weight:600;width:14px;text-align:center;flex-shrink:0}.file-change-path{font-family:var(--font-mono);font-size:12px;color:var(--text);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.file-change-agent{font-family:var(--font-mono);font-size:10px;color:#4ade80;background:#4ade8014;border:1px solid rgba(74,222,128,.15);border-radius:4px;padding:1px 6px;flex-shrink:0;white-space:nowrap}.file-change-time{font-family:var(--font-mono);font-size:10px;color:var(--text-muted);flex-shrink:0}.file-change-expand{font-size:9px;color:var(--text-muted);width:12px;text-align:center}@media(max-width:767px){.file-changes-header{padding:10px 14px}.file-change-row{padding:8px 14px;gap:8px;flex-wrap:wrap}.file-change-path{font-size:11px;min-width:0}.file-change-agent{order:5}.file-change-time{order:6}}.prs-tab{display:flex;flex-direction:column;height:100%}.prs-header{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;border-bottom:1px solid var(--border);color:var(--text-muted)}.prs-header-left{display:flex;align-items:center;gap:12px}.prs-filter{font-size:11px;padding:2px 6px;background:var(--bg-tertiary);color:var(--text);border:1px solid var(--border);border-radius:4px;text-transform:none;letter-spacing:normal;font-weight:400;cursor:pointer}.prs-repo-link{font-size:11px;color:var(--text-muted);text-decoration:none;text-transform:none;letter-spacing:normal;font-weight:400;font-family:var(--font-mono)}.prs-repo-link:hover{color:var(--blue)}.prs-list{flex:1;overflow-y:auto;padding:4px 0}.prs-empty{text-align:center;color:var(--text-muted);padding:48px 24px;font-size:12px}.prs-unavailable{text-align:center;color:var(--text-muted);padding:48px 24px;font-size:12px;line-height:1.6}.prs-unavailable code{background:var(--bg-tertiary);padding:2px 6px;border-radius:4px;font-family:var(--font-mono);font-size:11px}.pr-item{border-bottom:1px solid var(--border-subtle)}.pr-row{display:flex;align-items:center;gap:10px;padding:8px 20px;cursor:pointer;transition:background .1s ease}.pr-row:hover{background:var(--bg-tertiary)}.pr-status-badge{width:8px;height:8px;border-radius:50%;flex-shrink:0}.pr-status-badge.open{background:#4ade80}.pr-status-badge.merged{background:#a78bfa}.pr-status-badge.closed{background:#f87171}.pr-status-badge.draft{background:#666}.pr-number{font-family:var(--font-mono);font-size:12px;color:var(--text-muted);flex-shrink:0;min-width:40px}.pr-title{font-size:12px;color:var(--text);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pr-author{font-family:var(--font-mono);font-size:10px;color:var(--text-muted);flex-shrink:0}.pr-branch{font-family:var(--font-mono);font-size:10px;color:#4ade80;background:#4ade8014;border:1px solid rgba(74,222,128,.15);border-radius:4px;padding:1px 6px;flex-shrink:0;max-width:160px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pr-ci{flex-shrink:0;font-size:12px;width:16px;text-align:center}.pr-review{flex-shrink:0;font-size:10px;font-family:var(--font-mono);padding:1px 6px;border-radius:4px}.pr-review.approved{color:#4ade80;background:#4ade8014;border:1px solid rgba(74,222,128,.15)}.pr-review.changes_requested{color:#f87171;background:#f8717114;border:1px solid rgba(248,113,113,.15)}.pr-review.review_required{color:#fbbf24;background:#fbbf2414;border:1px solid rgba(251,191,36,.15)}.pr-time{font-family:var(--font-mono);font-size:10px;color:var(--text-muted);flex-shrink:0}.pr-link-btn{background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:12px;padding:2px 4px;flex-shrink:0}.pr-link-btn:hover{color:var(--blue)}.pr-expand{font-size:9px;color:var(--text-muted);width:12px;text-align:center}.pr-detail{padding:12px 20px 12px 52px;border-top:1px solid var(--border-subtle);background:var(--bg-secondary)}.pr-detail-loading{color:var(--text-muted);font-size:11px}.pr-detail-body{font-size:12px;color:var(--text);line-height:1.5;white-space:pre-wrap;word-break:break-word;margin-bottom:12px;max-height:200px;overflow-y:auto}.pr-detail-section-title{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;color:var(--text-muted);margin:12px 0 6px}.pr-detail-checks{display:flex;flex-wrap:wrap;gap:6px}.pr-check{font-family:var(--font-mono);font-size:10px;padding:2px 8px;border-radius:4px;background:var(--bg-tertiary);border:1px solid var(--border)}.pr-check.success{color:#4ade80;border-color:#4ade804d}.pr-check.failure{color:#f87171;border-color:#f871714d}.pr-check.pending{color:#fbbf24;border-color:#fbbf244d}.pr-comment{padding:8px 0;border-bottom:1px solid var(--border-subtle)}.pr-comment:last-child{border-bottom:none}.pr-comment-header{font-size:10px;color:var(--text-muted);margin-bottom:4px}.pr-comment-header strong{color:var(--text)}.pr-comment-body{font-size:12px;color:var(--text);line-height:1.4;white-space:pre-wrap;word-break:break-word}.branches-section{border-top:1px solid var(--border)}.branches-header{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;color:var(--text-muted);cursor:pointer;-webkit-user-select:none;user-select:none}.branches-header:hover{background:var(--bg-tertiary)}.branches-toggle{font-size:9px}.branches-list{padding:4px 0}.branch-item{display:flex;align-items:center;gap:10px;padding:6px 20px}.branch-item.current{background:#4ade800a}.branch-current-marker{color:#4ade80;font-size:10px;width:8px;flex-shrink:0}.branch-name{font-family:var(--font-mono);font-size:12px;color:var(--text);flex-shrink:0;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.branch-name.current{color:#4ade80}.branch-message{font-size:11px;color:var(--text-muted);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.branch-author{font-family:var(--font-mono);font-size:10px;color:var(--text-muted);flex-shrink:0}.branch-ahead-behind{display:flex;gap:4px;flex-shrink:0}.branch-badge{font-family:var(--font-mono);font-size:9px;padding:1px 5px;border-radius:3px;background:var(--bg-tertiary);border:1px solid var(--border)}.branch-badge.ahead{color:#4ade80}.branch-badge.behind{color:#f87171}.branch-time{font-family:var(--font-mono);font-size:10px;color:var(--text-muted);flex-shrink:0}@media(max-width:767px){.prs-header{padding:10px 14px;flex-wrap:wrap;gap:6px}.pr-row{padding:8px 14px;gap:6px;flex-wrap:wrap}.pr-branch,.pr-author,.pr-time{display:none}.pr-title{flex-basis:100%;order:2;white-space:normal;margin-top:2px;font-size:12px}.pr-detail{padding:12px 14px}.branch-item{padding:6px 14px;flex-wrap:wrap;gap:6px}.branch-message,.branch-author,.branch-time{display:none}}.crewmd-editor{display:flex;flex-direction:column;height:100%;background:#0a0a0a}.crewmd-header{display:flex;align-items:center;justify-content:space-between;padding:10px 20px;border-bottom:1px solid var(--border);background:var(--bg-secondary);min-height:40px}.crewmd-title{font-size:12px;font-weight:600;color:var(--text);font-family:var(--font-mono, "JetBrains Mono", monospace);display:flex;align-items:center;gap:10px}.crewmd-path{font-size:10px;font-weight:400;color:var(--text-muted)}.crewmd-actions{display:flex;align-items:center;gap:10px}.crewmd-dirty{font-size:10px;color:#fbbf24;font-style:italic}.crewmd-save-btn{font-size:11px;padding:4px 14px;background:var(--bg-tertiary);color:var(--text-secondary);border:1px solid var(--border);border-radius:4px;cursor:pointer;transition:all .15s ease}.crewmd-save-btn:hover:not(:disabled){background:#4ade80;color:#000;border-color:#4ade80}.crewmd-save-btn:disabled{opacity:.4;cursor:default}.crewmd-textarea{flex:1;background:#0a0a0a;color:#c8c8c8;border:none;outline:none;resize:none;padding:20px;font-family:var(--font-mono, "JetBrains Mono", monospace);font-size:13px;line-height:1.6;-moz-tab-size:2;tab-size:2;white-space:pre;overflow:auto}.crewmd-textarea::placeholder{color:#333}.crewmd-textarea::-webkit-scrollbar{width:6px}.crewmd-textarea::-webkit-scrollbar-track{background:transparent}.crewmd-textarea::-webkit-scrollbar-thumb{background:#222;border-radius:3px}@media(max-width:767px){.crewmd-header{padding:8px 14px;flex-wrap:wrap;gap:6px}.crewmd-title{font-size:11px;flex-wrap:wrap}.crewmd-textarea{padding:14px;font-size:14px}}.dialog-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#000000bf;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);display:flex;align-items:center;justify-content:center;z-index:100;animation:overlay-in .2s ease-out}@keyframes overlay-in{0%{opacity:0}to{opacity:1}}@keyframes dialog-in{0%{opacity:0;transform:translateY(8px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}.dialog{background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius-lg);padding:28px;width:460px;max-width:90vw;animation:dialog-in .25s cubic-bezier(.16,1,.3,1)}.dialog h2{font-size:15px;font-weight:500;margin-bottom:20px;color:var(--text)}.dialog-mode-tabs{display:flex;gap:0;margin-bottom:24px;border:1px solid var(--border);border-radius:var(--radius-md);overflow:hidden}.dialog-mode-tab{flex:1;border:none;border-radius:0;padding:9px 16px;font-size:12px;font-weight:500;background:var(--bg);color:var(--text-muted);cursor:pointer;transition:all var(--transition);letter-spacing:.02em}.dialog-mode-tab:hover{background:var(--bg-tertiary);color:var(--text-secondary)}.dialog-mode-tab.active{background:var(--white);color:#000}.dialog label{display:block;font-size:11px;font-weight:500;color:var(--text-muted);margin-bottom:16px;text-transform:uppercase;letter-spacing:.06em}.dialog label .optional{font-weight:400;opacity:.5;text-transform:none;letter-spacing:0}.dialog label input,.dialog label textarea{display:block;width:100%;margin-top:6px;text-transform:none;letter-spacing:-.01em}.dialog textarea{resize:vertical;font-family:var(--font-body);line-height:1.5}.browse-row{display:flex;gap:6px;margin-top:6px}.browse-row input{flex:1;margin-top:0!important}.browse-btn{flex-shrink:0;padding:7px 14px;font-size:12px;background:var(--bg-tertiary);color:var(--text-secondary);border:1px solid var(--border);border-radius:var(--radius-sm);cursor:pointer;transition:all .15s ease;white-space:nowrap}.browse-btn:hover:not(:disabled){background:var(--white);color:#000;border-color:var(--white)}.browse-btn:disabled{opacity:.5;cursor:default}.service-selector{display:flex;gap:0;margin-top:6px;border:1px solid var(--border);border-radius:var(--radius-sm);overflow:hidden}.service-btn{flex:1;border:none;border-radius:0;padding:7px 14px;font-size:12px;font-weight:500;background:var(--bg);color:var(--text-muted);cursor:pointer;transition:all var(--transition)}.service-btn:hover{background:var(--bg-tertiary);color:var(--text-secondary)}.service-btn.active{background:var(--white);color:#000}.dialog-error{color:#ff6b6b;background:#ff6b6b1a;border:1px solid rgba(255,107,107,.3);border-radius:6px;padding:8px 12px;font-size:13px;margin-top:12px}.dialog-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:24px;padding-top:20px;border-top:1px solid var(--border)}@media(max-width:767px){.dialog-overlay{align-items:flex-end;padding:0}.dialog{width:100%;max-width:100%;border-radius:var(--radius-lg) var(--radius-lg) 0 0;padding:20px 16px;max-height:90vh;overflow-y:auto}.dialog h2{font-size:14px}.dialog-mode-tab,.service-btn{padding:10px 12px}.browse-row{flex-direction:column}.browse-btn{width:100%}.dialog-actions{flex-direction:column}.dialog-actions button{width:100%;justify-content:center}}.app{display:flex;flex-direction:column;height:100%;background:var(--bg)}.app-header{display:flex;align-items:center;justify-content:space-between;padding:0 20px;height:52px;min-height:52px;border-bottom:1px solid var(--border);background:var(--bg)}.header-brand{display:flex;align-items:center;gap:10px;color:var(--text)}.app-header h1{font-size:14px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--text)}.header-total-cost{font-family:var(--font-mono);font-size:11px;color:var(--text-secondary);padding:4px 10px;background:var(--bg-tertiary);border:1px solid var(--border);border-radius:4px}.header-actions{display:flex;gap:8px}.app-body{display:flex;flex:1;overflow:hidden}.sidebar{width:260px;min-width:260px;border-right:1px solid var(--border);background:var(--bg-secondary);overflow-y:auto;display:flex;flex-direction:column;position:relative;transition:width .2s ease,min-width .2s ease}.sidebar.collapsed{width:36px;min-width:36px;overflow:hidden}.sidebar-toggle{position:absolute;top:8px;right:8px;width:22px;height:22px;border:1px solid var(--border);border-radius:4px;background:var(--bg-tertiary);color:var(--text-secondary);font-size:14px;cursor:pointer;display:flex;align-items:center;justify-content:center;z-index:2;padding:0;line-height:1;transition:all .15s ease}.sidebar.collapsed .sidebar-toggle{right:auto;left:7px}.sidebar-toggle:hover{background:var(--bg);color:var(--text);border-color:#444}.main-content{flex:1;display:flex;flex-direction:column;overflow:hidden;background:var(--bg)}.tabs{display:flex;gap:0;border-bottom:1px solid var(--border);background:var(--bg);padding:0 16px;height:40px;min-height:40px;align-items:stretch}.tab{border:none;border-bottom:2px solid transparent;border-radius:0;background:none;padding:0 16px;font-size:12px;font-weight:500;color:var(--text-secondary);letter-spacing:.04em;text-transform:uppercase;transition:all var(--transition);display:flex;align-items:center}.tab:hover{color:var(--text);background:#ffffff0a}.tab.active{color:var(--white);border-bottom-color:var(--white);font-weight:600}.terminal-view-toggle{display:flex;align-items:center;gap:2px;margin-left:auto;padding-right:4px}.view-toggle-btn{border:none;border-radius:4px;background:none;color:var(--text-muted);font-size:15px;width:28px;height:28px;display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;transition:all .15s ease;line-height:1}.view-toggle-btn:hover{color:var(--text-secondary);background:var(--bg-tertiary)}.view-toggle-btn.active{color:var(--text);background:var(--bg-tertiary)}.tab-content{flex:1;overflow:hidden;position:relative;background:#000}.app-footer{display:flex;gap:8px;padding:10px 20px;border-top:1px solid var(--border);background:var(--bg-secondary);align-items:center}.app-footer select{background:var(--bg);border:1px solid var(--border);color:var(--text-secondary);padding:7px 10px;border-radius:var(--radius-sm);font-size:12px;font-family:var(--font-body);min-width:140px;cursor:pointer}.app-footer select:hover{border-color:#333}.app-footer input{flex:1;background:var(--bg)}.header-hamburger{display:none;border:none;background:none;color:var(--text-secondary);font-size:18px;padding:4px 8px;cursor:pointer;line-height:1;min-height:unset}.header-connect-phone{border:1px solid var(--border);background:transparent;font-size:13px;padding:6px 12px;cursor:pointer;border-radius:6px;color:var(--text);opacity:.8}.header-connect-phone:hover{opacity:1;background:var(--surface);border-color:var(--border)}.pair-modal-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#000000bf;z-index:300;display:flex;align-items:center;justify-content:center;padding:20px}.pair-modal{background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius-lg);padding:28px 24px 24px;width:100%;max-width:400px;display:flex;flex-direction:column;align-items:center;gap:16px}.pair-modal-header{width:100%;display:flex;align-items:center;justify-content:space-between}.pair-modal-header h2{font-size:14px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--text)}.pair-modal-close{border:none;background:none;color:var(--text-muted);font-size:14px;padding:4px;min-height:unset;line-height:1}.pair-modal-close:hover{color:var(--text);background:none;border-color:transparent}.pair-modal-hint{font-size:12px;color:var(--text-muted);text-align:center}.pair-modal-loading{font-size:12px;color:var(--text-muted);padding:24px 0}.pair-modal-error{font-size:12px;color:#f87171;padding:24px 0}.pair-qr{width:200px;height:200px;background:#000;border-radius:var(--radius-md);padding:12px}.pair-urls{width:100%;display:flex;flex-direction:column;gap:8px}.pair-url-row{display:flex;align-items:center;gap:8px;background:var(--bg-tertiary);border:1px solid var(--border);border-radius:var(--radius-sm);padding:8px 12px}.pair-url-label{font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:var(--text-muted);min-width:44px}.pair-url-text{flex:1;font-family:var(--font-mono);font-size:11px;color:var(--text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pair-tunnel-hint{font-size:11px;color:var(--text-muted);text-align:center;line-height:1.5}.pair-tunnel-hint code{font-family:var(--font-mono);background:var(--bg-tertiary);padding:1px 5px;border-radius:3px;color:var(--text-secondary)}.sidebar-backdrop{display:none}@media(max-width:767px){.header-hamburger{display:flex;align-items:center}.sidebar-toggle{display:none}.sidebar{position:fixed;top:0;left:0;height:100%;z-index:200;transform:translate(-100%);transition:transform .25s ease,width .2s ease,min-width .2s ease;width:85vw;max-width:320px;min-width:260px}.sidebar:not(.collapsed){transform:translate(0)}.sidebar.collapsed{transform:translate(-100%);width:85vw;max-width:320px;min-width:260px;overflow:hidden}.sidebar-backdrop{display:block;position:fixed;top:0;right:0;bottom:0;left:0;background:#0009;z-index:199}.app-header{padding:0 10px;gap:6px;height:48px;min-height:48px}.app-header h1{font-size:13px}.header-brand{gap:6px}.header-total-cost,.header-connect-phone{display:none}.header-actions{gap:6px}.header-actions button{padding:6px 10px;font-size:11px;min-height:34px}.tabs{padding:0 6px;height:36px;min-height:36px;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;scrollbar-width:none}.tabs::-webkit-scrollbar{display:none}.tab{white-space:nowrap;flex-shrink:0;padding:0 10px;font-size:11px}.terminal-view-toggle{display:none}.app-footer{flex-direction:row;flex-wrap:wrap;padding:8px 10px;gap:6px;align-items:center}.app-footer select{width:auto;min-width:100px;flex-shrink:0;padding:6px 8px;font-size:12px;min-height:36px}.app-footer input{flex:1;min-width:0;font-size:14px;padding:8px 10px;min-height:36px}.app-footer button{min-height:36px;padding:6px 14px}.pair-modal{max-width:100%;border-radius:var(--radius-lg) var(--radius-lg) 0 0;position:fixed;bottom:0;left:0;right:0;margin:0}.pair-modal-overlay{align-items:flex-end;padding:0}}*{margin:0;padding:0;box-sizing:border-box}:root{--bg: #000000;--bg-secondary: #0a0a0a;--bg-tertiary: #151515;--bg-elevated: #1a1a1a;--border: #2a2a2a;--border-subtle: #1c1c1c;--text: #eeeeee;--text-secondary: #b0b0b0;--text-muted: #707070;--white: #ffffff;--accent: #ffffff;--green: #4ade80;--yellow: #fbbf24;--red: #f87171;--radius-sm: 4px;--radius-md: 8px;--radius-lg: 12px;--font-body: "DM Sans", -apple-system, BlinkMacSystemFont, sans-serif;--font-mono: "JetBrains Mono", "SF Mono", "Fira Code", monospace;--transition: .18s cubic-bezier(.4, 0, .2, 1)}html,body,#root{height:100%;width:100%;overflow:hidden;overscroll-behavior:none}body{font-family:var(--font-body);background:var(--bg);color:var(--text);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:13px;letter-spacing:-.01em}button{cursor:pointer;border:1px solid var(--border);background:var(--bg-tertiary);color:var(--text-secondary);padding:7px 14px;border-radius:var(--radius-sm);font-size:12px;font-family:var(--font-body);font-weight:500;letter-spacing:.02em;transition:all var(--transition)}button:hover{color:var(--text);border-color:#444;background:var(--bg-elevated)}button.primary{background:var(--white);border-color:var(--white);color:#000}button.primary:hover{background:#d4d4d4;border-color:#d4d4d4}button.primary:disabled{background:#333;border-color:#333;color:#666;cursor:not-allowed}button.danger{background:transparent;border-color:#3a1515;color:var(--red)}button.danger:hover{background:#1a0808;border-color:var(--red)}button:disabled{opacity:.35;cursor:not-allowed}input,textarea,select{background:var(--bg);border:1px solid var(--border);color:var(--text);padding:8px 12px;border-radius:var(--radius-sm);font-size:13px;font-family:var(--font-body);outline:none;transition:border-color var(--transition)}input:focus,textarea:focus,select:focus{border-color:#444}input::placeholder,textarea::placeholder{color:var(--text-muted)}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#222;border-radius:3px}::-webkit-scrollbar-thumb:hover{background:#333}::selection{background:#ffffff1f}.react-flow__controls{background:#0a0a0a!important;border:1px solid var(--border)!important;border-radius:6px!important;overflow:hidden}.react-flow__controls-button{background:#0a0a0a!important;border:none!important;border-bottom:1px solid #1c1c1c!important;fill:#888!important;width:28px!important;height:28px!important}.react-flow__controls-button:hover{background:#1a1a1a!important;fill:#eee!important}.react-flow__controls-button:last-child{border-bottom:none!important}.react-flow__controls-button svg{fill:inherit!important}@media(max-width:767px){html,body,#root{overflow:hidden;overscroll-behavior:none;-webkit-overflow-scrolling:touch}body{padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)}input,textarea,select{font-size:16px}button{min-height:36px}.react-flow__controls-button{width:40px!important;height:40px!important}::-webkit-scrollbar{width:3px;height:3px}}.xterm{background:#000!important}.xterm-viewport{background-color:#000!important;overscroll-behavior:contain!important}.xterm-screen{background:#000!important}
32
+ */.xterm{cursor:text;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm .xterm-scroll-area{visibility:hidden}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent;pointer-events:none}.xterm .xterm-accessibility-tree:not(.debug) *::selection{color:transparent}.xterm .xterm-accessibility-tree{-webkit-user-select:text;user-select:text;white-space:pre}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{text-decoration:double underline}.xterm-underline-3{text-decoration:wavy underline}.xterm-underline-4{text-decoration:dotted underline}.xterm-underline-5{text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{text-decoration:overline double underline}.xterm-overline.xterm-underline-3{text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}.xterm-decoration-top{z-index:2;position:relative}.multi-term-container{display:flex;flex-direction:row;height:100%;width:100%;background:#1a1a1a;overflow:hidden}.multi-term-pane{display:flex;flex-direction:column;background:#0a0a0a;overflow:hidden;min-width:100px;min-height:0;border:1px solid transparent;transition:border-color .15s ease;flex-shrink:0;flex-grow:0}.multi-term-divider{flex-shrink:0;background:#1a1a1a;transition:background .15s ease}.multi-term-divider.horizontal{width:4px;cursor:col-resize}.multi-term-divider.vertical{height:4px;cursor:row-resize}.multi-term-divider:hover{background:#4ade80}.multi-term-pane.focused{border-color:#333}.multi-term-pane-header{display:flex;align-items:center;gap:6px;padding:4px 10px;background:#111;border-bottom:1px solid #1a1a1a;min-height:26px;cursor:pointer;-webkit-user-select:none;user-select:none}.multi-term-pane.focused .multi-term-pane-header{background:#161616;border-bottom-color:#222}.multi-term-status-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}.multi-term-pane-name{font-size:11px;font-weight:600;color:#ccc;font-family:var(--font-mono, "JetBrains Mono", monospace);white-space:nowrap;flex-shrink:0}.multi-term-pane.focused .multi-term-pane-name{color:#fff}.multi-term-pane-task{font-size:10px;color:#555;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}.multi-term-pane-body{flex:1;overflow:hidden;min-height:0;padding:2px}.multi-term-pane-body .xterm{height:100%}.multi-term-pane-body .xterm-viewport{overflow-y:auto!important}.multi-term-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:12px;color:#333}.multi-term-empty-icon{font-size:28px;font-family:JetBrains Mono,monospace;font-weight:400;letter-spacing:.05em}.multi-term-empty-text{font-size:12px;color:#444;font-family:DM Sans,sans-serif;letter-spacing:.02em}@media(max-width:767px){.multi-term-container{flex-direction:column;overflow-y:auto;-webkit-overflow-scrolling:touch}.multi-term-pane{min-width:0;min-height:200px;flex-shrink:0;flex-grow:0;width:100%!important;height:250px!important}.multi-term-divider.horizontal{width:100%;height:4px;cursor:row-resize}.multi-term-pane-header{padding:6px 10px;min-height:32px}.multi-term-pane-name{font-size:12px}}.message-feed{display:flex;flex-direction:column;height:100%}.message-feed-header{padding:12px 20px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;border-bottom:1px solid var(--border);color:var(--text-muted);display:flex;align-items:center;justify-content:space-between}.clear-messages-btn{font-size:10px;padding:3px 10px;background:#f871711a;color:var(--red);border:1px solid rgba(248,113,113,.3);border-radius:4px;cursor:pointer;text-transform:none;letter-spacing:normal;font-weight:500}.clear-messages-btn:hover{background:#f8717133;color:var(--red);border-color:#f8717180}.message-feed-list{flex:1;overflow-y:auto;padding:4px 0}.message-feed-empty{text-align:center;color:var(--text-muted);padding:48px 24px;font-size:12px}.message-item{padding:10px 20px;border-bottom:1px solid var(--border-subtle);transition:background var(--transition)}.message-item:hover{background:var(--bg-tertiary)}.message-meta{font-size:11px;margin-bottom:4px;display:flex;align-items:center;gap:4px}.message-from{color:var(--green);font-weight:600;font-family:var(--font-mono);font-size:11px}.message-arrow{color:var(--text-secondary);font-size:10px}.message-to{color:#60a5fa;font-weight:600;font-family:var(--font-mono);font-size:11px}.message-time{color:var(--text-secondary);margin-left:auto;font-size:10px;font-family:var(--font-mono)}.message-content{font-size:13px;line-height:1.6;white-space:pre-wrap;word-break:break-word;color:var(--text);padding-left:0}@media(max-width:767px){.message-feed-header,.message-item{padding:10px 14px}.message-meta{flex-wrap:wrap;gap:4px}.message-time{width:100%;margin-left:0;margin-top:2px}}.context-viewer{height:100%;overflow-y:auto}.context-header{padding:12px 20px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;border-bottom:1px solid var(--border);color:var(--text-muted)}.context-empty{text-align:center;color:var(--text-muted);padding:48px 24px;font-size:12px}.context-table{width:100%;border-collapse:collapse;font-size:12px}.context-table th{text-align:left;padding:10px 20px;border-bottom:1px solid var(--border);color:var(--text-muted);font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.08em}.context-table td{padding:10px 20px;border-bottom:1px solid var(--border-subtle);vertical-align:top}.context-table tr{transition:background var(--transition)}.context-table tbody tr:hover{background:var(--bg-tertiary)}.context-key{color:var(--text);font-family:var(--font-mono);font-size:11px;white-space:nowrap}.context-value{max-width:400px;overflow:hidden;text-overflow:ellipsis;white-space:pre-wrap;word-break:break-word;color:var(--text-secondary);font-size:12px}.context-time{color:var(--text-muted);white-space:nowrap;font-size:11px;font-family:var(--font-mono)}.context-remove-btn{background:none;border:1px solid transparent;border-radius:var(--radius-sm);color:var(--text-muted);cursor:pointer;padding:2px 6px;font-size:10px;opacity:0;transition:all var(--transition)}.context-table tr:hover .context-remove-btn{opacity:1}.context-remove-btn:hover{background:#1a0808;color:var(--red);border-color:#3a1515}@media(max-width:767px){.context-header{padding:10px 14px}.context-table th,.context-table td{padding:8px 12px;font-size:11px}.context-value{max-width:200px;font-size:11px}.context-remove-btn{opacity:1}}.diff-viewer{background:#0a0a0a;border:1px solid var(--border);border-radius:6px;overflow:hidden}.diff-filename{padding:8px 14px;font-size:11px;font-family:var(--font-mono);color:var(--text-secondary);background:#111;border-bottom:1px solid var(--border)}.diff-content{margin:0;padding:8px 0;font-family:var(--font-mono);font-size:12px;line-height:1.5;overflow-x:auto}.diff-line{padding:0 14px;white-space:pre;min-height:18px}.diff-add{background:#4ade801a;color:#4ade80}.diff-del{background:#f871711a;color:#f87171}.diff-hunk{color:#93c5fd;padding-top:4px;padding-bottom:4px}.diff-meta{color:var(--text-muted);font-style:italic}@media(max-width:767px){.diff-content{font-size:11px}.diff-line{padding:0 10px}.diff-filename{padding:6px 10px;font-size:10px}}.file-changes{display:flex;flex-direction:column;height:100%}.file-changes-header{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;border-bottom:1px solid var(--border);color:var(--text-muted)}.file-changes-clear-btn{font-size:10px;padding:2px 8px;background:var(--bg-tertiary);color:var(--text-muted);border:1px solid var(--border);border-radius:4px;cursor:pointer;text-transform:none;letter-spacing:normal;font-weight:400}.file-changes-clear-btn:hover{background:var(--red);color:#fff;border-color:var(--red)}.file-changes-list{flex:1;overflow-y:auto;padding:4px 0}.file-changes-empty{text-align:center;color:var(--text-muted);padding:48px 24px;font-size:12px}.file-change-item{border-bottom:1px solid var(--border-subtle)}.file-change-row{display:flex;align-items:center;gap:10px;padding:8px 20px;cursor:pointer;transition:background .1s ease}.file-change-row:hover{background:var(--bg-tertiary)}.file-change-type{font-family:var(--font-mono);font-size:11px;font-weight:600;width:14px;text-align:center;flex-shrink:0}.file-change-path{font-family:var(--font-mono);font-size:12px;color:var(--text);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.file-change-agent{font-family:var(--font-mono);font-size:10px;color:#4ade80;background:#4ade8014;border:1px solid rgba(74,222,128,.15);border-radius:4px;padding:1px 6px;flex-shrink:0;white-space:nowrap}.file-change-time{font-family:var(--font-mono);font-size:10px;color:var(--text-muted);flex-shrink:0}.file-change-expand{font-size:9px;color:var(--text-muted);width:12px;text-align:center}@media(max-width:767px){.file-changes-header{padding:10px 14px}.file-change-row{padding:8px 14px;gap:8px;flex-wrap:wrap}.file-change-path{font-size:11px;min-width:0}.file-change-agent{order:5}.file-change-time{order:6}}.prs-tab{display:flex;flex-direction:column;height:100%}.prs-header{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;border-bottom:1px solid var(--border);color:var(--text-muted)}.prs-header-left{display:flex;align-items:center;gap:12px}.prs-filter{font-size:11px;padding:2px 6px;background:var(--bg-tertiary);color:var(--text);border:1px solid var(--border);border-radius:4px;text-transform:none;letter-spacing:normal;font-weight:400;cursor:pointer}.prs-repo-link{font-size:11px;color:var(--text-muted);text-decoration:none;text-transform:none;letter-spacing:normal;font-weight:400;font-family:var(--font-mono)}.prs-repo-link:hover{color:var(--blue)}.prs-list{flex:1;overflow-y:auto;padding:4px 0}.prs-empty{text-align:center;color:var(--text-muted);padding:48px 24px;font-size:12px}.prs-unavailable{text-align:center;color:var(--text-muted);padding:48px 24px;font-size:12px;line-height:1.6}.prs-unavailable code{background:var(--bg-tertiary);padding:2px 6px;border-radius:4px;font-family:var(--font-mono);font-size:11px}.pr-item{border-bottom:1px solid var(--border-subtle)}.pr-row{display:flex;align-items:center;gap:10px;padding:8px 20px;cursor:pointer;transition:background .1s ease}.pr-row:hover{background:var(--bg-tertiary)}.pr-status-badge{width:8px;height:8px;border-radius:50%;flex-shrink:0}.pr-status-badge.open{background:#4ade80}.pr-status-badge.merged{background:#a78bfa}.pr-status-badge.closed{background:#f87171}.pr-status-badge.draft{background:#666}.pr-number{font-family:var(--font-mono);font-size:12px;color:var(--text-muted);flex-shrink:0;min-width:40px}.pr-title{font-size:12px;color:var(--text);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pr-author{font-family:var(--font-mono);font-size:10px;color:var(--text-muted);flex-shrink:0}.pr-branch{font-family:var(--font-mono);font-size:10px;color:#4ade80;background:#4ade8014;border:1px solid rgba(74,222,128,.15);border-radius:4px;padding:1px 6px;flex-shrink:0;max-width:160px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pr-ci{flex-shrink:0;font-size:12px;width:16px;text-align:center}.pr-review{flex-shrink:0;font-size:10px;font-family:var(--font-mono);padding:1px 6px;border-radius:4px}.pr-review.approved{color:#4ade80;background:#4ade8014;border:1px solid rgba(74,222,128,.15)}.pr-review.changes_requested{color:#f87171;background:#f8717114;border:1px solid rgba(248,113,113,.15)}.pr-review.review_required{color:#fbbf24;background:#fbbf2414;border:1px solid rgba(251,191,36,.15)}.pr-time{font-family:var(--font-mono);font-size:10px;color:var(--text-muted);flex-shrink:0}.pr-link-btn{background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:12px;padding:2px 4px;flex-shrink:0}.pr-link-btn:hover{color:var(--blue)}.pr-expand{font-size:9px;color:var(--text-muted);width:12px;text-align:center}.pr-detail{padding:12px 20px 12px 52px;border-top:1px solid var(--border-subtle);background:var(--bg-secondary)}.pr-detail-loading{color:var(--text-muted);font-size:11px}.pr-detail-body{font-size:12px;color:var(--text);line-height:1.5;white-space:pre-wrap;word-break:break-word;margin-bottom:12px;max-height:200px;overflow-y:auto}.pr-detail-section-title{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;color:var(--text-muted);margin:12px 0 6px}.pr-detail-checks{display:flex;flex-wrap:wrap;gap:6px}.pr-check{font-family:var(--font-mono);font-size:10px;padding:2px 8px;border-radius:4px;background:var(--bg-tertiary);border:1px solid var(--border)}.pr-check.success{color:#4ade80;border-color:#4ade804d}.pr-check.failure{color:#f87171;border-color:#f871714d}.pr-check.pending{color:#fbbf24;border-color:#fbbf244d}.pr-comment{padding:8px 0;border-bottom:1px solid var(--border-subtle)}.pr-comment:last-child{border-bottom:none}.pr-comment-header{font-size:10px;color:var(--text-muted);margin-bottom:4px}.pr-comment-header strong{color:var(--text)}.pr-comment-body{font-size:12px;color:var(--text);line-height:1.4;white-space:pre-wrap;word-break:break-word}.branches-section{border-top:1px solid var(--border)}.branches-header{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;color:var(--text-muted);cursor:pointer;-webkit-user-select:none;user-select:none}.branches-header:hover{background:var(--bg-tertiary)}.branches-toggle{font-size:9px}.branches-list{padding:4px 0}.branch-item{display:flex;align-items:center;gap:10px;padding:6px 20px}.branch-item.current{background:#4ade800a}.branch-current-marker{color:#4ade80;font-size:10px;width:8px;flex-shrink:0}.branch-name{font-family:var(--font-mono);font-size:12px;color:var(--text);flex-shrink:0;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.branch-name.current{color:#4ade80}.branch-message{font-size:11px;color:var(--text-muted);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.branch-author{font-family:var(--font-mono);font-size:10px;color:var(--text-muted);flex-shrink:0}.branch-ahead-behind{display:flex;gap:4px;flex-shrink:0}.branch-badge{font-family:var(--font-mono);font-size:9px;padding:1px 5px;border-radius:3px;background:var(--bg-tertiary);border:1px solid var(--border)}.branch-badge.ahead{color:#4ade80}.branch-badge.behind{color:#f87171}.branch-time{font-family:var(--font-mono);font-size:10px;color:var(--text-muted);flex-shrink:0}@media(max-width:767px){.prs-header{padding:10px 14px;flex-wrap:wrap;gap:6px}.pr-row{padding:8px 14px;gap:6px;flex-wrap:wrap}.pr-branch,.pr-author,.pr-time{display:none}.pr-title{flex-basis:100%;order:2;white-space:normal;margin-top:2px;font-size:12px}.pr-detail{padding:12px 14px}.branch-item{padding:6px 14px;flex-wrap:wrap;gap:6px}.branch-message,.branch-author,.branch-time{display:none}}.crewmd-editor{display:flex;flex-direction:column;height:100%;background:#0a0a0a}.crewmd-header{display:flex;align-items:center;justify-content:space-between;padding:10px 20px;border-bottom:1px solid var(--border);background:var(--bg-secondary);min-height:40px}.crewmd-title{font-size:12px;font-weight:600;color:var(--text);font-family:var(--font-mono, "JetBrains Mono", monospace);display:flex;align-items:center;gap:10px}.crewmd-path{font-size:10px;font-weight:400;color:var(--text-muted)}.crewmd-actions{display:flex;align-items:center;gap:10px}.crewmd-dirty{font-size:10px;color:#fbbf24;font-style:italic}.crewmd-save-btn{font-size:11px;padding:4px 14px;background:var(--bg-tertiary);color:var(--text-secondary);border:1px solid var(--border);border-radius:4px;cursor:pointer;transition:all .15s ease}.crewmd-save-btn:hover:not(:disabled){background:#4ade80;color:#000;border-color:#4ade80}.crewmd-save-btn:disabled{opacity:.4;cursor:default}.crewmd-textarea{flex:1;background:#0a0a0a;color:#c8c8c8;border:none;outline:none;resize:none;padding:20px;font-family:var(--font-mono, "JetBrains Mono", monospace);font-size:13px;line-height:1.6;-moz-tab-size:2;tab-size:2;white-space:pre;overflow:auto}.crewmd-textarea::placeholder{color:#333}.crewmd-textarea::-webkit-scrollbar{width:6px}.crewmd-textarea::-webkit-scrollbar-track{background:transparent}.crewmd-textarea::-webkit-scrollbar-thumb{background:#222;border-radius:3px}@media(max-width:767px){.crewmd-header{padding:8px 14px;flex-wrap:wrap;gap:6px}.crewmd-title{font-size:11px;flex-wrap:wrap}.crewmd-textarea{padding:14px;font-size:14px}}.dialog-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#000000bf;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);display:flex;align-items:center;justify-content:center;z-index:100;animation:overlay-in .2s ease-out}@keyframes overlay-in{0%{opacity:0}to{opacity:1}}@keyframes dialog-in{0%{opacity:0;transform:translateY(8px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}.dialog{background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius-lg);padding:28px;width:460px;max-width:90vw;animation:dialog-in .25s cubic-bezier(.16,1,.3,1)}.dialog h2{font-size:15px;font-weight:500;margin-bottom:20px;color:var(--text)}.dialog-mode-tabs{display:flex;gap:0;margin-bottom:24px;border:1px solid var(--border);border-radius:var(--radius-md);overflow:hidden}.dialog-mode-tab{flex:1;border:none;border-radius:0;padding:9px 16px;font-size:12px;font-weight:500;background:var(--bg);color:var(--text-muted);cursor:pointer;transition:all var(--transition);letter-spacing:.02em}.dialog-mode-tab:hover{background:var(--bg-tertiary);color:var(--text-secondary)}.dialog-mode-tab.active{background:var(--white);color:#000}.dialog label{display:block;font-size:11px;font-weight:500;color:var(--text-muted);margin-bottom:16px;text-transform:uppercase;letter-spacing:.06em}.dialog label .optional{font-weight:400;opacity:.5;text-transform:none;letter-spacing:0}.dialog label input,.dialog label textarea{display:block;width:100%;margin-top:6px;text-transform:none;letter-spacing:-.01em}.dialog textarea{resize:vertical;font-family:var(--font-body);line-height:1.5}.browse-row{display:flex;gap:6px;margin-top:6px}.browse-row input{flex:1;margin-top:0!important}.browse-btn{flex-shrink:0;padding:7px 14px;font-size:12px;background:var(--bg-tertiary);color:var(--text-secondary);border:1px solid var(--border);border-radius:var(--radius-sm);cursor:pointer;transition:all .15s ease;white-space:nowrap}.browse-btn:hover:not(:disabled){background:var(--white);color:#000;border-color:var(--white)}.browse-btn:disabled{opacity:.5;cursor:default}.service-selector{display:flex;gap:0;margin-top:6px;border:1px solid var(--border);border-radius:var(--radius-sm);overflow:hidden}.service-btn{flex:1;border:none;border-radius:0;padding:7px 14px;font-size:12px;font-weight:500;background:var(--bg);color:var(--text-muted);cursor:pointer;transition:all var(--transition)}.service-btn:hover{background:var(--bg-tertiary);color:var(--text-secondary)}.service-btn.active{background:var(--white);color:#000}.dialog-error{color:#ff6b6b;background:#ff6b6b1a;border:1px solid rgba(255,107,107,.3);border-radius:6px;padding:8px 12px;font-size:13px;margin-top:12px}.dialog-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:24px;padding-top:20px;border-top:1px solid var(--border)}@media(max-width:767px){.dialog-overlay{align-items:flex-end;padding:0}.dialog{width:100%;max-width:100%;border-radius:var(--radius-lg) var(--radius-lg) 0 0;padding:20px 16px;max-height:90vh;overflow-y:auto}.dialog h2{font-size:14px}.dialog-mode-tab,.service-btn{padding:10px 12px}.browse-row{flex-direction:column}.browse-btn{width:100%}.dialog-actions{flex-direction:column}.dialog-actions button{width:100%;justify-content:center}}.app{display:flex;flex-direction:column;height:100%;background:var(--bg)}.app-header{display:flex;align-items:center;justify-content:space-between;padding:0 20px;height:52px;min-height:52px;border-bottom:1px solid var(--border);background:var(--bg)}.header-brand{display:flex;align-items:center;gap:10px;color:var(--text)}.app-header h1{font-size:14px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--text)}.header-total-cost{font-family:var(--font-mono);font-size:11px;color:var(--text-secondary);padding:4px 10px;background:var(--bg-tertiary);border:1px solid var(--border);border-radius:4px}.header-actions{display:flex;gap:8px}.app-body{display:flex;flex:1;overflow:hidden}.sidebar{width:260px;min-width:260px;border-right:1px solid var(--border);background:var(--bg-secondary);overflow-y:auto;display:flex;flex-direction:column;position:relative;transition:width .2s ease,min-width .2s ease}.sidebar.collapsed{width:36px;min-width:36px;overflow:hidden}.sidebar-toggle{position:absolute;top:8px;right:8px;width:22px;height:22px;border:1px solid var(--border);border-radius:4px;background:var(--bg-tertiary);color:var(--text-secondary);font-size:14px;cursor:pointer;display:flex;align-items:center;justify-content:center;z-index:2;padding:0;line-height:1;transition:all .15s ease}.sidebar.collapsed .sidebar-toggle{right:auto;left:7px}.sidebar-toggle:hover{background:var(--bg);color:var(--text);border-color:#444}.main-content{flex:1;display:flex;flex-direction:column;overflow:hidden;background:var(--bg)}.tabs{display:flex;gap:0;border-bottom:1px solid var(--border);background:var(--bg);padding:0 16px;height:40px;min-height:40px;align-items:stretch}.tab{border:none;border-bottom:2px solid transparent;border-radius:0;background:none;padding:0 16px;font-size:12px;font-weight:500;color:var(--text-secondary);letter-spacing:.04em;text-transform:uppercase;transition:all var(--transition);display:flex;align-items:center}.tab:hover{color:var(--text);background:#ffffff0a}.tab.active{color:var(--white);border-bottom-color:var(--white);font-weight:600}.terminal-view-toggle{display:flex;align-items:center;gap:2px;margin-left:auto;padding-right:4px}.view-toggle-btn{border:none;border-radius:4px;background:none;color:var(--text-muted);font-size:15px;width:28px;height:28px;display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;transition:all .15s ease;line-height:1}.view-toggle-btn:hover{color:var(--text-secondary);background:var(--bg-tertiary)}.view-toggle-btn.active{color:var(--text);background:var(--bg-tertiary)}.tab-content{flex:1;overflow:hidden;position:relative;background:#000}.app-footer{display:flex;gap:8px;padding:10px 20px;border-top:1px solid var(--border);background:var(--bg-secondary);align-items:center}.app-footer select{background:var(--bg);border:1px solid var(--border);color:var(--text-secondary);padding:7px 10px;border-radius:var(--radius-sm);font-size:12px;font-family:var(--font-body);min-width:140px;cursor:pointer}.app-footer select:hover{border-color:#333}.app-footer input{flex:1;background:var(--bg)}.header-hamburger{display:none;border:none;background:none;color:var(--text-secondary);font-size:18px;padding:4px 8px;cursor:pointer;line-height:1;min-height:unset}.header-connect-phone{border:1px solid var(--border);background:transparent;font-size:13px;padding:6px 12px;cursor:pointer;border-radius:6px;color:var(--text);opacity:.8}.header-connect-phone:hover{opacity:1;background:var(--surface);border-color:var(--border)}.pair-modal-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#000000bf;z-index:300;display:flex;align-items:center;justify-content:center;padding:20px}.pair-modal{background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius-lg);padding:28px 24px 24px;width:100%;max-width:400px;display:flex;flex-direction:column;align-items:center;gap:16px}.pair-modal-header{width:100%;display:flex;align-items:center;justify-content:space-between}.pair-modal-header h2{font-size:14px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--text)}.pair-modal-close{border:none;background:none;color:var(--text-muted);font-size:14px;padding:4px;min-height:unset;line-height:1}.pair-modal-close:hover{color:var(--text);background:none;border-color:transparent}.pair-modal-hint{font-size:12px;color:var(--text-muted);text-align:center}.pair-modal-loading{font-size:12px;color:var(--text-muted);padding:24px 0}.pair-modal-error{font-size:12px;color:#f87171;padding:24px 0}.pair-qr{width:200px;height:200px;background:#000;border-radius:var(--radius-md);padding:12px}.pair-urls{width:100%;display:flex;flex-direction:column;gap:8px}.pair-url-row{display:flex;align-items:center;gap:8px;background:var(--bg-tertiary);border:1px solid var(--border);border-radius:var(--radius-sm);padding:8px 12px}.pair-url-label{font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:var(--text-muted);min-width:44px}.pair-url-text{flex:1;font-family:var(--font-mono);font-size:11px;color:var(--text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pair-tunnel-hint{font-size:11px;color:var(--text-muted);text-align:center;line-height:1.5}.pair-tunnel-hint code{font-family:var(--font-mono);background:var(--bg-tertiary);padding:1px 5px;border-radius:3px;color:var(--text-secondary)}.sidebar-backdrop{display:none}@media(max-width:767px){.header-hamburger{display:flex;align-items:center}.sidebar-toggle{display:none}.sidebar{position:fixed;top:0;left:0;height:100%;z-index:200;transform:translate(-100%);transition:transform .25s ease,width .2s ease,min-width .2s ease;width:85vw;max-width:320px;min-width:260px}.sidebar:not(.collapsed){transform:translate(0)}.sidebar.collapsed{transform:translate(-100%);width:85vw;max-width:320px;min-width:260px;overflow:hidden}.sidebar-backdrop{display:block;position:fixed;top:0;right:0;bottom:0;left:0;background:#0009;z-index:199}.app-header{padding:0 10px;gap:6px;height:48px;min-height:48px}.app-header h1{font-size:13px}.header-brand{gap:6px}.header-total-cost,.header-connect-phone{display:none}.header-actions{gap:6px}.header-actions button{display:none}.tabs{padding:0 6px;height:36px;min-height:36px;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;scrollbar-width:none}.tabs::-webkit-scrollbar{display:none}.tab{white-space:nowrap;flex-shrink:0;padding:0 10px;font-size:11px}.terminal-view-toggle{display:none}.app-footer{flex-direction:row;flex-wrap:wrap;padding:8px 10px;gap:6px;align-items:center}.app-footer select{width:auto;min-width:100px;flex-shrink:0;padding:6px 8px;font-size:12px;min-height:36px}.app-footer input{flex:1;min-width:0;font-size:14px;padding:8px 10px;min-height:36px}.app-footer button{min-height:36px;padding:6px 14px}.pair-modal{max-width:100%;border-radius:var(--radius-lg) var(--radius-lg) 0 0;position:fixed;bottom:0;left:0;right:0;margin:0}.pair-modal-overlay{align-items:flex-end;padding:0}}*{margin:0;padding:0;box-sizing:border-box}:root{--bg: #000000;--bg-secondary: #0a0a0a;--bg-tertiary: #151515;--bg-elevated: #1a1a1a;--border: #2a2a2a;--border-subtle: #1c1c1c;--text: #eeeeee;--text-secondary: #b0b0b0;--text-muted: #707070;--white: #ffffff;--accent: #ffffff;--green: #4ade80;--yellow: #fbbf24;--red: #f87171;--radius-sm: 4px;--radius-md: 8px;--radius-lg: 12px;--font-body: "DM Sans", -apple-system, BlinkMacSystemFont, sans-serif;--font-mono: "JetBrains Mono", "SF Mono", "Fira Code", monospace;--transition: .18s cubic-bezier(.4, 0, .2, 1)}html,body,#root{height:100%;width:100%;overflow:hidden;overscroll-behavior:none}body{font-family:var(--font-body);background:var(--bg);color:var(--text);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:13px;letter-spacing:-.01em}button{cursor:pointer;border:1px solid var(--border);background:var(--bg-tertiary);color:var(--text-secondary);padding:7px 14px;border-radius:var(--radius-sm);font-size:12px;font-family:var(--font-body);font-weight:500;letter-spacing:.02em;transition:all var(--transition)}button:hover{color:var(--text);border-color:#444;background:var(--bg-elevated)}button.primary{background:var(--white);border-color:var(--white);color:#000}button.primary:hover{background:#d4d4d4;border-color:#d4d4d4}button.primary:disabled{background:#333;border-color:#333;color:#666;cursor:not-allowed}button.danger{background:transparent;border-color:#3a1515;color:var(--red)}button.danger:hover{background:#1a0808;border-color:var(--red)}button:disabled{opacity:.35;cursor:not-allowed}input,textarea,select{background:var(--bg);border:1px solid var(--border);color:var(--text);padding:8px 12px;border-radius:var(--radius-sm);font-size:13px;font-family:var(--font-body);outline:none;transition:border-color var(--transition)}input:focus,textarea:focus,select:focus{border-color:#444}input::placeholder,textarea::placeholder{color:var(--text-muted)}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#222;border-radius:3px}::-webkit-scrollbar-thumb:hover{background:#333}::selection{background:#ffffff1f}.react-flow__controls{background:#0a0a0a!important;border:1px solid var(--border)!important;border-radius:6px!important;overflow:hidden}.react-flow__controls-button{background:#0a0a0a!important;border:none!important;border-bottom:1px solid #1c1c1c!important;fill:#888!important;width:28px!important;height:28px!important}.react-flow__controls-button:hover{background:#1a1a1a!important;fill:#eee!important}.react-flow__controls-button:last-child{border-bottom:none!important}.react-flow__controls-button svg{fill:inherit!important}@media(max-width:767px){html,body,#root{overflow:hidden;overscroll-behavior:none;-webkit-overflow-scrolling:touch}body{padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)}input,textarea,select{font-size:16px}button{min-height:36px}.react-flow__controls-button{width:40px!important;height:40px!important}::-webkit-scrollbar{width:3px;height:3px}}.xterm{background:#000!important}.xterm-viewport{background-color:#000!important;overscroll-behavior:contain!important}.xterm-screen{background:#000!important}
@@ -7,8 +7,8 @@
7
7
  <link rel="manifest" href="/manifest.json" />
8
8
  <meta name="theme-color" content="#000000" />
9
9
  <title>Clustr</title>
10
- <script type="module" crossorigin src="/assets/index-BPO55CwU.js"></script>
11
- <link rel="stylesheet" crossorigin href="/assets/index-CW63oPzm.css">
10
+ <script type="module" crossorigin src="/assets/index-fPFhHLSl.js"></script>
11
+ <link rel="stylesheet" crossorigin href="/assets/index-DGsuwoi9.css">
12
12
  </head>
13
13
  <body>
14
14
  <div id="root">
@@ -170,7 +170,7 @@ Now execute the following task:
170
170
  agent_id TEXT,
171
171
  created_at TEXT DEFAULT (datetime('now'))
172
172
  )
173
- `).run();try{sr.prepare("ALTER TABLE file_changes ADD COLUMN agent_id TEXT").run()}catch{}var Sq=sr.prepare("INSERT INTO file_changes (file_path, change_type, diff_text, agent_id) VALUES (?, ?, ?, ?)"),kq=sr.prepare("SELECT id FROM agents WHERE agent_cwd IS NOT NULL AND status = 'running' ORDER BY length(agent_cwd) DESC"),Tq=sr.prepare("SELECT * FROM file_changes ORDER BY created_at DESC LIMIT ?"),Cq=sr.prepare("DELETE FROM file_changes");async function Aq(t){for(let e of["master","main"])try{return await ME("git",["rev-parse","--verify",e],{cwd:t}),e}catch{}return"master"}async function Oq(t,e,r){try{let{stdout:n}=await ME("git",["show",`${r}:${e}`],{cwd:t,maxBuffer:5242880});return n}catch{return""}}function zE(t){UE=t}function HE(t){Rq(),Tc=null,Aq(t).then(e=>{Tc=e}).catch(()=>{Tc="master"}),Hr=bc.watch(t,{ignored:e=>{let r=cf.relative(t,e),n=r.split(cf.sep);return n.includes(".git")||n.includes("node_modules")||n.includes("dist")||n.includes(".next")||n.includes("__pycache__")||n.includes("logs")||n.includes("log")||n.includes(".cache")||n.includes(".tmp")||n.includes("target")||n.includes("build")||n.includes("coverage")||r.endsWith(".pyc")||r.endsWith(".log")||r==="package-lock.json"||r==="yarn.lock"||r==="pnpm-lock.yaml"},persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:300,pollInterval:100}}),Hr.on("add",e=>of(e,"add",t)),Hr.on("change",e=>of(e,"change",t)),Hr.on("unlink",e=>of(e,"unlink",t))}function Rq(){Hr&&(Hr.close(),Hr=null)}async function of(t,e,r){let n=cf.relative(r,t),i=Tc||"master",s=null;try{let p=await Oq(r,n,i);if(e==="unlink")p&&(s=kc(n,p,"",i,"deleted"));else{let u=wq.readFileSync(t,"utf-8");p!==u&&(s=kc(n,p,u,i,"working"))}}catch{return}if(!s)return;let a=null,o=kq.all();for(let p of o){let u=sr.prepare("SELECT agent_cwd FROM agents WHERE id = ?").get(p.id);if(u?.agent_cwd&&t.startsWith(u.agent_cwd)){a=p.id;break}}let l={id:Sq.run(n,e,s,a).lastInsertRowid,file_path:n,change_type:e,diff_text:s,agent_id:a,created_at:new Date().toISOString()};UE?.emit("file:changed",l)}function WE(t=50){return Tq.all(t)}function $E(){Cq.run()}import{execFile as Pq}from"child_process";import{promisify as Iq}from"util";var Nq=Iq(Pq);async function Cc(t,e){return Nq("gh",t,{cwd:e,maxBuffer:10*1024*1024})}async function GE(t){try{return await Cc(["auth","status"],t),!0}catch{return!1}}async function VE(t){try{let{stdout:e}=await Cc(["repo","view","--json","nameWithOwner,url"],t);return JSON.parse(e)}catch{return null}}var YE="number,title,state,author,headRefName,baseRefName,createdAt,url,body,isDraft,reviewDecision,statusCheckRollup";async function lf(t,e="all"){try{let r=["pr","list","--state",e,"--json",YE,"--limit","50"],{stdout:n}=await Cc(r,t);return JSON.parse(n)}catch{return[]}}var Lq=YE+",reviews,comments";async function KE(t,e){try{let{stdout:r}=await Cc(["pr","view",String(e),"--json",Lq],t);return JSON.parse(r)}catch{return null}}import{execFile as aF}from"child_process";import{promisify as oF}from"util";import x8 from"os";import Bq from"crypto";import Ps from"fs";import XE from"path";import qq from"os";var uf=XE.join(qq.homedir(),".clustr"),pf=XE.join(uf,"config.json"),Ac=null;function JE(){if(Ac)return Ac;Ps.existsSync(uf)||Ps.mkdirSync(uf,{recursive:!0});let t;if(Ps.existsSync(pf))try{t=JSON.parse(Ps.readFileSync(pf,"utf8"))}catch{t={authToken:""}}else t={authToken:""};return t.authToken||(t.authToken=Bq.randomBytes(32).toString("hex"),Ps.writeFileSync(pf,JSON.stringify(t,null,2),{mode:384})),Ac=t,Ac}var o8=Ys(a8(),1);import Zj from"os";function Qj(){let t=Zj.networkInterfaces();for(let e of Object.keys(t))for(let r of t[e]||[])if(r.family==="IPv4"&&!r.internal)return r.address;return"127.0.0.1"}async function c8(t,e,r){let i=`http://${Qj()}:${t}`,s=JSON.stringify({url:r||i,localUrl:i,token:e}),a=await o8.default.toString(s,{type:"svg",color:{dark:"#ffffff",light:"#00000000"},margin:1});return{localUrl:i,remoteUrl:r,token:e,qrSvg:a}}import{spawn as eF}from"child_process";import{execFile as tF}from"child_process";import{promisify as rF}from"util";var nF=rF(tF),mr=null,Ws=null,At=null;function l8(){return Ws}async function iF(){try{return await nF("which",["cloudflared"]),!0}catch{return!1}}async function p8(t){return await iF()?new Promise(e=>{At=e,mr=eF("cloudflared",["tunnel","--url",`http://localhost:${t}`],{stdio:["ignore","pipe","pipe"]});let r=n=>{let s=n.toString().match(/https:\/\/[a-z0-9-]+\.trycloudflare\.com/);s&&At&&(Ws=s[0],At(Ws),At=null)};mr.stdout?.on("data",r),mr.stderr?.on("data",r),mr.on("exit",()=>{Ws=null,mr=null,At&&(At(null),At=null)}),setTimeout(()=>{At&&(At(null),At=null)},15e3)}):null}function rh(){mr&&(mr.kill(),mr=null,Ws=null)}var nh=oF(aF),Gs=parseInt(process.env.CLUSTR_PORT||"3100",10),$c=JE();process.env.CLUSTR_TUNNEL==="1"&&p8(Gs).then(t=>{console.log(t?`Clustr tunnel active: ${t}`:"Clustr tunnel: cloudflared not found or timed out")});process.on("SIGINT",()=>{rh(),process.exit(0)});process.on("SIGTERM",()=>{rh(),process.exit(0)});var P=(0,Wc.default)();P.use((0,v8.default)());P.use(Wc.default.json({limit:"20mb"}));var u8=process.env.CLUSTR_SERVE_CLIENT,Hc=u8==="true"?zt.resolve(zt.dirname(sh(import.meta.url)),"..","client"):u8||"";Hc&&P.use(Wc.default.static(Hc));var d8=zt.resolve(zt.dirname(sh(import.meta.url)),"connect.html"),f8=zt.resolve(zt.dirname(sh(import.meta.url)),"..","server","connect.html"),h8=$s.existsSync(d8)?d8:$s.existsSync(f8)?f8:null;P.get("/connect",(t,e)=>{h8?e.sendFile(h8):e.status(404).send("Connect page not found")});P.get("/api/pair",async(t,e)=>{if(!(t.socket.localAddress==="127.0.0.1"||t.socket.localAddress==="::1"||t.socket.localAddress==="::ffff:127.0.0.1")){e.status(403).json({error:"Pairing info only accessible from localhost"});return}let n=await c8(Gs,$c.authToken,l8());e.json(n)});P.use("/api",(t,e,r)=>{if(t.path==="/pair"||t.socket.localAddress==="127.0.0.1"||t.socket.localAddress==="::1"||t.socket.localAddress==="::ffff:127.0.0.1")return r();if((t.query.token||t.headers.authorization?.replace("Bearer ",""))!==$c.authToken){e.status(401).json({error:"Unauthorized"});return}r()});var y8=sF(P),xe=new T_(y8,{cors:{origin:"*"}});xe.use((t,e)=>{let r=t.handshake.address;if(r==="127.0.0.1"||r==="::1"||r==="::ffff:127.0.0.1")return e();if((t.handshake.auth?.token||t.handshake.query?.token)!==$c.authToken)return e(new Error("Unauthorized"));e()});I_();PE(xe);LE(xe);fE(xe);zE(xe);kE(xe,()=>{xe.emit("agents:updated",St())});P.post("/api/agents",(t,e)=>{try{let{id:r,name:n,service:i="claude",task:s}=t.body;if(r)He(r,{status:"running"}),xe.emit("agents:updated",St()),e.json({id:r,status:"registered"});else{let a=F_(n,i,s,null);xe.emit("agents:updated",St()),e.json({id:a,status:"registered"})}}catch(r){e.status(400).json({error:r.message})}});P.get("/api/agents",(t,e)=>{e.json(St())});P.post("/api/agents/:id/ping",(t,e)=>{M_(t.params.id),e.json({status:"ok"})});P.delete("/api/agents/:id",(t,e)=>{U_(t.params.id),ef(t.params.id),xe.emit("agents:updated",St()),e.json({status:"deregistered"})});P.delete("/api/agents/:id/remove",(t,e)=>{ef(t.params.id),R_(t.params.id),xe.emit("agents:updated",St()),e.json({status:"removed"})});P.post("/api/messages",(t,e)=>{try{let{from:r,to:n,content:i}=t.body;if(n==="all"||n==="*"){let s=NE(r,i);e.json(s)}else{let s=n;if(!Mt(n)){let c=P_(n);c&&(s=c.id)}let o=tf(r,s,i);e.json(o)}}catch(r){e.status(400).json({error:r.message})}});P.get("/api/messages/:agentId",(t,e)=>{e.json(IE(t.params.agentId))});P.get("/api/messages",(t,e)=>{e.json(pc())});P.delete("/api/messages",(t,e)=>{B_(),xe.emit("messages:all",[]),e.json({status:"cleared"})});P.get("/api/context/:key?",(t,e)=>{let r=t.params.key;e.json(BE(r))});P.put("/api/context",(t,e)=>{try{let{key:r,value:n,updatedBy:i}=t.body;qE(r,n,i),e.json({status:"ok"})}catch(r){e.status(400).json({error:r.message})}});P.delete("/api/context/:key",(t,e)=>{try{DE(t.params.key),e.json({status:"removed"})}catch(r){e.status(400).json({error:r.message})}});P.get("/api/crewmd",(t,e)=>{e.json({content:As()})});P.put("/api/crewmd",(t,e)=>{try{let{content:r}=t.body;gE(r),e.json({status:"ok"})}catch(r){e.status(400).json({error:r.message})}});P.get("/api/agents/:id/cost",(t,e)=>{let r=Mt(t.params.id);if(!r){e.status(404).json({error:"Agent not found"});return}e.json({total_tokens:r.total_tokens||0,total_cost:r.total_cost||0})});P.get("/api/agents/:id/diff",async(t,e)=>{let r=Mt(t.params.id);if(!r||!r.checkpoint_hash||!r.agent_cwd){e.json({diff:""});return}let n=await H_(r.agent_cwd,r.checkpoint_hash);e.json({diff:n})});P.post("/api/agents/:id/rollback",async(t,e)=>{let r=Mt(t.params.id);if(!r||!r.checkpoint_hash||!r.agent_cwd){e.status(400).json({error:"No checkpoint available for this agent"});return}let n=await $_(r.agent_cwd,r.checkpoint_hash);n.success?e.json({status:"rolled_back",message:n.message}):e.status(400).json({error:n.message})});P.get("/api/file-changes",(t,e)=>{let r=parseInt(t.query.limit)||50;e.json(WE(r))});P.delete("/api/file-changes",(t,e)=>{$E(),xe.emit("file:changes:cleared"),e.json({status:"cleared"})});function Vs(){return St().find(r=>r.agent_cwd)?.agent_cwd||process.cwd()}P.get("/api/github/status",async(t,e)=>{let r=Vs(),n=await GE(r),i=n?await VE(r):null;e.json({available:n,repo:i})});P.get("/api/github/prs",async(t,e)=>{let r=Vs(),n=t.query.state||"all",i=await lf(r,n);e.json(i)});P.get("/api/github/prs/:number",async(t,e)=>{let r=Vs(),n=parseInt(t.params.number,10);if(isNaN(n)){e.status(400).json({error:"Invalid PR number"});return}let i=await KE(r,n);i?e.json(i):e.status(404).json({error:"PR not found"})});P.get("/api/git/branches",async(t,e)=>{let r=Vs(),n=await jd(r);e.json(n)});P.post("/api/pick-folder",async(t,e)=>{try{let r=x8.platform(),n="";if(r==="darwin"){let{stdout:i}=await nh("osascript",["-e",'set chosenFolder to choose folder with prompt "Select project directory"',"-e","return POSIX path of chosenFolder"]);n=i.trim().replace(/\/$/,"")}else if(r==="win32"){let{stdout:i}=await nh("powershell",["-NoProfile","-Command","Add-Type -AssemblyName System.Windows.Forms; $d = New-Object System.Windows.Forms.FolderBrowserDialog; $d.Description = 'Select project directory'; if ($d.ShowDialog() -eq 'OK') { $d.SelectedPath } else { '' }"]);n=i.trim()}else{let{stdout:i}=await nh("zenity",["--file-selection","--directory","--title=Select project directory"]);n=i.trim()}n?e.json({path:n}):e.json({path:null,cancelled:!0})}catch{e.json({path:null,cancelled:!0})}});var ih=zt.join(x8.homedir(),".clustr","uploads");P.post("/api/upload-image",(t,e)=>{try{let{data:r,mimeType:n}=t.body;if(!r||!n){e.status(400).json({error:"Missing data or mimeType"});return}$s.existsSync(ih)||$s.mkdirSync(ih,{recursive:!0});let i=(n.split("/")[1]||"png").replace(/[^a-zA-Z0-9]/g,"")||"png",s=`paste-${Date.now()}.${i}`,a=zt.join(ih,s),o=Buffer.from(r,"base64");$s.writeFileSync(a,o),e.json({path:a,filename:s})}catch(r){e.status(500).json({error:r.message})}});P.post("/api/spawn",(t,e)=>{try{let{name:r,task:n,cwd:i,service:s}=t.body,a=i||process.cwd();HE(a);let o=TE(r,n,{cwd:i,service:s});xe.emit("agents:updated",St()),e.json({id:o,status:"spawning"})}catch(r){e.status(400).json({error:r.message})}});P.post("/api/agents/:id/message",(t,e)=>{let{content:r}=t.body;Qd(t.params.id,r+"\r")?e.json({status:"sent"}):e.status(404).json({error:"Agent not running"})});P.get("/api/agents/:id/scrollback",(t,e)=>{e.json({scrollback:OE(t.params.id)})});xe.on("connection",t=>{t.emit("agents:updated",St()),t.emit("messages:all",pc()),t.emit("crewmd:updated",As()),t.on("agent:input",(e,r)=>{Qd(e,r)}),t.on("agent:resize",(e,r,n)=>{AE(e,r,n)})});Hc&&P.get("*",(t,e)=>{e.sendFile(zt.join(Hc,"index.html"))});var m8="",g8="";setInterval(async()=>{if(xe.engine.clientsCount===0)return;let t=Vs();try{let e=await lf(t,"all"),r=JSON.stringify(e.map(n=>`${n.number}:${n.state}:${n.reviewDecision}`));r!==m8&&(m8=r,xe.emit("github:prs:updated",e))}catch{}try{let e=await jd(t),r=JSON.stringify(e.branches.map(n=>n.name));r!==g8&&(g8=r,xe.emit("git:branches:updated",e))}catch{}},3e4);y8.listen(Gs,"0.0.0.0",()=>{console.log(`Clustr server running on http://localhost:${Gs}`),console.log(`Connect from phone: http://localhost:${Gs}/connect`),console.log(`Auth token: ${$c.authToken}`)});
173
+ `).run();try{sr.prepare("ALTER TABLE file_changes ADD COLUMN agent_id TEXT").run()}catch{}var Sq=sr.prepare("INSERT INTO file_changes (file_path, change_type, diff_text, agent_id) VALUES (?, ?, ?, ?)"),kq=sr.prepare("SELECT id FROM agents WHERE agent_cwd IS NOT NULL AND status = 'running' ORDER BY length(agent_cwd) DESC"),Tq=sr.prepare("SELECT * FROM file_changes ORDER BY created_at DESC LIMIT ?"),Cq=sr.prepare("DELETE FROM file_changes");async function Aq(t){for(let e of["master","main"])try{return await ME("git",["rev-parse","--verify",e],{cwd:t}),e}catch{}return"master"}async function Oq(t,e,r){try{let{stdout:n}=await ME("git",["show",`${r}:${e}`],{cwd:t,maxBuffer:5242880});return n}catch{return""}}function zE(t){UE=t}function HE(t){Rq(),Tc=null,Aq(t).then(e=>{Tc=e}).catch(()=>{Tc="master"}),Hr=bc.watch(t,{ignored:e=>{let r=cf.relative(t,e),n=r.split(cf.sep);return n.includes(".git")||n.includes("node_modules")||n.includes("dist")||n.includes(".next")||n.includes("__pycache__")||n.includes("logs")||n.includes("log")||n.includes(".cache")||n.includes(".tmp")||n.includes("target")||n.includes("build")||n.includes("coverage")||r.endsWith(".pyc")||r.endsWith(".log")||r==="package-lock.json"||r==="yarn.lock"||r==="pnpm-lock.yaml"},persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:300,pollInterval:100}}),Hr.on("add",e=>of(e,"add",t)),Hr.on("change",e=>of(e,"change",t)),Hr.on("unlink",e=>of(e,"unlink",t))}function Rq(){Hr&&(Hr.close(),Hr=null)}async function of(t,e,r){let n=cf.relative(r,t),i=Tc||"master",s=null;try{let p=await Oq(r,n,i);if(e==="unlink")p&&(s=kc(n,p,"",i,"deleted"));else{let u=wq.readFileSync(t,"utf-8");p!==u&&(s=kc(n,p,u,i,"working"))}}catch{return}if(!s)return;let a=null,o=kq.all();for(let p of o){let u=sr.prepare("SELECT agent_cwd FROM agents WHERE id = ?").get(p.id);if(u?.agent_cwd&&t.startsWith(u.agent_cwd)){a=p.id;break}}let l={id:Sq.run(n,e,s,a).lastInsertRowid,file_path:n,change_type:e,diff_text:s,agent_id:a,created_at:new Date().toISOString()};UE?.emit("file:changed",l)}function WE(t=50){return Tq.all(t)}function $E(){Cq.run()}import{execFile as Pq}from"child_process";import{promisify as Iq}from"util";var Nq=Iq(Pq);async function Cc(t,e){return Nq("gh",t,{cwd:e,maxBuffer:10*1024*1024})}async function GE(t){try{return await Cc(["auth","status"],t),!0}catch{return!1}}async function VE(t){try{let{stdout:e}=await Cc(["repo","view","--json","nameWithOwner,url"],t);return JSON.parse(e)}catch{return null}}var YE="number,title,state,author,headRefName,baseRefName,createdAt,url,body,isDraft,reviewDecision,statusCheckRollup";async function lf(t,e="all"){try{let r=["pr","list","--state",e,"--json",YE,"--limit","50"],{stdout:n}=await Cc(r,t);return JSON.parse(n)}catch{return[]}}var Lq=YE+",reviews,comments";async function KE(t,e){try{let{stdout:r}=await Cc(["pr","view",String(e),"--json",Lq],t);return JSON.parse(r)}catch{return null}}import{execFile as aF}from"child_process";import{promisify as oF}from"util";import x8 from"os";import Bq from"crypto";import Ps from"fs";import XE from"path";import qq from"os";var uf=XE.join(qq.homedir(),".clustr"),pf=XE.join(uf,"config.json"),Ac=null;function JE(){if(Ac)return Ac;Ps.existsSync(uf)||Ps.mkdirSync(uf,{recursive:!0});let t;if(Ps.existsSync(pf))try{t=JSON.parse(Ps.readFileSync(pf,"utf8"))}catch{t={authToken:""}}else t={authToken:""};return t.authToken||(t.authToken=Bq.randomBytes(32).toString("hex"),Ps.writeFileSync(pf,JSON.stringify(t,null,2),{mode:384})),Ac=t,Ac}var o8=Ys(a8(),1);import Zj from"os";function Qj(){let t=Zj.networkInterfaces();for(let e of Object.keys(t))for(let r of t[e]||[])if(r.family==="IPv4"&&!r.internal)return r.address;return"127.0.0.1"}async function c8(t,e,r){let i=`http://${Qj()}:${t}`,a=`${r||i}?token=${e}`,o=await o8.default.toString(a,{type:"svg",color:{dark:"#ffffff",light:"#00000000"},margin:1});return{localUrl:i,remoteUrl:r,token:e,qrSvg:o}}import{spawn as eF}from"child_process";import{execFile as tF}from"child_process";import{promisify as rF}from"util";var nF=rF(tF),mr=null,Ws=null,At=null;function l8(){return Ws}async function iF(){try{return await nF("which",["cloudflared"]),!0}catch{return!1}}async function p8(t){return await iF()?new Promise(e=>{At=e,mr=eF("cloudflared",["tunnel","--url",`http://localhost:${t}`],{stdio:["ignore","pipe","pipe"]});let r=n=>{let s=n.toString().match(/https:\/\/[a-z0-9-]+\.trycloudflare\.com/);s&&At&&(Ws=s[0],At(Ws),At=null)};mr.stdout?.on("data",r),mr.stderr?.on("data",r),mr.on("exit",()=>{Ws=null,mr=null,At&&(At(null),At=null)}),setTimeout(()=>{At&&(At(null),At=null)},15e3)}):null}function rh(){mr&&(mr.kill(),mr=null,Ws=null)}var nh=oF(aF),Gs=parseInt(process.env.CLUSTR_PORT||"3100",10),$c=JE();process.env.CLUSTR_TUNNEL==="1"&&p8(Gs).then(t=>{console.log(t?`Clustr tunnel active: ${t}`:"Clustr tunnel: cloudflared not found or timed out")});process.on("SIGINT",()=>{rh(),process.exit(0)});process.on("SIGTERM",()=>{rh(),process.exit(0)});var P=(0,Wc.default)();P.use((0,v8.default)());P.use(Wc.default.json({limit:"20mb"}));var u8=process.env.CLUSTR_SERVE_CLIENT,Hc=u8==="true"?zt.resolve(zt.dirname(sh(import.meta.url)),"..","client"):u8||"";Hc&&P.use(Wc.default.static(Hc));var d8=zt.resolve(zt.dirname(sh(import.meta.url)),"connect.html"),f8=zt.resolve(zt.dirname(sh(import.meta.url)),"..","server","connect.html"),h8=$s.existsSync(d8)?d8:$s.existsSync(f8)?f8:null;P.get("/connect",(t,e)=>{h8?e.sendFile(h8):e.status(404).send("Connect page not found")});P.get("/api/pair",async(t,e)=>{if(!(t.socket.localAddress==="127.0.0.1"||t.socket.localAddress==="::1"||t.socket.localAddress==="::ffff:127.0.0.1")){e.status(403).json({error:"Pairing info only accessible from localhost"});return}let n=await c8(Gs,$c.authToken,l8());e.json(n)});P.use("/api",(t,e,r)=>{if(t.path==="/pair"||t.socket.localAddress==="127.0.0.1"||t.socket.localAddress==="::1"||t.socket.localAddress==="::ffff:127.0.0.1")return r();if((t.query.token||t.headers.authorization?.replace("Bearer ",""))!==$c.authToken){e.status(401).json({error:"Unauthorized"});return}r()});var y8=sF(P),xe=new T_(y8,{cors:{origin:"*"}});xe.use((t,e)=>{let r=t.handshake.address;if(r==="127.0.0.1"||r==="::1"||r==="::ffff:127.0.0.1")return e();if((t.handshake.auth?.token||t.handshake.query?.token)!==$c.authToken)return e(new Error("Unauthorized"));e()});I_();PE(xe);LE(xe);fE(xe);zE(xe);kE(xe,()=>{xe.emit("agents:updated",St())});P.post("/api/agents",(t,e)=>{try{let{id:r,name:n,service:i="claude",task:s}=t.body;if(r)He(r,{status:"running"}),xe.emit("agents:updated",St()),e.json({id:r,status:"registered"});else{let a=F_(n,i,s,null);xe.emit("agents:updated",St()),e.json({id:a,status:"registered"})}}catch(r){e.status(400).json({error:r.message})}});P.get("/api/agents",(t,e)=>{e.json(St())});P.post("/api/agents/:id/ping",(t,e)=>{M_(t.params.id),e.json({status:"ok"})});P.delete("/api/agents/:id",(t,e)=>{U_(t.params.id),ef(t.params.id),xe.emit("agents:updated",St()),e.json({status:"deregistered"})});P.delete("/api/agents/:id/remove",(t,e)=>{ef(t.params.id),R_(t.params.id),xe.emit("agents:updated",St()),e.json({status:"removed"})});P.post("/api/messages",(t,e)=>{try{let{from:r,to:n,content:i}=t.body;if(n==="all"||n==="*"){let s=NE(r,i);e.json(s)}else{let s=n;if(!Mt(n)){let c=P_(n);c&&(s=c.id)}let o=tf(r,s,i);e.json(o)}}catch(r){e.status(400).json({error:r.message})}});P.get("/api/messages/:agentId",(t,e)=>{e.json(IE(t.params.agentId))});P.get("/api/messages",(t,e)=>{e.json(pc())});P.delete("/api/messages",(t,e)=>{B_(),xe.emit("messages:all",[]),e.json({status:"cleared"})});P.get("/api/context/:key?",(t,e)=>{let r=t.params.key;e.json(BE(r))});P.put("/api/context",(t,e)=>{try{let{key:r,value:n,updatedBy:i}=t.body;qE(r,n,i),e.json({status:"ok"})}catch(r){e.status(400).json({error:r.message})}});P.delete("/api/context/:key",(t,e)=>{try{DE(t.params.key),e.json({status:"removed"})}catch(r){e.status(400).json({error:r.message})}});P.get("/api/crewmd",(t,e)=>{e.json({content:As()})});P.put("/api/crewmd",(t,e)=>{try{let{content:r}=t.body;gE(r),e.json({status:"ok"})}catch(r){e.status(400).json({error:r.message})}});P.get("/api/agents/:id/cost",(t,e)=>{let r=Mt(t.params.id);if(!r){e.status(404).json({error:"Agent not found"});return}e.json({total_tokens:r.total_tokens||0,total_cost:r.total_cost||0})});P.get("/api/agents/:id/diff",async(t,e)=>{let r=Mt(t.params.id);if(!r||!r.checkpoint_hash||!r.agent_cwd){e.json({diff:""});return}let n=await H_(r.agent_cwd,r.checkpoint_hash);e.json({diff:n})});P.post("/api/agents/:id/rollback",async(t,e)=>{let r=Mt(t.params.id);if(!r||!r.checkpoint_hash||!r.agent_cwd){e.status(400).json({error:"No checkpoint available for this agent"});return}let n=await $_(r.agent_cwd,r.checkpoint_hash);n.success?e.json({status:"rolled_back",message:n.message}):e.status(400).json({error:n.message})});P.get("/api/file-changes",(t,e)=>{let r=parseInt(t.query.limit)||50;e.json(WE(r))});P.delete("/api/file-changes",(t,e)=>{$E(),xe.emit("file:changes:cleared"),e.json({status:"cleared"})});function Vs(){return St().find(r=>r.agent_cwd)?.agent_cwd||process.cwd()}P.get("/api/github/status",async(t,e)=>{let r=Vs(),n=await GE(r),i=n?await VE(r):null;e.json({available:n,repo:i})});P.get("/api/github/prs",async(t,e)=>{let r=Vs(),n=t.query.state||"all",i=await lf(r,n);e.json(i)});P.get("/api/github/prs/:number",async(t,e)=>{let r=Vs(),n=parseInt(t.params.number,10);if(isNaN(n)){e.status(400).json({error:"Invalid PR number"});return}let i=await KE(r,n);i?e.json(i):e.status(404).json({error:"PR not found"})});P.get("/api/git/branches",async(t,e)=>{let r=Vs(),n=await jd(r);e.json(n)});P.post("/api/pick-folder",async(t,e)=>{try{let r=x8.platform(),n="";if(r==="darwin"){let{stdout:i}=await nh("osascript",["-e",'set chosenFolder to choose folder with prompt "Select project directory"',"-e","return POSIX path of chosenFolder"]);n=i.trim().replace(/\/$/,"")}else if(r==="win32"){let{stdout:i}=await nh("powershell",["-NoProfile","-Command","Add-Type -AssemblyName System.Windows.Forms; $d = New-Object System.Windows.Forms.FolderBrowserDialog; $d.Description = 'Select project directory'; if ($d.ShowDialog() -eq 'OK') { $d.SelectedPath } else { '' }"]);n=i.trim()}else{let{stdout:i}=await nh("zenity",["--file-selection","--directory","--title=Select project directory"]);n=i.trim()}n?e.json({path:n}):e.json({path:null,cancelled:!0})}catch{e.json({path:null,cancelled:!0})}});var ih=zt.join(x8.homedir(),".clustr","uploads");P.post("/api/upload-image",(t,e)=>{try{let{data:r,mimeType:n}=t.body;if(!r||!n){e.status(400).json({error:"Missing data or mimeType"});return}$s.existsSync(ih)||$s.mkdirSync(ih,{recursive:!0});let i=(n.split("/")[1]||"png").replace(/[^a-zA-Z0-9]/g,"")||"png",s=`paste-${Date.now()}.${i}`,a=zt.join(ih,s),o=Buffer.from(r,"base64");$s.writeFileSync(a,o),e.json({path:a,filename:s})}catch(r){e.status(500).json({error:r.message})}});P.post("/api/spawn",(t,e)=>{try{let{name:r,task:n,cwd:i,service:s}=t.body,a=i||process.cwd();HE(a);let o=TE(r,n,{cwd:i,service:s});xe.emit("agents:updated",St()),e.json({id:o,status:"spawning"})}catch(r){e.status(400).json({error:r.message})}});P.post("/api/agents/:id/message",(t,e)=>{let{content:r}=t.body;Qd(t.params.id,r+"\r")?e.json({status:"sent"}):e.status(404).json({error:"Agent not running"})});P.get("/api/agents/:id/scrollback",(t,e)=>{e.json({scrollback:OE(t.params.id)})});xe.on("connection",t=>{t.emit("agents:updated",St()),t.emit("messages:all",pc()),t.emit("crewmd:updated",As()),t.on("agent:input",(e,r)=>{Qd(e,r)}),t.on("agent:resize",(e,r,n)=>{AE(e,r,n)})});Hc&&P.get("*",(t,e)=>{e.sendFile(zt.join(Hc,"index.html"))});var m8="",g8="";setInterval(async()=>{if(xe.engine.clientsCount===0)return;let t=Vs();try{let e=await lf(t,"all"),r=JSON.stringify(e.map(n=>`${n.number}:${n.state}:${n.reviewDecision}`));r!==m8&&(m8=r,xe.emit("github:prs:updated",e))}catch{}try{let e=await jd(t),r=JSON.stringify(e.branches.map(n=>n.name));r!==g8&&(g8=r,xe.emit("git:branches:updated",e))}catch{}},3e4);y8.listen(Gs,"0.0.0.0",()=>{console.log(`Clustr server running on http://localhost:${Gs}`),console.log(`Connect from phone: http://localhost:${Gs}/connect`),console.log(`Auth token: ${$c.authToken}`)});
174
174
  /*! Bundled license information:
175
175
 
176
176
  depd/index.js:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clustr-ai",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "description": "Multi-agent workspace for AI coding sessions",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Clustr",