vibe-coding-master 0.0.13 → 0.0.15

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.
Files changed (30) hide show
  1. package/README.md +36 -36
  2. package/dist/backend/api/claude-hook-routes.js +5 -0
  3. package/dist/backend/api/message-routes.js +8 -36
  4. package/dist/backend/server.js +12 -26
  5. package/dist/backend/services/artifact-service.js +27 -2
  6. package/dist/backend/services/claude-hook-service.js +67 -0
  7. package/dist/backend/services/harness-service.js +112 -0
  8. package/dist/backend/services/message-service.js +283 -175
  9. package/dist/backend/services/round-service.js +17 -127
  10. package/dist/backend/services/session-service.js +55 -2
  11. package/dist/backend/services/status-service.js +0 -76
  12. package/dist/backend/templates/handoff.js +3 -0
  13. package/dist/backend/templates/harness/architect-agent.js +5 -0
  14. package/dist/backend/templates/harness/claude-root.js +6 -2
  15. package/dist/backend/templates/harness/coder-agent.js +5 -0
  16. package/dist/backend/templates/harness/project-manager-agent.js +7 -3
  17. package/dist/backend/templates/harness/reviewer-agent.js +5 -0
  18. package/dist/backend/templates/message-envelope.js +7 -1
  19. package/dist/shared/types/claude-hook.js +1 -0
  20. package/dist-frontend/assets/{index-CyJrJge9.js → index-QhzvzTMZ.js} +43 -42
  21. package/dist-frontend/assets/index-jEkUTnIY.css +32 -0
  22. package/dist-frontend/index.html +2 -2
  23. package/docs/cc-best-practices.md +13 -4
  24. package/docs/product-design.md +74 -47
  25. package/docs/v1-architecture-design.md +53 -53
  26. package/docs/v1-implementation-plan.md +94 -61
  27. package/package.json +2 -3
  28. package/scripts/verify-package.mjs +0 -3
  29. package/dist/cli/vcmctl.js +0 -141
  30. 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}
@@ -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-CyJrJge9.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-N5DA0uE9.css">
7
+ <script type="module" crossorigin src="/assets/index-QhzvzTMZ.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-jEkUTnIY.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
@@ -214,7 +214,11 @@ Role-specific behavior lives in `.claude/agents/`.
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
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.
217
+ - Send role messages by writing or updating the fixed route file under `.ai/vcm/handoffs/messages/<from-role>-<to-role>.md`.
218
+ - For a given target role, update the same route file instead of creating multiple fragmented messages.
219
+ - After writing or updating a role message file, end the current Claude Code turn. Treat the file write as the final coordination action of that turn.
220
+ - Do not poll message files, start shell loops, or keep the turn open waiting for another role's answer. VCM dispatches pending route files after Claude Code `Stop`.
221
+ - Do not use Claude Code Task/Subagent for VCM role delegation; VCM owns the four long-running role sessions.
218
222
  - If new information appears while a role is still processing, update the handoff artifact or wait instead of sending fragmented follow-up messages.
219
223
  - When the required role route includes `architect`, coding must not start until the architecture and plan artifact exists.
220
224
  - 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.
@@ -562,7 +566,7 @@ Do not include:
562
566
 
563
567
  For large projects, the default execution model should be explicit role-based sessions, not dynamic role routing inside one generic Claude conversation.
564
568
 
565
- The user-facing task should start with a `project-manager` role session. The project manager owns user communication, role command dispatch, severity classification, role routing, progress tracking, and process verification. It does not own architecture, coding, and independent review for the same non-trivial task.
569
+ The user-facing task should start with a `project-manager` role session. The project manager owns user communication, route-file message preparation, severity classification, role routing, progress tracking, and process verification. It does not own architecture, coding, and independent review for the same non-trivial task.
566
570
 
567
571
  Do not make one generic Claude session own architecture, planning, coding, final testing, and review for non-trivial work. That blurs responsibility and makes acceptance weak.
