claude-code-session-manager 0.117.0 → 0.119.0
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/dist/assets/{AgentLibrary-BLRc_YvR.js → AgentLibrary-CdRrehRI.js} +1 -1
- package/dist/assets/{Button-DHEnLfDi.js → Button-BTANn6A_.js} +1 -1
- package/dist/assets/{DataModel-C2ytUxJm.js → DataModel-D4DhKYDV.js} +1 -1
- package/dist/assets/{History-eoVSG_DX.js → History-Dd1SM-AR.js} +1 -1
- package/dist/assets/{Hooks-rS9UvMcI.js → Hooks-BaSxmXkk.js} +1 -1
- package/dist/assets/{Library-CdUqaZIj.js → Library-DiRx14Qs.js} +1 -1
- package/dist/assets/{ListDetail-DhtJPQvm.js → ListDetail-DD12P0m2.js} +1 -1
- package/dist/assets/{McpServers-DoOcEGFd.js → McpServers-B5Zhq3uc.js} +1 -1
- package/dist/assets/{Memory-BbYwtTBZ.js → Memory-D8Uibw65.js} +1 -1
- package/dist/assets/{Panel-M4ouFOKI.js → Panel-cUxN--SY.js} +1 -1
- package/dist/assets/{Permissions-DB0DjkgF.js → Permissions-CgocoJzX.js} +1 -1
- package/dist/assets/{Plugins-DnBwH9PN.js → Plugins-BJPK6dlg.js} +2 -2
- package/dist/assets/{ProvenanceBadge-1MQmqxxO.js → ProvenanceBadge-Cw0cwJ1w.js} +1 -1
- package/dist/assets/{RemoteMachines-DnT08vg8.js → RemoteMachines-BIaTLP0C.js} +1 -1
- package/dist/assets/{SaveBar-DGBVV6ro.js → SaveBar-DlGYYdsI.js} +1 -1
- package/dist/assets/{Scheduler-CGDLYpdc.js → Scheduler-I4qOJsyy.js} +1 -1
- package/dist/assets/{ScopeSwitcher-jgpoKdvH.js → ScopeSwitcher-hTMYmy6R.js} +1 -1
- package/dist/assets/{Settings-Ch0zc2cZ.js → Settings-C8AGOoqw.js} +1 -1
- package/dist/assets/{SkillReferenceGraph-Cd04i1nZ.js → SkillReferenceGraph-D9a_UFm6.js} +1 -1
- package/dist/assets/{Skills-DLJLLulV.js → Skills-Bzn5Wasd.js} +1 -1
- package/dist/assets/{SystemPrompt-E4VOiMJN.js → SystemPrompt-D0LpRn5u.js} +1 -1
- package/dist/assets/{TagLibrary-2sCAw54h.js → TagLibrary-CgqAdpwI.js} +1 -1
- package/dist/assets/{TiptapBody-CzqJev6v.js → TiptapBody-u-CUpM2Q.js} +1 -1
- package/dist/assets/{Toggle-D5znlR_5.js → Toggle-Bb6BJMNB.js} +1 -1
- package/dist/assets/{ViewTabs-BENAWvOs.js → ViewTabs-Ck2NIjLp.js} +1 -1
- package/dist/assets/{historyTotals-DsE82z-I.js → historyTotals-vNPWEsnZ.js} +1 -1
- package/dist/assets/{index-B_3CV5Po.js → index-Cq-Ppqar.js} +3 -3
- package/dist/assets/{settingsSchema-CmuwD4OX.js → settingsSchema-D2dkl1uu.js} +1 -1
- package/dist/assets/{skillFrontmatter-CdlHJV9x.js → skillFrontmatter-CW0PqdDX.js} +1 -1
- package/dist/assets/{useAgentsDirWatch-RVq9wMFY.js → useAgentsDirWatch-C9ya0GpQ.js} +1 -1
- package/dist/assets/{useRemotePeers-Cpt47RWb.js → useRemotePeers-4evTc_IE.js} +1 -1
- package/dist/index.html +1 -1
- package/package.json +1 -1
- package/plugins/session-manager-dev/skills/develop/SKILL.md +13 -10
- package/src/main/build-info.json +4 -4
- package/src/main/lib/epic/epicSettle.cjs +105 -0
- package/src/main/lib/epic/epicSweepValidator.cjs +74 -0
- package/src/main/lib/epic/epicValidationHook.cjs +171 -141
- package/src/main/lib/prd/prdCreate.cjs +23 -0
- package/src/main/lib/prd/prdWorktreeReach.cjs +77 -0
- package/src/main/lib/scheduler/rcaReport.cjs +14 -2
- package/src/main/promptSessionEvents.cjs +5 -1
- package/src/main/scheduler.cjs +38 -61
- package/src/main/templates/PRD_AUTHORING.md +5 -1
- package/src/main/webRemote.cjs +27 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{aF as b,ap as n,S as N,a_ as O}from"./index-B_3CV5Po.js";import{r as K}from"./claude-settings-schema-COigsajx.js";function G({node:e,targetScope:r,onOverride:s,schema:a,rootLabel:m}){const[f,x]=b.useState(""),[u,o]=b.useState(!0),g=[],d=e.kind==="object"&&Object.keys(e.children).length===0,y=((a==null?void 0:a.rootKeys())??[]).length>0;return n.jsxs("div",{className:"h-full flex flex-col",children:[n.jsxs("div",{className:"shrink-0 border-b border-line bg-bg-elev px-3 py-1.5 flex items-center gap-2 text-xs",children:[n.jsxs("span",{className:"text-fg-faint",children:["merged · overrides → ",n.jsx("span",{className:"text-fg-dim",children:N[r].label})]}),y&&n.jsxs("label",{className:"flex items-center gap-1 text-fg-faint cursor-pointer",children:[n.jsx("input",{type:"checkbox",checked:u,onChange:t=>o(t.target.checked),className:"accent-accent"}),"show unset keys"]}),n.jsx("div",{className:"flex-1"}),n.jsx("input",{value:f,onChange:t=>x(t.target.value),placeholder:"filter keys or descriptions…",className:"bg-bg border border-line rounded px-2 py-0.5 text-xs text-fg w-56"})]}),n.jsx("div",{className:"flex-1 overflow-auto px-3 py-2 font-mono text-xs",children:d&&!u?n.jsx("div",{className:"text-fg-faint italic px-2 py-4",children:"no settings resolved — all scope files empty or missing"}):n.jsx(E,{node:e,path:g,label:m??"(root)",targetScope:r,onOverride:s,filter:f,depth:0,schema:a,showGhosts:u,defaultOpen:!0})})]})}function E(e){return e.node.kind==="object"?n.jsx(P,{...e,node:e.node}):e.node.kind==="array"?n.jsx(J,{...e,node:e.node}):n.jsx(R,{...e,node:e.node})}function A(e,r){return r.trim()?e.toLowerCase().includes(r.toLowerCase()):!0}function w(e,r,s){return!!(!s.trim()||e.some(a=>A(a,s))||r!=null&&r.description&&A(r.description,s))}function P({node:e,path:r,label:s,targetScope:a,onOverride:m,filter:f,depth:x,schema:u,showGhosts:o,defaultOpen:g}){const[d,h]=b.useState(g??x<2),y=(u==null?void 0:u.at(r))??null,t=new Set(Object.keys(e.children)),i=o?(y==null?void 0:y.knownChildren)??[]:[],c=Array.from(new Set([...t,...i])).sort(),l=b.useMemo(()=>f.trim()?c.filter(p=>{const v=(u==null?void 0:u.at([...r,p]))??null;return w([...r,p],v,f)?!0:t.has(p)?L(e.children[p],[...r,p],f,u):!1}):c,[c.join(","),f,e,r.join("."),u]);if(f.trim()&&l.length===0&&!w(r,y,f))return null;if(r.length===0)return n.jsx("div",{children:l.map(p=>j(p))});return n.jsxs("div",{children:[n.jsxs("div",{className:"flex items-center gap-1 py-0.5 hover:bg-bg-elev/50 rounded cursor-pointer",style:{paddingLeft:x*14},onClick:()=>h(!d),children:[n.jsx("span",{className:"text-fg-faint w-3 shrink-0",children:d?"▾":"▸"}),n.jsx("span",{className:"text-fg",children:s}),n.jsxs("span",{className:"text-fg-faint",children:[" {",t.size,i.length>t.size?`/${new Set([...t,...i]).size}`:"","}"]}),(y==null?void 0:y.description)&&n.jsxs("span",{className:"text-fg-faint truncate max-w-md",title:y.description,children:["— ",y.description]})]}),d&&l.map(p=>j(p))]});function j(p){if(t.has(p))return n.jsx(E,{node:e.children[p],path:[...r,p],label:p,targetScope:a,onOverride:m,filter:f,depth:x+1,schema:u,showGhosts:o},p);const v=(u==null?void 0:u.at([...r,p]))??null;return v?n.jsx(_,{path:[...r,p],label:p,info:v,targetScope:a,onSet:m,depth:x+1,filter:f},p):null}}function L(e,r,s,a){const m=(a==null?void 0:a.at(r))??null;if(w(r,m,s))return!0;if(e.kind!=="object")return!1;for(const f of Object.keys(e.children))if(L(e.children[f],[...r,f],s,a))return!0;return!1}function J({node:e,path:r,label:s,filter:a,depth:m,schema:f}){const[x,u]=b.useState(!0),o=(f==null?void 0:f.at(r))??null;return w(r,o,a)?n.jsxs("div",{children:[n.jsxs("div",{className:"flex items-center gap-1 py-0.5 hover:bg-bg-elev/50 rounded cursor-pointer",style:{paddingLeft:m*14},onClick:()=>u(!x),children:[n.jsx("span",{className:"text-fg-faint w-3 shrink-0",children:x?"▾":"▸"}),n.jsx("span",{className:"text-fg",children:s}),n.jsxs("span",{className:"text-fg-faint",children:[" [",e.items.length,"]"]}),n.jsx(S,{tone:"warn",children:"accumulated"}),(o==null?void 0:o.description)&&n.jsxs("span",{className:"text-fg-faint truncate max-w-md",title:o.description,children:["— ",o.description]})]}),x&&e.items.map((g,d)=>n.jsxs("div",{className:"flex items-start gap-2 py-0.5",style:{paddingLeft:(m+1)*14},children:[n.jsx("span",{className:"text-fg-faint w-3 shrink-0"}),n.jsxs("span",{className:"text-fg-faint",children:[d,":"]}),n.jsx("span",{className:"text-fg-dim truncate max-w-xl",children:k(g.value)}),n.jsx(C,{scope:g.fromScope})]},d))]}):null}function R({node:e,path:r,label:s,targetScope:a,onOverride:m,filter:f,depth:x,schema:u}){const[o,g]=b.useState(!1),d=(u==null?void 0:u.at(r))??null;if(!w(r,d,f))return null;const h=e.winner!==a,y=e.shadowed.length>0;return n.jsxs("div",{children:[n.jsxs("div",{className:"group flex items-center gap-2 py-0.5 hover:bg-bg-elev/50 rounded",style:{paddingLeft:x*14},children:[n.jsx("span",{className:`w-3 shrink-0 ${y?"text-fg-faint cursor-pointer":""}`,onClick:()=>y&&g(!o),children:y?o?"▾":"▸":""}),n.jsxs("span",{className:"text-fg",children:[s,":"]}),n.jsx("span",{className:"text-fg-dim truncate max-w-md",children:k(e.value)}),n.jsx(C,{scope:e.winner}),(d==null?void 0:d.deprecated)&&n.jsx(S,{tone:"warn",children:"deprecated"}),(d==null?void 0:d.default)!==void 0&&I(e.value,d.default)&&n.jsx(S,{tone:"dim",children:"= default"}),e.typeMismatch&&n.jsx("span",{className:"text-yellow-500/80",title:"shadowed scopes have a different value type",children:"⚠"}),(d==null?void 0:d.description)&&n.jsxs("span",{className:"text-fg-faint truncate max-w-md",title:d.description,children:["— ",d.description]}),n.jsx("div",{className:"flex-1"}),(d==null?void 0:d.enum)&&n.jsx(F,{values:d.enum}),n.jsx("button",{disabled:!h,onClick:()=>m(r,e.value),className:`opacity-0 group-hover:opacity-100 px-1.5 py-0 text-[10px] border rounded transition-opacity ${h?"border-accent/50 text-accent hover:bg-accent hover:text-bg":"border-line text-fg-faint cursor-not-allowed"}`,title:h?`copy into ${N[a].label} draft`:`already winning in ${N[a].label}`,children:"override"})]}),o&&e.shadowed.map((t,i)=>n.jsxs("div",{className:"flex items-center gap-2 py-0.5 text-fg-faint line-through",style:{paddingLeft:(x+1)*14+12},children:[n.jsx("span",{children:"shadowed:"}),n.jsx("span",{className:"truncate max-w-xl",children:k(t.value)}),n.jsx(C,{scope:t.scope,dim:!0})]},i))]})}function _({path:e,label:r,info:s,targetScope:a,onSet:m,depth:f,filter:x}){if(!w(e,s,x))return null;const u=s.default!==void 0?s.default:M(s.type),o=Array.isArray(s.type)?s.type.join("|"):s.type??"?";return n.jsxs("div",{className:"group flex items-center gap-2 py-0.5 hover:bg-bg-elev/50 rounded opacity-60",style:{paddingLeft:f*14},children:[n.jsx("span",{className:"w-3 shrink-0"}),n.jsx("span",{className:"text-fg-dim",children:r}),n.jsx(S,{tone:"dim",children:o}),s.required&&n.jsx(S,{tone:"warn",children:"required"}),s.default!==void 0&&n.jsxs("span",{className:"text-fg-faint",children:["default: ",k(s.default)]}),s.description&&n.jsxs("span",{className:"text-fg-faint truncate max-w-md",title:s.description,children:["— ",s.description]}),n.jsx("div",{className:"flex-1"}),s.enum&&n.jsx(F,{values:s.enum}),n.jsx("button",{onClick:()=>m(e,u),className:"opacity-0 group-hover:opacity-100 px-1.5 py-0 text-[10px] border border-accent/50 rounded text-accent hover:bg-accent hover:text-bg transition-opacity",title:`write to ${N[a].label} draft`,children:"set"})]})}function I(e,r){return e===r?!0:typeof e!=typeof r?!1:e&&r&&typeof e=="object"?JSON.stringify(e)===JSON.stringify(r):!1}function M(e){switch(Array.isArray(e)?e[0]:e){case"boolean":return!1;case"integer":case"number":return 0;case"string":return"";case"array":return[];case"object":return{};case"null":return null;default:return null}}function k(e){if(typeof e=="string")return JSON.stringify(e);if(e===null)return"null";if(typeof e=="object"){const r=JSON.stringify(e);return r.length>100?r.slice(0,100)+"…":r}return String(e)}function C({scope:e,dim:r}){const s=e==="user"?"bg-bg-hi text-fg-dim border-line":e==="project"?"bg-blue-950/30 text-blue-400/80 border-blue-900/40":"bg-purple-950/30 text-purple-400/80 border-purple-900/40";return n.jsx("span",{className:`text-[10px] px-1 py-0 rounded border uppercase tracking-wide shrink-0 ${s} ${r?"opacity-60":""}`,children:N[e].label})}function S({children:e,tone:r="default"}){const s={default:"bg-bg-hi text-fg-dim border-line",warn:"bg-yellow-950/30 text-yellow-500/80 border-yellow-900/40",dim:"bg-bg-elev text-fg-faint border-line"}[r];return n.jsx("span",{className:`text-[10px] px-1 py-0 rounded border uppercase tracking-wide shrink-0 ${s}`,children:e})}function F({values:e}){const r=e.map(s=>String(s)).join(" | ");return n.jsxs("span",{className:"text-[10px] text-fg-faint truncate max-w-xs",title:`allowed: ${r}`,children:["∈ ",r.length>30?r.slice(0,30)+"…":r]})}function V(e,r,s){const a=O(o=>o.files),m=O(o=>o.loadJson),f=O(o=>o.watchFile),x=O(o=>o.unwatchFile),u=b.useMemo(()=>{const o={};for(const g of e.scopes){const d=e.resolve(g,r??"",s);d&&(o[g]=d)}return o},[e,r,s]);return b.useEffect(()=>{const o=Object.values(u).filter(Boolean);return o.forEach(g=>{a[g]||m(g),f(g)}),()=>{o.forEach(g=>x(g))}},[JSON.stringify(u)]),u}function B(e){const r=e??{},s={...r.$defs??{},...r.definitions??{}},a=t=>{if(!t)return{};if(!t.$ref)return x(t);const i=/^#\/(\$defs|definitions)\/(.+)$/.exec(t.$ref);if(!i)return x(t);const c=s[i[2]];return c?a({...c,...u(t)}):x(t)},m=new Set(["__proto__","constructor","prototype"]),f=t=>{if(!t)return{};const i={};for(const[c,l]of Object.entries(t))m.has(c)||(i[c]=l);return i},x=t=>{if(!t.allOf||t.allOf.length===0)return t;const i={...t};delete i.allOf;for(const c of t.allOf){const l=a(c);Object.assign(i,{properties:{...f(i.properties),...f(l.properties)},required:q([...i.required??[],...l.required??[]])}),!i.description&&l.description&&(i.description=l.description),i.default===void 0&&l.default!==void 0&&(i.default=l.default),!i.type&&l.type&&(i.type=l.type)}return i},u=t=>{const{$ref:i,...c}=t;return c},o=(t,i)=>{let c=a(t);for(const l of i){if(!c)return null;if(/^\d+$/.test(l)){const v=Array.isArray(c.items)?c.items[Number(l)]:c.items;c=v?a(v):null;continue}const j=c.properties;if(j&&!m.has(l)&&l in j){c=a(j[l]);continue}const p=c.additionalProperties;if(p&&typeof p=="object"){c=a(p);continue}return null}return c},g=(t,i,c)=>{if(!t)return null;const l={};if(t.description&&(l.description=t.description),t.type&&(l.type=t.type),t.default!==void 0&&(l.default=t.default),t.enum&&(l.enum=t.enum),t.const!==void 0&&(l.const=t.const),t.deprecated&&(l.deprecated=!0),t.examples&&(l.examples=t.examples),t.properties&&(l.knownChildren=Object.keys(t.properties)),c&&(i!=null&&i.includes(c))&&(l.required=!0),t.items&&!Array.isArray(t.items)){const j=a(t.items),p=g(j,void 0,null);p&&(l.itemsInfo=p)}return(t.additionalProperties===!0||typeof t.additionalProperties=="object")&&(l.open=!0),l},d=t=>i=>{if(i.length===0)return g(a(t),void 0,null);const c=o(t,i.slice(0,-1));if(!c)return null;const l=i[i.length-1],j=o(c,[l]);return g(j,c.required,l)},h=t=>{const i=a(t);return Object.keys(i.properties??{})},y=t=>({at:d(t),rootKeys:()=>h(t),rootedAt:i=>{const c=o(t,i);return y(c??{})}});return y(r)}function q(e){return Array.from(new Set(e))}let $=null;function D(){return $||($=B(K)),$}export{G as E,D as s,V as u};
|
|
1
|
+
import{aF as b,ap as n,S as N,a_ as O}from"./index-Cq-Ppqar.js";import{r as K}from"./claude-settings-schema-COigsajx.js";function G({node:e,targetScope:r,onOverride:s,schema:a,rootLabel:m}){const[f,x]=b.useState(""),[u,o]=b.useState(!0),g=[],d=e.kind==="object"&&Object.keys(e.children).length===0,y=((a==null?void 0:a.rootKeys())??[]).length>0;return n.jsxs("div",{className:"h-full flex flex-col",children:[n.jsxs("div",{className:"shrink-0 border-b border-line bg-bg-elev px-3 py-1.5 flex items-center gap-2 text-xs",children:[n.jsxs("span",{className:"text-fg-faint",children:["merged · overrides → ",n.jsx("span",{className:"text-fg-dim",children:N[r].label})]}),y&&n.jsxs("label",{className:"flex items-center gap-1 text-fg-faint cursor-pointer",children:[n.jsx("input",{type:"checkbox",checked:u,onChange:t=>o(t.target.checked),className:"accent-accent"}),"show unset keys"]}),n.jsx("div",{className:"flex-1"}),n.jsx("input",{value:f,onChange:t=>x(t.target.value),placeholder:"filter keys or descriptions…",className:"bg-bg border border-line rounded px-2 py-0.5 text-xs text-fg w-56"})]}),n.jsx("div",{className:"flex-1 overflow-auto px-3 py-2 font-mono text-xs",children:d&&!u?n.jsx("div",{className:"text-fg-faint italic px-2 py-4",children:"no settings resolved — all scope files empty or missing"}):n.jsx(E,{node:e,path:g,label:m??"(root)",targetScope:r,onOverride:s,filter:f,depth:0,schema:a,showGhosts:u,defaultOpen:!0})})]})}function E(e){return e.node.kind==="object"?n.jsx(P,{...e,node:e.node}):e.node.kind==="array"?n.jsx(J,{...e,node:e.node}):n.jsx(R,{...e,node:e.node})}function A(e,r){return r.trim()?e.toLowerCase().includes(r.toLowerCase()):!0}function w(e,r,s){return!!(!s.trim()||e.some(a=>A(a,s))||r!=null&&r.description&&A(r.description,s))}function P({node:e,path:r,label:s,targetScope:a,onOverride:m,filter:f,depth:x,schema:u,showGhosts:o,defaultOpen:g}){const[d,h]=b.useState(g??x<2),y=(u==null?void 0:u.at(r))??null,t=new Set(Object.keys(e.children)),i=o?(y==null?void 0:y.knownChildren)??[]:[],c=Array.from(new Set([...t,...i])).sort(),l=b.useMemo(()=>f.trim()?c.filter(p=>{const v=(u==null?void 0:u.at([...r,p]))??null;return w([...r,p],v,f)?!0:t.has(p)?L(e.children[p],[...r,p],f,u):!1}):c,[c.join(","),f,e,r.join("."),u]);if(f.trim()&&l.length===0&&!w(r,y,f))return null;if(r.length===0)return n.jsx("div",{children:l.map(p=>j(p))});return n.jsxs("div",{children:[n.jsxs("div",{className:"flex items-center gap-1 py-0.5 hover:bg-bg-elev/50 rounded cursor-pointer",style:{paddingLeft:x*14},onClick:()=>h(!d),children:[n.jsx("span",{className:"text-fg-faint w-3 shrink-0",children:d?"▾":"▸"}),n.jsx("span",{className:"text-fg",children:s}),n.jsxs("span",{className:"text-fg-faint",children:[" {",t.size,i.length>t.size?`/${new Set([...t,...i]).size}`:"","}"]}),(y==null?void 0:y.description)&&n.jsxs("span",{className:"text-fg-faint truncate max-w-md",title:y.description,children:["— ",y.description]})]}),d&&l.map(p=>j(p))]});function j(p){if(t.has(p))return n.jsx(E,{node:e.children[p],path:[...r,p],label:p,targetScope:a,onOverride:m,filter:f,depth:x+1,schema:u,showGhosts:o},p);const v=(u==null?void 0:u.at([...r,p]))??null;return v?n.jsx(_,{path:[...r,p],label:p,info:v,targetScope:a,onSet:m,depth:x+1,filter:f},p):null}}function L(e,r,s,a){const m=(a==null?void 0:a.at(r))??null;if(w(r,m,s))return!0;if(e.kind!=="object")return!1;for(const f of Object.keys(e.children))if(L(e.children[f],[...r,f],s,a))return!0;return!1}function J({node:e,path:r,label:s,filter:a,depth:m,schema:f}){const[x,u]=b.useState(!0),o=(f==null?void 0:f.at(r))??null;return w(r,o,a)?n.jsxs("div",{children:[n.jsxs("div",{className:"flex items-center gap-1 py-0.5 hover:bg-bg-elev/50 rounded cursor-pointer",style:{paddingLeft:m*14},onClick:()=>u(!x),children:[n.jsx("span",{className:"text-fg-faint w-3 shrink-0",children:x?"▾":"▸"}),n.jsx("span",{className:"text-fg",children:s}),n.jsxs("span",{className:"text-fg-faint",children:[" [",e.items.length,"]"]}),n.jsx(S,{tone:"warn",children:"accumulated"}),(o==null?void 0:o.description)&&n.jsxs("span",{className:"text-fg-faint truncate max-w-md",title:o.description,children:["— ",o.description]})]}),x&&e.items.map((g,d)=>n.jsxs("div",{className:"flex items-start gap-2 py-0.5",style:{paddingLeft:(m+1)*14},children:[n.jsx("span",{className:"text-fg-faint w-3 shrink-0"}),n.jsxs("span",{className:"text-fg-faint",children:[d,":"]}),n.jsx("span",{className:"text-fg-dim truncate max-w-xl",children:k(g.value)}),n.jsx(C,{scope:g.fromScope})]},d))]}):null}function R({node:e,path:r,label:s,targetScope:a,onOverride:m,filter:f,depth:x,schema:u}){const[o,g]=b.useState(!1),d=(u==null?void 0:u.at(r))??null;if(!w(r,d,f))return null;const h=e.winner!==a,y=e.shadowed.length>0;return n.jsxs("div",{children:[n.jsxs("div",{className:"group flex items-center gap-2 py-0.5 hover:bg-bg-elev/50 rounded",style:{paddingLeft:x*14},children:[n.jsx("span",{className:`w-3 shrink-0 ${y?"text-fg-faint cursor-pointer":""}`,onClick:()=>y&&g(!o),children:y?o?"▾":"▸":""}),n.jsxs("span",{className:"text-fg",children:[s,":"]}),n.jsx("span",{className:"text-fg-dim truncate max-w-md",children:k(e.value)}),n.jsx(C,{scope:e.winner}),(d==null?void 0:d.deprecated)&&n.jsx(S,{tone:"warn",children:"deprecated"}),(d==null?void 0:d.default)!==void 0&&I(e.value,d.default)&&n.jsx(S,{tone:"dim",children:"= default"}),e.typeMismatch&&n.jsx("span",{className:"text-yellow-500/80",title:"shadowed scopes have a different value type",children:"⚠"}),(d==null?void 0:d.description)&&n.jsxs("span",{className:"text-fg-faint truncate max-w-md",title:d.description,children:["— ",d.description]}),n.jsx("div",{className:"flex-1"}),(d==null?void 0:d.enum)&&n.jsx(F,{values:d.enum}),n.jsx("button",{disabled:!h,onClick:()=>m(r,e.value),className:`opacity-0 group-hover:opacity-100 px-1.5 py-0 text-[10px] border rounded transition-opacity ${h?"border-accent/50 text-accent hover:bg-accent hover:text-bg":"border-line text-fg-faint cursor-not-allowed"}`,title:h?`copy into ${N[a].label} draft`:`already winning in ${N[a].label}`,children:"override"})]}),o&&e.shadowed.map((t,i)=>n.jsxs("div",{className:"flex items-center gap-2 py-0.5 text-fg-faint line-through",style:{paddingLeft:(x+1)*14+12},children:[n.jsx("span",{children:"shadowed:"}),n.jsx("span",{className:"truncate max-w-xl",children:k(t.value)}),n.jsx(C,{scope:t.scope,dim:!0})]},i))]})}function _({path:e,label:r,info:s,targetScope:a,onSet:m,depth:f,filter:x}){if(!w(e,s,x))return null;const u=s.default!==void 0?s.default:M(s.type),o=Array.isArray(s.type)?s.type.join("|"):s.type??"?";return n.jsxs("div",{className:"group flex items-center gap-2 py-0.5 hover:bg-bg-elev/50 rounded opacity-60",style:{paddingLeft:f*14},children:[n.jsx("span",{className:"w-3 shrink-0"}),n.jsx("span",{className:"text-fg-dim",children:r}),n.jsx(S,{tone:"dim",children:o}),s.required&&n.jsx(S,{tone:"warn",children:"required"}),s.default!==void 0&&n.jsxs("span",{className:"text-fg-faint",children:["default: ",k(s.default)]}),s.description&&n.jsxs("span",{className:"text-fg-faint truncate max-w-md",title:s.description,children:["— ",s.description]}),n.jsx("div",{className:"flex-1"}),s.enum&&n.jsx(F,{values:s.enum}),n.jsx("button",{onClick:()=>m(e,u),className:"opacity-0 group-hover:opacity-100 px-1.5 py-0 text-[10px] border border-accent/50 rounded text-accent hover:bg-accent hover:text-bg transition-opacity",title:`write to ${N[a].label} draft`,children:"set"})]})}function I(e,r){return e===r?!0:typeof e!=typeof r?!1:e&&r&&typeof e=="object"?JSON.stringify(e)===JSON.stringify(r):!1}function M(e){switch(Array.isArray(e)?e[0]:e){case"boolean":return!1;case"integer":case"number":return 0;case"string":return"";case"array":return[];case"object":return{};case"null":return null;default:return null}}function k(e){if(typeof e=="string")return JSON.stringify(e);if(e===null)return"null";if(typeof e=="object"){const r=JSON.stringify(e);return r.length>100?r.slice(0,100)+"…":r}return String(e)}function C({scope:e,dim:r}){const s=e==="user"?"bg-bg-hi text-fg-dim border-line":e==="project"?"bg-blue-950/30 text-blue-400/80 border-blue-900/40":"bg-purple-950/30 text-purple-400/80 border-purple-900/40";return n.jsx("span",{className:`text-[10px] px-1 py-0 rounded border uppercase tracking-wide shrink-0 ${s} ${r?"opacity-60":""}`,children:N[e].label})}function S({children:e,tone:r="default"}){const s={default:"bg-bg-hi text-fg-dim border-line",warn:"bg-yellow-950/30 text-yellow-500/80 border-yellow-900/40",dim:"bg-bg-elev text-fg-faint border-line"}[r];return n.jsx("span",{className:`text-[10px] px-1 py-0 rounded border uppercase tracking-wide shrink-0 ${s}`,children:e})}function F({values:e}){const r=e.map(s=>String(s)).join(" | ");return n.jsxs("span",{className:"text-[10px] text-fg-faint truncate max-w-xs",title:`allowed: ${r}`,children:["∈ ",r.length>30?r.slice(0,30)+"…":r]})}function V(e,r,s){const a=O(o=>o.files),m=O(o=>o.loadJson),f=O(o=>o.watchFile),x=O(o=>o.unwatchFile),u=b.useMemo(()=>{const o={};for(const g of e.scopes){const d=e.resolve(g,r??"",s);d&&(o[g]=d)}return o},[e,r,s]);return b.useEffect(()=>{const o=Object.values(u).filter(Boolean);return o.forEach(g=>{a[g]||m(g),f(g)}),()=>{o.forEach(g=>x(g))}},[JSON.stringify(u)]),u}function B(e){const r=e??{},s={...r.$defs??{},...r.definitions??{}},a=t=>{if(!t)return{};if(!t.$ref)return x(t);const i=/^#\/(\$defs|definitions)\/(.+)$/.exec(t.$ref);if(!i)return x(t);const c=s[i[2]];return c?a({...c,...u(t)}):x(t)},m=new Set(["__proto__","constructor","prototype"]),f=t=>{if(!t)return{};const i={};for(const[c,l]of Object.entries(t))m.has(c)||(i[c]=l);return i},x=t=>{if(!t.allOf||t.allOf.length===0)return t;const i={...t};delete i.allOf;for(const c of t.allOf){const l=a(c);Object.assign(i,{properties:{...f(i.properties),...f(l.properties)},required:q([...i.required??[],...l.required??[]])}),!i.description&&l.description&&(i.description=l.description),i.default===void 0&&l.default!==void 0&&(i.default=l.default),!i.type&&l.type&&(i.type=l.type)}return i},u=t=>{const{$ref:i,...c}=t;return c},o=(t,i)=>{let c=a(t);for(const l of i){if(!c)return null;if(/^\d+$/.test(l)){const v=Array.isArray(c.items)?c.items[Number(l)]:c.items;c=v?a(v):null;continue}const j=c.properties;if(j&&!m.has(l)&&l in j){c=a(j[l]);continue}const p=c.additionalProperties;if(p&&typeof p=="object"){c=a(p);continue}return null}return c},g=(t,i,c)=>{if(!t)return null;const l={};if(t.description&&(l.description=t.description),t.type&&(l.type=t.type),t.default!==void 0&&(l.default=t.default),t.enum&&(l.enum=t.enum),t.const!==void 0&&(l.const=t.const),t.deprecated&&(l.deprecated=!0),t.examples&&(l.examples=t.examples),t.properties&&(l.knownChildren=Object.keys(t.properties)),c&&(i!=null&&i.includes(c))&&(l.required=!0),t.items&&!Array.isArray(t.items)){const j=a(t.items),p=g(j,void 0,null);p&&(l.itemsInfo=p)}return(t.additionalProperties===!0||typeof t.additionalProperties=="object")&&(l.open=!0),l},d=t=>i=>{if(i.length===0)return g(a(t),void 0,null);const c=o(t,i.slice(0,-1));if(!c)return null;const l=i[i.length-1],j=o(c,[l]);return g(j,c.required,l)},h=t=>{const i=a(t);return Object.keys(i.properties??{})},y=t=>({at:d(t),rootKeys:()=>h(t),rootedAt:i=>{const c=o(t,i);return y(c??{})}});return y(r)}function q(e){return Array.from(new Set(e))}let $=null;function D(){return $||($=B(K)),$}export{G as E,D as s,V as u};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{ap as k,F as E}from"./index-
|
|
1
|
+
import{ap as k,F as E}from"./index-Cq-Ppqar.js";function M({value:t,onChange:n,path:e,readOnly:i}){return k.jsx(E,{path:`file://${e}`,defaultLanguage:"markdown",value:t,onChange:s=>n(s??""),theme:"vs-dark",options:{minimap:{enabled:!1},fontSize:13,fontFamily:"JetBrains Mono, ui-monospace, Menlo, monospace",lineNumbers:"on",renderLineHighlight:"line",scrollBeyondLastLine:!1,tabSize:2,wordWrap:"on",readOnly:i,automaticLayout:!0}})}const f=/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/,u="disable-model-invocation",g=/^\s*disable-model-invocation\s*:/;function j(t){const n=t.match(f);if(!n)return!1;for(const e of n[1].split(/\r?\n/)){if(!g.test(e))continue;const i=e.slice(e.indexOf(":")+1).trim().toLowerCase();return i==="true"||i==="yes"}return!1}function S(t){const n=t.trim();return n.length>=2&&(n[0]==='"'&&n[n.length-1]==='"'||n[0]==="'"&&n[n.length-1]==="'")?n.slice(1,-1):n}function h(t){return t.length-t.trimStart().length}function v(t){const n=t.match(f);if(!n)return{name:null,description:null,body:t};const e=n[1].split(/\r?\n/),i=n[2]??"";let s=null,r=null;for(let o=0;o<e.length;o++){const m=e[o],d=m.match(/^(\s*)(name|description)\s*:(.*)$/);if(!d)continue;const[,,y,$]=d,l=$.trim(),b=h(m);let c;if(l===""||l===">-"||l===">"||l==="|-"||l==="|"){const p=[];let a=o+1;for(;a<e.length&&e[a].trim()!==""&&h(e[a])>b;)p.push(e[a].trim()),a++;c=p.join(" ")}else c=S(l);y==="name"?s=c:r=c}return{name:s,description:r,body:i}}function w(t,n){const e=t.match(f);if(!e){if(!n)return t;const o=t.startsWith(`
|
|
2
2
|
`)?"":`
|
|
3
3
|
`;return`---
|
|
4
4
|
${u}: true
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{W as e,b4 as a,a$ as n}from"./index-
|
|
1
|
+
import{W as e,b4 as a,a$ as n}from"./index-Cq-Ppqar.js";const c=new Set(e.map(t=>t.tag));function l(t){return t.filter(o=>c.has(o))}function s(t,o={}){return{name:t.name,originalName:t.name,description:t.description??"",tools:t.tools,model:t.model??"inherit",effort:t.effort??void 0,color:t.color??"",tags:l(t.tags),projects:t.projects,action:t.action??void 0,actionLabel:t.actionLabel??void 0,title:t.title??void 0,body:t.body,...o}}function d(t,o){const i=a();n([i?`${i}/.claude/agents`:null,t?`${t}/.claude/agents`:null],o)}export{s as a,l as t,d as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ap as t,A as f,bf as g,aF as d}from"./index-
|
|
1
|
+
import{ap as t,A as f,bf as g,aF as d}from"./index-Cq-Ppqar.js";function j({children:s,right:e}){return t.jsxs("div",{className:"flex items-baseline justify-between mb-2.5",children:[t.jsx("span",{className:"text-[11.5px] font-bold uppercase tracking-[0.8px] text-fg-faint",children:s}),e]})}function y({kind:s="soft",icon:e,children:c,onClick:i,disabled:o,testId:n}){return t.jsxs("button",{type:"button","data-testid":n,onClick:i,disabled:o,className:`shrink-0 inline-flex items-center gap-2 rounded-lg px-3.5 py-2 text-[13px] font-semibold transition-colors disabled:opacity-50 ${s==="soft"?"bg-bg-hi border border-line text-fg hover:bg-bg":"text-fg-dim hover:text-fg"}`,children:[e&&t.jsx(f,{name:e,size:15}),c]})}function N({icon:s,title:e,subtitle:c,badge:i,action:o,testId:n}){return t.jsxs("div",{"data-testid":n,className:"flex items-center gap-3.5 bg-bg-hi border border-line rounded-xl px-[18px] py-3.5",children:[t.jsx("span",{className:"w-[34px] h-[34px] rounded-lg bg-bg border border-line grid place-items-center text-fg-dim shrink-0",children:t.jsx(f,{name:s,size:17})}),t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsxs("div",{className:"flex items-center gap-2.5 mb-0.5",children:[t.jsx("span",{className:"text-sm font-semibold text-fg truncate",children:e}),i]}),t.jsx("div",{className:"font-mono text-[11.5px] text-fg-faint truncate",children:c})]}),o]})}function v({onClick:s,disabled:e,testId:c,children:i="Revoke"}){return t.jsx("button",{"data-testid":c,onClick:s,disabled:e,className:"shrink-0 rounded-lg border border-line bg-bg text-accent px-3.5 py-1.5 text-[12.5px] font-semibold hover:bg-bg-hi disabled:opacity-50 transition-colors",children:i})}function k({code:s,onConfirm:e,testId:c,codeTestId:i,confirmTestId:o,peer:n="browser"}){return t.jsxs("div",{"data-testid":c,className:"flex items-start gap-3.5 px-5 py-4 rounded-2xl border border-accent/40 bg-accent/[0.06]",children:[t.jsx("span",{className:"w-[38px] h-[38px] rounded-[11px] shrink-0 grid place-items-center bg-bg-hi text-accent",children:t.jsx(f,{name:"shield",size:20})}),t.jsxs("div",{className:"flex-1 min-w-0 text-sm text-fg",children:[t.jsx("strong",{className:"font-semibold",children:"Verify E2E session."})," Compare this code with the ",n," — they must match.",t.jsx("div",{"data-testid":i,className:"my-2 text-3xl font-mono tracking-[0.3em] text-center text-accent select-all",children:s}),t.jsx("p",{className:"text-[12.5px] text-fg-faint mb-3",children:"If the codes match, confirm below. Mutating commands are blocked until confirmed."}),t.jsx("button",{"data-testid":o,onClick:e,className:"rounded-lg bg-accent text-white px-4 py-2 text-[13px] font-semibold hover:opacity-90 transition-opacity",children:"Codes match — confirm"})]})]})}function C({children:s,testId:e}){return t.jsx("div",{"data-testid":e,className:"bg-bg-hi border border-line rounded-xl p-5 text-center text-[13.5px] text-fg-faint italic font-serif",children:s})}const m=s=>(s==null?void 0:s.message)||String(s);function S(s){const e=g(r=>r.show),[c,i]=d.useState([]),o=d.useRef(s);o.current=s;const n=d.useCallback(async()=>{try{i(await window.api.remoteClient.list())}catch(r){e("error",m(r))}},[e]);d.useEffect(()=>{n();const r=window.api.remoteClient.onStatus(a=>{var x;(x=o.current)==null||x.call(o,a),i(l=>l.map(b=>b.peerId===a.peerId?{...b,status:a.status,reason:a.reason,sas:a.sas}:b))});return()=>{r()}},[n]);const p=d.useCallback(async r=>{try{const a=await window.api.remoteClient.connect(r);i(x=>x.map(l=>l.peerId===r?{...l,status:a.status,reason:a.reason,sas:a.sas}:l))}catch(a){e("error",m(a))}},[e]),u=d.useCallback(async r=>{try{const a=await window.api.remoteClient.confirmSas(r);a.ok||e("error",a.reason??"SAS confirmation failed"),await n()}catch(a){e("error",m(a))}},[e,n]),h=d.useCallback(async r=>{try{await window.api.remoteClient.remove(r),await n()}catch(a){e("error",m(a))}},[e,n]);return{peers:c,refresh:n,connect:p,confirmSas:u,revoke:h}}export{C as E,y as P,N as R,k as S,v as a,j as b,S as u};
|
package/dist/index.html
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
8
8
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
9
9
|
<link href="https://fonts.googleapis.com/css2?family=Newsreader:ital,opsz,wght@0,6..72,400;0,6..72,500;0,6..72,600;0,6..72,700;1,6..72,400&family=Geist:wght@300;400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
|
10
|
-
<script type="module" crossorigin src="./assets/index-
|
|
10
|
+
<script type="module" crossorigin src="./assets/index-Cq-Ppqar.js"></script>
|
|
11
11
|
<link rel="modulepreload" crossorigin href="./assets/monaco-editor-BsIlgG7c.js">
|
|
12
12
|
<link rel="stylesheet" crossorigin href="./assets/monaco-editor-Cu5D__1H.css">
|
|
13
13
|
<link rel="stylesheet" crossorigin href="./assets/index-DAMBm3UN.css">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-code-session-manager",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.119.0",
|
|
4
4
|
"description": "Local cockpit for the Claude Code CLI — multi-tab terminal, full config surface, scheduler, voice dictation, and live observability.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/main/index.cjs",
|
|
@@ -178,6 +178,8 @@ the API rejects that.
|
|
|
178
178
|
criterion. The executor ends with `SCHEDULER_VERDICT: NEEDS_HUMAN <question>` for those, and
|
|
179
179
|
the PRD notes say so. Why: no executor can pass such a gate, so the job parks as
|
|
180
180
|
`sentinel_fail`.
|
|
181
|
+
Live-run steps that need gitignored state follow PRD_AUTHORING.md §7 (absolute main-checkout
|
|
182
|
+
paths, artifact-only).
|
|
181
183
|
|
|
182
184
|
### files rules
|
|
183
185
|
|
|
@@ -222,13 +224,15 @@ End every plan with exactly one validate PRD:
|
|
|
222
224
|
itself, and a REFUTED PRD is still a successful validation.
|
|
223
225
|
|
|
224
226
|
The validator prints `VALIDATION: <slug> VERIFIED` or `VALIDATION: <slug> REFUTED — <reason>`
|
|
225
|
-
per PRD.
|
|
226
|
-
|
|
227
|
-
|
|
227
|
+
per PRD. Queue the validate PRD last: `dependsOn` accepts only slugs that already exist. The
|
|
228
|
+
scheduler sends no per-PRD validation prompt. When the Epic has no pending or running PRD for
|
|
229
|
+
`SM_EPIC_SETTLE_SECONDS` (default 120), it queues one `validate-sweep-*` validator for completed
|
|
230
|
+
PRDs no validator checked, then sends one PLAN SETTLED digest. Several validators in one Epic
|
|
231
|
+
are fine: each runs headless.
|
|
228
232
|
|
|
229
233
|
If the API rejects `agentType: "validator"`, the persona is not installed: keep the plan
|
|
230
|
-
queued, say so, ask the human to restart the app, and
|
|
231
|
-
|
|
234
|
+
queued, say so, ask the human to restart the app, and validate the digest's Not validated list
|
|
235
|
+
here. Never write the record yourself.
|
|
232
236
|
|
|
233
237
|
## Phase 2 — track to done
|
|
234
238
|
|
|
@@ -265,11 +269,10 @@ Rules:
|
|
|
265
269
|
A `needs_human` notice carries a question for the human: relay it verbatim, then act on
|
|
266
270
|
the answer with `scheduler_update_prd` + `scheduler_reset_job`. Why: the executor stopped
|
|
267
271
|
on a step only the human can answer.
|
|
268
|
-
2. **A
|
|
269
|
-
finding, means a fix wave: one `behavior` or `wire` PRD per finding
|
|
270
|
-
PRD. Never fix inline.
|
|
271
|
-
|
|
272
|
-
request.
|
|
272
|
+
2. **A PLAN SETTLED digest.** Read the validator records it names. A `REFUTED` PRD, or a
|
|
273
|
+
Critical or Important finding, means a fix wave: one `behavior` or `wire` PRD per finding
|
|
274
|
+
plus a new validate PRD. Never fix inline. A Not validated list means validate exactly
|
|
275
|
+
those PRDs here. All `VERIFIED` with nothing open means Done: write the final report.
|
|
273
276
|
4. **Done** = the latest validator marked every PRD `VERIFIED`, no Critical or Important
|
|
274
277
|
finding is open, and its record is committed. Never "done with caveats": a REFUTED PRD gets
|
|
275
278
|
a fix wave or an explicit human decision to stop.
|
package/src/main/build-info.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
3
|
-
"gitSha": "
|
|
4
|
-
"gitShortSha": "
|
|
2
|
+
"version": "0.119.0",
|
|
3
|
+
"gitSha": "3f151a674c06cd2354b7a62fb5e02e7e3ffe0a7f",
|
|
4
|
+
"gitShortSha": "3f151a67",
|
|
5
5
|
"gitBranch": "HEAD",
|
|
6
|
-
"builtAt": "2026-10-
|
|
6
|
+
"builtAt": "2026-10-17T02:36:09.952Z",
|
|
7
7
|
"dirty": false
|
|
8
8
|
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* epicSettle.cjs — pure settle evaluator for one Epic.
|
|
5
|
+
*
|
|
6
|
+
* Given the Epic's event chain and the scheduler queue rows, says whether the
|
|
7
|
+
* Epic has settled (no pending/running PRD) and which finished PRDs no
|
|
8
|
+
* validator has checked yet. No fs, no scheduler require.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const { createHash } = require('node:crypto');
|
|
12
|
+
const { bareSlug } = require('../prd/depSlugResolve.cjs');
|
|
13
|
+
|
|
14
|
+
const DEFAULT_SETTLE_HORIZON_MS = 24 * 60 * 60 * 1000;
|
|
15
|
+
|
|
16
|
+
const ts = (at) => {
|
|
17
|
+
const t = typeof at === 'string' ? Date.parse(at) : NaN;
|
|
18
|
+
return Number.isFinite(t) ? t : NaN;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const isValidatorCheckin = (e, bare) =>
|
|
22
|
+
e.agentType === 'validator' || (e.agentType == null && bare.startsWith('validate-'));
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @param {{ epicId: string, cwd?: string|null, events?: any[], jobs?: any[], now?: number, horizonMs?: number }} args
|
|
26
|
+
*/
|
|
27
|
+
function evaluateEpicSettle({ epicId, cwd, events, jobs, now, horizonMs } = {}) {
|
|
28
|
+
const evs = Array.isArray(events) ? events.filter((e) => e && typeof e === 'object') : [];
|
|
29
|
+
const rows = Array.isArray(jobs) ? jobs : [];
|
|
30
|
+
const nowMs = Number.isFinite(now) ? now : Date.now();
|
|
31
|
+
const horizon = Number.isFinite(horizonMs) ? horizonMs : DEFAULT_SETTLE_HORIZON_MS;
|
|
32
|
+
|
|
33
|
+
const epicRows = rows.filter(
|
|
34
|
+
(r) => r && (r.epicId === epicId || r.sourcePromptId === epicId) && (r.cwd == null || cwd == null || r.cwd === cwd),
|
|
35
|
+
);
|
|
36
|
+
const settled = !epicRows.some((r) => r.status === 'pending' || r.status === 'running');
|
|
37
|
+
const parked = epicRows
|
|
38
|
+
.filter((r) => r.status === 'needs_review')
|
|
39
|
+
.map((r) => String(r.slug))
|
|
40
|
+
.sort();
|
|
41
|
+
|
|
42
|
+
let windowStart = nowMs - horizon;
|
|
43
|
+
for (const e of evs) {
|
|
44
|
+
if (e.outcome === 'digest') {
|
|
45
|
+
const t = ts(e.at);
|
|
46
|
+
if (t > windowStart) windowStart = t;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const checkins = new Map(); // bare -> { event, t }
|
|
51
|
+
const verdicts = new Map();
|
|
52
|
+
for (const e of evs) {
|
|
53
|
+
if (e.kind !== 'response' || typeof e.prdSlug !== 'string') continue;
|
|
54
|
+
const t = ts(e.at);
|
|
55
|
+
if (!(t > windowStart)) continue;
|
|
56
|
+
const bare = bareSlug(e.prdSlug);
|
|
57
|
+
let target = null;
|
|
58
|
+
if (e.validation === 'unvalidated' && (e.outcome === 'completed' || e.outcome === 'failed')) {
|
|
59
|
+
if (isValidatorCheckin(e, bare)) continue;
|
|
60
|
+
target = checkins;
|
|
61
|
+
} else if (e.validation === 'verified' || e.validation === 'refuted') {
|
|
62
|
+
target = verdicts;
|
|
63
|
+
}
|
|
64
|
+
if (!target) continue;
|
|
65
|
+
const prev = target.get(bare);
|
|
66
|
+
if (!prev || t >= prev.t) target.set(bare, { event: e, t });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const verified = [];
|
|
70
|
+
const refuted = [];
|
|
71
|
+
for (const [bare, { event }] of verdicts) {
|
|
72
|
+
if (event.validation === 'verified') verified.push(bare);
|
|
73
|
+
else {
|
|
74
|
+
const text = typeof event.text === 'string' ? event.text : '';
|
|
75
|
+
const i = text.indexOf(' — ');
|
|
76
|
+
refuted.push({ slug: bare, reason: i >= 0 ? text.slice(i + 3).trim() : '' });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
verified.sort();
|
|
80
|
+
refuted.sort((a, b) => (a.slug < b.slug ? -1 : a.slug > b.slug ? 1 : 0));
|
|
81
|
+
|
|
82
|
+
const uncovered = [];
|
|
83
|
+
const failed = [];
|
|
84
|
+
for (const [bare, { event, t }] of checkins) {
|
|
85
|
+
if (event.outcome === 'failed') {
|
|
86
|
+
failed.push(event.prdSlug);
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const v = verdicts.get(bare);
|
|
90
|
+
if (v && v.t >= t) continue;
|
|
91
|
+
uncovered.push({ slug: event.prdSlug, bareSlug: bare });
|
|
92
|
+
}
|
|
93
|
+
uncovered.sort((a, b) => (a.slug < b.slug ? -1 : a.slug > b.slug ? 1 : 0));
|
|
94
|
+
failed.sort();
|
|
95
|
+
|
|
96
|
+
const digestKey = createHash('sha1')
|
|
97
|
+
.update(JSON.stringify({ verified, refuted, failed, parked, uncovered: uncovered.map((u) => u.slug) }))
|
|
98
|
+
.digest('hex')
|
|
99
|
+
.slice(0, 16);
|
|
100
|
+
const hasContent = [uncovered, verified, refuted, failed, parked].some((l) => l.length > 0);
|
|
101
|
+
|
|
102
|
+
return { settled, uncovered, verified, refuted, failed, parked, digestKey, hasContent };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
module.exports = { evaluateEpicSettle, DEFAULT_SETTLE_HORIZON_MS };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* epicSweepValidator.cjs — pure builder for the scheduler_create_prd input of a
|
|
5
|
+
* "sweep" validator PRD: one headless validator job (agentType validator) that
|
|
6
|
+
* checks the completed PRDs of a settled Epic that no validator has checked.
|
|
7
|
+
* Pure: no fs, no child_process. The caller decides when a sweep is needed and
|
|
8
|
+
* whether to create the PRD.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const { bareSlug } = require('../prd/depSlugResolve.cjs');
|
|
12
|
+
|
|
13
|
+
const SWEEP_SLUG_PREFIX = 'validate-sweep';
|
|
14
|
+
const MAX_SWEEP_PRDS = 25;
|
|
15
|
+
|
|
16
|
+
const PERSONA_LINE = 'Work as the validator persona — the procedure is your system prompt.';
|
|
17
|
+
|
|
18
|
+
/** True for `validate-sweep-…`, with or without a leading `NN-` prefix. */
|
|
19
|
+
function isSweepValidatorSlug(slug) {
|
|
20
|
+
if (typeof slug !== 'string') return false;
|
|
21
|
+
return slug.replace(/^\d+-/, '').startsWith(`${SWEEP_SLUG_PREFIX}-`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @param {{ epicId: string, cwd: string,
|
|
26
|
+
* uncovered: Array<{ slug: string, bareSlug?: string, landedCommit?: string }>,
|
|
27
|
+
* baseSha?: string | null, now: number | Date | string }} args
|
|
28
|
+
* @returns {{ input: object | null, carried: Array<object> }}
|
|
29
|
+
*/
|
|
30
|
+
function buildSweepValidatorInput({ epicId, cwd, uncovered, baseSha, now }) {
|
|
31
|
+
if (!Array.isArray(uncovered) || uncovered.length === 0) return { input: null, carried: [] };
|
|
32
|
+
|
|
33
|
+
const covered = uncovered.slice(0, MAX_SWEEP_PRDS);
|
|
34
|
+
const carried = uncovered.slice(MAX_SWEEP_PRDS);
|
|
35
|
+
const names = covered.map((entry) => entry.bareSlug || bareSlug(entry.slug));
|
|
36
|
+
|
|
37
|
+
const stamp = new Date(now).toISOString().replace(/\D/g, '').slice(0, 12);
|
|
38
|
+
const slug = `${SWEEP_SLUG_PREFIX}-${stamp}`;
|
|
39
|
+
const recordPath = `session-manager-operations/reviews/validation/${epicId}/${slug}.md`;
|
|
40
|
+
|
|
41
|
+
const acceptanceCriteria = names.map(
|
|
42
|
+
(name) => `${name} verified against its PRD file (find it by slug under $SM_PROJECT_ROOT/session-manager-operations/scheduler/epics/${epicId}/prds/ or prds-archived/, possibly in a timestamped subfolder)`,
|
|
43
|
+
);
|
|
44
|
+
acceptanceCriteria.push(`Record written and committed at ${recordPath}`);
|
|
45
|
+
|
|
46
|
+
const base = baseSha
|
|
47
|
+
? `Base: ${baseSha}`
|
|
48
|
+
: 'Base: unknown — review each PRD\'s own landed commit (git log --all --grep=<slug>)';
|
|
49
|
+
|
|
50
|
+
const input = {
|
|
51
|
+
title: `Validate: unchecked work in this session (${covered.length} PRDs)`,
|
|
52
|
+
slug,
|
|
53
|
+
goal: `validate. Sweep validator queued by the scheduler when this Epic settled with completed PRDs no validator had checked: ${names.join(', ')}.`,
|
|
54
|
+
acceptanceCriteria,
|
|
55
|
+
implementationNotes: [
|
|
56
|
+
PERSONA_LINE,
|
|
57
|
+
base,
|
|
58
|
+
'Created automatically by the scheduler; no human or planner wrote this PRD.',
|
|
59
|
+
].join('\n'),
|
|
60
|
+
outOfScope: ['Editing product code', 'Queuing fix PRDs'],
|
|
61
|
+
gate: ['none'],
|
|
62
|
+
files: [recordPath],
|
|
63
|
+
estimateMinutes: 10,
|
|
64
|
+
agentType: 'validator',
|
|
65
|
+
tag: 'build',
|
|
66
|
+
sourcePromptId: epicId,
|
|
67
|
+
cwd,
|
|
68
|
+
dependsOn: names,
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
return { input, carried };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
module.exports = { SWEEP_SLUG_PREFIX, MAX_SWEEP_PRDS, isSweepValidatorSlug, buildSweepValidatorInput };
|