@cluesmith/codev 3.3.2 → 3.3.3
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/dashboard-dist/assets/{index-D3XaKpZW.js → index-CUIjS_Vb.js} +41 -41
- package/dashboard-dist/assets/index-CUIjS_Vb.js.map +1 -0
- package/dashboard-dist/assets/index-DnYLy5C_.css +32 -0
- package/dashboard-dist/index.html +2 -2
- package/dist/agent-farm/commands/inbox.d.ts.map +1 -1
- package/dist/agent-farm/commands/inbox.js +67 -10
- package/dist/agent-farm/commands/inbox.js.map +1 -1
- package/dist/agent-farm/commands/interrupt.d.ts +4 -1
- package/dist/agent-farm/commands/interrupt.d.ts.map +1 -1
- package/dist/agent-farm/commands/interrupt.js +6 -3
- package/dist/agent-farm/commands/interrupt.js.map +1 -1
- package/dist/agent-farm/commands/reset.d.ts +4 -1
- package/dist/agent-farm/commands/reset.d.ts.map +1 -1
- package/dist/agent-farm/commands/reset.js +6 -3
- package/dist/agent-farm/commands/reset.js.map +1 -1
- package/dist/agent-farm/commands/send.d.ts +28 -0
- package/dist/agent-farm/commands/send.d.ts.map +1 -1
- package/dist/agent-farm/commands/send.js +64 -6
- package/dist/agent-farm/commands/send.js.map +1 -1
- package/dist/agent-farm/db/index.d.ts +3 -1
- package/dist/agent-farm/db/index.d.ts.map +1 -1
- package/dist/agent-farm/db/index.js +8 -443
- package/dist/agent-farm/db/index.js.map +1 -1
- package/dist/agent-farm/db/mailbox.d.ts +47 -7
- package/dist/agent-farm/db/mailbox.d.ts.map +1 -1
- package/dist/agent-farm/db/mailbox.js +56 -12
- package/dist/agent-farm/db/mailbox.js.map +1 -1
- package/dist/agent-farm/db/migrations.d.ts +57 -0
- package/dist/agent-farm/db/migrations.d.ts.map +1 -0
- package/dist/agent-farm/db/migrations.js +530 -0
- package/dist/agent-farm/db/migrations.js.map +1 -0
- package/dist/agent-farm/db/schema.d.ts +1 -1
- package/dist/agent-farm/db/schema.d.ts.map +1 -1
- package/dist/agent-farm/db/schema.js +1 -0
- package/dist/agent-farm/db/schema.js.map +1 -1
- package/dist/agent-farm/db/types.d.ts +22 -0
- package/dist/agent-farm/db/types.d.ts.map +1 -1
- package/dist/agent-farm/db/types.js.map +1 -1
- package/dist/agent-farm/lib/tunnel-client.d.ts.map +1 -1
- package/dist/agent-farm/lib/tunnel-client.js +43 -14
- package/dist/agent-farm/lib/tunnel-client.js.map +1 -1
- package/dist/agent-farm/servers/cron-delivery.d.ts +7 -1
- package/dist/agent-farm/servers/cron-delivery.d.ts.map +1 -1
- package/dist/agent-farm/servers/cron-delivery.js +2 -1
- package/dist/agent-farm/servers/cron-delivery.js.map +1 -1
- package/dist/agent-farm/servers/gate-profiles.d.ts +21 -0
- package/dist/agent-farm/servers/gate-profiles.d.ts.map +1 -1
- package/dist/agent-farm/servers/gate-profiles.js +36 -4
- package/dist/agent-farm/servers/gate-profiles.js.map +1 -1
- package/dist/agent-farm/servers/mailbox-delivery.d.ts +83 -8
- package/dist/agent-farm/servers/mailbox-delivery.d.ts.map +1 -1
- package/dist/agent-farm/servers/mailbox-delivery.js +102 -26
- package/dist/agent-farm/servers/mailbox-delivery.js.map +1 -1
- package/dist/agent-farm/servers/mailbox-wiring.d.ts +48 -15
- package/dist/agent-farm/servers/mailbox-wiring.d.ts.map +1 -1
- package/dist/agent-farm/servers/mailbox-wiring.js +116 -22
- package/dist/agent-farm/servers/mailbox-wiring.js.map +1 -1
- package/dist/agent-farm/servers/render-gate.d.ts +24 -1
- package/dist/agent-farm/servers/render-gate.d.ts.map +1 -1
- package/dist/agent-farm/servers/render-gate.js +50 -12
- package/dist/agent-farm/servers/render-gate.js.map +1 -1
- package/dist/agent-farm/servers/tower-cron.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-cron.js +3 -2
- package/dist/agent-farm/servers/tower-cron.js.map +1 -1
- package/dist/agent-farm/servers/tower-instances.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-instances.js +11 -3
- package/dist/agent-farm/servers/tower-instances.js.map +1 -1
- package/dist/agent-farm/servers/tower-routes.d.ts +32 -0
- package/dist/agent-farm/servers/tower-routes.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-routes.js +133 -13
- package/dist/agent-farm/servers/tower-routes.js.map +1 -1
- package/dist/agent-farm/servers/tower-server.js +15 -2
- package/dist/agent-farm/servers/tower-server.js.map +1 -1
- package/dist/agent-farm/servers/tower-terminals.d.ts +21 -0
- package/dist/agent-farm/servers/tower-terminals.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-terminals.js +53 -5
- package/dist/agent-farm/servers/tower-terminals.js.map +1 -1
- package/dist/agent-farm/servers/tower-utils.d.ts +35 -0
- package/dist/agent-farm/servers/tower-utils.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-utils.js +39 -0
- package/dist/agent-farm/servers/tower-utils.js.map +1 -1
- package/dist/agent-farm/servers/tower-websocket.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-websocket.js +8 -1
- package/dist/agent-farm/servers/tower-websocket.js.map +1 -1
- package/dist/agent-farm/utils/message-format.d.ts +78 -2
- package/dist/agent-farm/utils/message-format.d.ts.map +1 -1
- package/dist/agent-farm/utils/message-format.js +102 -5
- package/dist/agent-farm/utils/message-format.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +3 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/doctor.js +2 -2
- package/dist/commands/generate-image.d.ts +20 -1
- package/dist/commands/generate-image.d.ts.map +1 -1
- package/dist/commands/generate-image.js +188 -1
- package/dist/commands/generate-image.js.map +1 -1
- package/dist/commands/porch/prompts.d.ts.map +1 -1
- package/dist/commands/porch/prompts.js +18 -2
- package/dist/commands/porch/prompts.js.map +1 -1
- package/dist/lib/forge-contracts.d.ts +66 -5
- package/dist/lib/forge-contracts.d.ts.map +1 -1
- package/dist/lib/forge-contracts.js.map +1 -1
- package/dist/lib/forge.d.ts +1 -1
- package/dist/lib/forge.d.ts.map +1 -1
- package/dist/lib/forge.js +33 -11
- package/dist/lib/forge.js.map +1 -1
- package/dist/terminal/pty-manager.d.ts +10 -1
- package/dist/terminal/pty-manager.d.ts.map +1 -1
- package/dist/terminal/pty-manager.js +38 -9
- package/dist/terminal/pty-manager.js.map +1 -1
- package/dist/terminal/pty-session.d.ts +52 -4
- package/dist/terminal/pty-session.d.ts.map +1 -1
- package/dist/terminal/pty-session.js +157 -18
- package/dist/terminal/pty-session.js.map +1 -1
- package/dist/terminal/shellper-client.d.ts +73 -0
- package/dist/terminal/shellper-client.d.ts.map +1 -1
- package/dist/terminal/shellper-client.js +151 -0
- package/dist/terminal/shellper-client.js.map +1 -1
- package/dist/terminal/shellper-main.js +20 -3
- package/dist/terminal/shellper-main.js.map +1 -1
- package/dist/terminal/shellper-process.d.ts +2 -0
- package/dist/terminal/shellper-process.d.ts.map +1 -1
- package/dist/terminal/shellper-process.js +17 -1
- package/dist/terminal/shellper-process.js.map +1 -1
- package/dist/terminal/shellper-protocol.d.ts +28 -0
- package/dist/terminal/shellper-protocol.d.ts.map +1 -1
- package/dist/terminal/shellper-protocol.js.map +1 -1
- package/package.json +4 -4
- package/scripts/forge/gitea/_lib.sh +214 -0
- package/scripts/forge/gitea/issue-comment.sh +8 -1
- package/scripts/forge/gitea/issue-view.sh +95 -4
- package/scripts/forge/gitea/pr-create.sh +155 -0
- package/scripts/forge/gitea/pr-exists.sh +32 -4
- package/scripts/forge/gitea/pr-list.sh +40 -31
- package/scripts/forge/gitea/pr-view.sh +65 -4
- package/scripts/forge/gitea/recently-merged.sh +91 -21
- package/scripts/forge/gitea/user-identity.sh +30 -1
- package/scripts/forge/github/issue-view.sh +5 -2
- package/scripts/forge/github/pr-create.sh +47 -0
- package/scripts/forge/github/pr-search.sh +3 -1
- package/scripts/forge/gitlab/issue-view.sh +24 -4
- package/scripts/forge/gitlab/pr-create.sh +53 -0
- package/scripts/forge/gitlab/pr-search.sh +3 -1
- package/scripts/forge/linear/issue-view.sh +13 -2
- package/skeleton/.claude/skills/generate-image/SKILL.md +22 -1
- package/skeleton/.codex/skills/generate-image/SKILL.md +22 -1
- package/skeleton/protocols/air/prompts/pr.md +6 -1
- package/skeleton/protocols/aspir/prompts/review.md +6 -1
- package/skeleton/protocols/bugfix/prompts/pr.md +6 -1
- package/skeleton/protocols/bugfix/protocol.md +2 -1
- package/skeleton/protocols/maintain/prompts/review.md +6 -1
- package/skeleton/protocols/pir/prompts/review.md +10 -7
- package/skeleton/protocols/spir/prompts/review.md +6 -1
- package/skeleton/resources/commands/agent-farm.md +1 -1
- package/templates/tower.html +16 -1
- package/dashboard-dist/assets/index-BZRTEMtH.css +0 -32
- package/dashboard-dist/assets/index-D3XaKpZW.js.map +0 -1
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
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}:root{--bg-primary: #1a1a1a;--bg-secondary: #252525;--bg-tertiary: #2a2a2a;--bg-hover: #333333;--text-primary: #e0e0e0;--text-secondary: #a0a0a0;--text-muted: #666666;--border-color: #333333;--accent: #3b82f6;--accent-hover: #2563eb;--status-active: #22c55e;--status-waiting: #eab308;--status-error: #ef4444;--status-implementing: #f97316}*{margin:0;padding:0;box-sizing:border-box}html,body,#root{height:100%;width:100%;overflow:hidden}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,monospace;background:var(--bg-primary);color:var(--text-primary);font-size:13px}.fullscreen-terminal{height:100vh;width:100vw;overflow:hidden}.fullscreen-terminal>div{height:100%;width:100%}.app{display:flex;flex-direction:column;height:100vh}.app-header{display:flex;align-items:center;justify-content:space-between;padding:8px 16px;background:var(--bg-secondary);border-bottom:1px solid var(--border-color);height:40px;flex-shrink:0}.app-title{font-size:14px;font-weight:600;color:var(--text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.header-version{font-size:11px;color:var(--text-secondary);font-weight:400}.app-body{flex:1;overflow:hidden}.split-pane{display:flex;height:100%;width:100%}.split-left,.split-right{height:100%;overflow:hidden;position:relative}.split-handle{width:4px;cursor:col-resize;background:var(--border-color);flex-shrink:0}.split-handle:hover{background:var(--accent)}.expand-bar{width:24px;height:100%;flex-shrink:0;display:flex;align-items:center;justify-content:center;background:var(--bg-secondary);border:none;border-left:1px solid var(--border-color);border-right:1px solid var(--border-color);color:var(--text-muted);cursor:pointer;padding:0;font-family:inherit}.expand-bar:hover{background:var(--bg-hover);color:var(--accent)}.header-controls{display:flex;align-items:center;gap:4px}.header-btn{display:flex;align-items:center;justify-content:center;width:32px;height:28px;padding:0;background:transparent;border:1px solid var(--border-color);border-radius:4px;color:var(--text-secondary);cursor:pointer}.header-btn:hover{background:var(--bg-hover);color:var(--text-primary);border-color:var(--accent)}.right-panel{display:flex;flex-direction:column;height:100%}.tab-bar{display:flex;background:var(--bg-secondary);border-bottom:1px solid var(--border-color);overflow-x:auto;flex-shrink:0;height:34px}.tab{display:flex;align-items:center;gap:6px;padding:6px 12px;background:none;border:none;border-bottom:2px solid transparent;color:var(--text-secondary);font-size:12px;cursor:pointer;white-space:nowrap;font-family:inherit}.tab:hover{background:var(--bg-hover);color:var(--text-primary)}.tab-active{color:var(--text-primary);border-bottom-color:var(--accent)}.tab-icon{flex-shrink:0}.tab-label{max-width:120px;overflow:hidden;text-overflow:ellipsis}.tab-close{font-size:14px;line-height:1;opacity:.5;padding:0 2px;border-radius:3px}.tab-close:hover{opacity:1;background:var(--bg-hover)}.remove-architect-modal-backdrop,.confirm-dialog-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:1000}.remove-architect-modal,.confirm-dialog{background:var(--bg-primary, #1e1e1e);color:var(--text-primary, #e0e0e0);border-radius:6px;padding:24px;max-width:500px;width:90%;box-shadow:0 10px 40px #00000080}.remove-architect-modal h2,.confirm-dialog h2{margin:0 0 12px;font-size:18px}.remove-architect-modal p,.confirm-dialog p{margin:0 0 16px;line-height:1.5}.remove-architect-modal code,.confirm-dialog code{background:var(--bg-secondary, #2a2a2a);padding:2px 6px;border-radius:3px;font-family:ui-monospace,monospace}.remove-architect-error{color:var(--text-error, #ff6b6b)}.remove-architect-modal-actions,.confirm-dialog-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:16px}.remove-architect-modal-actions button,.confirm-dialog-actions button{padding:6px 14px;border:1px solid var(--border-color, #444);background:var(--bg-secondary, #2a2a2a);color:var(--text-primary, #e0e0e0);border-radius:4px;cursor:pointer}.remove-architect-modal-actions button:hover:not(:disabled),.confirm-dialog-actions button:hover:not(:disabled){background:var(--bg-hover, #333)}.remove-architect-modal-actions button.primary,.confirm-dialog-actions button.primary{background:var(--accent-color, #f44747);color:#fff;border-color:var(--accent-color, #f44747)}.remove-architect-modal-actions button:disabled,.confirm-dialog-actions button:disabled{opacity:.6;cursor:not-allowed}.tab-content{flex:1;overflow:hidden}.terminal-tab-pane{width:100%;height:100%}.file-path-decoration{border-bottom:1px dotted rgba(255,255,255,.3)!important;background:transparent!important;pointer-events:none}.file-path-decoration-hover{border-bottom-color:#ffffffb3!important}.terminal-iframe{display:block}.file-tree{padding:8px;overflow-y:auto;height:100%}.file-node{display:flex;align-items:center;gap:6px;padding:3px 0;cursor:pointer;font-size:12px;border-radius:4px}.file-node:hover{background:var(--bg-hover)}.file-icon{font-size:14px;flex-shrink:0}.file-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.file-tree-error,.file-tree-loading{padding:16px;color:var(--text-muted);font-size:12px}.no-architect{display:flex;align-items:center;justify-content:center;height:100%;color:var(--text-muted);font-size:14px}.architect-pane{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;flex-direction:column;min-height:0}.architect-pane-body{flex:1;min-height:0}.virtual-keyboard{display:flex;gap:6px;padding:6px 8px;background:var(--bg-secondary);border-bottom:1px solid var(--border-color);flex-shrink:0}.virtual-key{padding:4px 12px;background:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:4px;color:var(--text-secondary);font-size:12px;font-family:inherit;cursor:pointer;touch-action:manipulation;user-select:none;-webkit-user-select:none}.virtual-key:active{background:var(--bg-hover);color:var(--text-primary)}.virtual-key-active{background:var(--accent);border-color:var(--accent);color:#fff}.virtual-key-active:active{background:var(--accent-hover)}.terminal-controls{position:absolute;top:8px;right:12px;z-index:20;display:flex;align-items:center;gap:4px;padding:4px 6px;background:#1e1e1ed9;border:1px solid rgba(255,255,255,.12);border-radius:8px}.terminal-control-btn{display:flex;align-items:center;justify-content:center;min-width:32px;min-height:32px;padding:0;background:transparent;border:1px solid transparent;border-radius:5px;color:silver;cursor:pointer;touch-action:manipulation;user-select:none;-webkit-user-select:none}.terminal-control-btn:hover{background:#ffffff1a;border-color:#ffffff26;color:#fff}.terminal-control-btn:active{background:#ffffff26}.toolbar-divider{width:1px;height:20px;background:#ffffff26;margin:0 2px;flex-shrink:0}.terminal-status-icon{cursor:default}.terminal-status-icon.terminal-status-connected{color:#22c55e;opacity:.7}.terminal-status-icon.terminal-status-reconnecting{color:#eab308;opacity:.8;animation:terminal-pulse 1.2s ease-in-out infinite}.terminal-status-icon.terminal-status-disconnected{color:#ef4444;opacity:.8}@keyframes terminal-pulse{0%,to{opacity:.8}50%{opacity:.2}}.mobile-layout{display:flex;flex-direction:column;height:100vh}.mobile-content{flex:1;overflow:hidden;display:flex;flex-direction:column}@media(max-width:768px){.app-header{padding:6px 12px}.tab{padding:4px 8px;font-size:11px}}.file-viewer{display:flex;flex-direction:column;height:100%;background:var(--bg-primary)}.file-loading,.file-error{display:flex;align-items:center;justify-content:center;height:100%;color:var(--text-secondary)}.file-error{color:var(--status-error)}.file-header{display:flex;align-items:center;gap:12px;padding:8px 12px;background:var(--bg-secondary);border-bottom:1px solid var(--border-color);flex-shrink:0}.file-path{font-family:monospace;font-size:12px;color:var(--text-primary);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.file-language{font-size:11px;color:var(--text-muted);text-transform:uppercase}.file-save-btn{padding:4px 12px;font-size:11px;background:var(--accent);color:#fff;border:none;border-radius:4px;cursor:pointer}.file-save-btn:hover{background:var(--accent-hover)}.file-save-btn:disabled{opacity:.5;cursor:not-allowed}.file-content{display:flex;flex:1;overflow:auto;background:var(--bg-primary)}.line-numbers{display:flex;flex-direction:column;padding:12px 8px;background:var(--bg-secondary);color:var(--text-muted);font-family:Menlo,Monaco,Courier New,monospace;font-size:13px;line-height:1.5;text-align:right;-webkit-user-select:none;user-select:none;flex-shrink:0;min-width:40px}.line-number{padding-right:8px}.line-number.highlighted-line{background:#3b82f64d}.file-text{flex:1;padding:12px;font-family:Menlo,Monaco,Courier New,monospace;font-size:13px;line-height:1.5;background:var(--bg-primary);color:var(--text-primary);border:none;outline:none;resize:none;white-space:pre;overflow:auto}.file-image-container,.file-video-container{flex:1;display:flex;align-items:center;justify-content:center;overflow:auto;padding:20px}.file-image{max-width:100%;max-height:100%;object-fit:contain}.file-video{max-width:100%;max-height:100%}.file-tree-container{display:flex;flex-direction:column;height:100%;overflow:hidden}.file-search{position:relative;padding:8px;border-bottom:1px solid var(--border-color);flex-shrink:0}.file-search-input{width:100%;padding:6px 10px;font-size:12px;font-family:inherit;background:var(--bg-primary);border:1px solid var(--border-color);border-radius:4px;color:var(--text-primary);outline:none}.file-search-input:focus{border-color:var(--accent)}.file-search-input::placeholder{color:var(--text-muted)}.file-search-suggestions{position:absolute;top:100%;left:8px;right:8px;background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:4px;box-shadow:0 4px 12px #0000004d;z-index:100;max-height:240px;overflow-y:auto}.file-search-suggestion{display:flex;flex-direction:column;padding:8px 10px;cursor:pointer;border-bottom:1px solid var(--border-color)}.file-search-suggestion:last-child{border-bottom:none}.file-search-suggestion:hover{background:var(--bg-hover)}.suggestion-name{font-size:12px;color:var(--text-primary);font-weight:500}.suggestion-path{font-size:10px;color:var(--text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.file-tree-section{display:flex;flex-direction:column;overflow:hidden}.file-tree-section:first-of-type{flex-shrink:0}.file-tree-section:last-of-type{flex:1;overflow:hidden}.file-tree-section-header{padding:8px 12px;font-size:11px;font-weight:600;text-transform:uppercase;color:var(--text-muted);letter-spacing:.5px;border-bottom:1px solid var(--border-color);flex-shrink:0}.recent-file{color:var(--text-secondary)}.recent-file:hover{color:var(--text-primary)}.file-path-hint{font-size:10px;color:var(--text-muted);margin-left:auto;max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.git-indicator{font-family:monospace;font-size:10px;font-weight:700;padding:1px 4px;border-radius:3px;margin-left:auto;flex-shrink:0}.git-modified{color:var(--status-implementing);background:#f9731626}.git-staged{color:var(--status-active);background:#22c55e26}.git-untracked{color:var(--text-muted);background:#66666626}.cloud-status{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--text-secondary);margin-right:12px}.cloud-status--none{color:var(--text-muted)}.cloud-status--error{color:var(--status-error)}.cloud-dot{display:inline-block;width:8px;height:8px;border-radius:50%;flex-shrink:0}.cloud-dot--green{background:var(--status-active)}.cloud-dot--yellow{background:var(--status-waiting);animation:cloud-pulse 1.2s ease-in-out infinite}@keyframes cloud-pulse{0%,to{opacity:1}50%{opacity:.3}}.cloud-dot--red{background:var(--status-error)}.cloud-dot--gray{background:var(--text-muted)}.cloud-uptime{color:var(--text-muted);font-size:11px}.held-badge-wrapper{position:relative;display:inline-flex}.held-badge{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--text-secondary);white-space:nowrap;background:none;border:none;padding:0;font-family:inherit;cursor:pointer;text-decoration:underline dotted;text-underline-offset:3px}.held-badge:hover{color:var(--text-primary);text-decoration:underline solid}.held-badge:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:3px}.held-badge--attention{color:var(--status-waiting);font-weight:600}.held-popover{position:absolute;top:calc(100% + 8px);right:0;z-index:1000;min-width:280px;max-width:380px;max-height:320px;overflow-y:auto;padding:10px 12px;background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:6px;box-shadow:0 8px 24px #00000059;font-size:12px;text-align:left;cursor:default}.held-popover-note{margin:0;color:var(--text-secondary)}.held-popover-note--error{color:var(--status-error)}.held-group+.held-group{margin-top:12px;padding-top:10px;border-top:1px solid var(--border-color)}.held-group-title{margin:0 0 6px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted)}.held-group-note{margin:-2px 0 6px;font-size:11px;font-style:italic;color:var(--text-muted)}.held-list{margin:0;padding:0;list-style:none}.held-row{display:flex;flex-direction:column;gap:1px;padding:4px 0}.held-row+.held-row{border-top:1px solid var(--border-color)}.held-row-addresses{color:var(--text-primary);font-family:ui-monospace,monospace;word-break:break-word}.held-row-meta{font-size:11px;color:var(--text-muted)}.held-row--attention .held-row-meta{color:var(--status-waiting);font-weight:600}.held-popover-foot{margin:10px 0 0;padding-top:8px;border-top:1px solid var(--border-color);font-size:11px;color:var(--text-muted)}.held-popover-foot code{font-family:ui-monospace,monospace;font-size:11px}.held-dot{display:inline-block;width:8px;height:8px;border-radius:50%;flex-shrink:0;background:var(--text-muted)}.held-dot--attention{background:var(--status-waiting);animation:cloud-pulse 1.2s ease-in-out infinite}.cloud-hint{color:var(--text-muted);font-size:11px;font-style:italic}.cloud-link{color:var(--accent);text-decoration:none;font-size:11px}.cloud-link:hover{text-decoration:underline}.cloud-btn{background:transparent;border:1px solid var(--border-color);color:var(--text-secondary);font-size:11px;padding:1px 6px;border-radius:3px;cursor:pointer}.cloud-btn:hover{background:var(--bg-hover);color:var(--text-primary)}.cloud-btn:disabled{opacity:.5;cursor:default}.mobile-wrapper{display:flex;flex-direction:column;height:100vh}.mobile-header{padding:4px 8px;border-bottom:1px solid var(--border-color);background:var(--bg-primary)}.mobile-wrapper .mobile-layout{flex:1;min-height:0}.work-view{display:flex;flex-direction:column;height:100%;overflow:hidden}.work-content{flex:1;overflow-y:auto;padding:12px 16px}.work-view.file-panel-open .work-content{flex:2}.work-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}.work-title{font-size:19px;font-weight:600;color:var(--text-primary)}.work-actions{display:flex;gap:6px}.work-btn{background:var(--accent);color:#fff;border:none;padding:4px 10px;border-radius:4px;font-size:14px;cursor:pointer}.work-btn:hover{background:var(--accent-hover)}.work-btn-secondary{background:transparent;border:1px solid var(--border-color);color:var(--text-secondary)}.work-btn-secondary:hover{background:var(--bg-hover);color:var(--text-primary)}.tip-banner{display:flex;align-items:center;gap:8px;padding:6px 12px;margin-bottom:16px;background:var(--bg-tertiary);border-radius:4px;font-size:14px;color:var(--text-secondary)}.tip-banner-label{font-weight:600;color:var(--text-muted);white-space:nowrap}.tip-banner-text{flex:1;min-width:0}.tip-banner-text code{font-family:var(--font-mono, monospace);background:var(--bg-primary);padding:1px 4px;border-radius:2px;font-size:13px;color:var(--text-primary)}.tip-banner-nav{background:none;border:none;color:var(--text-muted);cursor:pointer;padding:2px 4px;font-size:14px;line-height:1;border-radius:2px}.tip-banner-nav:hover{color:var(--text-primary);background:var(--bg-hover)}.tip-banner-dismiss{background:none;border:none;color:var(--text-muted);cursor:pointer;padding:2px 4px;font-size:14px;line-height:1;border-radius:2px;margin-left:4px}.tip-banner-dismiss:hover{color:var(--text-primary);background:var(--bg-hover)}.work-section{margin-bottom:20px}.work-section-title{font-size:13px;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.5px;margin-bottom:8px;display:flex;align-items:center;gap:6px}.work-empty{color:var(--text-muted);font-style:italic;font-size:14px;padding:8px 0}.work-unavailable{color:var(--status-waiting);font-size:14px;padding:8px 0}.work-error{color:var(--status-error);font-size:14px;padding:8px;margin-bottom:12px;background:#ef44441a;border-radius:4px}.work-loading{color:var(--text-muted);padding:16px}.builder-table{width:100%;border-collapse:separate;border-spacing:0 4px}.builder-table thead th{font-size:13px;font-weight:500;color:var(--text-secondary);text-align:left;padding:0 10px 4px;white-space:nowrap}.builder-row td{background:var(--bg-secondary);padding:8px 10px;font-size:16px;border-top:1px solid var(--border-color);border-bottom:1px solid var(--border-color)}.builder-row td:first-child{border-left:1px solid var(--border-color);border-radius:8px 0 0 8px}.builder-row td:last-child{border-right:1px solid var(--border-color);border-radius:0 8px 8px 0}.builder-row:hover td{border-color:var(--accent)}.builder-row--blocked td:first-child{border-left:3px solid var(--status-waiting)}.builder-col-id{font-weight:500;color:var(--accent);white-space:nowrap;min-width:60px}.builder-attribution{font-size:.9em;color:var(--text-secondary);font-weight:400}.builder-col-title{color:var(--text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:0;width:40%}.builder-col-state{white-space:nowrap;width:140px}.builder-state-active{font-size:14px;color:var(--accent)}.builder-state-blocked{font-size:14px;color:var(--status-waiting)}.builder-col-progress{width:120px;white-space:nowrap}.progress-bar{width:80px;height:4px;background:var(--bg-tertiary);border-radius:2px;overflow:hidden;display:inline-block;vertical-align:middle}.progress-fill{height:100%;background:var(--status-active);border-radius:2px;transition:width .3s ease}.progress-fill--blocked{background:var(--status-waiting)}.progress-pct{font-size:13px;color:var(--text-secondary);margin-left:6px;vertical-align:middle}.builder-col-elapsed{font-size:14px;color:var(--text-secondary);white-space:nowrap;width:70px}.builder-col-actions{width:60px;text-align:right}.builder-row-open{font-size:13px;color:var(--accent);background:#3b82f614;border:1px solid rgba(59,130,246,.2);padding:3px 10px;border-radius:5px;cursor:pointer;white-space:nowrap}.builder-row-open:hover{background:#3b82f62e}.pr-rows{display:flex;flex-direction:column;gap:4px}a.pr-row{text-decoration:none;color:inherit;cursor:pointer}.pr-row{display:flex;align-items:center;gap:10px;background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:8px;padding:10px 14px}.pr-row:hover{border-color:var(--accent)}.pr-row-number{font-size:16px;font-weight:500;color:var(--accent);white-space:nowrap}.pr-row-title{flex:1;font-size:16px;color:var(--text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pr-row-status{font-size:13px;white-space:nowrap}.pr-status--approved{color:var(--status-active)}.pr-status--reviewing{color:var(--status-waiting)}.pr-status--changes{color:var(--status-error)}.pr-row-age{font-size:13px;color:var(--text-muted);white-space:nowrap}.pr-row-author{font-size:12px;color:var(--text-muted);white-space:nowrap}.attention-rows{display:flex;flex-direction:column;gap:4px}a.attention-row{text-decoration:none;color:inherit;cursor:pointer}.attention-row{display:flex;align-items:center;gap:10px;background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:8px;padding:10px 14px}.attention-row:hover{border-color:var(--accent)}.attention-row-id{font-size:16px;font-weight:500;color:var(--accent);white-space:nowrap}.attention-row-title{flex:1;font-size:16px;color:var(--text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.attention-row-kind{font-size:13px;white-space:nowrap}.attention-kind--pr{color:var(--status-waiting)}.attention-kind--spec,.attention-kind--plan{color:var(--status-error)}.attention-kind--dev{color:var(--status-implementing)}.attention-kind--verify{color:var(--status-waiting)}.attention-row-age{font-size:13px;color:var(--text-muted);white-space:nowrap}.backlog-rows{display:flex;flex-direction:column;gap:2px}.backlog-row{display:flex;align-items:center;gap:6px;padding:4px 14px;border-radius:6px}.backlog-row:hover{background:var(--bg-secondary)}.backlog-row-main{display:flex;align-items:center;gap:10px;flex:1;min-width:0;text-decoration:none;color:inherit}.backlog-row-main:hover .backlog-row-title{color:var(--accent)}.backlog-artifacts{display:flex;gap:4px;flex-shrink:0}.backlog-artifact-link{font-size:12px;padding:1px 5px;border-radius:3px;border:1px solid var(--border-color);background:transparent;color:var(--text-secondary);cursor:pointer;white-space:nowrap}.backlog-artifact-link:hover{background:var(--bg-hover);color:var(--accent);border-color:var(--accent)}.backlog-priority-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}.priority-dot--high{background:var(--status-error)}.priority-dot--med{background:var(--status-waiting)}.priority-dot--low{background:var(--text-muted)}.backlog-row-number{font-size:16px;font-weight:500;color:var(--accent);white-space:nowrap}.backlog-type-tag{font-size:12px;padding:1px 5px;border-radius:3px;font-weight:500;white-space:nowrap}.type-tag--bug{background:#ef444426;color:var(--status-error)}.type-tag--project{background:#a855f71f;color:#a855f7}.type-tag--spike{background:#0ea5e91f;color:#0ea5e9}.backlog-row-title{flex:1;font-size:16px;color:var(--text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.backlog-row-age{font-size:13px;color:var(--text-muted);white-space:nowrap}.backlog-row-author,.backlog-row-assignees{font-size:12px;color:var(--text-muted);white-space:nowrap}.recently-closed-rows{display:flex;flex-direction:column;gap:2px}.recently-closed-row{display:flex;align-items:center;gap:6px;padding:4px 14px;border-radius:6px;opacity:.7}.recently-closed-row:hover{background:var(--bg-secondary);opacity:1}.recently-closed-row-main{display:flex;align-items:center;gap:10px;flex:1;min-width:0;text-decoration:none;color:inherit}.recently-closed-check{font-size:13px;color:var(--status-active);flex-shrink:0}.work-file-panel{border-top:1px solid var(--border-color);background:var(--bg-secondary)}.work-file-panel.expanded{flex:1;display:flex;flex-direction:column;overflow:hidden}.work-file-panel.collapsed{flex-shrink:0}.work-file-panel-header{display:flex;align-items:center;gap:6px;padding:6px 12px;cursor:pointer;-webkit-user-select:none;user-select:none}.work-file-panel-header:hover{background:var(--bg-hover)}.work-file-panel-toggle{font-size:12px;color:var(--text-muted)}.work-file-panel-label{font-size:14px;font-weight:500;color:var(--text-secondary)}.work-file-panel-search{flex:1;margin-left:8px;background:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:3px;color:var(--text-primary);font-size:14px;padding:3px 8px;outline:none}.work-file-panel-search::placeholder{color:var(--text-muted)}.work-file-panel-search:focus{border-color:var(--accent)}.work-file-panel-content{flex:1;overflow-y:auto;padding:0 12px 12px}@media(max-width:768px){.work-content{padding:8px 12px}.work-header{flex-wrap:wrap;gap:8px}.pr-row,.attention-row{flex-wrap:wrap}.builder-table{font-size:14px}.builder-col-elapsed,.builder-table thead th:nth-child(5){display:none}.pr-row-title,.attention-row-title,.backlog-row-title{min-width:60%}}.analytics-view{display:flex;flex-direction:column;height:100%;overflow:hidden}.analytics-content{flex:1;overflow-y:auto;padding:12px 16px}.analytics-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}.analytics-title{font-size:16px;font-weight:600;color:var(--text-primary)}.analytics-actions{display:flex;gap:6px;align-items:center}.analytics-range-selector{display:flex;border:1px solid var(--border-color);border-radius:4px;overflow:hidden}.analytics-range-btn{background:transparent;border:none;border-right:1px solid var(--border-color);padding:3px 8px;font-size:11px;cursor:pointer;color:var(--text-secondary)}.analytics-range-btn:last-child{border-right:none}.analytics-range-btn:hover{background:var(--bg-hover)}.analytics-range-btn.active{background:var(--accent);color:#fff}.analytics-section{margin-bottom:16px}.analytics-section-title{font-size:11px;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.5px;margin-bottom:8px;display:flex;align-items:center;gap:4px}.analytics-collapse-icon{font-size:10px;width:12px;display:inline-block}.analytics-error{color:var(--status-error);font-size:12px;margin-bottom:8px;padding:6px 8px;background:#ef44441a;border-radius:4px}.analytics-loading{color:var(--text-secondary);font-size:13px;padding:20px 0;text-align:center}.analytics-metric-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:8px}.analytics-metric{display:flex;flex-direction:column;padding:8px 10px;background:var(--bg-secondary, var(--bg-hover));border-radius:4px}.analytics-metric-value{font-size:18px;font-weight:600;color:var(--text-primary);line-height:1.2}.analytics-metric-label{font-size:10px;color:var(--text-secondary);margin-top:2px}.analytics-sub-section{margin-top:10px}.analytics-sub-title{font-size:11px;font-weight:500;color:var(--text-secondary);margin-bottom:4px}.analytics-table{width:100%;border-collapse:collapse;font-size:11px}.analytics-table th{text-align:left;color:var(--text-secondary);font-weight:500;padding:3px 6px;border-bottom:1px solid var(--border-color)}.analytics-table td{padding:3px 6px;color:var(--text-primary);border-bottom:1px solid var(--border-subtle, var(--border-color))}.analytics-list{list-style:none;padding:0;margin:0}.analytics-list li{display:flex;justify-content:space-between;padding:2px 0;font-size:12px}.analytics-list-label{color:var(--text-secondary)}.analytics-list-value{color:var(--text-primary);font-weight:500}.analytics-charts-row{display:flex;gap:8px}.analytics-chart-half{flex:1;min-width:0}.team-view{display:flex;flex-direction:column;height:100%;overflow:hidden}.team-content{flex:1;overflow-y:auto;padding:12px 16px}.team-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}.team-title{font-size:16px;font-weight:600;color:var(--text-primary);margin:0}.team-refresh-btn{background:transparent;border:1px solid var(--border-color);border-radius:4px;padding:4px 10px;font-size:11px;color:var(--text-secondary);cursor:pointer}.team-refresh-btn:hover{background:var(--bg-hover);color:var(--text-primary)}.team-refresh-btn:disabled{opacity:.5;cursor:default}.team-error{color:var(--status-error);font-size:12px;margin-bottom:8px;padding:6px 8px;background:#ef44441a;border-radius:4px}.team-loading{color:var(--text-secondary);font-size:13px;padding:20px 0;text-align:center}.team-section{margin-bottom:16px}.team-section-title{font-size:11px;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.5px;margin-bottom:8px}.team-member-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:8px}.team-member-card{background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:6px;padding:10px 12px}.team-member-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:4px}.team-member-name{font-size:13px;font-weight:600;color:var(--text-primary)}.team-member-role{font-size:10px;color:var(--text-muted);background:var(--bg-tertiary);padding:1px 5px;border-radius:3px;text-transform:uppercase;letter-spacing:.3px}.team-member-github{font-size:11px;color:var(--accent);text-decoration:none;display:block;margin-bottom:6px}.team-member-github:hover{text-decoration:underline}.team-member-section{margin-top:6px}.team-section-label{font-size:10px;color:var(--text-muted);text-transform:uppercase;letter-spacing:.3px;display:block;margin-bottom:2px}.team-item-list{display:flex;flex-direction:column}.team-item-link{display:block;font-size:11px;color:var(--accent);text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;padding:1px 0}.team-item-link:hover{text-decoration:underline}.team-item-empty{font-size:11px;color:var(--text-muted);font-style:italic}.team-member-activity{display:flex;gap:8px;font-size:10px;color:var(--text-muted);margin-top:4px}.team-review-blocking-list{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:2px}.team-review-blocking-item{display:flex;align-items:baseline;gap:6px;font-size:11px;line-height:1.3;min-width:0}.team-review-blocking-sentence{flex:1 1 auto;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.team-review-blocking-sentence strong{font-weight:600}.team-review-blocking-link{display:inline;white-space:normal}.team-review-blocking-age{flex:0 0 auto;font-size:10px;color:var(--text-muted);font-style:italic}.team-activity-label{color:var(--text-muted);font-style:italic}.team-messages{display:flex;flex-direction:column;gap:6px}.team-message{padding:8px 10px;background:var(--bg-secondary);border-radius:4px;border-left:2px solid var(--border-color)}.team-message-header{display:flex;align-items:baseline;gap:8px;margin-bottom:4px}.team-message-author{font-size:12px;font-weight:600;color:var(--text-primary)}.team-message-time{font-size:10px;color:var(--text-muted)}.team-message-body{font-size:12px;color:var(--text-secondary);white-space:pre-wrap;word-break:break-word}.team-no-messages{font-size:12px;color:var(--text-muted);padding:8px 0}.team-activity-feed{display:flex;flex-direction:column;gap:2px}.team-activity-entry{display:flex;align-items:baseline;gap:6px;font-size:12px;color:var(--text-secondary);text-decoration:none;padding:4px 8px;border-radius:3px}.team-activity-entry:hover{background:var(--bg-secondary)}.team-activity-date{font-size:10px;color:var(--text-muted);min-width:50px;flex-shrink:0}.team-activity-author{color:var(--accent);flex-shrink:0}.team-activity-action{color:var(--text-muted);flex-shrink:0}.team-activity-ref{color:var(--text-secondary);flex-shrink:0}.team-activity-title{color:var(--text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}.ofs-rows{display:flex;flex-direction:column;gap:2px}.ofs-subgroup-label{font-size:11px;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.05em;padding:4px 14px 2px}.ofs-row{display:flex;align-items:center;gap:8px;padding:5px 14px;border-radius:6px;cursor:pointer;font-size:14px}.ofs-row:hover{background:var(--bg-secondary)}.ofs-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}.ofs-dot--running{background:var(--status-active)}.ofs-dot--idle{background:var(--text-secondary)}.ofs-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ofs-idle{font-size:12px;color:var(--text-secondary);white-space:nowrap}.ofs-file-icon{font-size:14px;flex-shrink:0}.ofs-path{font-size:12px;color:var(--text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🏗️</text></svg>">
|
|
7
7
|
<title>dashboard</title>
|
|
8
|
-
<script type="module" crossorigin src="./assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
8
|
+
<script type="module" crossorigin src="./assets/index-CUIjS_Vb.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="./assets/index-DnYLy5C_.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/commands/inbox.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/commands/inbox.ts"],"names":[],"mappings":"AAuCA,UAAU,gBAAgB;IACxB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,UAAU,mBAAmB;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAuBD,UAAU,gBAAgB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAgDD;;;;;;GAMG;AACH,wBAAsB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyE7E;AAED;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCzF;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAY/F"}
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
import { getTowerClient, DEFAULT_TOWER_PORT } from '../lib/tower-client.js';
|
|
16
16
|
import { logger, fatal } from '../utils/logger.js';
|
|
17
17
|
import { getConfig } from '../utils/config.js';
|
|
18
|
+
import { MAX_SENDER_ID_LENGTH } from '../utils/message-format.js';
|
|
19
|
+
import { formatVerdict } from '@cluesmith/codev-sdk/hold-verdict';
|
|
18
20
|
/** Compact human duration ("5s", "3m", "2h", "1d") from a millisecond delta. */
|
|
19
21
|
function formatDuration(ms) {
|
|
20
22
|
const secs = Math.max(0, Math.floor(ms / 1000));
|
|
@@ -32,6 +34,34 @@ function formatDuration(ms) {
|
|
|
32
34
|
function formatAge(createdAt, now) {
|
|
33
35
|
return formatDuration(now - createdAt);
|
|
34
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Fit `text` into `width`, marking a cut with an ellipsis rather than silently losing the tail
|
|
39
|
+
* (Issue #1482). The REASON column's values are now compound (`busy:no-composer-marker`), and a
|
|
40
|
+
* bare `.slice()` would render one of them as a shorter value that reads like a DIFFERENT
|
|
41
|
+
* verdict. The ellipsis is one character, so the visible prefix is `width - 1`.
|
|
42
|
+
*/
|
|
43
|
+
function truncate(text, width) {
|
|
44
|
+
return text.length <= width ? text : `${text.slice(0, width - 1)}…`;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* One line explaining a gate detail, for `afx inbox show` (Issue #1482).
|
|
48
|
+
*
|
|
49
|
+
* The split that matters to an operator is "will this clear by itself?": `user-text` will (a
|
|
50
|
+
* human is at the composer), the other two will not (the classifier cannot find a bounded
|
|
51
|
+
* composer region at all, so no amount of waiting helps).
|
|
52
|
+
*/
|
|
53
|
+
function describeDetail(detail) {
|
|
54
|
+
switch (detail) {
|
|
55
|
+
case 'user-text':
|
|
56
|
+
return 'a draft or menu occupies the composer; a human is at the line and delivery resumes when it clears';
|
|
57
|
+
case 'no-region-end':
|
|
58
|
+
return 'the composer marker was found but nothing bounds the region below it (a partial frame, or dimensions that do not match the real terminal) — this will not clear on its own';
|
|
59
|
+
case 'no-composer-marker':
|
|
60
|
+
return 'no composer marker on screen at all (a boot/wrapper screen, a drifted app profile, or an unrenderable frame) — this will not clear on its own';
|
|
61
|
+
default:
|
|
62
|
+
return 'unrecognized gate detail';
|
|
63
|
+
}
|
|
64
|
+
}
|
|
35
65
|
/**
|
|
36
66
|
* `afx inbox` — list held messages for a workspace. Workspace-scoped per spec
|
|
37
67
|
* decision 8: defaults to the current workspace (`getConfig().workspaceRoot`);
|
|
@@ -56,21 +86,44 @@ export async function inboxList(options = {}) {
|
|
|
56
86
|
return;
|
|
57
87
|
}
|
|
58
88
|
logger.header(`Held messages (${rows.length})`);
|
|
59
|
-
const widths = [38, 6, 13, 22, 14];
|
|
60
|
-
logger.row(['ID', 'AGE', 'REASON', 'FROM → TO', 'WORKSPACE'], widths);
|
|
61
|
-
logger.row(['─'.repeat(36), '─'.repeat(5), '─'.repeat(12), '─'.repeat(21), '─'.repeat(13)], widths);
|
|
62
89
|
const now = Date.now();
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
90
|
+
// Render the cells first so the FROM → TO column can be sized to its content
|
|
91
|
+
// (issue #1478). That column exists to answer "who sent this, to whom?", and a
|
|
92
|
+
// fixed 22-char slice cut long builder ids and `architect:<name>` senders
|
|
93
|
+
// mid-name — silently rendering an identity the operator can't act on.
|
|
94
|
+
const cells = rows.map((row) => {
|
|
66
95
|
// Spec 1313 round 3: a pre-due delayed (`--delay`) row is SCHEDULED, not stuck — render
|
|
67
96
|
// its due countdown ("→15s") in the AGE column and "scheduled" as the reason, so a delayed
|
|
68
97
|
// send that is simply waiting for its due time is not mistaken for a starving held message.
|
|
69
98
|
const preDue = row.notBefore != null && row.notBefore > now;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
99
|
+
return {
|
|
100
|
+
id: row.id,
|
|
101
|
+
age: preDue ? `→${formatDuration(row.notBefore - now)}` : formatAge(row.createdAt, now),
|
|
102
|
+
reason: preDue
|
|
103
|
+
? 'scheduled'
|
|
104
|
+
: `${formatVerdict(row.reason, row.detail)}${row.escalated ? '!' : ''}`,
|
|
105
|
+
fromTo: `${row.fromAgent ?? '?'} → ${row.toAgent}`,
|
|
106
|
+
workspace: row.workspacePath.split('/').pop() || row.workspacePath,
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
const fromToHeader = 'FROM → TO';
|
|
110
|
+
// Sized to content, so a long-but-legitimate agent id is never cut mid-name (issue
|
|
111
|
+
// #1478 — the old fixed 22 silently truncated them). The ceiling is defence in depth,
|
|
112
|
+
// not the old truncation returning: `POST /api/send` now refuses a sender longer than
|
|
113
|
+
// MAX_SENDER_ID_LENGTH, so a pair of valid ids cannot reach it, and rows persisted
|
|
114
|
+
// before that check existed cannot make every row in the table pad to their width.
|
|
115
|
+
const maxFromToWidth = MAX_SENDER_ID_LENGTH * 2 + ' → '.length;
|
|
116
|
+
const shown = cells.map((c) => c.fromTo.length > maxFromToWidth ? `${c.fromTo.slice(0, maxFromToWidth - 1)}…` : c.fromTo);
|
|
117
|
+
const fromToWidth = Math.max(fromToHeader.length, ...shown.map((c) => c.length)) + 2;
|
|
118
|
+
// REASON is 20 wide, not 13 (Issue #1482): it carries the gate detail as a `reason:detail`
|
|
119
|
+
// sub-code, and `busy:no-region-end` (18) has to fit. Only `busy:no-composer-marker` truncates,
|
|
120
|
+
// and it stays unambiguous at 20 (`busy:no-composer-ma…`).
|
|
121
|
+
const widths = [38, 6, 20, fromToWidth, 14];
|
|
122
|
+
logger.row(['ID', 'AGE', 'REASON', fromToHeader, 'WORKSPACE'], widths);
|
|
123
|
+
logger.row(['─'.repeat(36), '─'.repeat(5), '─'.repeat(19), '─'.repeat(fromToWidth - 1), '─'.repeat(13)], widths);
|
|
124
|
+
cells.forEach((cell, i) => {
|
|
125
|
+
logger.row([cell.id, cell.age, truncate(cell.reason, 20), shown[i], cell.workspace.slice(0, 14)], widths);
|
|
126
|
+
});
|
|
74
127
|
logger.blank();
|
|
75
128
|
logger.info('Show a message body: afx inbox show <id> · Dismiss: afx inbox dismiss <id>');
|
|
76
129
|
}
|
|
@@ -94,6 +147,10 @@ export async function inboxShow(id, options = {}) {
|
|
|
94
147
|
logger.header(`Message ${row.id}`);
|
|
95
148
|
logger.kv('Status', `${row.status}${row.escalated ? ' (escalated)' : ''}`);
|
|
96
149
|
logger.kv('Reason', row.reason ?? '—');
|
|
150
|
+
// Issue #1482: spelled out rather than shown as the list's `reason:detail` sub-code, because
|
|
151
|
+
// this is the view an operator opens when the sub-code is the thing they do not understand.
|
|
152
|
+
if (row.detail)
|
|
153
|
+
logger.kv('Detail', `${row.detail} — ${describeDetail(row.detail)}`);
|
|
97
154
|
logger.kv('From → To', `${from} → ${row.toAgent}`);
|
|
98
155
|
logger.kv('Workspace', row.workspacePath);
|
|
99
156
|
logger.kv('Created', new Date(row.createdAt).toISOString());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../../src/agent-farm/commands/inbox.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,EAAE;AACF,qFAAqF;AACrF,sFAAsF;AACtF,sFAAsF;AACtF,eAAe;AACf,EAAE;AACF,uFAAuF;AACvF,wFAAwF;AACxF,wFAAwF;AACxF,qFAAqF;AACrF,0FAA0F;AAC1F,yFAAyF;AACzF,wFAAwF;AAExF,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../../src/agent-farm/commands/inbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,7 +13,10 @@
|
|
|
13
13
|
* and had to be discovered under pressure.
|
|
14
14
|
*
|
|
15
15
|
* Addressing, workspace detection and sender identity are reused verbatim from
|
|
16
|
-
* `afx send` — there is exactly one address resolver.
|
|
16
|
+
* `afx send` — there is exactly one address resolver. "Verbatim" is literal: the
|
|
17
|
+
* sender comes from `detectCurrentBuilderId()` / `architectSenderId()`, the same two
|
|
18
|
+
* functions `afx send` calls, so one actor has one `from_agent` form across all three
|
|
19
|
+
* commands (issue #1478).
|
|
17
20
|
*/
|
|
18
21
|
import type { InterruptOptions } from '../types.js';
|
|
19
22
|
export declare function interrupt(options: InterruptOptions): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interrupt.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/commands/interrupt.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"interrupt.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/commands/interrupt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAKpD,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDxE"}
|
|
@@ -13,11 +13,14 @@
|
|
|
13
13
|
* and had to be discovered under pressure.
|
|
14
14
|
*
|
|
15
15
|
* Addressing, workspace detection and sender identity are reused verbatim from
|
|
16
|
-
* `afx send` — there is exactly one address resolver.
|
|
16
|
+
* `afx send` — there is exactly one address resolver. "Verbatim" is literal: the
|
|
17
|
+
* sender comes from `detectCurrentBuilderId()` / `architectSenderId()`, the same two
|
|
18
|
+
* functions `afx send` calls, so one actor has one `from_agent` form across all three
|
|
19
|
+
* commands (issue #1478).
|
|
17
20
|
*/
|
|
18
21
|
import { logger, fatal } from '../utils/logger.js';
|
|
19
22
|
import { TowerClient } from '../lib/tower-client.js';
|
|
20
|
-
import { detectWorkspaceRoot, detectCurrentBuilderId } from './send.js';
|
|
23
|
+
import { detectWorkspaceRoot, detectCurrentBuilderId, architectSenderId } from './send.js';
|
|
21
24
|
export async function interrupt(options) {
|
|
22
25
|
const target = options.builder;
|
|
23
26
|
if (!target) {
|
|
@@ -30,7 +33,7 @@ export async function interrupt(options) {
|
|
|
30
33
|
// sender, which Tower would silently route to 'main' (issue #1094).
|
|
31
34
|
let from;
|
|
32
35
|
try {
|
|
33
|
-
from = detectCurrentBuilderId() ??
|
|
36
|
+
from = detectCurrentBuilderId() ?? architectSenderId();
|
|
34
37
|
}
|
|
35
38
|
catch (err) {
|
|
36
39
|
fatal(err instanceof Error ? err.message : String(err));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interrupt.js","sourceRoot":"","sources":["../../../src/agent-farm/commands/interrupt.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"interrupt.js","sourceRoot":"","sources":["../../../src/agent-farm/commands/interrupt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE3F,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAyB;IACvD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAE/B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC;IAEzC,MAAM,SAAS,GAAG,mBAAmB,EAAE,IAAI,SAAS,CAAC;IAErD,uEAAuE;IACvE,wEAAwE;IACxE,oEAAoE;IACpE,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,sBAAsB,EAAE,IAAI,iBAAiB,EAAE,CAAC;IACzD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;IACjC,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC;QAChC,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAChE,CAAC;IAED,IAAI,CAAC;QACH,wEAAwE;QACxE,6EAA6E;QAC7E,wEAAwE;QACxE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE;YACtD,IAAI;YACJ,SAAS;YACT,aAAa,EAAE,SAAS;YACxB,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,eAAe,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,CAAC,OAAO,CAAC,2BAA2B,MAAM,CAAC,UAAU,IAAI,MAAM,EAAE,CAAC,CAAC;QACzE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,CAAC,kFAAkF,CAAC,CAAC;QAClG,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAChE,CAAC;AACH,CAAC"}
|
|
@@ -12,7 +12,10 @@
|
|
|
12
12
|
*
|
|
13
13
|
* Addressing, workspace detection and sender identity are reused verbatim from
|
|
14
14
|
* `afx send` — there is exactly one address resolver (the same rule `afx
|
|
15
|
-
* interrupt` follows).
|
|
15
|
+
* interrupt` follows). "Verbatim" is literal: the sender comes from
|
|
16
|
+
* `detectCurrentBuilderId()` / `architectSenderId()`, the same two functions
|
|
17
|
+
* `afx send` calls, so one actor has one `from_agent` form across all three
|
|
18
|
+
* commands (issue #1478).
|
|
16
19
|
*/
|
|
17
20
|
import type { ResetOptions } from '../types.js';
|
|
18
21
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reset.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/commands/reset.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"reset.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/commands/reset.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAwBH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAUhD;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,8FAC8D,CAAC;AAE9F;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA8GlE"}
|
|
@@ -12,7 +12,10 @@
|
|
|
12
12
|
*
|
|
13
13
|
* Addressing, workspace detection and sender identity are reused verbatim from
|
|
14
14
|
* `afx send` — there is exactly one address resolver (the same rule `afx
|
|
15
|
-
* interrupt` follows).
|
|
15
|
+
* interrupt` follows). "Verbatim" is literal: the sender comes from
|
|
16
|
+
* `detectCurrentBuilderId()` / `architectSenderId()`, the same two functions
|
|
17
|
+
* `afx send` calls, so one actor has one `from_agent` form across all three
|
|
18
|
+
* commands (issue #1478).
|
|
16
19
|
*/
|
|
17
20
|
import { existsSync, readFileSync, writeFileSync, statSync } from 'node:fs';
|
|
18
21
|
import { TowerClient } from '../lib/tower-client.js';
|
|
@@ -24,7 +27,7 @@ import { loadConfig } from '../../lib/config.js';
|
|
|
24
27
|
import { loadForgeConfig } from '../../lib/forge.js';
|
|
25
28
|
import { fetchIssue as fetchForgeIssue } from '../../lib/github.js';
|
|
26
29
|
import { buildPromptFromTemplate, buildResumeNotice } from './spawn-roles.js';
|
|
27
|
-
import { detectWorkspaceRoot, detectCurrentBuilderId } from './send.js';
|
|
30
|
+
import { detectWorkspaceRoot, detectCurrentBuilderId, architectSenderId } from './send.js';
|
|
28
31
|
import { buildContextFsPort, resolveBuilderContext } from './reset/context.js';
|
|
29
32
|
import { formatResetReport, runReset, ResetPreflightError, } from './reset/index.js';
|
|
30
33
|
/**
|
|
@@ -60,7 +63,7 @@ export async function refresh(options) {
|
|
|
60
63
|
const workspace = detectWorkspaceRoot() ?? undefined;
|
|
61
64
|
let from;
|
|
62
65
|
try {
|
|
63
|
-
from = detectCurrentBuilderId() ??
|
|
66
|
+
from = detectCurrentBuilderId() ?? architectSenderId();
|
|
64
67
|
}
|
|
65
68
|
catch (err) {
|
|
66
69
|
fatal(err instanceof Error ? err.message : String(err));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reset.js","sourceRoot":"","sources":["../../../src/agent-farm/commands/reset.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"reset.js","sourceRoot":"","sources":["../../../src/agent-farm/commands/reset.ts"],"names":[],"mappings":"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"}
|
|
@@ -61,6 +61,34 @@ export declare function describeStateDbOpenFailure(dbPath: string, worktreeDirNa
|
|
|
61
61
|
* unverified id silently misroutes `afx send architect` to `main` (#1094).
|
|
62
62
|
*/
|
|
63
63
|
export declare function detectCurrentBuilderId(): string | null;
|
|
64
|
+
/**
|
|
65
|
+
* The sender identity for a message that does NOT originate in a builder worktree:
|
|
66
|
+
* the *specific* architect, as the `architect:<name>` address form (issue #1478).
|
|
67
|
+
*
|
|
68
|
+
* Collapsing every architect sender to the bare string `architect` discarded the one
|
|
69
|
+
* fact both attribution surfaces exist to show — `afx inbox`'s FROM → TO column and
|
|
70
|
+
* the builder's composer header.
|
|
71
|
+
*
|
|
72
|
+
* **Why the env is read directly instead of via `currentArchitectName()`** (whose
|
|
73
|
+
* absent-value default is `main`): Tower injects `CODEV_ARCHITECT_NAME` into EVERY
|
|
74
|
+
* architect terminal it starts — `main` included (`tower-instances.ts` uses
|
|
75
|
+
* `DEFAULT_ARCHITECT_NAME`; the shellper-restart path re-injects `role_id || 'main'`).
|
|
76
|
+
* So a missing value does not mean "the main architect", it means "not an architect
|
|
77
|
+
* terminal" (a plain shell, a script, CI). Defaulting those to `architect:main` would
|
|
78
|
+
* turn today's honest ambiguity into a specific FALSE attribution — precisely the
|
|
79
|
+
* laundering of an unverified identity that #1094 exists to prevent. They keep the bare
|
|
80
|
+
* `architect` they send today, and every real architect terminal gains its name.
|
|
81
|
+
*
|
|
82
|
+
* The name is validated against `ARCHITECT_NAME_PATTERN` before it becomes an identity,
|
|
83
|
+
* so a malformed env value degrades to `architect` rather than travelling into a
|
|
84
|
+
* recipient's composer framing.
|
|
85
|
+
*
|
|
86
|
+
* The address form is deliberate: it is what Tower already accepts as an architect
|
|
87
|
+
* address, it stores directly as the mailbox row's `from_agent`, and it stays outside
|
|
88
|
+
* `looksLikeBuilderId`'s heuristic — so sender-affinity routing and the #1094
|
|
89
|
+
* anti-spoofing warning behave exactly as they did with the generic string.
|
|
90
|
+
*/
|
|
91
|
+
export declare function architectSenderId(): string;
|
|
64
92
|
/**
|
|
65
93
|
* Main send command handler.
|
|
66
94
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/commands/send.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/commands/send.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAgB/C;;;;;;GAMG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAkBnD;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;gBACrC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,CAWxG;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,GAAG,IAAI,CAyDtD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAM1C;AAsGD;;;;;GAKG;AACH,wBAAsB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAmK9D"}
|
|
@@ -15,7 +15,9 @@ import { loadState } from '../state.js';
|
|
|
15
15
|
import { getGlobalDbPath } from '../db/index.js';
|
|
16
16
|
import { normalizeWorkspacePath } from '../utils/workspace-path.js';
|
|
17
17
|
import { TowerClient } from '../lib/tower-client.js';
|
|
18
|
+
import { ARCHITECT_NAME_PATTERN, MAX_ARCHITECT_NAME_LENGTH } from '../utils/architect-name.js';
|
|
18
19
|
import { MAX_MESSAGE_BYTES, messageLimitError } from '../utils/message-format.js';
|
|
20
|
+
import { formatVerdict, isUnverifiableVerdict } from '@cluesmith/codev-sdk/hold-verdict';
|
|
19
21
|
/**
|
|
20
22
|
* `--file` attachment cap. One constant with the message-body ceiling (Issue #1573): the file's
|
|
21
23
|
* content is APPENDED to the message, so two independent numbers could only ever disagree.
|
|
@@ -159,6 +161,40 @@ export function detectCurrentBuilderId() {
|
|
|
159
161
|
gdb.close();
|
|
160
162
|
}
|
|
161
163
|
}
|
|
164
|
+
/**
|
|
165
|
+
* The sender identity for a message that does NOT originate in a builder worktree:
|
|
166
|
+
* the *specific* architect, as the `architect:<name>` address form (issue #1478).
|
|
167
|
+
*
|
|
168
|
+
* Collapsing every architect sender to the bare string `architect` discarded the one
|
|
169
|
+
* fact both attribution surfaces exist to show — `afx inbox`'s FROM → TO column and
|
|
170
|
+
* the builder's composer header.
|
|
171
|
+
*
|
|
172
|
+
* **Why the env is read directly instead of via `currentArchitectName()`** (whose
|
|
173
|
+
* absent-value default is `main`): Tower injects `CODEV_ARCHITECT_NAME` into EVERY
|
|
174
|
+
* architect terminal it starts — `main` included (`tower-instances.ts` uses
|
|
175
|
+
* `DEFAULT_ARCHITECT_NAME`; the shellper-restart path re-injects `role_id || 'main'`).
|
|
176
|
+
* So a missing value does not mean "the main architect", it means "not an architect
|
|
177
|
+
* terminal" (a plain shell, a script, CI). Defaulting those to `architect:main` would
|
|
178
|
+
* turn today's honest ambiguity into a specific FALSE attribution — precisely the
|
|
179
|
+
* laundering of an unverified identity that #1094 exists to prevent. They keep the bare
|
|
180
|
+
* `architect` they send today, and every real architect terminal gains its name.
|
|
181
|
+
*
|
|
182
|
+
* The name is validated against `ARCHITECT_NAME_PATTERN` before it becomes an identity,
|
|
183
|
+
* so a malformed env value degrades to `architect` rather than travelling into a
|
|
184
|
+
* recipient's composer framing.
|
|
185
|
+
*
|
|
186
|
+
* The address form is deliberate: it is what Tower already accepts as an architect
|
|
187
|
+
* address, it stores directly as the mailbox row's `from_agent`, and it stays outside
|
|
188
|
+
* `looksLikeBuilderId`'s heuristic — so sender-affinity routing and the #1094
|
|
189
|
+
* anti-spoofing warning behave exactly as they did with the generic string.
|
|
190
|
+
*/
|
|
191
|
+
export function architectSenderId() {
|
|
192
|
+
const name = process.env.CODEV_ARCHITECT_NAME?.trim();
|
|
193
|
+
if (!name || name.length > MAX_ARCHITECT_NAME_LENGTH || !ARCHITECT_NAME_PATTERN.test(name)) {
|
|
194
|
+
return 'architect';
|
|
195
|
+
}
|
|
196
|
+
return `architect:${name}`;
|
|
197
|
+
}
|
|
162
198
|
/**
|
|
163
199
|
* Read file content for --file flag, with size validation.
|
|
164
200
|
*/
|
|
@@ -219,7 +255,12 @@ async function sendToAll(client, message, workspace, from, options) {
|
|
|
219
255
|
results.scheduled.push(builder.id);
|
|
220
256
|
}
|
|
221
257
|
else if (result.held) {
|
|
222
|
-
results.held.push({
|
|
258
|
+
results.held.push({
|
|
259
|
+
id: builder.id,
|
|
260
|
+
reason: result.reason,
|
|
261
|
+
detail: result.detail, // Issue #1482: which kind of hold, not just that it held
|
|
262
|
+
mailboxId: result.mailboxId,
|
|
263
|
+
});
|
|
223
264
|
}
|
|
224
265
|
else {
|
|
225
266
|
results.delivered.push(builder.id);
|
|
@@ -275,13 +316,15 @@ export async function send(options) {
|
|
|
275
316
|
logger.header('Sending Instruction');
|
|
276
317
|
// Detect workspace for target resolution and sender provenance
|
|
277
318
|
const workspace = detectWorkspaceRoot() ?? undefined;
|
|
278
|
-
// Detect sender identity
|
|
319
|
+
// Detect sender identity: builder ID if in a worktree, otherwise this terminal's
|
|
320
|
+
// architect — `architect:<name>` when the terminal names one, else the bare
|
|
321
|
+
// `architect` (issue #1478; see architectSenderId for why it never guesses a name).
|
|
279
322
|
// In a confirmed builder worktree, detectCurrentBuilderId throws when the
|
|
280
323
|
// canonical id can't be verified — abort loudly here rather than send an
|
|
281
324
|
// unverified `from` that Tower would silently route to 'main' (issue #1094).
|
|
282
325
|
let from;
|
|
283
326
|
try {
|
|
284
|
-
from = detectCurrentBuilderId() ??
|
|
327
|
+
from = detectCurrentBuilderId() ?? architectSenderId();
|
|
285
328
|
}
|
|
286
329
|
catch (err) {
|
|
287
330
|
fatal(err instanceof Error ? err.message : String(err));
|
|
@@ -299,7 +342,9 @@ export async function send(options) {
|
|
|
299
342
|
logger.success(`Delivered to ${results.delivered.length} builder(s): ${results.delivered.join(', ')}`);
|
|
300
343
|
}
|
|
301
344
|
if (results.held.length > 0) {
|
|
302
|
-
const detail = results.held
|
|
345
|
+
const detail = results.held
|
|
346
|
+
.map((h) => `${h.id} (${formatVerdict(h.reason, h.detail, 'pending')})`)
|
|
347
|
+
.join(', ');
|
|
303
348
|
logger.info(`Held for ${results.held.length} builder(s): ${detail}. ` +
|
|
304
349
|
`Each delivers automatically when its prompt is clear.`);
|
|
305
350
|
}
|
|
@@ -337,16 +382,29 @@ export async function send(options) {
|
|
|
337
382
|
logger.info('Persisted and durable across a Tower restart; delivers onto a clear prompt when due. Inspect/cancel: afx inbox.');
|
|
338
383
|
}
|
|
339
384
|
else if (result.held) {
|
|
340
|
-
logger.info(`Message held for ${result.resolvedTo ?? target} (${result.reason
|
|
385
|
+
logger.info(`Message held for ${result.resolvedTo ?? target} (${formatVerdict(result.reason, result.detail, 'pending')})` +
|
|
341
386
|
`${result.mailboxId ? ` — mailbox id ${result.mailboxId}` : ''}. ` +
|
|
342
387
|
`It delivers automatically when the prompt is clear.`);
|
|
388
|
+
// Issue #1482: a hold the gate could not classify will NOT clear on its own, so saying
|
|
389
|
+
// "it delivers automatically" and stopping there would be misleading for exactly the
|
|
390
|
+
// case that needs a human. Say so, once, only for that case.
|
|
391
|
+
if (isUnverifiableVerdict(result.reason, result.detail)) {
|
|
392
|
+
logger.warn(`The render gate could not verify that composer (${result.detail ?? result.reason}), ` +
|
|
393
|
+
`so this hold will not clear by itself — inspect with 'afx inbox'.`);
|
|
394
|
+
}
|
|
343
395
|
}
|
|
344
396
|
else {
|
|
345
397
|
// Issue #1573: report WHAT was sent, not just that a send happened. The failures this
|
|
346
398
|
// echo exists for (#1564: a ~1,900-char message arriving as its final ~30) all read as
|
|
347
399
|
// an unqualified success at the sender.
|
|
348
400
|
const size = result.bodyLength !== undefined ? ` (${result.bodyLength} bytes)` : '';
|
|
349
|
-
|
|
401
|
+
// Issue #1584: say so when the bytes were accepted but the terminal never showed them.
|
|
402
|
+
// Tower records that row as delivered and does NOT re-write it — re-writing is what
|
|
403
|
+
// re-injected one message dozens of times in #1583 — so this line is the only place the
|
|
404
|
+
// sender learns the delivery was unconfirmed. `verified` absent (older Tower, or a body
|
|
405
|
+
// with no header worth matching) keeps today's wording.
|
|
406
|
+
const unverified = result.verified === false ? ' (unverified — header not seen on the terminal)' : '';
|
|
407
|
+
logger.success(`Message delivered to ${result.resolvedTo ?? target}${size}${unverified}`);
|
|
350
408
|
// Issue #1365: an interrupt/escape that gave up waiting for the terminal's submission
|
|
351
409
|
// lock wrote unserialized, so its bytes may have interleaved with the delivery it
|
|
352
410
|
// skipped. The row is claimed `delivered` before the write (un-claiming would risk a
|