568
572
 
@@ -716,7 +720,7 @@ Role responsibilities:
716
720
 
717
721
  ```text
718
722
  project-manager
719
- owns user communication, task clarification, task specs, role routing, and role command dispatch
723
+ owns user communication, task clarification, task specs, role routing, and route-file message preparation
720
724
  turns user input into an engineering task when needed
721
725
  summarizes role outputs back to the user
722
726
  creates and verifies handoff artifacts
@@ -1362,6 +1366,10 @@ Do not rely on `CLAUDE.md` for constraints that can be automated.
1362
1366
  Recommended hooks:
1363
1367
 
1364
1368
  ```text
1369
+ Stop:
1370
+ notify VCM that a role turn ended
1371
+ trigger VCM to scan .ai/vcm/handoffs/messages/ for pending route files
1372
+
1365
1373
  PreToolUse:
1366
1374
  block protected files
1367
1375
  block destructive commands
@@ -1376,6 +1384,7 @@ PostToolUse:
1376
1384
  run cheap lint
1377
1385
 
1378
1386
  Stop:
1387
+ switch the role activity state to idle
1379
1388
  check project manager did not bypass required role route
1380
1389
  check task severity and required role route
1381
1390
  check required handoff artifacts exist
@@ -2150,7 +2159,7 @@ Monthly review:
2150
2159
  If you can only enforce 16 rules, enforce these:
2151
2160
 
2152
2161
  1. User-facing tasks start with `claude --agent project-manager`; untagged sessions are not implicit project managers.
2153
- 2. The `project-manager` agent owns user communication, task clarification, and precise role command dispatch.
2162
+ 2. The `project-manager` agent owns user communication, task clarification, and precise route-file message preparation.
2154
2163
  3. Complex tasks use explicit role sessions, handoff artifacts, and plan first; do not edit directly.
2155
2164
  4. One task uses one branch, one worktree, one handoff directory, and one PR by default.
2156
2165
  5. Role sessions for the same task work in the same task worktree sequentially; parallel write work uses separate task or sub-task worktrees.
@@ -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, Events, and Workflow are in the sidebar.
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 Claude Code transcript JSONL, not from terminal silence.
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
- - `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.
323
+ - VCM terminal submit: 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 `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`.
329
+ - If VCM role messages exist, the latest active `submitted` 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 answer can complete the round.
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
 
@@ -435,52 +424,90 @@ Each task creates:
435
424
  review-report.md
436
425
  docs-sync-report.md
437
426
  messages/
438
- <message-id>.md
427
+ project-manager-architect.md
428
+ project-manager-coder.md
429
+ project-manager-reviewer.md
430
+ architect-project-manager.md
431
+ coder-project-manager.md
432
+ reviewer-project-manager.md
433
+ <optional-peer-route>.md
439
434
  ```
440
435
 
441
436
  The product treats handoff files as task-local coordination facts. The terminal is useful for live interaction, but handoff files and message history are the source of truth during a task. They live under `.ai/vcm/`, are ignored by Git, and are removed by `Close Task`; final decisions that should survive must be copied into normal project docs, source, commit messages, or PR text.
442
437
 
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.
438
+ The main UI no longer has a dedicated artifact panel. Artifact APIs still exist for status checks and future UI work.
444
439
 
445
440
  ## 12. Message Bus
446
441
 
447
- VCM messaging is API-driven.
442
+ VCM messaging is file-driven and dispatched by VCM after Claude Code turn completion. Roles do not call a VCM CLI to send messages.
448
443
 
449
444
  ```text
450
445
  role terminal
451
- -> vcmctl
452
- -> VCM backend API
453
- -> policy validation
454
- -> durable message snapshots
455
- -> target terminal write when allowed
446
+ -> writes/updates one route file under .ai/vcm/handoffs/messages/
447
+ -> ends the Claude Code turn
448
+ -> Claude Code Stop hook calls VCM backend directly
449
+ -> VCM scans pending route files
450
+ -> VCM validates, snapshots, and dispatches one allowed message per idle target role
456
451
  ```
