claude-code-session-manager 0.101.0 → 0.103.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/{DataModel-CXaH2GED.js → DataModel-Bgw2VqmP.js} +1 -1
- package/dist/assets/{History-Cerii-HA.js → History-De6GeUyP.js} +1 -1
- package/dist/assets/{Hooks-aXMb5LDy.js → Hooks-CgpCEy1J.js} +1 -1
- package/dist/assets/{Library-WrJFKEOJ.js → Library-D90JNcU4.js} +1 -1
- package/dist/assets/{MarkdownEditor-D1BMCXS7.js → MarkdownEditor-BaGbbB4D.js} +1 -1
- package/dist/assets/{McpServers-Cf0davLd.js → McpServers-DtzyQXmJ.js} +1 -1
- package/dist/assets/{Memory-Dn6NHWPe.js → Memory-CrkSYaZs.js} +1 -1
- package/dist/assets/{Permissions-CTVuFPjg.js → Permissions-C9R1FK2q.js} +1 -1
- package/dist/assets/{Plugins-C2TyF8Mn.js → Plugins-Dg-pT2P9.js} +2 -2
- package/dist/assets/{ProvenanceBadge-F_jwHSwE.js → ProvenanceBadge-D6DNK8MW.js} +1 -1
- package/dist/assets/{SaveBar-DA1KVJST.js → SaveBar-lMVYV4IY.js} +1 -1
- package/dist/assets/Scheduler-DhRGmvfB.js +16 -0
- package/dist/assets/{ScopeSwitcher-BygZlJca.js → ScopeSwitcher-CrmoviYs.js} +1 -1
- package/dist/assets/{Settings-BYCiv5KV.js → Settings-BTyqKJWr.js} +1 -1
- package/dist/assets/{SkillReferenceGraph-CcLnl9np.js → SkillReferenceGraph-Bi1KZT00.js} +1 -1
- package/dist/assets/{Skills-ChffsdTD.js → Skills-Cw31oTfc.js} +1 -1
- package/dist/assets/{SystemPrompt-dNkfHE_M.js → SystemPrompt-D_QGdY-s.js} +1 -1
- package/dist/assets/{TagLibrary-jVlEuB0m.js → TagLibrary-BhflRcxf.js} +1 -1
- package/dist/assets/{TiptapBody-6_cdwcP0.js → TiptapBody-DmzoRaV0.js} +1 -1
- package/dist/assets/{Toggle-CVXqGpAP.js → Toggle-BaBCNHq8.js} +1 -1
- package/dist/assets/{ViewTabs-DO1YVbpc.js → ViewTabs-DTrlvEUf.js} +1 -1
- package/dist/assets/{index-DbCQPWWY.js → index-ByE44RSO.js} +6 -4
- package/dist/assets/{settingsSchema-Wrvn-Yz1.js → settingsSchema-BLYLb3ul.js} +1 -1
- package/dist/index.html +1 -1
- package/package.json +1 -1
- package/plugins/session-manager-dev/skills/develop/SKILL.md +16 -2
- package/src/main/build-info.json +4 -4
- package/src/main/lib/builtinMacros.cjs +2 -2
- package/src/main/lib/shippedPersonaSeeds.cjs +44 -0
- package/src/main/templates/PRD_AUTHORING.md +2 -2
- package/src/seed/agents/demo-video-builder.md +44 -3
- package/dist/assets/Scheduler-Bm6Q_hlu.js +0 -16
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ax as b,ai as n,S as N,aO as O,av as K}from"./index-DbCQPWWY.js";function T({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(I,{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&&_(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 I({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 _(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 G(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 V(){return $||($=B(K)),$}export{T as E,V as s,G as u};
|
|
1
|
+
import{ax as b,ai as n,S as N,aO as O,av as K}from"./index-ByE44RSO.js";function T({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(I,{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&&_(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 I({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 _(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 G(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 V(){return $||($=B(K)),$}export{T as E,V as s,G 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-ByE44RSO.js"></script>
|
|
11
11
|
<link rel="modulepreload" crossorigin href="./assets/monaco-editor-BW5C4Iv1.js">
|
|
12
12
|
<link rel="stylesheet" crossorigin href="./assets/monaco-editor-BTnBOi8r.css">
|
|
13
13
|
<link rel="stylesheet" crossorigin href="./assets/index-D89EUizB.css">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-code-session-manager",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.103.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",
|
|
@@ -47,6 +47,18 @@ new work. **report** = your final message to the human.
|
|
|
47
47
|
|
|
48
48
|
Read `~/.claude/session-manager/scheduled-plans/PRD_AUTHORING.md` before writing PRDs.
|
|
49
49
|
|
|
50
|
+
### Plan objective
|
|
51
|
+
|
|
52
|
+
One goal = one validate PRD = one plan card on the Scheduler. Why: the Scheduler groups a plan
|
|
53
|
+
card as the validate PRD plus everything it transitively depends on.
|
|
54
|
+
The validate PRD's title is the card title, so write it as `Validate: <plain-language goal>`.
|
|
55
|
+
Keep one goal per validate PRD; a second goal is a second plan, with its own validate PRD.
|
|
56
|
+
Prefer wide over deep: PRDs that share no files run in parallel; only chain two PRDs on a real
|
|
57
|
+
file or output dependency, never to express reading order alone.
|
|
58
|
+
A follow-up or fix PRD for the same goal depends on that plan's open PRDs instead of starting
|
|
59
|
+
an unrelated root. Why: it keeps the fix inside the same card rather than minting a second,
|
|
60
|
+
unrelated one.
|
|
61
|
+
|
|
50
62
|
### Preflight — confirm the tool is even in your tool list
|
|
51
63
|
|
|
52
64
|
Before drafting, check that `mcp__session-manager-scheduler__scheduler_create_prd` is in your
|
|
@@ -101,7 +113,8 @@ failure modes have different fixes:
|
|
|
101
113
|
needs another PRD's output.
|
|
102
114
|
9. **Write plain, checkable criteria.** Each names a file, a symbol and the result; one names
|
|
103
115
|
the test file and tests. Commands go in `gate`. No open-ended "grep X and update" lines.
|
|
104
|
-
10. **Show the plan once
|
|
116
|
+
10. **Show the plan once**: the plan goal line, the stage view (for example `Stage 1: A ∥ B →
|
|
117
|
+
Stage 2: C → validate`), and a table (#, PRD, files, gate, dependsOn, estimate) — not PRD
|
|
105
118
|
drafts. Queue at once when the Epic is `feature` or `bug` and scope is clear; otherwise ask
|
|
106
119
|
one approval question, once.
|
|
107
120
|
11. Before the first `scheduler_create_prd` call, run `git -C "$SM_PROJECT_ROOT" rev-parse HEAD`
|
|
@@ -183,7 +196,8 @@ paths → verdict line.
|
|
|
183
196
|
End every plan with exactly one validate PRD:
|
|
184
197
|
|
|
185
198
|
1. `agentType: "validator"`, `tag: "build"`, `estimateMinutes: 10`, slug
|
|
186
|
-
`validate-<short-plan-name>`.
|
|
199
|
+
`validate-<short-plan-name>`. Its title is the plan goal shown on the Scheduler card, so
|
|
200
|
+
write it as `Validate: <plain-language goal>`.
|
|
187
201
|
2. `dependsOn`: every other slug in the plan. Past the cap of 100, only the sinks (PRDs nothing
|
|
188
202
|
depends on). Why: `dependsOn` is walked transitively.
|
|
189
203
|
3. Goal: the plan's slugs and titles.
|
package/src/main/build-info.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
3
|
-
"gitSha": "
|
|
4
|
-
"gitShortSha": "
|
|
2
|
+
"version": "0.103.0",
|
|
3
|
+
"gitSha": "dd29df2049979c09e87925296058af065d827ddd",
|
|
4
|
+
"gitShortSha": "dd29df20",
|
|
5
5
|
"gitBranch": "HEAD",
|
|
6
|
-
"builtAt": "2026-10-
|
|
6
|
+
"builtAt": "2026-10-03T20:25:48.708Z",
|
|
7
7
|
"dirty": false
|
|
8
8
|
}
|
|
@@ -30,9 +30,9 @@ const BUILTIN_MACROS = Object.freeze([
|
|
|
30
30
|
tag: 'project-home-builder',
|
|
31
31
|
surface: 'project-home',
|
|
32
32
|
projects: ['*'],
|
|
33
|
-
builtinVersion:
|
|
33
|
+
builtinVersion: 2,
|
|
34
34
|
prompt:
|
|
35
|
-
'Generate a 30-second demo video for this project as one self-contained HTML/JavaScript animation that presents its main goals and key features, grounded only in what you read in the repository. Save it with a single project_demo_video_write call.',
|
|
35
|
+
'Generate a 30-second demo video for this project as one self-contained HTML/JavaScript animation that presents its main goals and key features, grounded only in what you read in the repository, with a matching on-device narration track per the audio policy in the persona. Save it with a single project_demo_video_write call.',
|
|
36
36
|
}),
|
|
37
37
|
]);
|
|
38
38
|
|
|
@@ -220,6 +220,50 @@ const SHIPPED_PERSONA_SEEDS = deepFreeze({
|
|
|
220
220
|
effort: "medium",
|
|
221
221
|
},
|
|
222
222
|
},
|
|
223
|
+
{
|
|
224
|
+
commit: "93091f6f",
|
|
225
|
+
bodySha256: "57e4272bbdc8960eb033fcf45d4138b05c53a6c14d601bbb464283a96095e172",
|
|
226
|
+
fm: {
|
|
227
|
+
description: "30-second self-contained HTML/JS demo video for Project Home, saved via project_demo_video_write.",
|
|
228
|
+
tools: "Read, Grep, Glob, Bash, Write, Edit",
|
|
229
|
+
title: "Project Home — Demo Video",
|
|
230
|
+
model: "sonnet",
|
|
231
|
+
effort: "medium",
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
commit: "b1fce824",
|
|
236
|
+
bodySha256: "c89991e8aba90f63c1fa5094268aec0e19bd38e5f8af3df375b80112d7a4a781",
|
|
237
|
+
fm: {
|
|
238
|
+
description: "30-second self-contained HTML/JS demo video for Project Home, saved via project_demo_video_write.",
|
|
239
|
+
tools: "Read, Grep, Glob, Bash, Write, Edit",
|
|
240
|
+
title: "Project Home — Demo Video",
|
|
241
|
+
model: "sonnet",
|
|
242
|
+
effort: "medium",
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
commit: "4a7d4a80",
|
|
247
|
+
bodySha256: "6d61ec0653d7866c035d59c6ee09421a8ed8ce657f842040b064d84a83d447e0",
|
|
248
|
+
fm: {
|
|
249
|
+
description: "30-second self-contained HTML/JS demo video for Project Home, saved via project_demo_video_write.",
|
|
250
|
+
tools: "Read, Grep, Glob, Bash, Write, Edit",
|
|
251
|
+
title: "Project Home — Demo Video",
|
|
252
|
+
model: "sonnet",
|
|
253
|
+
effort: "medium",
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
commit: "6d484642",
|
|
258
|
+
bodySha256: "f663bd4f82ce140dd23d8a9760c1ad7237c99b741fc0f96dd66c41932df192ca",
|
|
259
|
+
fm: {
|
|
260
|
+
description: "30-second self-contained HTML/JS demo video for Project Home, saved via project_demo_video_write.",
|
|
261
|
+
tools: "Read, Grep, Glob, Bash, Write, Edit",
|
|
262
|
+
title: "Project Home — Demo Video",
|
|
263
|
+
model: "sonnet",
|
|
264
|
+
effort: "medium",
|
|
265
|
+
},
|
|
266
|
+
},
|
|
223
267
|
],
|
|
224
268
|
});
|
|
225
269
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- PRD_AUTHORING.md
|
|
1
|
+
<!-- PRD_AUTHORING.md v5 -->
|
|
2
2
|
# PRD Authoring Guide — Scheduler Safety Rules
|
|
3
3
|
|
|
4
4
|
Rule: every PRD you queue follows the rules below.
|
|
@@ -73,7 +73,7 @@ Rule: every PRD needs these fields.
|
|
|
73
73
|
|
|
74
74
|
`parallelGroup` is deprecated and ignored. `dependsOn: [<slug>, ...]` is the only ordering primitive.
|
|
75
75
|
|
|
76
|
-
`planId` is written by the API, never by you. It groups PRDs into the plan (wave) they belong to: an `append` PRD, or one with an explicit `dependsOn`, inherits the `planId` of the PRD it attaches behind; a fresh PRD mints a new one.
|
|
76
|
+
`planId` is written by the API, never by you. It groups PRDs into the plan (wave) they belong to: an `append` PRD, or one with an explicit `dependsOn`, inherits the `planId` of the PRD it attaches behind; a fresh PRD mints a new one. The Scheduler groups a plan card as a validate PRD (slug `validate-*`) plus everything it depends on, titled by that PRD's title.
|
|
77
77
|
|
|
78
78
|
Artifact-only PRDs (`deliverable: artifact` + `artifactPaths: [...]`) — use this ONLY when every deliverable is a file the repo deliberately git-excludes, so "no commit" is the correct outcome, not a miss.
|
|
79
79
|
1. Every artifact path is listed in `artifactPaths` and is relative, never `..`.
|
|
@@ -5,7 +5,7 @@ tools: Read, Grep, Glob, Bash, Write, Edit
|
|
|
5
5
|
title: 'Project Home — Demo Video'
|
|
6
6
|
model: sonnet
|
|
7
7
|
effort: medium
|
|
8
|
-
seedVersion:
|
|
8
|
+
seedVersion: 2
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
You are the demo-video-builder. You make a 30-second animated demo that shows someone what this
|
|
@@ -52,7 +52,7 @@ Produce exactly one complete HTML document:
|
|
|
52
52
|
- Expose `window.smDemo = { duration: 30, seek(t), play(), pause() }`, where `seek(t)` renders
|
|
53
53
|
the exact frame for time `t` in seconds, independent of whatever played before it.
|
|
54
54
|
- Autoplays once on load; shows play/pause, restart, and a progress bar.
|
|
55
|
-
-
|
|
55
|
+
- Optional narration audio (see `<audio_policy>`); the video must still make sense muted.
|
|
56
56
|
- No network: no `fetch`, `XMLHttpRequest`, `WebSocket`, `import()`, or `<iframe>`. No external
|
|
57
57
|
fonts or images — system font stack only, and any images as `data:` URIs.
|
|
58
58
|
- Respects `prefers-reduced-motion` by rendering the scenes as a static, steppable storyboard
|
|
@@ -61,6 +61,47 @@ Produce exactly one complete HTML document:
|
|
|
61
61
|
- A light/dark neutral palette with sufficient contrast in both.
|
|
62
62
|
</output_contract>
|
|
63
63
|
|
|
64
|
+
<audio_policy>
|
|
65
|
+
Narrate the storyboard captions with a short, pleasant on-device voice track — optional, never
|
|
66
|
+
block the video on it. Generate it at build time, not at playback time; the shipped document
|
|
67
|
+
never calls out to a network TTS service.
|
|
68
|
+
|
|
69
|
+
- Use **Kokoro-82M via the `kokoro-onnx` package** (`pip install kokoro-onnx`, Apache-2.0,
|
|
70
|
+
ONNX runtime only — no PyTorch needed despite earlier guidance here claiming otherwise;
|
|
71
|
+
confirmed by running it for real). If `python3 -m pip` isn't on PATH, bootstrap it first:
|
|
72
|
+
`curl -sS https://bootstrap.pypa.io/get-pip.py | python3 - --user --break-system-packages`,
|
|
73
|
+
then `python3 -m pip install --user --break-system-packages kokoro-onnx soundfile`. Pull the
|
|
74
|
+
model once: `kokoro-v1.0.onnx` (~325 MB) + `voices-v1.0.bin` (~28 MB) from
|
|
75
|
+
`https://github.com/thewh1teagle/kokoro-onnx/releases/download/model-files-v1.0/`. Use the
|
|
76
|
+
**`af_heart`** or **`af_bella`** voice (both are Kokoro's top-rated English voices and read
|
|
77
|
+
as clearly more natural than Piper, including Piper's `-high` tier — but which one of the
|
|
78
|
+
two sounds better is a taste call, not a settled fact; if the human reacts to a generated
|
|
79
|
+
video with "still not it," try the other one before reaching for a different library).
|
|
80
|
+
`Kokoro(model, voices).create(line, voice='af_heart', speed=1.0, lang='en-us')` returns
|
|
81
|
+
`(samples, sample_rate)` (24000 Hz); write each scene's line with `soundfile.write`. If
|
|
82
|
+
`kokoro-onnx`/its model download genuinely isn't available (offline, no bandwidth for a
|
|
83
|
+
~350 MB pull), fall back to **Piper** (`pip install piper-tts`) with a `-high` voice tier
|
|
84
|
+
(e.g. `en_US-lessac-high`, not `-medium` — `-medium` reads as noticeably robotic) from
|
|
85
|
+
`https://huggingface.co/rhasspy/piper-voices`.
|
|
86
|
+
- Synthesize one short line per scene, sized to fit that scene's on-screen hold time. Lay the
|
|
87
|
+
scene clips onto one mono track (at the model's native sample rate) at each scene's start
|
|
88
|
+
offset, encode the result with `ffmpeg -c:a libmp3lame -b:a 64k` **at that native sample
|
|
89
|
+
rate — do not downsample or drop below ~48 kbps; both make speech sound crushed/robotic for
|
|
90
|
+
only a small size win** (a 30 s mono track at 64 kbps is still only ~235 KB). Base64 it into
|
|
91
|
+
a single `<audio src="data:audio/mpeg;base64,...">` tag. Keep the whole document — markup
|
|
92
|
+
plus audio — under the 2 MB cap (plenty of headroom at this bitrate).
|
|
93
|
+
- Wire `play()`/`pause()`/`seek(t)` to the `<audio>` element too (`audio.currentTime = t` on
|
|
94
|
+
seek) so the narration never drifts from the visual clock, and start muted-fallback: call
|
|
95
|
+
`.play()` on load, and on rejection (autoplay-blocked browsers) show a small "tap for sound"
|
|
96
|
+
button instead of failing silently forever.
|
|
97
|
+
- Never write the literal pattern `function (` or `function(` in the inline `<script>` —
|
|
98
|
+
`project_demo_video_write`'s safety scanner blocks anything matching `/\bFunction\s*\(/i` to
|
|
99
|
+
stop dynamic `Function(...)` eval, and it cannot tell your IIFE apart from that. Use arrow
|
|
100
|
+
functions (`() => { ... }`) throughout instead.
|
|
101
|
+
- If pip/network/piper isn't available in this environment, skip audio entirely and ship the
|
|
102
|
+
silent video rather than failing the whole run — audio is a nice-to-have, never a blocker.
|
|
103
|
+
</audio_policy>
|
|
104
|
+
|
|
64
105
|
<process>
|
|
65
106
|
1. Read, with a bounded pass: the manifest, the README or top-level docs index, the top-level
|
|
66
107
|
directory tree, and `git log --oneline -30` for a sense of recent direction. Stop once you
|
|
@@ -68,7 +109,7 @@ Produce exactly one complete HTML document:
|
|
|
68
109
|
2. Write the claims list: for every goal or feature you plan to show, note the source you read
|
|
69
110
|
it from. Drop anything without a source.
|
|
70
111
|
3. Write the storyboard per `<storyboard>`, with scene timings summing to exactly 30 seconds.
|
|
71
|
-
4. Build the HTML per `<output_contract>`.
|
|
112
|
+
4. Build the HTML per `<output_contract>`, attempting narration per `<audio_policy>`.
|
|
72
113
|
5. Self-check before saving: scene durations sum to 30, every caption traces to a claim in your
|
|
73
114
|
list, and the document contains none of the forbidden network APIs.
|
|
74
115
|
6. Call `project_demo_video_write` exactly once with `{ html }`. It validates the document and
|