clustr-ai 0.1.23 → 0.1.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -4
- package/dist/client/assets/index-CyZJF1ZS.css +32 -0
- package/dist/client/assets/{index-ce7F3zpI.js → index-DfwASCOZ.js} +28 -28
- package/dist/client/index.html +2 -2
- package/dist/server/index.js +59 -56
- package/package.json +2 -2
- package/dist/client/assets/index-pgRSUOTG.css +0 -32
package/README.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Clustr
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Local multi-agent workspace for AI coding.
|
|
4
4
|
|
|
5
|
-
Clustr lets you
|
|
5
|
+
Clustr lets you run Claude Code and Codex agents side by side, monitor them from a live dashboard, and give them MCP tools to collaborate across your codebase. Agents can message each other, share context, spawn teammates, track file changes, and coordinate work across frontend, backend, tests, docs, and services.
|
|
6
|
+
|
|
7
|
+
Website: [hiclustrmvp.vercel.app](https://hiclustrmvp.vercel.app/)
|
|
6
8
|
|
|
7
9
|
## Quick Start
|
|
8
10
|
|
|
@@ -16,6 +18,7 @@ Open [http://localhost:3100](http://localhost:3100) in your browser.
|
|
|
16
18
|
|
|
17
19
|
- **Node.js 18+**
|
|
18
20
|
- **Claude Code CLI** — `npm install -g @anthropic-ai/claude-code`
|
|
21
|
+
- **OpenAI Codex CLI** — optional, for Codex agents
|
|
19
22
|
|
|
20
23
|
## Environment Variables
|
|
21
24
|
|
|
@@ -23,6 +26,21 @@ Open [http://localhost:3100](http://localhost:3100) in your browser.
|
|
|
23
26
|
|---|---|---|
|
|
24
27
|
| `CLUSTR_PORT` | `3100` | Server port |
|
|
25
28
|
| `CLUSTR_MAX_AGENTS` | `5` | Max concurrent agents |
|
|
29
|
+
| `CLUSTR_TUNNEL` | unset | Set to `1` to start a Cloudflare tunnel for mobile/remote access |
|
|
30
|
+
|
|
31
|
+
## Why Clustr
|
|
32
|
+
|
|
33
|
+
Most AI coding tools assume one agent should understand the whole project. Real engineering work is split across services, repos, tests, docs, and owners.
|
|
34
|
+
|
|
35
|
+
Clustr gives each agent a focused workspace and a shared coordination layer:
|
|
36
|
+
|
|
37
|
+
- **Multi-agent orchestration** — spawn multiple coding agents and watch them work in parallel
|
|
38
|
+
- **Inter-agent messaging** — agents can ask each other questions and hand off findings
|
|
39
|
+
- **Shared context** — one agent can write discoveries that every other agent can read
|
|
40
|
+
- **Live terminal dashboard** — inspect PTYs, logs, messages, file changes, and agent status
|
|
41
|
+
- **Claude + Codex support** — run different agent providers side by side
|
|
42
|
+
- **Git checkpoints** — checkpoint before agent work and roll back if needed
|
|
43
|
+
- **Mobile access** — pair a phone with a QR code and monitor your swarm away from your desk
|
|
26
44
|
|
|
27
45
|
## How It Works
|
|
28
46
|
|
|
@@ -33,8 +51,9 @@ Open [http://localhost:3100](http://localhost:3100) in your browser.
|
|
|
33
51
|
|
|
34
52
|
## Security Notes
|
|
35
53
|
|
|
36
|
-
- **Local
|
|
37
|
-
- **
|
|
54
|
+
- **Local-first** — Clustr runs on your machine and stores runtime state under `~/.clustr/`.
|
|
55
|
+
- **Remote auth token** — non-local API and Socket.io access requires the generated auth token.
|
|
56
|
+
- **Pairing endpoint is local-only** — the QR pairing details are only served from localhost.
|
|
38
57
|
- **Environment inheritance** — Spawned agents inherit your shell environment (including API keys and tokens). Be mindful of what's in your env.
|
|
39
58
|
- **Agent permissions** — Claude agents run with `--dangerously-skip-permissions` for unattended operation. Review the [Claude Code docs](https://docs.anthropic.com/en/docs/claude-code) for implications.
|
|
40
59
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
@import"https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;1,9..40,300&family=JetBrains+Mono:wght@400;500&display=swap";.agent-list{display:flex;flex-direction:column;height:100%}.agent-list-header{padding:14px 20px 10px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;color:var(--text-muted)}.agent-list-empty{padding:32px 20px;color:var(--text-muted);font-size:12px;text-align:center;line-height:1.6}.agent-item{padding:10px 20px;cursor:pointer;border-left:2px solid transparent;position:relative;transition:background var(--transition)}.agent-item:hover{background:var(--bg-tertiary)}.agent-item.selected{background:var(--bg-tertiary);border-left-color:var(--white)}.agent-item-header{display:flex;align-items:center;gap:10px}.status-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}.agent-name{font-weight:500;font-size:13px;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text)}.agent-status{font-size:10px;font-family:var(--font-mono);color:var(--text-muted);text-transform:lowercase;letter-spacing:.02em}.agent-task{font-size:11px;color:var(--text-muted);margin-top:3px;padding-left:16px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.4}.agent-running-actions{display:flex;gap:4px;padding-left:16px;max-height:0;overflow:hidden;opacity:0;transition:max-height .2s ease,opacity .15s ease,margin .2s ease;margin-top:0}.agent-item:hover .agent-running-actions{max-height:30px;opacity:1;margin-top:6px}.stop-btn{padding:3px 10px;font-size:10px;background:#f871711a;color:var(--red);border:1px solid rgba(248,113,113,.3);border-radius:var(--radius-sm);cursor:pointer;transition:all var(--transition);font-weight:500}.stop-btn:hover{background:#f8717133;color:var(--red);border-color:#f8717180}.agent-item:hover .remove-btn{opacity:1}.remove-btn{position:absolute;right:12px;top:10px;padding:3px 10px;font-size:10px;opacity:0;background:#f871711a;color:var(--red);border:1px solid rgba(248,113,113,.3);border-radius:var(--radius-sm);cursor:pointer;transition:all var(--transition);font-weight:500}.remove-btn:hover{background:#f8717133;color:var(--red);border-color:#f8717180}.agent-done-actions{display:flex;gap:4px;padding-left:16px;max-height:0;overflow:hidden;opacity:0;transition:max-height .2s ease,opacity .15s ease,margin .2s ease;margin-top:0}.agent-item:hover .agent-done-actions{max-height:30px;opacity:1;margin-top:6px}.agent-done-actions .remove-btn,.agent-done-actions .rollback-btn,.agent-done-actions .restart-btn{position:static;opacity:1;flex-shrink:0}.restart-btn{padding:3px 10px;font-size:10px;background:#4ade801a;color:var(--green);border:1px solid rgba(74,222,128,.3);border-radius:var(--radius-sm);cursor:pointer;transition:all var(--transition);font-weight:500}.restart-btn:hover{background:#4ade8033;color:var(--green);border-color:#4ade8080}.rollback-btn{padding:3px 10px;font-size:10px;background:#fbbf241a;color:#fbbf24;border:1px solid rgba(251,191,36,.3);border-radius:var(--radius-sm);cursor:pointer;transition:all var(--transition);font-weight:500}.rollback-btn:hover{background:#fbbf2433;color:#fbbf24;border-color:#fbbf2480}.agent-cost{font-family:var(--font-mono);font-size:10px;color:var(--text-muted);margin-left:auto;flex-shrink:0}.agent-service-badge{font-size:9px;font-weight:600;font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.04em;padding:1px 5px;border-radius:3px;flex-shrink:0}.agent-service-badge.service-claude{color:#c4a67a;background:#c4a67a1f}.agent-service-badge.service-codex{color:#10b981;background:#10b9811f}@media(max-width:767px){.agent-item{padding:10px 14px}.agent-running-actions,.agent-done-actions{max-height:30px;opacity:1;margin-top:6px}.remove-btn{opacity:1}.stop-btn,.restart-btn,.rollback-btn,.remove-btn{min-height:32px;padding:5px 12px;font-size:11px}.agent-list-header{padding:12px 14px 8px}}.react-flow{direction:ltr;--xy-edge-stroke-default: #b1b1b7;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #555;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(255, 255, 255, .5);--xy-minimap-background-color-default: #fff;--xy-minimap-mask-background-color-default: rgba(240, 240, 240, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #e2e2e2;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: transparent;--xy-background-pattern-dots-color-default: #91919a;--xy-background-pattern-lines-color-default: #eee;--xy-background-pattern-cross-color-default: #e2e2e2;background-color:var(--xy-background-color, var(--xy-background-color-default));--xy-node-color-default: inherit;--xy-node-border-default: 1px solid #1a192b;--xy-node-background-color-default: #fff;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(0, 0, 0, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #1a192b;--xy-node-border-radius-default: 3px;--xy-handle-background-color-default: #1a192b;--xy-handle-border-color-default: #fff;--xy-selection-background-color-default: rgba(0, 89, 220, .08);--xy-selection-border-default: 1px dotted rgba(0, 89, 220, .8);--xy-controls-button-background-color-default: #fefefe;--xy-controls-button-background-color-hover-default: #f4f4f4;--xy-controls-button-color-default: inherit;--xy-controls-button-color-hover-default: inherit;--xy-controls-button-border-color-default: #eee;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #ffffff;--xy-edge-label-color-default: inherit;--xy-resize-background-color-default: #3367d9}.react-flow.dark{--xy-edge-stroke-default: #3e3e3e;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #727272;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(150, 150, 150, .25);--xy-minimap-background-color-default: #141414;--xy-minimap-mask-background-color-default: rgba(60, 60, 60, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #2b2b2b;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: #141414;--xy-background-pattern-dots-color-default: #777;--xy-background-pattern-lines-color-default: #777;--xy-background-pattern-cross-color-default: #777;--xy-node-color-default: #f8f8f8;--xy-node-border-default: 1px solid #3c3c3c;--xy-node-background-color-default: #1e1e1e;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(255, 255, 255, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #999;--xy-handle-background-color-default: #bebebe;--xy-handle-border-color-default: #1e1e1e;--xy-selection-background-color-default: rgba(200, 200, 220, .08);--xy-selection-border-default: 1px dotted rgba(200, 200, 220, .8);--xy-controls-button-background-color-default: #2b2b2b;--xy-controls-button-background-color-hover-default: #3e3e3e;--xy-controls-button-color-default: #f8f8f8;--xy-controls-button-color-hover-default: #fff;--xy-controls-button-border-color-default: #5b5b5b;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #141414;--xy-edge-label-color-default: #f8f8f8}.react-flow__background{background-color:var(--xy-background-color-props, var(--xy-background-color, var(--xy-background-color-default)));pointer-events:none;z-index:-1}.react-flow__container{position:absolute;width:100%;height:100%;top:0;left:0}.react-flow__pane{z-index:1}.react-flow__pane.draggable{cursor:grab}.react-flow__pane.dragging{cursor:grabbing}.react-flow__pane.selection{cursor:pointer}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow__edge-path{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default));stroke-width:var(--xy-edge-stroke-width, var(--xy-edge-stroke-width-default));fill:none}.react-flow__connection-path{stroke:var(--xy-connectionline-stroke, var(--xy-connectionline-stroke-default));stroke-width:var(--xy-connectionline-stroke-width, var(--xy-connectionline-stroke-width-default));fill:none}.react-flow .react-flow__edges{position:absolute}.react-flow .react-flow__edges svg{overflow:visible;position:absolute;pointer-events:none}.react-flow__edge{pointer-events:visibleStroke}.react-flow__edge.selectable{cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;animation:dashdraw .5s linear infinite}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge.selectable:focus .react-flow__edge-path,.react-flow__edge.selectable:focus-visible .react-flow__edge-path{stroke:var(--xy-edge-stroke-selected, var(--xy-edge-stroke-selected-default))}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__arrowhead polyline{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__arrowhead polyline.arrowclosed{fill:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;animation:dashdraw .5s linear infinite}svg.react-flow__connectionline{z-index:1001;overflow:visible;position:absolute}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:default}.react-flow__node.selectable{cursor:pointer}.react-flow__node.draggable{cursor:grab;pointer-events:all}.react-flow__node.draggable.dragging{cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:left top;pointer-events:none}.react-flow__nodesselection-rect{position:absolute;pointer-events:all;cursor:grab}.react-flow__handle{position:absolute;pointer-events:none;min-width:5px;min-height:5px;width:6px;height:6px;background-color:var(--xy-handle-background-color, var(--xy-handle-background-color-default));border:1px solid var(--xy-handle-border-color, var(--xy-handle-border-color-default));border-radius:100%}.react-flow__handle.connectingfrom{pointer-events:all}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;left:50%;bottom:0;transform:translate(-50%,50%)}.react-flow__handle-top{top:0;left:50%;transform:translate(-50%,-50%)}.react-flow__handle-left{top:50%;left:0;transform:translate(-50%,-50%)}.react-flow__handle-right{top:50%;right:0;transform:translate(50%,-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__pane.selection .react-flow__panel{pointer-events:none}.react-flow__panel{position:absolute;z-index:5;margin:15px}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.top.center,.react-flow__panel.bottom.center{left:50%;transform:translate(-15px) translate(-50%)}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.left.center,.react-flow__panel.right.center{top:50%;transform:translateY(-15px) translateY(-50%)}.react-flow__attribution{font-size:10px;background:var(--xy-attribution-background-color, var(--xy-attribution-background-color-default));padding:2px 3px;margin:0}.react-flow__attribution a{text-decoration:none;color:#999}@keyframes dashdraw{0%{stroke-dashoffset:10}}.react-flow__edgelabel-renderer{position:absolute;width:100%;height:100%;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;left:0;top:0}.react-flow__viewport-portal{position:absolute;width:100%;height:100%;left:0;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__minimap{background:var( --xy-minimap-background-color-props, var(--xy-minimap-background-color, var(--xy-minimap-background-color-default)) )}.react-flow__minimap-svg{display:block}.react-flow__minimap-mask{fill:var( --xy-minimap-mask-background-color-props, var(--xy-minimap-mask-background-color, var(--xy-minimap-mask-background-color-default)) );stroke:var( --xy-minimap-mask-stroke-color-props, var(--xy-minimap-mask-stroke-color, var(--xy-minimap-mask-stroke-color-default)) );stroke-width:var( --xy-minimap-mask-stroke-width-props, var(--xy-minimap-mask-stroke-width, var(--xy-minimap-mask-stroke-width-default)) )}.react-flow__minimap-node{fill:var( --xy-minimap-node-background-color-props, var(--xy-minimap-node-background-color, var(--xy-minimap-node-background-color-default)) );stroke:var( --xy-minimap-node-stroke-color-props, var(--xy-minimap-node-stroke-color, var(--xy-minimap-node-stroke-color-default)) );stroke-width:var( --xy-minimap-node-stroke-width-props, var(--xy-minimap-node-stroke-width, var(--xy-minimap-node-stroke-width-default)) )}.react-flow__background-pattern.dots{fill:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-dots-color-default)) )}.react-flow__background-pattern.lines{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-lines-color-default)) )}.react-flow__background-pattern.cross{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-cross-color-default)) )}.react-flow__controls{display:flex;flex-direction:column;box-shadow:var(--xy-controls-box-shadow, var(--xy-controls-box-shadow-default))}.react-flow__controls.horizontal{flex-direction:row}.react-flow__controls-button{display:flex;justify-content:center;align-items:center;height:26px;width:26px;padding:4px;border:none;background:var(--xy-controls-button-background-color, var(--xy-controls-button-background-color-default));border-bottom:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) );color:var( --xy-controls-button-color-props, var(--xy-controls-button-color, var(--xy-controls-button-color-default)) );cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__controls-button svg{width:100%;max-width:12px;max-height:12px;fill:currentColor}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-input,.react-flow__node-default,.react-flow__node-output,.react-flow__node-group{padding:10px;border-radius:var(--xy-node-border-radius, var(--xy-node-border-radius-default));width:150px;font-size:12px;color:var(--xy-node-color, var(--xy-node-color-default));text-align:center;border:var(--xy-node-border, var(--xy-node-border-default));background-color:var(--xy-node-background-color, var(--xy-node-background-color-default))}.react-flow__node-input.selectable:hover,.react-flow__node-default.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:var(--xy-node-boxshadow-hover, var(--xy-node-boxshadow-hover-default))}.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:var(--xy-node-boxshadow-selected, var(--xy-node-boxshadow-selected-default))}.react-flow__node-group{background-color:var(--xy-node-group-background-color, var(--xy-node-group-background-color-default))}.react-flow__nodesselection-rect,.react-flow__selection{background:var(--xy-selection-background-color, var(--xy-selection-background-color-default));border:var(--xy-selection-border, var(--xy-selection-border-default))}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls-button:hover{background:var( --xy-controls-button-background-color-hover-props, var(--xy-controls-button-background-color-hover, var(--xy-controls-button-background-color-hover-default)) );color:var( --xy-controls-button-color-hover-props, var(--xy-controls-button-color-hover, var(--xy-controls-button-color-hover-default)) )}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__controls-button:last-child{border-bottom:none}.react-flow__controls.horizontal .react-flow__controls-button{border-bottom:none;border-right:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) )}.react-flow__controls.horizontal .react-flow__controls-button:last-child{border-right:none}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{width:5px;height:5px;border:1px solid #fff;border-radius:1px;background-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));translate:-50% -50%}.react-flow__resize-control.handle.left{left:0;top:50%}.react-flow__resize-control.handle.right{left:100%;top:50%}.react-flow__resize-control.handle.top{left:50%;top:0}.react-flow__resize-control.handle.bottom{left:50%;top:100%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));border-width:0;border-style:solid}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;transform:translate(-50%);top:0;height:100%}.react-flow__resize-control.line.left{left:0;border-left-width:1px}.react-flow__resize-control.line.right{left:100%;border-right-width:1px}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{height:1px;transform:translateY(-50%);left:0;width:100%}.react-flow__resize-control.line.top{top:0;border-top-width:1px}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}.react-flow__edge-textbg{fill:var(--xy-edge-label-background-color, var(--xy-edge-label-background-color-default))}.react-flow__edge-text{fill:var(--xy-edge-label-color, var(--xy-edge-label-color-default))}/**
|
|
2
|
+
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
|
|
3
|
+
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
|
|
4
|
+
* https://github.com/chjj/term.js
|
|
5
|
+
* @license MIT
|
|
6
|
+
*
|
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
* in the Software without restriction, including without limitation the rights
|
|
10
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
* furnished to do so, subject to the following conditions:
|
|
13
|
+
*
|
|
14
|
+
* The above copyright notice and this permission notice shall be included in
|
|
15
|
+
* all copies or substantial portions of the Software.
|
|
16
|
+
*
|
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
23
|
+
* THE SOFTWARE.
|
|
24
|
+
*
|
|
25
|
+
* Originally forked from (with the author's permission):
|
|
26
|
+
* Fabrice Bellard's javascript vt100 for jslinux:
|
|
27
|
+
* http://bellard.org/jslinux/
|
|
28
|
+
* Copyright (c) 2011 Fabrice Bellard
|
|
29
|
+
* The original design remains. The terminal itself
|
|
30
|
+
* has been extended to include xterm CSI codes, among
|
|
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}}.user-shell-panel{position:absolute;left:16px;right:16px;bottom:16px;height:min(36vh,340px);z-index:40;display:flex;flex-direction:column;overflow:hidden;border:1px solid rgba(255,255,255,.16);border-radius:12px;background:#050505;box-shadow:0 24px 80px #00000080}.user-shell-header{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:38px;padding:8px 12px;border-bottom:1px solid rgba(255,255,255,.12);background:#0e0e0ef5}.user-shell-header>div{min-width:0;display:flex;align-items:baseline;gap:8px}.user-shell-title{color:var(--text);font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;white-space:nowrap}.user-shell-subtitle{min-width:0;overflow:hidden;color:var(--text-muted);font-family:var(--font-mono);font-size:10px;text-overflow:ellipsis;white-space:nowrap}.user-shell-close{min-height:24px;padding:3px 8px;border:1px solid var(--border);border-radius:5px;background:var(--bg-tertiary);color:var(--text-secondary);font-size:11px}.user-shell-close:hover{border-color:#444;color:var(--text)}.user-shell-terminal{flex:1;min-height:0;padding:4px 0}@media(max-width:767px){.user-shell-panel{left:8px;right:8px;bottom:8px;height:42vh}.user-shell-header>div{flex-direction:column;gap:2px}}.agent-logs{--logs-bg: #050608;--logs-line: rgba(178, 188, 204, .12);--logs-line-strong: rgba(178, 188, 204, .2);--logs-text: #d7dde7;--logs-soft: #8a93a3;--logs-muted: #596170;--logs-info: #9aa7b8;--logs-yellow: #f4c95d;--logs-red: #ff6b6b;--logs-blue: #72b7ff;display:flex;flex-direction:column;height:100%;background:radial-gradient(circle at 80% 0,rgba(114,183,255,.06),transparent 28%),linear-gradient(180deg,#080a0f 0%,var(--logs-bg) 48%,#030406 100%);color:var(--logs-text)}.agent-logs-header{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:12px 18px;border-bottom:1px solid var(--logs-line-strong);background:linear-gradient(90deg,rgba(114,183,255,.05),transparent 34%),#05070bdb;box-shadow:inset 0 -1px #ffffff05}.agent-logs-title{display:flex;align-items:center;gap:10px;color:var(--logs-text);font-size:11px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;white-space:nowrap}.agent-logs-title>div{display:grid;gap:2px}.agent-logs-subtitle{display:block;color:var(--logs-muted);font-size:9px;font-weight:500;letter-spacing:.06em;text-transform:none}.agent-logs-count{padding:3px 7px;border:1px solid var(--logs-line-strong);border-radius:999px;background:#9aa7b814;color:var(--logs-soft);font-family:var(--font-mono);font-size:10px;letter-spacing:0}.agent-logs-controls{display:flex;align-items:center;justify-content:flex-end;gap:7px;flex:1;min-width:0}.agent-logs-controls select,.agent-logs-controls input{height:32px;padding:5px 10px;border:1px solid var(--logs-line-strong);border-radius:9px;background:#05070bd6;color:var(--logs-text);font-size:12px;outline:none;transition:border-color .12s ease,box-shadow .12s ease,background .12s ease}.agent-logs-controls select{max-width:190px}.agent-logs-controls input{width:min(280px,35vw)}.agent-logs-controls select:focus,.agent-logs-controls input:focus{border-color:#72b7ff80;box-shadow:0 0 0 3px #72b7ff1a}.agent-logs-controls input::placeholder{color:var(--logs-muted)}.agent-logs-controls button{height:32px;min-height:32px;padding:4px 11px;border:1px solid var(--logs-line-strong);border-radius:9px;background:#9aa7b814;color:var(--logs-text);font-size:11px}.agent-logs-controls button:hover:not(:disabled){border-color:#72b7ff5c;background:#72b7ff1a}.agent-logs-controls button:disabled{color:var(--logs-muted);opacity:.55}.agent-logs-autoscroll{display:flex;align-items:center;gap:6px;padding:0 2px;color:var(--logs-soft);font-size:11px;white-space:nowrap}.agent-logs-autoscroll input{width:auto;height:auto}.agent-logs-list{flex:1;overflow-y:auto;padding:10px 10px 14px;font-family:var(--font-mono);scrollbar-color:rgba(154,167,184,.28) transparent}.agent-logs-empty{width:min(560px,calc(100% - 32px));margin:56px auto;padding:28px 26px;border:1px dashed var(--logs-line-strong);border-radius:18px;background:#06080ca8;color:var(--logs-soft);font-family:var(--font-body);font-size:12px;text-align:center;box-shadow:0 24px 70px #0003}.agent-log-row{position:relative;display:grid;grid-template-columns:74px 42px minmax(0,1fr);gap:7px;margin:0 0 4px;padding:7px 12px 7px 16px;border:1px solid transparent;border-radius:10px;background:#080a0f94;color:var(--logs-text);font-size:12px;line-height:1.45;transition:background .12s ease,border-color .12s ease,transform .12s ease}.agent-log-row:before{content:"";position:absolute;inset:7px auto 7px 6px;width:3px;border-radius:999px;background:var(--logs-info);opacity:.7}.agent-log-row:hover{border-color:var(--logs-line-strong);background:#0d1017e0;transform:translate(1px)}.agent-log-time{color:var(--logs-soft);white-space:nowrap;font-size:10px}.agent-log-level{font-weight:600;letter-spacing:.01em;text-transform:uppercase;font-size:10px}.agent-log-row.error{background:#320a0c57}.agent-log-row.error:before{background:var(--logs-red)}.agent-log-row.warn:before{background:var(--logs-yellow)}.agent-log-row.debug:before{background:var(--logs-blue)}.agent-log-level.error{color:var(--logs-red)}.agent-log-level.warn{color:var(--logs-yellow)}.agent-log-level.info{color:var(--logs-info)}.agent-log-level.debug{color:var(--logs-blue)}.agent-log-text{min-width:0;display:flex;align-items:baseline;gap:8px;white-space:pre-wrap;overflow-wrap:anywhere;color:var(--logs-text)}.agent-log-source{flex:0 0 auto;max-width:150px;padding:1px 7px;border:1px solid rgba(154,167,184,.16);border-radius:7px;background:#9aa7b812;color:#aeb7c5;font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.agent-log-message{min-width:0;white-space:pre-wrap;overflow-wrap:anywhere}@media(max-width:767px){.agent-logs-header{align-items:stretch;flex-direction:column;padding:12px 14px;gap:10px}.agent-logs-controls{flex-wrap:wrap;justify-content:flex-start}.agent-logs-controls select,.agent-logs-controls input{flex:1 1 140px;width:auto;max-width:none}.agent-log-row{grid-template-columns:66px 38px minmax(0,1fr);gap:7px;padding:6px 10px 6px 14px;font-size:11px}.agent-log-source{max-width:120px}}.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)}.user-shell-toggle{height:28px;min-height:28px;padding:0 10px;border:1px solid var(--border);border-radius:5px;background:transparent;color:var(--text-secondary);font-size:11px;font-weight:600;letter-spacing:.03em}.user-shell-toggle:hover{border-color:#444;color:var(--text);background:var(--bg-tertiary)}.user-shell-toggle.active{border-color:#555;color:var(--white);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}
|