457
452
 
458
- Allowed message routes:
453
+ Route files:
454
+
455
+ - File name format is `<from-role>-<to-role>.md`.
456
+ - Role names use VCM role slugs, for example `project-manager-coder.md`.
457
+ - The file path determines `from` and `to`; frontmatter cannot override the route.
458
+ - The file body is Markdown.
459
+ - Optional YAML frontmatter may provide `type`, `severity`, `title`, or `related_artifact`.
460
+ - Blank or whitespace-only files mean "no pending message".
461
+ - Non-empty files mean "pending message waiting for VCM dispatch".
462
+
463
+ The important product rule is one file per directed route. If role A decides several times during one turn that it needs to call role B, it must edit the same `A-B.md` file instead of creating multiple messages. This turns duplicate sends into a single latest pending instruction.
464
+
465
+ Default route policy:
459
466
 
460
- - `project-manager` to `architect` / `coder` / `reviewer`: `task`, `question`, `review-request`, `revise`, `cancel`
461
- - `architect` / `coder` / `reviewer` to `project-manager`: `result`, `question`, `blocked`, `finding`
462
- - `user` to `project-manager`: `user-request`
467
+ - `project-manager` may send to `architect`, `coder`, and `reviewer`.
468
+ - `architect`, `coder`, and `reviewer` may send to `project-manager`.
469
+ - Peer routes such as `coder-reviewer.md` may exist for explicit task designs, but VCM still serializes delivery per target role.
470
+ - `user` talks to `project-manager` through the normal active terminal or translation composer, not through a route file.
471
+
472
+ Stop-triggered scan:
473
+
474
+ - VCM injects a Claude Code `Stop` hook into `.claude/settings.json`.
475
+ - The hook does not call `vcmctl`; it POSTs directly to the local VCM backend.
476
+ - When any role stops, VCM marks that role idle, then scans pending route files.
477
+ - VCM scans the stopped role's outgoing files and also any pending files targeting newly idle roles, so messages that were blocked by a busy target can be delivered after that target stops.
478
+ - VCM reads only stable, non-empty files and ignores blank files.
479
+ - VCM delivers at most one message to a target role per scan.
480
+ - If multiple pending files target the same idle role, VCM chooses deterministically by oldest modified time, then route name.
463
481
 
464
482
  Manual mode:
465
483
 
466
484
  - message status becomes `pending_approval` when the target role is running
467
485
  - user opens `Messages`
468
486
  - message rows show sequence, timestamp, status, body preview, path, and `Copy`
487
+ - `Mark All Done` marks open message records as `acknowledged` after the user manually handled stuck messages
469
488
  - user decides whether to copy or manually act on the message
470
489
  - VCM does not write to the target terminal or submit Enter
490
+ - VCM does not clear the source route file until the user marks it done or VCM later dispatches it in auto mode
471
491
 
472
492
  Auto mode:
473
493
 
474
- - if target role is running, VCM writes a `[VCM MESSAGE]` envelope and submits it
475
- - PM remains the routing hub
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
494
+ - if the target role is idle and has no active delivered message, VCM writes a `[VCM MESSAGE]` envelope to that role's embedded terminal and submits Enter
495
+ - terminal write success stores a durable message snapshot and marks the delivery `submitted`
496
+ - after VCM successfully submits the message to Claude Code, VCM archives the body in message history and clears the source route file
497
+ - if the target role is not running, is busy, or terminal submission fails, VCM leaves the route file non-empty so it remains pending
498
+ - when VCM dispatches a message, the GUI switches to the target role tab so the user can watch execution
499
+ - the target role answers by writing its own route file back to the next role and then ending its turn
500
+ - `Mark All Done` is a manual recovery action for stuck orchestration. It marks open message records as `acknowledged` and may clear route files only after the user confirms the pending file contents were manually handled.
501
+
502
+ VCM Harness injects Claude Code hooks into `.claude/settings.json`:
503
+
504
+ - `Stop`: posts directly to the VCM backend, marks the role idle, and triggers pending route-file dispatch
505
+
506
+ VCM does not need `UserPromptSubmit` for message delivery in this design. Role activity becomes running when VCM submits user or message input to the embedded terminal, and returns to idle on `Stop`.
507
+
508
+ The injected role rules require asynchronous file messaging: after writing or updating a route file, the role must end the current Claude Code turn and wait for VCM to deliver a later reply. Roles must not poll files, start shell loops, or keep the turn open waiting for another role to answer, and they must not use Claude Code Task/Subagent for VCM role delegation.
482
509
 
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.
510
+ There is no `vcmctl` in the target design. The only hook entrypoint is direct HTTP from Claude Code hooks to the local VCM backend.
484
511
 
