vibe-coding-master 0.0.13 → 0.0.14
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 +16 -12
- package/dist/backend/api/claude-hook-routes.js +5 -0
- package/dist/backend/api/message-routes.js +4 -0
- package/dist/backend/server.js +11 -3
- package/dist/backend/services/claude-hook-service.js +70 -0
- package/dist/backend/services/harness-service.js +95 -0
- package/dist/backend/services/message-service.js +76 -6
- package/dist/backend/services/round-service.js +17 -127
- package/dist/backend/services/session-service.js +39 -0
- package/dist/backend/services/status-service.js +0 -76
- package/dist/backend/templates/harness/architect-agent.js +4 -0
- package/dist/backend/templates/harness/claude-root.js +3 -0
- package/dist/backend/templates/harness/coder-agent.js +4 -0
- package/dist/backend/templates/harness/project-manager-agent.js +4 -0
- package/dist/backend/templates/harness/reviewer-agent.js +4 -0
- package/dist/backend/templates/message-envelope.js +3 -1
- package/dist/cli/vcmctl.js +30 -0
- package/dist/shared/types/claude-hook.js +1 -0
- package/dist-frontend/assets/{index-CyJrJge9.js → index-DVhkEVnA.js} +36 -35
- package/dist-frontend/assets/index-jEkUTnIY.css +32 -0
- package/dist-frontend/index.html +2 -2
- package/docs/cc-best-practices.md +8 -0
- package/docs/product-design.md +24 -25
- package/docs/v1-architecture-design.md +36 -36
- package/docs/v1-implementation-plan.md +44 -31
- package/package.json +1 -1
- package/dist-frontend/assets/index-N5DA0uE9.css +0 -32
|
@@ -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}.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,.modal-actions,.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-idle{border-color:#9aa3a8;background:#edf0f1;color:#465056}.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-delivering,.status-submitted,.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-delivery_failed,.status-response_ready_missing_result,.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))}.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{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] .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] .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] .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] .status-idle{border-color:#69717d;background:#20262f;color:#d6deeb}: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-delivery_failed,:root[data-theme=dark] .status-response_ready_missing_result,: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-delivering,:root[data-theme=dark] .status-submitted,: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-DVhkEVnA.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="/assets/index-jEkUTnIY.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="root"></div>
|
|
@@ -215,6 +215,9 @@ Role-specific behavior lives in `.claude/agents/`.
|
|
|
215
215
|
- Role outputs are exchanged through `.ai/vcm/handoffs/`, not through chat history.
|
|
216
216
|
- Role messaging is turn-based. Keep at most one active message to the same target role.
|
|
217
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
|
+
- After any successful `vcmctl send`, `vcmctl reply`, or `vcmctl result`, end the current Claude Code turn. Treat the command as the final coordination action of that turn.
|
|
219
|
+
- Do not run `vcmctl inbox`, poll files, start shell loops, or keep the turn open waiting for another role's answer.
|
|
220
|
+
- Do not use Claude Code Task/Subagent for VCM role delegation; VCM owns the four long-running role sessions.
|
|
218
221
|
- If new information appears while a role is still processing, update the handoff artifact or wait instead of sending fragmented follow-up messages.
|
|
219
222
|
- When the required role route includes `architect`, coding must not start until the architecture and plan artifact exists.
|
|
220
223
|
- 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.
|
|
@@ -1362,6 +1365,10 @@ Do not rely on `CLAUDE.md` for constraints that can be automated.
|
|
|
1362
1365
|
Recommended hooks:
|
|
1363
1366
|
|
|
1364
1367
|
```text
|
|
1368
|
+
UserPromptSubmit:
|
|
1369
|
+
confirm that a VCM message actually entered the target Claude Code role session
|
|
1370
|
+
switch the role activity state to running
|
|
1371
|
+
|
|
1365
1372
|
PreToolUse:
|
|
1366
1373
|
block protected files
|
|
1367
1374
|
block destructive commands
|
|
@@ -1376,6 +1383,7 @@ PostToolUse:
|
|
|
1376
1383
|
run cheap lint
|
|
1377
1384
|
|
|
1378
1385
|
Stop:
|
|
1386
|
+
switch the role activity state to idle
|
|
1379
1387
|
check project manager did not bypass required role route
|
|
1380
1388
|
check task severity and required role route
|
|
1381
1389
|
check required handoff artifacts exist
|
package/docs/product-design.md
CHANGED
|
@@ -62,8 +62,6 @@ project-manager
|
|
|
62
62
|
-> project-manager final acceptance, commit, and PR
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
The workflow is a soft guide in V1. VCM computes readiness from handoff artifact checks and session state, then shows the result in the sidebar. It does not block the user from manually starting a role out of order.
|
|
66
|
-
|
|
67
65
|
### 4.1 Task Worktree Model
|
|
68
66
|
|
|
69
67
|
Task-level worktree management is the recommended default model for multi-task parallelism:
|
|
@@ -221,7 +219,6 @@ Sections:
|
|
|
221
219
|
|
|
222
220
|
- `Repository Path`
|
|
223
221
|
- `Repository`
|
|
224
|
-
- `Workflow`
|
|
225
222
|
- `Settings`
|
|
226
223
|
- `VCM Harness`
|
|
227
224
|
- `New Task`
|
|
@@ -243,24 +240,18 @@ Repository Path
|
|
|
243
240
|
|
|
244
241
|
The old `Dirty: yes/no` label is not used. The UI uses `Working tree: clean` or `Working tree: uncommitted changes`.
|
|
245
242
|
|
|
246
|
-
`Workflow` shows the five soft workflow gates:
|
|
247
|
-
|
|
248
|
-
- Architecture
|
|
249
|
-
- Implementation
|
|
250
|
-
- Review
|
|
251
|
-
- Docs Sync
|
|
252
|
-
- PM Final
|
|
253
|
-
|
|
254
243
|
`Settings` contains:
|
|
255
244
|
|
|
256
245
|
- `Theme` button, cycling through `System`, `Light`, and `Dark`.
|
|
257
246
|
- `Round alert` button, on by default, controlling the completion prompt and sound.
|
|
247
|
+
- `Try alert` button, firing the same completion prompt and sound for local verification.
|
|
258
248
|
- `Messages` button, opening a modal list of role messages.
|
|
259
249
|
- `Events` button, opening a modal list of runtime UI events for the current task.
|
|
260
250
|
|
|
261
251
|
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.
|
|
262
252
|
|
|
263
253
|
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.
|
|
254
|
+
`Try alert` must work even when no conversation has just completed so the user can verify browser sound and notification behavior.
|
|
264
255
|
|
|
265
256
|
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`.
|
|
266
257
|
|
|
@@ -288,7 +279,7 @@ TASK WORKSPACE <task> <branch> <worktree> [Project Manager] [Architect] [Co
|
|
|
288
279
|
|
|
289
280
|
Role tabs show the session status for each role.
|
|
290
281
|
|
|
291
|
-
The main task workspace only renders the active role console. Messages
|
|
282
|
+
The main task workspace only renders the active role console. Messages and Events are opened from the sidebar.
|
|
292
283
|
|
|
293
284
|
## 7. Role Console
|
|
294
285
|
|
|
@@ -325,22 +316,20 @@ The split should stay close to 50/50 width. Both panes expand vertically to fill
|
|
|
325
316
|
|
|
326
317
|
## 8. Round Completion Detection
|
|
327
318
|
|
|
328
|
-
VCM detects answer completion from
|
|
319
|
+
VCM detects answer completion from VCM's hook-driven role activity state, not from terminal silence.
|
|
329
320
|
|
|
330
321
|
Backend role state:
|
|
331
322
|
|
|
332
|
-
- `
|
|
333
|
-
- `
|
|
334
|
-
-
|
|
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.
|
|
323
|
+
- `UserPromptSubmit`: role becomes `running`.
|
|
324
|
+
- `Stop`: role becomes `idle` and records `lastStopAt`.
|
|
325
|
+
- The role tab and Round alert use the same activity state source.
|
|
337
326
|
|
|
338
327
|
Task-level round state:
|
|
339
328
|
|
|
340
|
-
- If VCM role messages exist, the latest `
|
|
341
|
-
- A PM -> Coder -> PM chain completes only when the latest target role, PM, reaches
|
|
329
|
+
- If VCM role messages exist, the latest active `delivering`, `submitted`, `delivered`, or `staged` message defines the current target role.
|
|
330
|
+
- A PM -> Coder -> PM chain completes only when the latest target role, PM, reaches hook `Stop`.
|
|
342
331
|
- Queued or pending messages prevent completion because more role work is waiting.
|
|
343
|
-
- If no VCM role message is involved, the latest direct role
|
|
332
|
+
- If no VCM role message is involved, the latest direct role `Stop` can complete the round.
|
|
344
333
|
|
|
345
334
|
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
335
|
|
|
@@ -466,19 +455,29 @@ Manual mode:
|
|
|
466
455
|
- message status becomes `pending_approval` when the target role is running
|
|
467
456
|
- user opens `Messages`
|
|
468
457
|
- message rows show sequence, timestamp, status, body preview, path, and `Copy`
|
|
458
|
+
- `Mark All Done` marks open message records as `acknowledged` after the user manually handled stuck messages
|
|
469
459
|
- user decides whether to copy or manually act on the message
|
|
470
460
|
- VCM does not write to the target terminal or submit Enter
|
|
471
461
|
|
|
472
462
|
Auto mode:
|
|
473
463
|
|
|
474
|
-
- if target role is running, VCM writes a `[VCM MESSAGE]` envelope and
|
|
464
|
+
- if target role is running, VCM writes a `[VCM MESSAGE]` envelope, submits Enter, and marks the message `delivering`
|
|
465
|
+
- Claude Code `UserPromptSubmit` is the delivery acknowledgement; when the hook prompt contains the message id, VCM marks the message `submitted`
|
|
475
466
|
- PM remains the routing hub
|
|
476
467
|
- non-PM roles reply to PM
|
|
477
468
|
- VCM enforces per-target-role turn-taking
|
|
478
|
-
- each target role may have at most one active delivered message
|
|
469
|
+
- each target role may have at most one active `delivering`, `submitted`, `delivered`, or `staged` message
|
|
479
470
|
- extra messages to the same busy target role remain queued and are not written to the terminal
|
|
480
|
-
- when the GUI sees a newly
|
|
471
|
+
- when the GUI sees a newly submitted auto message, it switches the active role tab to the target role
|
|
481
472
|
- a role's `vcmctl reply` or `vcmctl result` acknowledges the active message and releases the next queued message for that role
|
|
473
|
+
- `Mark All Done` is a manual recovery action for stuck orchestration. It marks `pending_approval`, `queued`, `staged`, `delivering`, `submitted`, `delivered`, and failed message states as `acknowledged` so the next queued work is not permanently blocked after the user manually copied or sent a message.
|
|
474
|
+
|
|
475
|
+
VCM Harness injects Claude Code hooks into `.claude/settings.json`:
|
|
476
|
+
|
|
477
|
+
- `UserPromptSubmit`: sets the role tab activity to `running` and confirms submitted VCM messages
|
|
478
|
+
- `Stop`: sets the role tab activity to `idle`
|
|
479
|
+
|
|
480
|
+
The injected role rules require asynchronous role messaging: after any successful `vcmctl send`, `vcmctl reply`, or `vcmctl result`, the role must end the current Claude Code turn and wait for VCM to deliver a later reply. Roles must not run `vcmctl inbox`, loop, poll, or wait inside the same turn for another role to answer, and they must not use Claude Code Task/Subagent for VCM role delegation.
|
|
482
481
|
|
|
483
482
|
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.
|
|
484
483
|
|
|
@@ -662,7 +661,7 @@ VCM V1 is successful when:
|
|
|
662
661
|
- PM can route messages through `vcmctl`.
|
|
663
662
|
- Manual orchestration lets the user inspect and stage messages without auto-submitting Enter.
|
|
664
663
|
- 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
|
|
664
|
+
- Auto orchestration switches to the target role tab when a new message is confirmed by `UserPromptSubmit`.
|
|
666
665
|
- Round completion detection waits for the final role in a chained conversation and can alert with prompt plus sound.
|
|
667
666
|
- Translation settings save to `~/.vcm/settings.json`.
|
|
668
667
|
- Translation reads Claude transcript JSONL reliably after start, resume, and restart.
|
|
@@ -69,7 +69,6 @@ Main state lives in `App`:
|
|
|
69
69
|
- task list
|
|
70
70
|
- active task
|
|
71
71
|
- active role
|
|
72
|
-
- active workflow report
|
|
73
72
|
- active messages
|
|
74
73
|
- active orchestration state
|
|
75
74
|
- task-local event list
|
|
@@ -93,8 +92,7 @@ Responsibilities:
|
|
|
93
92
|
- Render collapsible sidebar sections.
|
|
94
93
|
- Render repository connect form.
|
|
95
94
|
- Render repository summary.
|
|
96
|
-
- Render
|
|
97
|
-
- Render settings section with Theme, Round alert, Messages, and Events.
|
|
95
|
+
- Render settings section with Theme, Round alert, Try alert, Messages, and Events.
|
|
98
96
|
- Render harness status/actions.
|
|
99
97
|
- 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
98
|
- Render task list.
|
|
@@ -115,10 +113,10 @@ Responsibilities:
|
|
|
115
113
|
- Render compact header with task title, branch, immutable worktree path, role tabs, Refresh, and red `Close Task`.
|
|
116
114
|
- Hold per-role permission mode selection.
|
|
117
115
|
- Hold task orchestration state and pass its on/off control to the active role console.
|
|
118
|
-
- Detect newly
|
|
116
|
+
- Detect newly submitted auto-orchestration messages from Claude Code `UserPromptSubmit` hooks and switch the active role tab to the target role.
|
|
119
117
|
- Emit task round state to `App` so completion alerts can be deduplicated and displayed.
|
|
120
118
|
- Render one `SessionConsole` per role but only show the active role.
|
|
121
|
-
- Emit
|
|
119
|
+
- Emit messages/orchestration/events back to `App` so sidebar stays synchronized.
|
|
122
120
|
|
|
123
121
|
### SessionConsole
|
|
124
122
|
|
|
@@ -434,9 +432,9 @@ Artifact checks are simple V1 checks:
|
|
|
434
432
|
- placeholder / incomplete
|
|
435
433
|
- ok
|
|
436
434
|
|
|
437
|
-
They are used for
|
|
435
|
+
They are used for missing/incomplete artifact warnings, not content quality judgment.
|
|
438
436
|
|
|
439
|
-
## 8.
|
|
437
|
+
## 8. Task Status Report
|
|
440
438
|
|
|
441
439
|
File:
|
|
442
440
|
|
|
@@ -448,21 +446,7 @@ Endpoint:
|
|
|
448
446
|
GET /api/tasks/:taskSlug/status
|
|
449
447
|
```
|
|
450
448
|
|
|
451
|
-
The
|
|
452
|
-
|
|
453
|
-
```text
|
|
454
|
-
architecture-plan -> implementation -> review -> docs-sync -> final-acceptance
|
|
455
|
-
```
|
|
456
|
-
|
|
457
|
-
Step readiness:
|
|
458
|
-
|
|
459
|
-
- Architecture is ready until `architecture-plan.md` is ok.
|
|
460
|
-
- Implementation is blocked until architecture is ok.
|
|
461
|
-
- Review is blocked until `implementation-log.md` and `validation-log.md` are ok.
|
|
462
|
-
- Docs Sync is blocked until `review-report.md` is ok.
|
|
463
|
-
- PM Final is blocked until `docs-sync-report.md` is ok.
|
|
464
|
-
|
|
465
|
-
The report is displayed in the sidebar `Workflow` section.
|
|
449
|
+
The status report returns the task record, role sessions, artifact checks, and warnings. VCM no longer computes or renders a Workflow panel; role sequencing is guided by the injected Claude rules and PM-mediated messages.
|
|
466
450
|
|
|
467
451
|
## 9. Session Runtime
|
|
468
452
|
|
|
@@ -591,17 +575,22 @@ Manual mode:
|
|
|
591
575
|
send -> pending_approval or queued -> Messages modal -> Copy/manual action
|
|
592
576
|
```
|
|
593
577
|
|
|
594
|
-
The current GUI shows sequence, timestamp, status, body preview, path, and
|
|
578
|
+
The current GUI shows sequence, timestamp, status, body preview, path, `Copy`, and `Mark All Done`. It does not expose Open Role, Stage, or Reject buttons. The backend still exposes stage/approve/reject routes; `Stage` writes `Read and handle VCM message <id> at <bodyPath>` without appending Enter.
|
|
595
579
|
|
|
596
580
|
Auto mode:
|
|
597
581
|
|
|
598
582
|
```text
|
|
599
|
-
send ->
|
|
600
|
-
|
|
583
|
+
send -> delivering when target has no active message
|
|
584
|
+
UserPromptSubmit hook containing message id -> submitted
|
|
585
|
+
send -> queued when target is already handling an active delivering/submitted/staged message
|
|
601
586
|
target role reply/result -> acknowledge active message -> deliver next queued message for that role
|
|
602
587
|
```
|
|
603
588
|
|
|
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
|
|
589
|
+
The backend pastes a `[VCM MESSAGE]` envelope into the target terminal, then sends Enter as a separate terminal input event. That terminal write is only `delivering`. Delivery is confirmed by the target Claude Code `UserPromptSubmit` hook, which includes the submitted prompt and message id. 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 workflow-complete signal for that message.
|
|
590
|
+
|
|
591
|
+
VCM Harness owns Claude Code hook injection through `.claude/settings.json`. V1 injects only `UserPromptSubmit` and `Stop`. `UserPromptSubmit` switches the role activity badge to `running` and confirms submitted messages. `Stop` switches the role activity badge to `idle`. VCM does not use Claude Code Subagent hooks for role delegation.
|
|
592
|
+
|
|
593
|
+
`Mark All Done` is a manual recovery action for stuck orchestration. It appends `acknowledged` snapshots for open messages, including `pending_approval`, `queued`, `staged`, `delivering`, `submitted`, `delivered`, and failed message states. It is intended for the case where the user manually copied or delivered stuck messages and wants auto orchestration to continue.
|
|
605
594
|
|
|
606
595
|
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.
|
|
607
596
|
|
|
@@ -623,28 +612,29 @@ API:
|
|
|
623
612
|
GET /api/tasks/:taskSlug/round
|
|
624
613
|
```
|
|
625
614
|
|
|
626
|
-
The round service
|
|
615
|
+
The round service reads hook-driven role activity from `RoleSessionRecord`. It does not use transcript tailing as the source of truth for round completion.
|
|
627
616
|
|
|
628
617
|
- `unknown`
|
|
629
|
-
- `answering`
|
|
630
|
-
- `using_tools`
|
|
631
|
-
- `waiting_user`
|
|
632
|
-
- `abnormal`
|
|
633
618
|
- `idle`
|
|
619
|
+
- `answering`
|
|
634
620
|
|
|
635
|
-
|
|
621
|
+
Mapping:
|
|
622
|
+
|
|
623
|
+
- `UserPromptSubmit` updates the session to `activityStatus: "running"` and the round role state to `answering`
|
|
624
|
+
- `Stop` updates the session to `activityStatus: "idle"`, records `lastStopAt`, and the round role state becomes `idle`
|
|
636
625
|
|
|
637
626
|
Task-level completion:
|
|
638
627
|
|
|
639
|
-
- If a message is currently `
|
|
640
|
-
- In a PM -> role -> PM chain, completion follows the newest
|
|
628
|
+
- If a message is currently `delivering`, `submitted`, `delivered`, or `staged`, the latest such message defines the round target.
|
|
629
|
+
- In a PM -> role -> PM chain, completion follows the newest active message, so the round completes after PM emits hook `Stop` for the final response.
|
|
641
630
|
- Queued or pending messages prevent completion.
|
|
642
|
-
- If no VCM message is in the round, the latest direct role
|
|
631
|
+
- If no VCM message is in the round, the latest direct role `Stop` can still produce a completion state.
|
|
643
632
|
|
|
644
633
|
Frontend behavior:
|
|
645
634
|
|
|
646
635
|
- `TaskWorkspace` polls the round endpoint with the other task state.
|
|
647
636
|
- `App` stores the sidebar `Round alert` preference in `~/.vcm/settings.json`.
|
|
637
|
+
- `Try alert` is frontend-only and calls the same round completion notice/sound path without persisting any setting.
|
|
648
638
|
- `App` deduplicates `completionId`, then shows a small `Round complete` prompt and plays a short Web Audio tone when alerts are enabled.
|
|
649
639
|
|
|
650
640
|
## 13. Role Command Compatibility
|
|
@@ -688,6 +678,7 @@ Harness files:
|
|
|
688
678
|
```text
|
|
689
679
|
CLAUDE.md
|
|
690
680
|
.gitignore
|
|
681
|
+
.claude/settings.json
|
|
691
682
|
.claude/agents/project-manager.md
|
|
692
683
|
.claude/agents/architect.md
|
|
693
684
|
.claude/agents/coder.md
|
|
@@ -711,6 +702,8 @@ Managed block:
|
|
|
711
702
|
# VCM:END
|
|
712
703
|
```
|
|
713
704
|
|
|
705
|
+
`.claude/settings.json` is JSON-merged by the harness. VCM preserves existing settings and adds command hooks for `UserPromptSubmit` and `Stop` that call `vcmctl hook-event` through the session-provided `VCM_CTL_COMMAND`.
|
|
706
|
+
|
|
714
707
|
The service:
|
|
715
708
|
|
|
716
709
|
- checks whether files exist
|
|
@@ -891,6 +884,7 @@ Messages:
|
|
|
891
884
|
```text
|
|
892
885
|
GET /api/tasks/:taskSlug/messages
|
|
893
886
|
POST /api/tasks/:taskSlug/messages
|
|
887
|
+
POST /api/tasks/:taskSlug/messages/mark-all-done
|
|
894
888
|
POST /api/tasks/:taskSlug/messages/:messageId/stage
|
|
895
889
|
POST /api/tasks/:taskSlug/messages/:messageId/approve
|
|
896
890
|
POST /api/tasks/:taskSlug/messages/:messageId/reject
|
|
@@ -900,6 +894,12 @@ POST /api/tasks/:taskSlug/orchestration/pause
|
|
|
900
894
|
POST /api/tasks/:taskSlug/orchestration/resume
|
|
901
895
|
```
|
|
902
896
|
|
|
897
|
+
Claude Code hooks:
|
|
898
|
+
|
|
899
|
+
```text
|
|
900
|
+
POST /api/hooks/claude-code
|
|
901
|
+
```
|
|
902
|
+
|
|
903
903
|
Round:
|
|
904
904
|
|
|
905
905
|
```text
|
|
@@ -1002,6 +1002,6 @@ Current boundaries:
|
|
|
1002
1002
|
- No branch switching for an existing task.
|
|
1003
1003
|
- No main-page artifact inspector.
|
|
1004
1004
|
- No raw PTY output translation.
|
|
1005
|
-
- No hard
|
|
1005
|
+
- No computed Workflow panel or hard gate enforcement.
|
|
1006
1006
|
- No durable backend event log for the sidebar Events modal; current events are frontend runtime events for the active task.
|
|
1007
1007
|
- No hosted multi-user collaboration.
|
|
@@ -304,10 +304,6 @@ Defines:
|
|
|
304
304
|
|
|
305
305
|
- `ApiErrorResponse`
|
|
306
306
|
- `TaskStatusReport`
|
|
307
|
-
- `TaskWorkflowStepId`
|
|
308
|
-
- `TaskWorkflowStepStatus`
|
|
309
|
-
- `TaskWorkflowStep`
|
|
310
|
-
- `TaskWorkflowReport`
|
|
311
307
|
- `DispatchRoleCommandResult`
|
|
312
308
|
- `BootstrapState`
|
|
313
309
|
|
|
@@ -640,7 +636,7 @@ Responsibilities:
|
|
|
640
636
|
- assemble `TaskStatusReport`
|
|
641
637
|
- list sessions
|
|
642
638
|
- list artifact checks
|
|
643
|
-
-
|
|
639
|
+
- emit missing/incomplete artifact warnings
|
|
644
640
|
|
|
645
641
|
### `src/backend/services/session-service.ts`
|
|
646
642
|
|
|
@@ -690,6 +686,8 @@ Responsibilities:
|
|
|
690
686
|
|
|
691
687
|
- list messages
|
|
692
688
|
- send messages
|
|
689
|
+
- confirm submitted messages from Claude Code `UserPromptSubmit` hooks
|
|
690
|
+
- mark all open messages done for manual recovery
|
|
693
691
|
- stage/approve/reject messages
|
|
694
692
|
- get/update orchestration state
|
|
695
693
|
- enforce message policy
|
|
@@ -699,7 +697,7 @@ Responsibilities:
|
|
|
699
697
|
- deliver the next queued message for that role after acknowledgement
|
|
700
698
|
- persist message snapshots
|
|
701
699
|
- write message body markdown
|
|
702
|
-
- write staged or
|
|
700
|
+
- write staged or delivering messages to target terminal
|
|
703
701
|
|
|
704
702
|
In task-worktree mode:
|
|
705
703
|
|
|
@@ -709,6 +707,29 @@ In task-worktree mode:
|
|
|
709
707
|
- terminal delivery uses the runtime session for the role, whose cwd is the task worktree
|
|
710
708
|
- message mutations are serialized per task inside the VCM process to avoid concurrent API calls bypassing the in-flight check
|
|
711
709
|
|
|
710
|
+
Auto-delivery state:
|
|
711
|
+
|
|
712
|
+
- `send` writes the envelope and Enter, then stores `delivering`
|
|
713
|
+
- `UserPromptSubmit` hook with the same message id stores `submitted`
|
|
714
|
+
- `delivering`, `submitted`, `delivered`, and `staged` all count as active for per-role turn-taking
|
|
715
|
+
- target-role `vcmctl reply` / `vcmctl result` acknowledges the active message and releases the next queued message
|
|
716
|
+
- `markAllDone` appends `acknowledged` snapshots for open messages so the user can recover after manually copying or sending stuck queued work
|
|
717
|
+
|
|
718
|
+
### `src/backend/services/claude-hook-service.ts`
|
|
719
|
+
|
|
720
|
+
Exports:
|
|
721
|
+
|
|
722
|
+
- `ClaudeHookService`
|
|
723
|
+
- `createClaudeHookService(deps)`
|
|
724
|
+
|
|
725
|
+
Responsibilities:
|
|
726
|
+
|
|
727
|
+
- accept Claude Code hook events from `vcmctl hook-event`
|
|
728
|
+
- support only `UserPromptSubmit` and `Stop` in V1
|
|
729
|
+
- map hook events to the current VCM project, task, role, and persisted Claude session id
|
|
730
|
+
- update `RoleSessionRecord.activityStatus`: `UserPromptSubmit -> running`, `Stop -> idle`
|
|
731
|
+
- call `MessageService.confirmPromptSubmitted` when a `UserPromptSubmit` prompt contains a VCM message id
|
|
732
|
+
|
|
712
733
|
### `src/backend/services/command-dispatcher.ts`
|
|
713
734
|
|
|
714
735
|
Exports:
|
|
@@ -846,13 +867,13 @@ Exports:
|
|
|
846
867
|
|
|
847
868
|
Responsibilities:
|
|
848
869
|
|
|
849
|
-
-
|
|
850
|
-
-
|
|
851
|
-
-
|
|
870
|
+
- read hook-driven role activity from `RoleSessionRecord`
|
|
871
|
+
- map `activityStatus: "running"` to role state `answering`
|
|
872
|
+
- map `activityStatus: "idle"` plus `lastStopAt` to role state `idle`
|
|
852
873
|
- evaluate task-level round completion from messages plus role states
|
|
853
|
-
- wait for the latest delivered/staged target role in PM -> role -> PM chains
|
|
874
|
+
- wait for the latest active delivering/submitted/delivered/staged target role in PM -> role -> PM chains
|
|
854
875
|
- ignore completion while queued or pending messages exist
|
|
855
|
-
-
|
|
876
|
+
- keep `stopSession` and `stopTask` as no-op lifecycle compatibility hooks
|
|
856
877
|
|
|
857
878
|
## 9. Backend API
|
|
858
879
|
|
|
@@ -878,7 +899,8 @@ Registers HTTP routes and the terminal WebSocket.
|
|
|
878
899
|
- `src/backend/api/task-routes.ts`: tasks, task status, and Close Task cleanup endpoint; Close Task stops running role sessions before translation/task cleanup
|
|
879
900
|
- `src/backend/api/session-routes.ts`: session lifecycle and dispatch compatibility endpoint
|
|
880
901
|
- `src/backend/api/artifact-routes.ts`: artifact, role command, and log reads/writes
|
|
881
|
-
- `src/backend/api/message-routes.ts`: messages and orchestration
|
|
902
|
+
- `src/backend/api/message-routes.ts`: messages, Mark All Done recovery, and orchestration
|
|
903
|
+
- `src/backend/api/claude-hook-routes.ts`: Claude Code `UserPromptSubmit` and `Stop` hook receiver
|
|
882
904
|
- `src/backend/api/round-routes.ts`: task round completion state
|
|
883
905
|
- `src/backend/api/translation-routes.ts`: settings, prompt previews, provider test, start/poll, input/send, clear/retry
|
|
884
906
|
|
|
@@ -898,7 +920,7 @@ Terminal WebSocket forwards PTY output/input/resize.
|
|
|
898
920
|
|
|
899
921
|
Translation does not use WebSocket. The backend writes cached translation events under `<taskRepoRoot>/.ai/vcm/translation/<task>/<role>/<session-id>.jsonl`; the frontend polls `GET /api/translation/sessions/:sessionId/events?after=<cursor>`. The cursor is the next expected seq, so `after=18` means seq `1..17` can be removed and seq `18+` should be returned.
|
|
900
922
|
|
|
901
|
-
Round completion is HTTP-polled too. `GET /api/tasks/:taskSlug/round` returns `VcmTaskRoundState` from
|
|
923
|
+
Round completion is HTTP-polled too. `GET /api/tasks/:taskSlug/round` returns `VcmTaskRoundState` from hook-driven role activity and message state; it is not a WebSocket stream.
|
|
902
924
|
|
|
903
925
|
## 10. Backend Templates
|
|
904
926
|
|
|
@@ -993,7 +1015,7 @@ Responsibilities:
|
|
|
993
1015
|
- load tasks and harness status after connect
|
|
994
1016
|
- pass sidebar props to `ProjectDashboard`
|
|
995
1017
|
- pass task props to `TaskWorkspace`
|
|
996
|
-
- keep active
|
|
1018
|
+
- keep active messages/orchestration/events synchronized by task
|
|
997
1019
|
- dedupe task round `completionId` values and show/play completion alerts when enabled
|
|
998
1020
|
|
|
999
1021
|
### `src/frontend/routes/project-dashboard.tsx`
|
|
@@ -1008,9 +1030,9 @@ Responsibilities:
|
|
|
1008
1030
|
- collapsible sidebar
|
|
1009
1031
|
- repository connect form
|
|
1010
1032
|
- repository summary
|
|
1011
|
-
- workflow panel
|
|
1012
1033
|
- settings section
|
|
1013
1034
|
- round completion alert toggle
|
|
1035
|
+
- try alert test button
|
|
1014
1036
|
- messages modal
|
|
1015
1037
|
- events modal
|
|
1016
1038
|
- harness panel
|
|
@@ -1070,15 +1092,6 @@ Exports:
|
|
|
1070
1092
|
|
|
1071
1093
|
Shows harness status and install/update action.
|
|
1072
1094
|
|
|
1073
|
-
### `src/frontend/components/workflow-panel.tsx`
|
|
1074
|
-
|
|
1075
|
-
Exports:
|
|
1076
|
-
|
|
1077
|
-
- `WorkflowPanelProps`
|
|
1078
|
-
- `WorkflowPanel({ workflow })`
|
|
1079
|
-
|
|
1080
|
-
Renders the sidebar workflow steps.
|
|
1081
|
-
|
|
1082
1095
|
### `src/frontend/components/message-timeline.tsx`
|
|
1083
1096
|
|
|
1084
1097
|
Exports:
|
|
@@ -1087,7 +1100,7 @@ Exports:
|
|
|
1087
1100
|
- `getMessageCounts(messages)`
|
|
1088
1101
|
- `MessageTimeline(props)`
|
|
1089
1102
|
|
|
1090
|
-
Used inside the Messages modal. Current UI rows show sequence, timestamp, route, type, status, body preview, body path, and a `Copy` button. Stage/approve/reject backend APIs remain compatibility paths, but those buttons are not displayed in the current modal.
|
|
1103
|
+
Used inside the Messages modal. Current UI rows show sequence, timestamp, route, type, status, body preview, body path, and a `Copy` button. The modal header includes `Mark All Done` for manual recovery from stuck queued/in-flight messages. Stage/approve/reject backend APIs remain compatibility paths, but those buttons are not displayed in the current modal.
|
|
1091
1104
|
|
|
1092
1105
|
### `src/frontend/components/event-log.tsx`
|
|
1093
1106
|
|
|
@@ -1197,23 +1210,23 @@ Sidebar:
|
|
|
1197
1210
|
|
|
1198
1211
|
- all groups default collapsed
|
|
1199
1212
|
- `Repository Path` default open only when no task is selected
|
|
1200
|
-
- `Settings` includes `Theme`, `Round alert`, `Messages`, and `Events`
|
|
1213
|
+
- `Settings` includes `Theme`, `Round alert`, `Try alert`, `Messages`, and `Events`
|
|
1201
1214
|
- `Theme` cycles through `System`, `Light`, and `Dark`; `System` follows the browser/OS color-scheme preference
|
|
1202
1215
|
- `Round alert` is on by default and controls the in-app completion prompt plus short sound
|
|
1216
|
+
- `Try alert` calls the same prompt/sound path without waiting for a real completed round
|
|
1203
1217
|
|
|
1204
1218
|
Task workspace:
|
|
1205
1219
|
|
|
1206
1220
|
- role tabs in the first header row
|
|
1207
|
-
- workflow is not in main workspace
|
|
1208
1221
|
- messages/events are not in main workspace
|
|
1209
1222
|
- active role console fills available space
|
|
1210
1223
|
- `Auto orchestration` appears immediately to the left of `Translate` and uses the same compact toggle style
|
|
1211
1224
|
|
|
1212
1225
|
Round completion:
|
|
1213
1226
|
|
|
1214
|
-
-
|
|
1215
|
-
-
|
|
1216
|
-
- PM -> role -> PM chains complete after PM's final `
|
|
1227
|
+
- task state follows the latest active delivering/submitted/delivered/staged message target role
|
|
1228
|
+
- role activity uses `UserPromptSubmit -> running` and `Stop -> idle`
|
|
1229
|
+
- PM -> role -> PM chains complete after PM's final hook `Stop`, not after the intermediate role's `Stop`
|
|
1217
1230
|
- queued or pending messages keep the round active
|
|
1218
1231
|
- frontend dedupes `completionId` before showing a prompt or playing sound
|
|
1219
1232
|
|
|
@@ -1317,7 +1330,7 @@ For frontend layout changes, also verify manually:
|
|
|
1317
1330
|
- Messages modal opens from sidebar Settings
|
|
1318
1331
|
- Events modal opens from sidebar Settings
|
|
1319
1332
|
- Auto orchestration toggles on/off from the role toolbar
|
|
1320
|
-
- Auto orchestration switches to the target role tab when a new message is
|
|
1333
|
+
- Auto orchestration switches to the target role tab when a new message is confirmed by `UserPromptSubmit`
|
|
1321
1334
|
- Round alert can be toggled from sidebar Settings and fires once after a chained round truly completes
|
|
1322
1335
|
- `Enter` in translation composer translates/sends
|
|
1323
1336
|
- `Shift+Enter` inserts newline
|