vibe-coding-master 0.0.12 → 0.0.13
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 +24 -9
- package/dist/backend/api/round-routes.js +33 -0
- package/dist/backend/api/session-routes.js +2 -0
- package/dist/backend/api/task-routes.js +1 -0
- package/dist/backend/server.js +19 -3
- package/dist/backend/services/app-settings-service.js +2 -1
- package/dist/backend/services/message-service.js +158 -55
- package/dist/backend/services/project-service.js +1 -1
- package/dist/backend/services/round-service.js +227 -0
- package/dist/backend/services/task-service.js +14 -6
- package/dist/backend/templates/harness/architect-agent.js +1 -0
- package/dist/backend/templates/harness/claude-root.js +3 -0
- package/dist/backend/templates/harness/coder-agent.js +1 -0
- package/dist/backend/templates/harness/gitignore.js +2 -1
- package/dist/backend/templates/harness/project-manager-agent.js +3 -0
- package/dist/backend/templates/harness/reviewer-agent.js +1 -0
- package/dist/backend/ws/terminal-ws.js +15 -1
- package/dist/shared/types/round.js +1 -0
- package/dist-frontend/assets/index-CyJrJge9.js +88 -0
- package/dist-frontend/assets/index-N5DA0uE9.css +32 -0
- package/dist-frontend/index.html +2 -2
- package/docs/cc-best-practices.md +7 -4
- package/docs/product-design.md +59 -25
- package/docs/v1-architecture-design.md +86 -27
- package/docs/v1-implementation-plan.md +74 -12
- package/package.json +1 -1
- package/dist-frontend/assets/index-Bi4X3GSR.css +0 -32
- package/dist-frontend/assets/index-DaHXq14j.js +0 -88
|
@@ -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{color-scheme:light;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;background:#f5f2ea;color:#1c2024;line-height:1.5}html,body,#root{height:100%}*{box-sizing:border-box}body{margin:0;min-width:320px;min-height:100vh;background:#f5f2ea}button,input,select,textarea{font:inherit}button{border:1px solid #9ba6ad;background:#f8f7f2;color:#1d252b;border-radius:6px;min-height:34px;padding:6px 10px;cursor:pointer}button:hover:not(:disabled){background:#eef4f2;border-color:#607d74}button:disabled{cursor:not-allowed;opacity:.55}.danger-button{border-color:#b84a45;background:#fff1ee;color:#8d211d;font-weight:750}.danger-button:hover:not(:disabled){border-color:#8d211d;background:#ffe2dc}input,select,textarea:not(.xterm-helper-textarea){width:100%;border:1px solid #b9b0a1;border-radius:6px;background:#fffdf8;color:#202326;padding:8px 10px}textarea:not(.xterm-helper-textarea){min-height:240px;resize:vertical;font-family:Menlo,Monaco,Consolas,monospace;font-size:12px}h1,h2,p{margin-top:0}h1{margin-bottom:4px;font-size:26px;line-height:1.15}h2{margin-bottom:10px;font-size:14px;letter-spacing:0}.app-shell{display:grid;grid-template-columns:minmax(280px,320px) minmax(0,1fr);height:100vh;min-height:0;overflow:hidden}.app-shell.is-sidebar-collapsed{grid-template-columns:46px minmax(0,1fr)}.app-sidebar{position:relative;min-width:0;border-right:1px solid #d3c9b8;background:#fbfaf6;padding:14px;overflow:auto}.app-shell.is-sidebar-collapsed .app-sidebar{overflow:hidden;padding:8px}.sidebar-toggle{position:absolute;top:10px;right:10px;z-index:2;display:grid;place-items:center;width:28px;min-height:28px;padding:0;background:#fffdf8}.sidebar-toggle:before{width:8px;height:8px;border-color:currentColor;border-style:solid;border-width:0 2px 2px 0;content:"";transform:translate(2px) rotate(135deg)}.app-shell.is-sidebar-collapsed .sidebar-toggle{left:9px;right:auto}.app-shell.is-sidebar-collapsed .sidebar-toggle:before{transform:translate(-2px) rotate(-45deg)}.sidebar-content{min-width:0}.app-shell.is-sidebar-collapsed .sidebar-content{width:0;opacity:0;pointer-events:none}.app-main{min-width:0;height:100%;padding:14px 16px;overflow:auto}.brand-header{display:flex;gap:12px;align-items:baseline;margin-bottom:10px;padding-right:34px}.brand-header strong{font-size:18px}.brand-header span,.muted,.workspace-branch,.workspace-worktree{color:#667071;font-size:13px}.sidebar-section{margin-bottom:8px;border:1px solid #e0d6c7;border-radius:8px;background:#fffdfa;overflow:hidden}.sidebar-section-toggle{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:center;width:100%;min-height:34px;border:0;border-radius:0;background:transparent;color:#1c2024;font-size:13px;font-weight:750;text-align:left}.sidebar-section-toggle:hover{background:#f5f1e8}.sidebar-section-toggle[aria-expanded=true]{border-bottom:1px solid #ece5d9}.sidebar-section-chevron{width:8px;height:8px;border-color:currentColor;border-style:solid;border-width:0 2px 2px 0;transform:rotate(45deg)}.sidebar-section-toggle[aria-expanded=true] .sidebar-section-chevron{transform:rotate(-135deg)}.sidebar-section-content{padding:8px}.repo-connect,.project-summary,.harness-panel,.task-create{margin:0}.inline-form{display:grid;grid-template-columns:minmax(0,1fr);gap:8px}.inline-form.has-recent-paths{grid-template-columns:minmax(0,1fr) auto}.inline-form>input{grid-column:1 / -1}.inline-form>button{justify-self:end}.inline-form.has-recent-paths>button{justify-self:auto}.repo-recent-select{min-width:0;max-width:none}.project-summary dl{display:grid;gap:8px;margin:0}.project-summary div{min-width:0}.project-summary dt{color:#6c6255;font-size:12px}.project-summary dd{margin:0;overflow-wrap:anywhere;font-size:13px}.warnings,.error-banner{border:1px solid #c87b54;background:#fff4ed;color:#6f3218;border-radius:6px;padding:10px 12px}.round-notice{position:fixed;right:20px;bottom:20px;z-index:30;display:grid;gap:2px;min-width:220px;max-width:min(360px,calc(100vw - 40px));border:1px solid #2f6f73;border-radius:8px;background:#e8f4f2;color:#123f43;box-shadow:0 14px 32px #1f242b29;padding:10px 12px}.round-notice strong{font-size:13px}.round-notice span{font-size:12px}.warnings{margin:12px 0 0;padding-left:26px;font-size:13px}.harness-panel{display:grid;gap:8px}.harness-panel-header{display:flex;justify-content:space-between;gap:8px;align-items:center}.harness-panel-header h2,.harness-panel-header p,.harness-result p{margin-bottom:0}.harness-actions{display:flex;flex-wrap:wrap;gap:6px;justify-content:flex-end}.harness-file-list{display:grid;gap:6px;margin:0;padding:0;list-style:none}.harness-file-list li{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:center;border:1px solid #ece5d9;border-radius:6px;padding:6px 8px;background:#fffdfa}.harness-file-list span{overflow:hidden;font-size:12px;font-weight:650;text-overflow:ellipsis;white-space:nowrap}.harness-changes,.harness-result{border:1px solid #e0d6c7;border-radius:6px;padding:8px;background:#f8f7f2;font-size:12px}.harness-changes h3{margin:0 0 4px;font-size:12px}.harness-changes ul,.harness-result ul{margin:0;padding-left:18px}.task-create form{display:grid;gap:8px}.task-create-preview{display:grid;gap:2px;border:1px solid #e0d6c7;border-radius:6px;background:#f8f7f2;padding:6px 8px}.task-create-option{display:flex;align-items:center;gap:8px;color:#1f242b;font-size:13px;font-weight:700}.task-create-option input{width:16px;height:16px;margin:0}.task-create-preview span{color:#255f3d;font-size:12px;font-weight:700}.task-create-preview small{overflow:hidden;color:#687273;font-size:11px;text-overflow:ellipsis;white-space:nowrap}.task-nav{display:grid;gap:8px}.task-nav-item{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:center;text-align:left}.task-nav-item.is-active,.role-tab.is-active{border-color:#2f6f73;background:#e8f1ef}.sidebar-settings{display:grid;gap:8px}.sidebar-settings button{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:center;width:100%;text-align:left}.sidebar-settings .settings-toggle.is-active{border-color:#2f6f73;background:#e8f1ef}.sidebar-settings .theme-mode-toggle span:last-child{font-weight:750}.workspace-header{display:grid;grid-template-columns:minmax(180px,auto) minmax(420px,1fr) auto auto;gap:16px;align-items:center;margin-bottom:6px}.workspace-title-line{display:flex;flex-wrap:wrap;gap:10px;align-items:baseline;min-width:0}.workspace-title-line h1{margin-bottom:0;font-size:18px;line-height:1.15}.workspace-branch{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.workspace-worktree{max-width:260px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.eyebrow{color:#7a5c2f;font-size:12px;font-weight:700;text-transform:uppercase}.role-tabs{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;margin-bottom:8px;min-width:0}.workspace-header .role-tabs{margin-bottom:0}.role-tab{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px;align-items:center;min-height:30px;padding:4px 8px;text-align:left}.workflow-panel{display:grid;gap:8px;margin:0}.workflow-summary p{margin-bottom:0}.workflow-summary p{color:#4f5558;font-size:13px}.workflow-steps{display:grid;grid-template-columns:minmax(0,1fr);gap:6px;margin:0;padding:0;list-style:none}.workflow-steps li{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px;align-items:center;min-height:28px;border:1px solid #ece5d9;border-radius:6px;padding:4px 6px;background:#fffdfa}.workflow-steps li.is-current{border-color:#2f6f73;background:#e8f1ef}.workflow-steps span{overflow:hidden;color:#394246;font-size:12px;font-weight:650;text-overflow:ellipsis;white-space:nowrap}.workspace-grid{display:grid;grid-template-columns:minmax(0,1fr);flex:1;gap:10px;align-items:stretch;min-height:0}.workspace-main{min-width:0;min-height:0;display:flex;flex-direction:column;gap:8px}.role-console-stack{min-width:0;min-height:0;flex:1;display:flex;flex-direction:column}.role-console-panel{min-width:0;min-height:0;flex:1;display:none}.role-console-panel.is-active{display:flex;flex-direction:column}.session-console,.message-panel,.event-log,.empty-workspace{border:1px solid #d6d0c6;border-radius:8px;background:#fffdf8;padding:10px}.task-workspace{display:flex;flex-direction:column;gap:8px;height:100%;min-height:0}.session-console{display:grid;grid-template-rows:auto minmax(0,1fr);gap:8px;flex:1;height:100%;min-height:0}.session-console-top{display:flex;gap:10px;align-items:center;justify-content:space-between}.session-console-actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center;justify-content:flex-end}.session-controls{display:flex;flex-wrap:wrap;gap:8px;align-items:center;justify-content:space-between;margin:0 0 8px}.permission-mode-field{display:grid;grid-template-columns:auto minmax(180px,260px);gap:8px;align-items:center;width:fit-content;max-width:100%}.permission-mode-field span{color:#5f6a6c;font-size:13px;font-weight:650}.permission-mode-field small{display:block;color:#7b8587;font-size:11px;font-weight:500;line-height:1.2}.permission-mode-field select{width:100%;min-height:30px;border:1px solid #b9b0a1;border-radius:6px;background:#fffdf8;color:#202326;padding:4px 8px}.session-toolbar{display:flex;flex-wrap:wrap;gap:6px;justify-content:flex-end}.session-toolbar button{min-height:30px;padding:4px 9px}.translation-toggle{display:inline-flex;align-items:center;justify-content:center;min-height:28px;border:1px solid #b5bec4;border-radius:6px;background:#fffefa;color:#4f5558;font-size:12px;font-weight:650;padding:3px 10px;white-space:nowrap}.translation-toggle.is-active{border-color:#2f7e84;background:#e8f4f2;color:#145e64}.translation-settings-grid input[type=checkbox]{width:auto}.session-console-body{display:grid;grid-template-columns:minmax(0,1fr);min-width:0;min-height:0;height:100%}.session-console-body.has-translation{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:10px;align-items:stretch}.terminal-pane,.translation-pane{display:grid;min-width:0;min-height:0;height:100%}.terminal-frame,.terminal-empty{width:100%;height:100%;min-height:0;border-radius:6px;overflow:hidden;background:#111316}.terminal-empty{display:grid;place-items:center;align-content:center;gap:8px;color:#d6d0c6;border:1px solid #292d31}.translation-panel{display:grid;grid-template-rows:auto minmax(0,1fr) auto;gap:8px;height:100%;min-height:0;border:1px solid #292d31;border-radius:6px;background:#0d1117;color:#d6deeb;padding:8px;min-width:0;width:100%;overflow:hidden;font-family:Menlo,Monaco,Consolas,monospace}.translation-panel-header{display:grid;gap:3px}.translation-panel-titlebar,.translation-panel-actions,.translation-status-row{display:flex;flex-wrap:wrap;gap:6px;align-items:center;justify-content:space-between}.translation-panel-header h2,.translation-panel-header p{margin-bottom:0}.translation-panel-titlebar h2{font-size:16px}.translation-panel-header p,.translation-composer span{color:#8b949e;font-size:12px}.translation-panel-actions button{border-color:#3a4149;background:#161b22;color:#d6deeb;min-height:26px;padding:2px 8px;font-size:12px}.translation-panel-actions button:hover:not(:disabled),.translation-composer-actions button:hover:not(:disabled){border-color:#58a6ff;background:#1f2937}.translation-panel-actions .auto-send-toggle.is-active{border-color:#56d364;background:#12261a;color:#d6deeb}.translation-panel-actions{justify-content:flex-end}.translation-status-row{flex-wrap:nowrap}.translation-status-row p:last-child{flex:0 0 auto;text-align:right}.translation-entry-list{display:grid;align-content:start;gap:8px;min-height:0;min-width:0;overflow-x:hidden;overflow-y:auto;scrollbar-color:#4b5563 #0d1117}.translation-entry{border:0;border-radius:0;background:transparent;min-width:0;max-width:100%;padding:0}.translation-entry.is-user-input{border-top:4px solid #3a4149;margin-top:14px;padding-top:14px}.translation-entry.is-user-input:first-child{margin-top:0}.translation-entry pre{box-sizing:border-box;margin:0;max-height:none;max-width:100%;min-width:0;overflow:visible;white-space:pre-wrap;overflow-wrap:anywhere;font-family:Menlo,Monaco,Consolas,monospace;font-size:12px;line-height:1.45;color:#d6deeb}.translation-markdown{max-width:100%;min-width:0;color:#d6deeb;font-size:12px;line-height:1.55;overflow-wrap:anywhere}.translation-markdown>:first-child{margin-top:0}.translation-markdown>:last-child{margin-bottom:0}.translation-markdown p,.translation-markdown ul,.translation-markdown ol,.translation-markdown blockquote,.translation-markdown pre,.translation-markdown table{margin:0 0 8px}.translation-markdown h1,.translation-markdown h2,.translation-markdown h3,.translation-markdown h4,.translation-markdown h5,.translation-markdown h6{margin:10px 0 6px;color:#f0f6fc;font-weight:700;line-height:1.25}.translation-markdown h1{font-size:17px}.translation-markdown h2{font-size:15px}.translation-markdown h3,.translation-markdown h4,.translation-markdown h5,.translation-markdown h6{font-size:13px}.translation-markdown ul,.translation-markdown ol{padding-left:22px}.translation-markdown li{margin:2px 0}.translation-markdown .task-list-item{list-style:none}.translation-markdown input[type=checkbox]{width:13px;height:13px;margin:0 6px 0 0;accent-color:#56d364}.translation-markdown blockquote{border-left:3px solid #3a4149;color:#b7c0ca;padding-left:10px}.translation-markdown a{color:#79c0ff}.translation-markdown code{border-radius:4px;background:#161b22;color:#f0f6fc;padding:1px 4px;font-family:Menlo,Monaco,Consolas,monospace;font-size:.95em}.translation-markdown pre{overflow-x:auto;border:1px solid #292d31;border-radius:6px;background:#111316;padding:8px;white-space:pre}.translation-markdown pre code{background:transparent;padding:0}.translation-markdown table{display:block;max-width:100%;overflow-x:auto;border-collapse:collapse}.translation-markdown img{max-width:100%;border-radius:4px}.translation-markdown th,.translation-markdown td{border:1px solid #30363d;padding:4px 6px;text-align:left;vertical-align:top}.translation-markdown hr{border:0;border-top:1px solid #292d31;margin:10px 0}.translation-entry.is-tool-output pre{display:block;overflow:hidden;color:#7d8590;text-overflow:ellipsis;white-space:nowrap;width:100%}.translation-entry-note{margin:2px 0 0;color:#6e7681;font-size:10px;line-height:1.35}.translation-entry-note.is-error{color:#a3715f}.translation-composer{display:grid;gap:6px;border-top:1px solid #292d31;padding-top:8px}.translation-composer-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:stretch}.translation-composer textarea{width:100%;min-height:38px;max-height:88px;border-color:#3a4149;background:#0d1117;color:#d6deeb;font-family:inherit;font-size:12px;line-height:1.35;resize:vertical}.translation-composer textarea::placeholder{color:#7d8590}.translation-composer textarea::selection{background:#8b949e59;color:#fff}.translation-composer textarea:focus,.translation-composer textarea:focus-visible{border-color:#4b5563;outline:none;box-shadow:none}.translation-composer-actions{display:grid;align-content:start;gap:6px;min-width:104px}.translation-composer-actions button{border-color:#3a4149;background:#161b22;color:#d6deeb;width:100%;min-height:38px;padding:4px 9px;font-size:12px}.translation-panel .muted{color:#8b949e}.translation-panel .error-banner{border-color:#da7b72;background:#2d1518;color:#ffdcd7}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:20;display:grid;place-items:center;background:#181c1f61;padding:18px}.translation-settings-modal{display:grid;gap:12px;width:min(980px,100%);max-height:min(760px,92vh);overflow:auto;border:1px solid #d6d0c6;border-radius:8px;background:#fffdf8;padding:14px}.message-modal,.event-modal{display:grid;grid-template-rows:auto minmax(0,1fr);gap:12px;width:min(980px,100%);max-height:min(760px,92vh);overflow:hidden;border:1px solid #d6d0c6;border-radius:8px;background:#fffdf8;padding:14px}.translation-settings-modal header,.message-modal header,.event-modal header,.translation-settings-modal footer{display:flex;gap:8px;align-items:center;justify-content:space-between}.translation-prompt-settings{display:grid;gap:10px;border-top:1px solid #ece5d9;padding-top:12px}.translation-prompt-settings header{display:flex;gap:10px;align-items:end;justify-content:space-between}.translation-prompt-settings h3,.translation-prompt-settings p{margin-bottom:0}.translation-prompt-settings h3{font-size:13px}.translation-prompt-settings textarea{min-height:120px;max-height:260px;font-family:Menlo,Monaco,Consolas,monospace;font-size:12px}.translation-prompt-stack{display:grid;gap:10px}.translation-prompt-stack label{display:grid;gap:4px}.translation-prompt-stack span{color:#4f5558;font-size:12px;font-weight:650}.translation-settings-modal h2,.message-modal h2,.message-modal p,.event-modal h2,.event-modal p,.translation-settings-modal p{margin-bottom:0}.translation-settings-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.translation-settings-grid label{display:grid;gap:4px}.translation-settings-grid span{color:#4f5558;font-size:12px;font-weight:650}.translation-settings-grid select,.translation-prompt-settings select{min-height:34px;border:1px solid #b9b0a1;border-radius:6px;background:#fffdf8;color:#202326;padding:6px 10px}.translation-test-result{border-radius:6px;padding:8px;font-size:13px}.translation-test-result.is-ok{border:1px solid #6ea77e;background:#e6f3e9;color:#245334}.translation-test-result.is-error{border:1px solid #c46e5f;background:#fae9e6;color:#6f2b21}.message-panel{display:grid;gap:8px}.message-modal .message-panel,.event-modal .event-log{min-height:0;overflow:auto;border:0;background:transparent;padding:0}.message-panel-header{display:flex;justify-content:space-between;gap:12px;align-items:center}.message-panel-header h2,.message-panel-header p{margin-bottom:0}.message-controls,.message-mode-toggle,.message-actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center}.message-mode-toggle{color:#4f5558;font-size:13px;font-weight:650}.message-mode-toggle input{width:auto}.message-list{display:grid;gap:8px;margin:0;padding:0;list-style:none}.message-item{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:10px;align-items:start;border:1px solid #ece5d9;border-radius:6px;padding:8px;background:#fffdfa}.message-meta{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:4px}.message-meta time,.message-meta span:not(.status-badge),.message-reason,.message-path{color:#667071;font-size:12px}.message-sequence{min-width:32px;color:#1f242b;font-weight:800}.message-actions button{min-height:30px;padding:4px 10px}.message-item p{display:-webkit-box;margin-bottom:4px;overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:2}.message-reason,.message-path{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.event-log ol{margin:0;padding-left:22px;font-size:13px}.event-log{max-height:92px;overflow:auto}.event-log h2{margin-bottom:4px;font-size:13px}.event-log p{margin-bottom:0}.event-log li{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.status-badge{display:inline-flex;align-items:center;justify-content:center;min-width:66px;min-height:20px;border-radius:999px;padding:2px 8px;border:1px solid #c7c1b8;background:#f2eee7;color:#4f5558;font-size:11px;white-space:nowrap}.status-running,.status-ok{border-color:#6ea77e;background:#e6f3e9;color:#245334}.status-blocked,.status-crashed,.status-missing,.status-empty{border-color:#c46e5f;background:#fae9e6;color:#6f2b21}.status-waiting,.status-starting,.status-incomplete{border-color:#c4a34e;background:#f7efcf;color:#604e16}.status-exited,.status-done,.status-resumable,.status-staged,.status-delivered,.status-acknowledged{border-color:#7b98b8;background:#e9f0f8;color:#2e4e70}.status-pending_approval,.status-queued,.status-translating,.status-ready,.status-create,.status-insert,.status-update{border-color:#c4a34e;background:#f7efcf;color:#604e16}.status-rejected,.status-failed,.status-cancelled,.status-blocked{border-color:#c46e5f;background:#fae9e6;color:#6f2b21}.status-pending{border-color:#c7c1b8;background:#f2eee7;color:#4f5558}.status-translated,.status-preserved{border-color:#7b98b8;background:#e9f0f8;color:#2e4e70}.empty-workspace{max-width:680px}@media(max-width:980px){.app-shell,.workspace-grid{grid-template-columns:1fr}.app-sidebar{border-right:0;border-bottom:1px solid #d3c9b8}.role-tabs{grid-template-columns:repeat(2,minmax(0,1fr))}.workflow-panel,.workflow-steps,.session-console-body.has-translation,.translation-settings-grid{grid-template-columns:1fr}}@media(max-width:560px){.app-main,.app-sidebar{padding:12px}.workspace-header,.inline-form,.inline-form.has-recent-paths{grid-template-columns:1fr;display:grid}.role-tabs{grid-template-columns:1fr}.terminal-frame,.terminal-empty{min-height:300px;height:54vh}.permission-mode-field{grid-template-columns:1fr;width:100%}}:root[data-theme=dark]{color-scheme:dark;background:#0d1117;color:#e6edf3}:root[data-theme=dark] body,:root[data-theme=dark] .app-main{background:#0d1117;color:#e6edf3}:root[data-theme=dark] button{border-color:#3d4652;background:#161b22;color:#e6edf3}:root[data-theme=dark] button:hover:not(:disabled){border-color:#58a6ff;background:#1f2937}:root[data-theme=dark] input,:root[data-theme=dark] select,:root[data-theme=dark] textarea:not(.xterm-helper-textarea){border-color:#3d4652;background:#0d1117;color:#e6edf3}:root[data-theme=dark] input::placeholder,:root[data-theme=dark] textarea::placeholder{color:#7d8590}:root[data-theme=dark] .danger-button{border-color:#da7b72;background:#2d1518;color:#ffdcd7}:root[data-theme=dark] .danger-button:hover:not(:disabled){border-color:#ffa198;background:#3d1f23}:root[data-theme=dark] .app-sidebar{border-color:#30363d;background:#0f141b}:root[data-theme=dark] .sidebar-toggle{background:#161b22}:root[data-theme=dark] .brand-header span,:root[data-theme=dark] .muted,:root[data-theme=dark] .workspace-branch,:root[data-theme=dark] .workspace-worktree,:root[data-theme=dark] .message-meta time,:root[data-theme=dark] .message-meta span:not(.status-badge),:root[data-theme=dark] .message-reason,:root[data-theme=dark] .message-path{color:#8b949e}:root[data-theme=dark] .sidebar-section,:root[data-theme=dark] .session-console,:root[data-theme=dark] .message-panel,:root[data-theme=dark] .event-log,:root[data-theme=dark] .empty-workspace,:root[data-theme=dark] .translation-settings-modal,:root[data-theme=dark] .message-modal,:root[data-theme=dark] .event-modal{border-color:#30363d;background:#11161d}:root[data-theme=dark] .sidebar-section-toggle{color:#e6edf3}:root[data-theme=dark] .sidebar-section-toggle:hover{background:#161b22}:root[data-theme=dark] .sidebar-section-toggle[aria-expanded=true],:root[data-theme=dark] .translation-prompt-settings{border-color:#30363d}:root[data-theme=dark] .project-summary dt,:root[data-theme=dark] .permission-mode-field span,:root[data-theme=dark] .translation-settings-grid span,:root[data-theme=dark] .translation-prompt-stack span,:root[data-theme=dark] .message-mode-toggle,:root[data-theme=dark] .workflow-summary p{color:#b7c0ca}:root[data-theme=dark] .permission-mode-field small,:root[data-theme=dark] .task-create-preview small{color:#8b949e}:root[data-theme=dark] .warnings,:root[data-theme=dark] .error-banner{border-color:#da7b72;background:#2d1518;color:#ffdcd7}:root[data-theme=dark] .round-notice{border-color:#56d4dd;background:#10262b;color:#d6fbff;box-shadow:0 14px 32px #0104097a}:root[data-theme=dark] .harness-file-list li,:root[data-theme=dark] .harness-changes,:root[data-theme=dark] .harness-result,:root[data-theme=dark] .task-create-preview,:root[data-theme=dark] .workflow-steps li,:root[data-theme=dark] .message-item{border-color:#30363d;background:#0d1117}:root[data-theme=dark] .task-create-option{color:#e6edf3}:root[data-theme=dark] .task-create-preview span{color:#7ee787}:root[data-theme=dark] .workflow-steps span{color:#d6deeb}:root[data-theme=dark] .message-sequence{color:#f0f6fc}:root[data-theme=dark] .eyebrow{color:#d29922}:root[data-theme=dark] .task-nav-item.is-active,:root[data-theme=dark] .role-tab.is-active,:root[data-theme=dark] .workflow-steps li.is-current,:root[data-theme=dark] .sidebar-settings .settings-toggle.is-active,:root[data-theme=dark] .translation-toggle.is-active{border-color:#56d4dd;background:#10262b;color:#d6fbff}:root[data-theme=dark] .translation-toggle{border-color:#3d4652;background:#161b22;color:#b7c0ca}:root[data-theme=dark] .permission-mode-field select,:root[data-theme=dark] .translation-settings-grid select,:root[data-theme=dark] .translation-prompt-settings select{border-color:#3d4652;background:#0d1117;color:#e6edf3}:root[data-theme=dark] .terminal-empty{border-color:#30363d}:root[data-theme=dark] .modal-backdrop{background:#010409b8}:root[data-theme=dark] .message-modal .message-panel,:root[data-theme=dark] .event-modal .event-log{background:transparent}:root[data-theme=dark] .status-badge{border-color:#3d4652;background:#161b22;color:#d6deeb}:root[data-theme=dark] .translation-test-result.is-ok,:root[data-theme=dark] .status-running,:root[data-theme=dark] .status-ok{border-color:#3fb950;background:#12261a;color:#aff5b4}:root[data-theme=dark] .translation-test-result.is-error,:root[data-theme=dark] .status-blocked,:root[data-theme=dark] .status-crashed,:root[data-theme=dark] .status-missing,:root[data-theme=dark] .status-empty,:root[data-theme=dark] .status-rejected,:root[data-theme=dark] .status-failed,:root[data-theme=dark] .status-cancelled{border-color:#f85149;background:#2d1518;color:#ffdcd7}:root[data-theme=dark] .status-waiting,:root[data-theme=dark] .status-starting,:root[data-theme=dark] .status-incomplete,:root[data-theme=dark] .status-pending_approval,:root[data-theme=dark] .status-queued,:root[data-theme=dark] .status-translating,:root[data-theme=dark] .status-ready,:root[data-theme=dark] .status-create,:root[data-theme=dark] .status-insert,:root[data-theme=dark] .status-update{border-color:#d29922;background:#2d2208;color:#f8e3a1}:root[data-theme=dark] .status-exited,:root[data-theme=dark] .status-done,:root[data-theme=dark] .status-resumable,:root[data-theme=dark] .status-staged,:root[data-theme=dark] .status-delivered,:root[data-theme=dark] .status-acknowledged,:root[data-theme=dark] .status-translated,:root[data-theme=dark] .status-preserved{border-color:#388bfd;background:#10223a;color:#c9e2ff}:root[data-theme=dark] .status-pending{border-color:#3d4652;background:#161b22;color:#d6deeb}
|
package/dist-frontend/index.html
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>VibeCodingMaster</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-CyJrJge9.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="/assets/index-N5DA0uE9.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="root"></div>
|
|
@@ -213,6 +213,9 @@ Role-specific behavior lives in `.claude/agents/`.
|
|
|
213
213
|
- The `project-manager` role owns user communication, task routing, role commands, handoff verification, final status reporting, and PR preparation after required gates pass.
|
|
214
214
|
- Do not let one coding session own architecture/plan decisions, implementation, final testing responsibility, and review.
|
|
215
215
|
- Role outputs are exchanged through `.ai/vcm/handoffs/`, not through chat history.
|
|
216
|
+
- Role messaging is turn-based. Keep at most one active message to the same target role.
|
|
217
|
+
- After sending a role message, wait for that role to respond with `vcmctl reply` or `vcmctl result` before sending another message to the same role.
|
|
218
|
+
- If new information appears while a role is still processing, update the handoff artifact or wait instead of sending fragmented follow-up messages.
|
|
216
219
|
- When the required role route includes `architect`, coding must not start until the architecture and plan artifact exists.
|
|
217
220
|
- If the current session was not started with the required role, stop and ask the user to restart with `claude --agent <role>`; do not pretend to be that role inside the wrong session.
|
|
218
221
|
- Critical global rules may be repeated in role agent files for defense in depth, but repeated rules must use stable rule IDs and be checked by `tools/check-agent-rules`. Do not maintain untracked manual copies.
|
|
@@ -959,7 +962,7 @@ Worktree isolation is by task, not by role:
|
|
|
959
962
|
```text
|
|
960
963
|
one task
|
|
961
964
|
-> one branch: feature/<task-slug>
|
|
962
|
-
-> one worktree: .
|
|
965
|
+
-> one worktree: .claude/worktrees/<task-slug>
|
|
963
966
|
-> one handoff directory
|
|
964
967
|
-> architect -> coder -> reviewer in sequence
|
|
965
968
|
```
|
|
@@ -1438,7 +1441,7 @@ Default rule:
|
|
|
1438
1441
|
```text
|
|
1439
1442
|
one task
|
|
1440
1443
|
-> one branch: feature/<task-slug>
|
|
1441
|
-
-> one worktree: .
|
|
1444
|
+
-> one worktree: .claude/worktrees/<task-slug>
|
|
1442
1445
|
-> one handoff directory
|
|
1443
1446
|
-> one PR
|
|
1444
1447
|
```
|
|
@@ -1479,8 +1482,8 @@ Branch rules:
|
|
|
1479
1482
|
- never do AI implementation work directly on the main branch
|
|
1480
1483
|
- one task branch should map to one task worktree
|
|
1481
1484
|
- VCM-managed task branches should use `feature/<task-slug>`
|
|
1482
|
-
- VCM-managed task worktrees should live under `.
|
|
1483
|
-
- `.gitignore` should contain a VCM managed block that ignores `.ai/vcm/`
|
|
1485
|
+
- VCM-managed task worktrees should live under `.claude/worktrees/<task-slug>`
|
|
1486
|
+
- `.gitignore` should contain a VCM managed block that ignores `.ai/vcm/` and `.claude/worktrees/`
|
|
1484
1487
|
- a task should not switch to a different branch/worktree after creation; create a new task instead
|
|
1485
1488
|
- large work should use phase commits on the same task branch unless phases are independently releasable
|
|
1486
1489
|
- if a task becomes too large, split it into child tasks with explicit branch and PR ownership
|
package/docs/product-design.md
CHANGED
|
@@ -91,7 +91,7 @@ feature/<task-name>
|
|
|
91
91
|
Worktree path:
|
|
92
92
|
|
|
93
93
|
```text
|
|
94
|
-
<base-repo>/.
|
|
94
|
+
<base-repo>/.claude/worktrees/<task-name>
|
|
95
95
|
```
|
|
96
96
|
|
|
97
97
|
Example:
|
|
@@ -100,10 +100,10 @@ Example:
|
|
|
100
100
|
base repo: /workspace
|
|
101
101
|
task: docs-cleanup
|
|
102
102
|
branch: feature/docs-cleanup
|
|
103
|
-
worktree: /workspace/.
|
|
103
|
+
worktree: /workspace/.claude/worktrees/docs-cleanup
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
-
The repo's `.gitignore` must ignore `.ai/vcm/`. This is mandatory because the task worktrees live under `.
|
|
106
|
+
The repo's `.gitignore` must ignore `.ai/vcm/` and `.claude/worktrees/`. This is mandatory because the task worktrees live under `.claude/worktrees/`, and the base repository must not see nested worktree files as untracked source files.
|
|
107
107
|
|
|
108
108
|
Task creation flow:
|
|
109
109
|
|
|
@@ -111,11 +111,12 @@ Task creation flow:
|
|
|
111
111
|
New Task submit
|
|
112
112
|
-> validate task name
|
|
113
113
|
-> verify .ai/vcm/ is ignored
|
|
114
|
+
-> verify .claude/worktrees/ is ignored
|
|
114
115
|
-> if Create worktree and branch is selected:
|
|
115
116
|
-> derive branch feature/<task-name>
|
|
116
|
-
-> derive worktree path .
|
|
117
|
+
-> derive worktree path .claude/worktrees/<task-name>
|
|
117
118
|
-> verify the base repo is clean
|
|
118
|
-
-> git worktree add -b feature/<task-name> .
|
|
119
|
+
-> git worktree add -b feature/<task-name> .claude/worktrees/<task-name> <base-ref>
|
|
119
120
|
-> otherwise:
|
|
120
121
|
-> use the connected repo path and current branch
|
|
121
122
|
-> reject if another inline task is already active
|
|
@@ -253,13 +254,15 @@ The old `Dirty: yes/no` label is not used. The UI uses `Working tree: clean` or
|
|
|
253
254
|
`Settings` contains:
|
|
254
255
|
|
|
255
256
|
- `Theme` button, cycling through `System`, `Light`, and `Dark`.
|
|
257
|
+
- `Round alert` button, on by default, controlling the completion prompt and sound.
|
|
256
258
|
- `Messages` button, opening a modal list of role messages.
|
|
257
259
|
- `Events` button, opening a modal list of runtime UI events for the current task.
|
|
258
|
-
- `Auto orchestration` on/off toggle.
|
|
259
260
|
|
|
260
261
|
The default theme mode is `System`, which follows the OS/browser color-scheme preference. The entire application chrome, sidebar, forms, modals, status badges, and workspace panels must support both light and dark rendering. Embedded terminals keep their terminal-native dark styling.
|
|
261
262
|
|
|
262
|
-
|
|
263
|
+
When `Round alert` is on, VCM shows a compact in-app prompt and plays a short local sound after a full conversation round truly ends.
|
|
264
|
+
|
|
265
|
+
There is no separate `Pause orchestration` or `Resume orchestration` control in the GUI. The current product model is one on/off toggle in the active role toolbar, immediately to the left of `Translate`.
|
|
263
266
|
|
|
264
267
|
`VCM Harness` shows whether VCM managed blocks are installed/up to date in the project rules files and `.gitignore`.
|
|
265
268
|
|
|
@@ -268,7 +271,7 @@ There is no separate `Pause orchestration` or `Resume orchestration` control in
|
|
|
268
271
|
- `task name`
|
|
269
272
|
- a `Create worktree and branch` checkbox, selected by default
|
|
270
273
|
- generated branch preview when selected: `feature/<task-name>`
|
|
271
|
-
- generated worktree preview when selected: `.
|
|
274
|
+
- generated worktree preview when selected: `.claude/worktrees/<task-name>`
|
|
272
275
|
- current repository/current branch note when cleared
|
|
273
276
|
|
|
274
277
|
There is no optional title input in the current UI.
|
|
@@ -320,7 +323,28 @@ When translation is on, the console splits horizontally:
|
|
|
320
323
|
|
|
321
324
|
The split should stay close to 50/50 width. Both panes expand vertically to fill the remaining workspace height.
|
|
322
325
|
|
|
323
|
-
## 8.
|
|
326
|
+
## 8. Round Completion Detection
|
|
327
|
+
|
|
328
|
+
VCM detects answer completion from Claude Code transcript JSONL, not from terminal silence.
|
|
329
|
+
|
|
330
|
+
Backend role state:
|
|
331
|
+
|
|
332
|
+
- `tool_use`: role is using tools.
|
|
333
|
+
- `tool_result`: tool is no longer pending.
|
|
334
|
+
- `question`: role is waiting for user input.
|
|
335
|
+
- assistant text with `stop_reason === "end_turn"`: candidate answer end.
|
|
336
|
+
- candidate answer end becomes idle only after no pending tools remain and a short debounce passes.
|
|
337
|
+
|
|
338
|
+
Task-level round state:
|
|
339
|
+
|
|
340
|
+
- If VCM role messages exist, the latest `delivered` or `staged` message defines the current target role.
|
|
341
|
+
- A PM -> Coder -> PM chain completes only when the latest target role, PM, reaches the debounced `end_turn`.
|
|
342
|
+
- Queued or pending messages prevent completion because more role work is waiting.
|
|
343
|
+
- If no VCM role message is involved, the latest direct role answer can complete the round.
|
|
344
|
+
|
|
345
|
+
The frontend polls this task-level round state. It deduplicates `completionId`, then shows the prompt and plays the sound only once per completed round.
|
|
346
|
+
|
|
347
|
+
## 9. Session Lifecycle
|
|
324
348
|
|
|
325
349
|
Buttons:
|
|
326
350
|
|
|
@@ -350,7 +374,7 @@ VCM persists:
|
|
|
350
374
|
- pid when running
|
|
351
375
|
- log path
|
|
352
376
|
|
|
353
|
-
##
|
|
377
|
+
## 10. Harness Installation
|
|
354
378
|
|
|
355
379
|
On repository connect, VCM checks:
|
|
356
380
|
|
|
@@ -378,10 +402,11 @@ For `.gitignore`, VCM uses hash comments:
|
|
|
378
402
|
```gitignore
|
|
379
403
|
# VCM:BEGIN version=1
|
|
380
404
|
.ai/vcm/
|
|
405
|
+
.claude/worktrees/
|
|
381
406
|
# VCM:END
|
|
382
407
|
```
|
|
383
408
|
|
|
384
|
-
`.ai/vcm/` is the active VCM local control area. The base repo keeps the task index
|
|
409
|
+
`.ai/vcm/` is the active VCM local control area, and `.claude/worktrees/` is the Claude-compatible task worktree area. The base repo keeps the task index; each task runtime repo keeps its own session, message, orchestration, and translation state.
|
|
385
410
|
|
|
386
411
|
VCM must preserve all user-authored content outside the managed block.
|
|
387
412
|
|
|
@@ -389,7 +414,7 @@ After applying harness changes, the UI tells the user what changed and recommend
|
|
|
389
414
|
|
|
390
415
|
Role sessions get VCM behavior from `CLAUDE.md` and `.claude/agents/*.md`, not from a pasted startup context.
|
|
391
416
|
|
|
392
|
-
##
|
|
417
|
+
## 11. Handoff Files
|
|
393
418
|
|
|
394
419
|
Each task creates:
|
|
395
420
|
|
|
@@ -417,7 +442,7 @@ The product treats handoff files as task-local coordination facts. The terminal
|
|
|
417
442
|
|
|
418
443
|
The main UI no longer has a dedicated artifact panel. Artifact APIs still exist for status checks, role command compatibility, and future UI work.
|
|
419
444
|
|
|
420
|
-
##
|
|
445
|
+
## 12. Message Bus
|
|
421
446
|
|
|
422
447
|
VCM messaging is API-driven.
|
|
423
448
|
|
|
@@ -449,10 +474,15 @@ Auto mode:
|
|
|
449
474
|
- if target role is running, VCM writes a `[VCM MESSAGE]` envelope and submits it
|
|
450
475
|
- PM remains the routing hub
|
|
451
476
|
- non-PM roles reply to PM
|
|
477
|
+
- VCM enforces per-target-role turn-taking
|
|
478
|
+
- each target role may have at most one active delivered message
|
|
479
|
+
- extra messages to the same busy target role remain queued and are not written to the terminal
|
|
480
|
+
- when the GUI sees a newly delivered auto message, it switches the active role tab to the target role
|
|
481
|
+
- a role's `vcmctl reply` or `vcmctl result` acknowledges the active message and releases the next queued message for that role
|
|
452
482
|
|
|
453
483
|
The backend still has `stage`, `approve`, `reject`, `paused`, and pause/resume API compatibility paths. The current GUI exposes only message copy plus manual/auto orchestration.
|
|
454
484
|
|
|
455
|
-
##
|
|
485
|
+
## 13. Translation
|
|
456
486
|
|
|
457
487
|
Translation is a local assistant layer beside the role terminal.
|
|
458
488
|
|
|
@@ -548,7 +578,9 @@ Translation panel `Auto-send` is separate from task `Auto orchestration`:
|
|
|
548
578
|
- `Auto-send` on: translate and send if there is no translation warning.
|
|
549
579
|
- `Auto-send` off: translate to English draft and wait for user send.
|
|
550
580
|
|
|
551
|
-
|
|
581
|
+
Task `Auto orchestration` is an adjacent toolbar button to the left of `Translate` and uses the same compact selected/unselected button styling.
|
|
582
|
+
|
|
583
|
+
## 14. Local State
|
|
552
584
|
|
|
553
585
|
App-level settings:
|
|
554
586
|
|
|
@@ -566,7 +598,7 @@ Repository-level VCM state:
|
|
|
566
598
|
|
|
567
599
|
```text
|
|
568
600
|
.ai/vcm/tasks/<task>.json
|
|
569
|
-
.
|
|
601
|
+
.claude/worktrees/<task>/
|
|
570
602
|
```
|
|
571
603
|
|
|
572
604
|
Project config:
|
|
@@ -576,16 +608,16 @@ Project config:
|
|
|
576
608
|
~/.vcm/projects/index.json
|
|
577
609
|
```
|
|
578
610
|
|
|
579
|
-
The base repository's `.ai/vcm/` directory stores the task index
|
|
611
|
+
The base repository's `.ai/vcm/` directory stores the task index, while `.claude/worktrees/` stores nested task worktrees. Long-lived project config is stored under `~/.vcm` so it survives outside Git-ignored repo state.
|
|
580
612
|
|
|
581
613
|
Task worktree local files:
|
|
582
614
|
|
|
583
615
|
```text
|
|
584
|
-
.
|
|
585
|
-
.
|
|
586
|
-
.
|
|
587
|
-
.
|
|
588
|
-
.
|
|
616
|
+
.claude/worktrees/<task>/.ai/vcm/sessions/<task>.json
|
|
617
|
+
.claude/worktrees/<task>/.ai/vcm/messages/<task>.jsonl
|
|
618
|
+
.claude/worktrees/<task>/.ai/vcm/orchestration/<task>.json
|
|
619
|
+
.claude/worktrees/<task>/.ai/vcm/translation/<task>/
|
|
620
|
+
.claude/worktrees/<task>/.ai/vcm/handoffs/
|
|
589
621
|
```
|
|
590
622
|
|
|
591
623
|
For tasks created without a worktree, the task runtime repo is the connected base repo, so the runtime state resolves under the base repo's `.ai/vcm/`. Because `.ai/vcm/handoffs/` has no task-name segment, VCM allows only one active inline task in a connected repo.
|
|
@@ -596,7 +628,7 @@ External Claude transcripts:
|
|
|
596
628
|
~/.claude/projects/<project-hash>/<claude-session-id>.jsonl
|
|
597
629
|
```
|
|
598
630
|
|
|
599
|
-
##
|
|
631
|
+
## 15. Packaging Expectations
|
|
600
632
|
|
|
601
633
|
Published npm packages must include built output:
|
|
602
634
|
|
|
@@ -616,12 +648,12 @@ npm run build && npm run verify:package
|
|
|
616
648
|
|
|
617
649
|
This protects against publishing raw TypeScript bin files or missing frontend assets.
|
|
618
650
|
|
|
619
|
-
##
|
|
651
|
+
## 16. Success Criteria
|
|
620
652
|
|
|
621
653
|
VCM V1 is successful when:
|
|
622
654
|
|
|
623
655
|
- A user can connect a repo without global Git safe-directory setup.
|
|
624
|
-
- A user can create a default task, which creates `feature/<task>` and `.
|
|
656
|
+
- A user can create a default task, which creates `feature/<task>` and `.claude/worktrees/<task>`.
|
|
625
657
|
- A user can clear `Create worktree and branch` and create a task in the connected repo/current branch.
|
|
626
658
|
- A user can start all four role sessions in the task runtime repo.
|
|
627
659
|
- Switching roles never loses the embedded terminal.
|
|
@@ -630,6 +662,8 @@ VCM V1 is successful when:
|
|
|
630
662
|
- PM can route messages through `vcmctl`.
|
|
631
663
|
- Manual orchestration lets the user inspect and stage messages without auto-submitting Enter.
|
|
632
664
|
- Auto orchestration can deliver PM-approved work to running target roles.
|
|
665
|
+
- Auto orchestration switches to the target role tab when a new message is delivered.
|
|
666
|
+
- Round completion detection waits for the final role in a chained conversation and can alert with prompt plus sound.
|
|
633
667
|
- Translation settings save to `~/.vcm/settings.json`.
|
|
634
668
|
- Translation reads Claude transcript JSONL reliably after start, resume, and restart.
|
|
635
669
|
- Terminal and translation panel have equal, stable reading space.
|
|
@@ -94,7 +94,7 @@ Responsibilities:
|
|
|
94
94
|
- Render repository connect form.
|
|
95
95
|
- Render repository summary.
|
|
96
96
|
- Render workflow panel.
|
|
97
|
-
- Render settings section with Theme,
|
|
97
|
+
- Render settings section with Theme, Round alert, Messages, and Events.
|
|
98
98
|
- Render harness status/actions.
|
|
99
99
|
- Render task creation form with one task-name field, a `Create worktree and branch` checkbox selected by default, and generated branch/path previews when selected.
|
|
100
100
|
- Render task list.
|
|
@@ -110,10 +110,13 @@ File:
|
|
|
110
110
|
|
|
111
111
|
Responsibilities:
|
|
112
112
|
|
|
113
|
-
- Fetch task status, messages, and
|
|
113
|
+
- Fetch task status, messages, orchestration state, and round state.
|
|
114
114
|
- Poll those every three seconds.
|
|
115
115
|
- Render compact header with task title, branch, immutable worktree path, role tabs, Refresh, and red `Close Task`.
|
|
116
116
|
- Hold per-role permission mode selection.
|
|
117
|
+
- Hold task orchestration state and pass its on/off control to the active role console.
|
|
118
|
+
- Detect newly delivered auto-orchestration messages and switch the active role tab to the target role.
|
|
119
|
+
- Emit task round state to `App` so completion alerts can be deduplicated and displayed.
|
|
117
120
|
- Render one `SessionConsole` per role but only show the active role.
|
|
118
121
|
- Emit workflow/messages/orchestration/events back to `App` so sidebar stays synchronized.
|
|
119
122
|
|
|
@@ -125,6 +128,12 @@ File:
|
|
|
125
128
|
|
|
126
129
|
Responsibilities:
|
|
127
130
|
|
|
131
|
+
- Render role session controls and embedded terminal.
|
|
132
|
+
- Render `Auto orchestration` immediately to the left of `Translate`, using the same compact toggle styling.
|
|
133
|
+
- Render the translation split panel when `Translate` is enabled.
|
|
134
|
+
|
|
135
|
+
Responsibilities:
|
|
136
|
+
|
|
128
137
|
- Render role toolbar.
|
|
129
138
|
- Render embedded terminal for running sessions.
|
|
130
139
|
- Render empty/resume state for stopped sessions.
|
|
@@ -242,7 +251,7 @@ feature/<taskSlug>
|
|
|
242
251
|
Worktree path:
|
|
243
252
|
|
|
244
253
|
```text
|
|
245
|
-
<baseRepoRoot>/.
|
|
254
|
+
<baseRepoRoot>/.claude/worktrees/<taskSlug>
|
|
246
255
|
```
|
|
247
256
|
|
|
248
257
|
VCM does not support switching a task to another branch or worktree mode after creation. If the user needs a different branch/worktree choice, they should create a new task.
|
|
@@ -258,7 +267,7 @@ worktreePath: undefined
|
|
|
258
267
|
VCM does not create worktrees by role. All four role sessions for a task share the same task worktree:
|
|
259
268
|
|
|
260
269
|
```text
|
|
261
|
-
.
|
|
270
|
+
.claude/worktrees/<taskSlug>/
|
|
262
271
|
project-manager session cwd
|
|
263
272
|
architect session cwd
|
|
264
273
|
coder session cwd
|
|
@@ -274,11 +283,11 @@ VCM distinguishes:
|
|
|
274
283
|
- `branch`: `feature/<taskSlug>`.
|
|
275
284
|
- `worktreePath`: same as `taskRepoRoot`.
|
|
276
285
|
|
|
277
|
-
Base repo state is
|
|
286
|
+
Base repo state is the task index plus the Claude-compatible container for nested task worktrees:
|
|
278
287
|
|
|
279
288
|
```text
|
|
280
289
|
<baseRepoRoot>/.ai/vcm/tasks/<task>.json
|
|
281
|
-
<baseRepoRoot>/.
|
|
290
|
+
<baseRepoRoot>/.claude/worktrees/<task>/
|
|
282
291
|
```
|
|
283
292
|
|
|
284
293
|
Project configuration is app-local and stored outside the repository:
|
|
@@ -291,11 +300,11 @@ Project configuration is app-local and stored outside the repository:
|
|
|
291
300
|
Task runtime state, source changes, and handoff artifacts live in the task runtime repo. For worktree-backed tasks this is the nested task worktree:
|
|
292
301
|
|
|
293
302
|
```text
|
|
294
|
-
<baseRepoRoot>/.
|
|
295
|
-
<baseRepoRoot>/.
|
|
296
|
-
<baseRepoRoot>/.
|
|
297
|
-
<baseRepoRoot>/.
|
|
298
|
-
<baseRepoRoot>/.
|
|
303
|
+
<baseRepoRoot>/.claude/worktrees/<task>/.ai/vcm/sessions/<task>.json
|
|
304
|
+
<baseRepoRoot>/.claude/worktrees/<task>/.ai/vcm/messages/<task>.jsonl
|
|
305
|
+
<baseRepoRoot>/.claude/worktrees/<task>/.ai/vcm/orchestration/<task>.json
|
|
306
|
+
<baseRepoRoot>/.claude/worktrees/<task>/.ai/vcm/translation/<task>/
|
|
307
|
+
<baseRepoRoot>/.claude/worktrees/<task>/.ai/vcm/handoffs/
|
|
299
308
|
```
|
|
300
309
|
|
|
301
310
|
For inline tasks, `taskRepoRoot` is the connected base repo, so these same runtime paths resolve under the connected repo's `.ai/vcm/`.
|
|
@@ -306,15 +315,15 @@ This split lets VCM list tasks from the base repo after worktrees are created, w
|
|
|
306
315
|
|
|
307
316
|
### 6.2 Git Ignore Requirement
|
|
308
317
|
|
|
309
|
-
The base repository must ignore `.ai/vcm/`.
|
|
318
|
+
The base repository must ignore `.ai/vcm/` and `.claude/worktrees/`.
|
|
310
319
|
|
|
311
320
|
Reason:
|
|
312
321
|
|
|
313
|
-
- `.
|
|
314
|
-
- Without `.
|
|
322
|
+
- `.claude/worktrees/<task>` is a nested git worktree.
|
|
323
|
+
- Without `.claude/worktrees/` in `.gitignore`, the base repo sees worktree files as untracked noise.
|
|
315
324
|
- `.ai/vcm` also contains local task/session/message metadata that should not be committed by default.
|
|
316
325
|
|
|
317
|
-
The VCM harness manages a `.gitignore` block that ignores `.ai/vcm/` before task worktree creation.
|
|
326
|
+
The VCM harness manages a `.gitignore` block that ignores `.ai/vcm/` and `.claude/worktrees/` before task worktree creation.
|
|
318
327
|
|
|
319
328
|
### 6.3 Task Creation Flow
|
|
320
329
|
|
|
@@ -323,8 +332,9 @@ POST /api/tasks
|
|
|
323
332
|
-> validate taskSlug
|
|
324
333
|
-> assert .ai/vcm/ is ignored by Git
|
|
325
334
|
-> if createWorktree is not false:
|
|
335
|
+
-> assert .claude/worktrees/ is ignored by Git
|
|
326
336
|
-> compute branch feature/<taskSlug>
|
|
327
|
-
-> compute worktreePath <baseRepoRoot>/.
|
|
337
|
+
-> compute worktreePath <baseRepoRoot>/.claude/worktrees/<taskSlug>
|
|
328
338
|
-> assert branch does not already exist
|
|
329
339
|
-> assert worktreePath does not already exist
|
|
330
340
|
-> assert base repo has no uncommitted changes
|
|
@@ -347,7 +357,7 @@ POST /api/tasks/:taskSlug/cleanup
|
|
|
347
357
|
-> list role sessions for the task
|
|
348
358
|
-> stop each VCM-managed role session whose runtime status is running
|
|
349
359
|
-> stop translation tailers and clear task translation cache
|
|
350
|
-
-> when worktreePath exists, verify it belongs under <baseRepoRoot>/.
|
|
360
|
+
-> when worktreePath exists, verify it belongs under <baseRepoRoot>/.claude/worktrees/
|
|
351
361
|
-> when worktreePath exists, git worktree remove --force <worktreePath>
|
|
352
362
|
-> when worktreePath exists, delete the task branch by default
|
|
353
363
|
-> delete base task metadata
|
|
@@ -586,16 +596,58 @@ The current GUI shows sequence, timestamp, status, body preview, path, and a `Co
|
|
|
586
596
|
Auto mode:
|
|
587
597
|
|
|
588
598
|
```text
|
|
589
|
-
send -> delivered
|
|
599
|
+
send -> delivered when target has no active message
|
|
600
|
+
send -> queued when target is already handling a delivered message
|
|
601
|
+
target role reply/result -> acknowledge active message -> deliver next queued message for that role
|
|
590
602
|
```
|
|
591
603
|
|
|
592
|
-
The backend pastes a `[VCM MESSAGE]` envelope into the target terminal, then sends Enter as a separate terminal input event.
|
|
604
|
+
The backend pastes a `[VCM MESSAGE]` envelope into the target terminal, then sends Enter as a separate terminal input event. Delivery is serialized per target role. VCM does not infer Claude Code readiness from PTY silence; it treats `vcmctl reply` and `vcmctl result` from that role as the turn-complete signal.
|
|
605
|
+
|
|
606
|
+
The message service also serializes message mutations per task inside the VCM process so concurrent API calls cannot bypass the per-role in-flight check.
|
|
593
607
|
|
|
594
608
|
The backend still exposes pause/resume orchestration API routes and stores `paused` for compatibility. The current GUI only toggles `mode` between `manual` and `auto`.
|
|
595
609
|
|
|
596
610
|
Messages and orchestration snapshots are task runtime state under `taskRepoRoot/.ai/vcm`. Message body markdown also lives in the task worktree handoff directory.
|
|
597
611
|
|
|
598
|
-
## 12.
|
|
612
|
+
## 12. Round Completion Architecture
|
|
613
|
+
|
|
614
|
+
Files:
|
|
615
|
+
|
|
616
|
+
- `src/backend/services/round-service.ts`
|
|
617
|
+
- `src/backend/api/round-routes.ts`
|
|
618
|
+
- `src/shared/types/round.ts`
|
|
619
|
+
|
|
620
|
+
API:
|
|
621
|
+
|
|
622
|
+
```text
|
|
623
|
+
GET /api/tasks/:taskSlug/round
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
The round service subscribes to the same backend Claude transcript tailer used by translation. It tracks one lightweight state record per running role session:
|
|
627
|
+
|
|
628
|
+
- `unknown`
|
|
629
|
+
- `answering`
|
|
630
|
+
- `using_tools`
|
|
631
|
+
- `waiting_user`
|
|
632
|
+
- `abnormal`
|
|
633
|
+
- `idle`
|
|
634
|
+
|
|
635
|
+
`stop_reason === "end_turn"` is treated only as a candidate answer end. The service waits until pending tool uses are cleared and a short debounce passes before marking that role `idle`.
|
|
636
|
+
|
|
637
|
+
Task-level completion:
|
|
638
|
+
|
|
639
|
+
- If a message is currently `delivered` or `staged`, the latest such message defines the round target.
|
|
640
|
+
- In a PM -> role -> PM chain, completion follows the newest delivered message, so the round completes after PM finishes the final response.
|
|
641
|
+
- Queued or pending messages prevent completion.
|
|
642
|
+
- If no VCM message is in the round, the latest direct role answer can still produce a completion state.
|
|
643
|
+
|
|
644
|
+
Frontend behavior:
|
|
645
|
+
|
|
646
|
+
- `TaskWorkspace` polls the round endpoint with the other task state.
|
|
647
|
+
- `App` stores the sidebar `Round alert` preference in `~/.vcm/settings.json`.
|
|
648
|
+
- `App` deduplicates `completionId`, then shows a small `Round complete` prompt and plays a short Web Audio tone when alerts are enabled.
|
|
649
|
+
|
|
650
|
+
## 13. Role Command Compatibility
|
|
599
651
|
|
|
600
652
|
Files:
|
|
601
653
|
|
|
@@ -625,7 +677,7 @@ The dispatcher:
|
|
|
625
677
|
|
|
626
678
|
This is a compatibility path. The preferred V1 coordination path is `vcmctl` message bus.
|
|
627
679
|
|
|
628
|
-
##
|
|
680
|
+
## 14. Harness Service
|
|
629
681
|
|
|
630
682
|
File:
|
|
631
683
|
|
|
@@ -655,6 +707,7 @@ Managed block:
|
|
|
655
707
|
```gitignore
|
|
656
708
|
# VCM:BEGIN version=1
|
|
657
709
|
.ai/vcm/
|
|
710
|
+
.claude/worktrees/
|
|
658
711
|
# VCM:END
|
|
659
712
|
```
|
|
660
713
|
|
|
@@ -668,7 +721,7 @@ The service:
|
|
|
668
721
|
|
|
669
722
|
It must not overwrite user content outside the VCM block.
|
|
670
723
|
|
|
671
|
-
##
|
|
724
|
+
## 15. Translation Architecture
|
|
672
725
|
|
|
673
726
|
Files:
|
|
674
727
|
|
|
@@ -782,7 +835,7 @@ POST translation/send -> bracketed paste English text -> short delay -> runtime.
|
|
|
782
835
|
|
|
783
836
|
The backend strips trailing newlines before pasting and sends Enter separately. This avoids Claude Code TUI cases where a single large PTY write containing both text and `\r` fills the input line but does not submit it.
|
|
784
837
|
|
|
785
|
-
##
|
|
838
|
+
## 16. API Surface
|
|
786
839
|
|
|
787
840
|
Project:
|
|
788
841
|
|
|
@@ -847,6 +900,12 @@ POST /api/tasks/:taskSlug/orchestration/pause
|
|
|
847
900
|
POST /api/tasks/:taskSlug/orchestration/resume
|
|
848
901
|
```
|
|
849
902
|
|
|
903
|
+
Round:
|
|
904
|
+
|
|
905
|
+
```text
|
|
906
|
+
GET /api/tasks/:taskSlug/round
|
|
907
|
+
```
|
|
908
|
+
|
|
850
909
|
App settings:
|
|
851
910
|
|
|
852
911
|
```text
|
|
@@ -875,7 +934,7 @@ WebSockets:
|
|
|
875
934
|
/ws/terminal/:sessionId
|
|
876
935
|
```
|
|
877
936
|
|
|
878
|
-
##
|
|
937
|
+
## 17. Error Handling
|
|
879
938
|
|
|
880
939
|
File:
|
|
881
940
|
|
|
@@ -900,7 +959,7 @@ Fastify error handler returns:
|
|
|
900
959
|
}
|
|
901
960
|
```
|
|
902
961
|
|
|
903
|
-
##
|
|
962
|
+
## 18. Packaging Architecture
|
|
904
963
|
|
|
905
964
|
`package.json` publishes built artifacts:
|
|
906
965
|
|
|
@@ -922,7 +981,7 @@ Important scripts:
|
|
|
922
981
|
- `prepack`: build and package verification
|
|
923
982
|
- `postinstall`: fixes `node-pty` spawn helper when needed
|
|
924
983
|
|
|
925
|
-
##
|
|
984
|
+
## 19. Security And Safety Boundaries
|
|
926
985
|
|
|
927
986
|
Current boundaries:
|
|
928
987
|
|
|
@@ -936,7 +995,7 @@ Current boundaries:
|
|
|
936
995
|
- Task worktrees are created only during task creation; VCM does not expose branch/worktree switching APIs.
|
|
937
996
|
- Sandbox isolation should come from a devContainer, Docker container, VM, or other user-controlled environment.
|
|
938
997
|
|
|
939
|
-
##
|
|
998
|
+
## 20. Known Implementation Boundaries
|
|
940
999
|
|
|
941
1000
|
- No tmux backend.
|
|
942
1001
|
- No per-role worktree manager.
|