485
512
  ## 13. Translation
486
513
 
@@ -618,6 +645,7 @@ Task worktree local files:
618
645
  .claude/worktrees/<task>/.ai/vcm/orchestration/<task>.json
619
646
  .claude/worktrees/<task>/.ai/vcm/translation/<task>/
620
647
  .claude/worktrees/<task>/.ai/vcm/handoffs/
648
+ .claude/worktrees/<task>/.ai/vcm/handoffs/messages/<from-role>-<to-role>.md
621
649
  ```
622
650
 
623
651
  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.
@@ -633,7 +661,6 @@ External Claude transcripts:
633
661
  Published npm packages must include built output:
634
662
 
635
663
  - `dist/main.js`
636
- - `dist/cli/vcmctl.js`
637
664
  - backend route/service/template output in `dist/`
638
665
  - frontend static assets in `dist-frontend/`
639
666
  - `README.md`
@@ -659,10 +686,10 @@ VCM V1 is successful when:
659
686
  - Switching roles never loses the embedded terminal.
660
687
  - Restart creates a fresh Claude session; Resume reconnects to the persisted one.
661
688
  - Permission modes are reflected in the Claude command.
662
- - PM can route messages through `vcmctl`.
663
- - Manual orchestration lets the user inspect and stage messages without auto-submitting Enter.
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.
689
+ - Roles can route messages by writing fixed route files under `.ai/vcm/handoffs/messages/`.
690
+ - Manual orchestration lets the user inspect pending route-file messages without auto-submitting Enter.
691
+ - Auto orchestration can deliver pending route-file messages to idle running target roles.
692
+ - Auto orchestration switches to the target role tab when VCM submits a route-file message.
666
693
  - Round completion detection waits for the final role in a chained conversation and can alert with prompt plus sound.
667
694
  - Translation settings save to `~/.vcm/settings.json`.
668
695
  - 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 workflow panel.
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 delivered auto-orchestration messages and switch the active role tab to the target role.
116
+ - Detect newly submitted auto-orchestration messages from VCM dispatch 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 workflow/messages/orchestration/events back to `App` so sidebar stays synchronized.
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 workflow readiness, not content quality judgment.
435
+ They are used for missing/incomplete artifact warnings, not content quality judgment.
438
436
 
439
- ## 8. Workflow Computation
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 workflow has five steps:
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
 
@@ -569,45 +553,55 @@ Files:
569
553
 
570
554
  - `src/backend/services/message-service.ts`
571
555
  - `src/backend/templates/message-envelope.ts`
572
- - `src/cli/vcmctl.ts`
573
556
 
574
557
  State:
575
558
 
576
559
  ```text
577
560
  <taskRepoRoot>/.ai/vcm/messages/<task>.jsonl
578
561
  <taskRepoRoot>/.ai/vcm/orchestration/<task>.json
579
- <taskRepoRoot>/.ai/vcm/handoffs/messages/<message-id>.md
562
+ <taskRepoRoot>/.ai/vcm/handoffs/messages/<from-role>-<to-role>.md
580
563
  ```
581
564
 
582
565
  Policy:
583
566
 
584
- - User can only send `user-request` to `project-manager`.
585
- - PM can send `task`, `question`, `review-request`, `revise`, `cancel` to non-PM roles.
586
- - Non-PM roles can send `result`, `question`, `blocked`, `finding` to PM.
567
+ - Roles never call a VCM CLI to send messages.
568
+ - A role writes or updates exactly one route file for each directed target role.
569
+ - File name format is `<from-role>-<to-role>.md`; the filename is the authoritative route.
570
+ - Blank route files are not pending.
571
+ - Non-empty route files are pending and are dispatched only by VCM.
572
+ - Optional YAML frontmatter may provide message type and metadata, but cannot override the route.
573
+ - PM-to-role and role-to-PM routes are the default policy. Peer route files are supported only when the task design explicitly allows them.
587
574
 
588
575
  Manual mode:
589
576
 
590
577
  ```text
591
- send -> pending_approval or queued -> Messages modal -> Copy/manual action
578
+ role writes route file -> Stop hook -> VCM records pending snapshot -> Messages modal -> Copy/manual action
592
579
  ```
593
580
 
594
- The current GUI shows sequence, timestamp, status, body preview, path, and a `Copy` button. 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.
581
+ The current GUI shows sequence, timestamp, status, route file path, body preview, `Copy`, and `Mark All Done`. VCM leaves the route file non-empty until the user confirms the pending content was handled or auto mode later dispatches it.
595
582
 
596
583
  Auto mode:
597
584
 
598
585
  ```text
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
586
+ role writes route file
587
+ Stop hook -> VCM scans pending route files
588
+ target idle and running -> VCM writes envelope + Enter -> submitted
589
+ submitted -> VCM archives body -> clears source route file
590
+ target busy/unavailable/failure -> source route file remains non-empty
591
+ target Stop hook -> VCM scans again and may deliver next pending route file
602
592
  ```
603
593
 
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.
594
+ The backend pastes a `[VCM MESSAGE]` envelope into the target terminal, then sends Enter as a separate terminal input event. A successful terminal submit is the delivery point for this design. VCM snapshots the message body before clearing the source route file so the message history remains auditable. Delivery is serialized per target role; VCM never sends two pending route files into the same target role during one scan.
595
+
596
+ VCM Harness owns Claude Code hook injection through `.claude/settings.json`. The target design injects only `Stop`. The hook posts directly to a local VCM backend endpoint and does not use `vcmctl`. `Stop` switches the role activity badge to `idle` and triggers a pending route-file scan. VCM marks a role `running` when it submits user input or a VCM message to that embedded terminal. VCM does not use Claude Code Subagent hooks for role delegation.
597
+
598
+ `Mark All Done` is a manual recovery action for stuck orchestration. It appends `acknowledged` snapshots for open messages and, after user confirmation, clears pending route files that the user already handled manually.
605
599
 
606
600
  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
601
 
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`.
602
+ The backend should not keep compatibility-only message command paths after this migration. Removing `vcmctl` is part of the target simplification.
609
603
 
610
- Messages and orchestration snapshots are task runtime state under `taskRepoRoot/.ai/vcm`. Message body markdown also lives in the task worktree handoff directory.
604
+ Messages and orchestration snapshots are task runtime state under `taskRepoRoot/.ai/vcm`. Pending route files live in the task worktree handoff directory and are cleared after successful VCM submission.
611
605
 
612
606
  ## 12. Round Completion Architecture
613
607
 
@@ -623,28 +617,29 @@ API:
623
617
  GET /api/tasks/:taskSlug/round
624
618
  ```
625
619
 
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:
620
+ 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
621
 
628
622
  - `unknown`
629
- - `answering`
630
- - `using_tools`
631
- - `waiting_user`
632
- - `abnormal`
633
623
  - `idle`
624
+ - `answering`
634
625
 
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`.
626
+ Mapping:
627
+
628
+ - VCM terminal submit updates the session to `activityStatus: "running"` and the round role state to `answering`
629
+ - `Stop` updates the session to `activityStatus: "idle"`, records `lastStopAt`, and the round role state becomes `idle`
636
630
 
637
631
  Task-level completion:
638
632
 
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.
633
+ - If a message is currently `submitted`, the latest such message defines the round target.
634
+ - 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
635
  - 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.
636
+ - If no VCM message is in the round, the latest direct role `Stop` can still produce a completion state.
643
637
 
644
638
  Frontend behavior:
645
639
 
646
640
  - `TaskWorkspace` polls the round endpoint with the other task state.
647
641
  - `App` stores the sidebar `Round alert` preference in `~/.vcm/settings.json`.
642
+ - `Try alert` is frontend-only and calls the same round completion notice/sound path without persisting any setting.
648
643
  - `App` deduplicates `completionId`, then shows a small `Round complete` prompt and plays a short Web Audio tone when alerts are enabled.
649
644
 
650
645
  ## 13. Role Command Compatibility
@@ -675,7 +670,7 @@ The dispatcher:
675
670
  4. Resolves primary command path `role-commands/<role>.md`, with legacy fallback `<role>-command.md`.
676
671
  5. Pastes `Please read and execute the role command at: <path>` to the target terminal, then sends Enter as a separate terminal input event.
677
672
 
678
- This is a compatibility path. The preferred V1 coordination path is `vcmctl` message bus.
673
+ This is an obsolete compatibility path and should be removed when route-file messaging lands. The preferred V1 coordination path is VCM-dispatched route files under `.ai/vcm/handoffs/messages/`.
679
674
 
680
675
  ## 14. Harness Service
681
676
 
@@ -688,6 +683,7 @@ Harness files:
688
683
  ```text
689
684
  CLAUDE.md
690
685
  .gitignore
686
+ .claude/settings.json
691
687
  .claude/agents/project-manager.md
692
688
  .claude/agents/architect.md
693
689
  .claude/agents/coder.md
@@ -711,6 +707,8 @@ Managed block:
711
707
  # VCM:END
712
708
  ```
713
709
 
710
+ `.claude/settings.json` is JSON-merged by the harness. VCM preserves existing settings and adds a `Stop` hook that posts directly to the local VCM backend using the session-provided VCM API URL, task slug, role, and Claude session id. The hook must not call `vcmctl`.
711
+
714
712
  The service:
715
713
 
716
714
  - checks whether files exist
@@ -890,14 +888,17 @@ Messages:
890
888
 
891
889
  ```text
892
890
  GET /api/tasks/:taskSlug/messages
893
- POST /api/tasks/:taskSlug/messages
894
- POST /api/tasks/:taskSlug/messages/:messageId/stage
895
- POST /api/tasks/:taskSlug/messages/:messageId/approve
896
- POST /api/tasks/:taskSlug/messages/:messageId/reject
891
+ GET /api/tasks/:taskSlug/messages/pending-route-files
892
+ POST /api/tasks/:taskSlug/messages/scan
893
+ POST /api/tasks/:taskSlug/messages/mark-all-done
897
894
  GET /api/tasks/:taskSlug/orchestration
898
895
  PUT /api/tasks/:taskSlug/orchestration
899
- POST /api/tasks/:taskSlug/orchestration/pause
900
- POST /api/tasks/:taskSlug/orchestration/resume
896
+ ```
897
+
898
+ Claude Code hooks:
899
+
900
+ ```text
901
+ POST /api/hooks/claude-code/stop
901
902
  ```
902
903
 
903
904
  Round:
@@ -972,7 +973,6 @@ Fastify error handler returns:
972
973
  Bins:
973
974
 
974
975
  - `vcm` -> `dist/main.js`
975
- - `vcmctl` -> `dist/cli/vcmctl.js`
976
976
 
977
977
  Important scripts:
978
978
 
@@ -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 workflow gate enforcement.
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.