claude-code-session-manager 0.103.0 → 0.104.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/README.md +4 -0
- package/dist/assets/{DataModel-Bgw2VqmP.js → DataModel-jHE3YZ1R.js} +1 -1
- package/dist/assets/{History-De6GeUyP.js → History-BcmzvveB.js} +1 -1
- package/dist/assets/{Hooks-CgpCEy1J.js → Hooks-7s-8_Swz.js} +1 -1
- package/dist/assets/{Library-D90JNcU4.js → Library-87gLWVw2.js} +1 -1
- package/dist/assets/{MarkdownEditor-BaGbbB4D.js → MarkdownEditor--uC2uo5Z.js} +1 -1
- package/dist/assets/{McpServers-DtzyQXmJ.js → McpServers-JMiSnVw_.js} +1 -1
- package/dist/assets/{Memory-CrkSYaZs.js → Memory-BVA6XrVK.js} +1 -1
- package/dist/assets/{Permissions-C9R1FK2q.js → Permissions-DIoNtYJd.js} +1 -1
- package/dist/assets/{Plugins-Dg-pT2P9.js → Plugins-DG7XAIlT.js} +2 -2
- package/dist/assets/{ProvenanceBadge-D6DNK8MW.js → ProvenanceBadge-fipaqRJJ.js} +1 -1
- package/dist/assets/{SaveBar-lMVYV4IY.js → SaveBar-C7DFPoFJ.js} +1 -1
- package/dist/assets/{Scheduler-DhRGmvfB.js → Scheduler-CfKSiT_a.js} +1 -1
- package/dist/assets/{ScopeSwitcher-CrmoviYs.js → ScopeSwitcher-C5Uhek3u.js} +1 -1
- package/dist/assets/{Settings-BTyqKJWr.js → Settings-BAkeG1FK.js} +1 -1
- package/dist/assets/{SkillReferenceGraph-Bi1KZT00.js → SkillReferenceGraph-BjAnQnCI.js} +1 -1
- package/dist/assets/{Skills-Cw31oTfc.js → Skills-Bm0nqhpf.js} +1 -1
- package/dist/assets/{SystemPrompt-D_QGdY-s.js → SystemPrompt-DeCfwhFB.js} +1 -1
- package/dist/assets/{TagLibrary-BhflRcxf.js → TagLibrary-B2zo54TL.js} +1 -1
- package/dist/assets/{TiptapBody-DmzoRaV0.js → TiptapBody-BnSRUmUc.js} +1 -1
- package/dist/assets/{Toggle-BaBCNHq8.js → Toggle-dYmhVb17.js} +1 -1
- package/dist/assets/{ViewTabs-DTrlvEUf.js → ViewTabs-DsC7dKoh.js} +1 -1
- package/dist/assets/{index-ByE44RSO.js → index-B-h-PcUp.js} +3 -3
- package/dist/assets/{settingsSchema-BLYLb3ul.js → settingsSchema-B0xACLrZ.js} +1 -1
- package/dist/index.html +1 -1
- package/package.json +16 -9
- package/scripts/scheduler-mcp-server.cjs +47 -0
- package/src/main/build-info.json +4 -4
- package/src/main/index.cjs +2 -0
- package/src/main/lib/macroAdminRoutes.cjs +111 -0
- package/src/main/lib/mcpToolCatalog.cjs +36 -1
- package/src/main/lib/projectHomeAdminRoutes.cjs +1 -0
- package/src/main/otel.cjs +7 -7
|
@@ -1 +1 @@
|
|
|
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};
|
|
1
|
+
import{ax as b,ai as n,S as N,aO as O,av as K}from"./index-B-h-PcUp.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-B-h-PcUp.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.104.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",
|
|
@@ -100,23 +100,30 @@
|
|
|
100
100
|
"node": ">=22.12.0"
|
|
101
101
|
},
|
|
102
102
|
"overrides": {
|
|
103
|
-
"dompurify": "^3.4.8"
|
|
103
|
+
"dompurify": "^3.4.8",
|
|
104
|
+
"@hono/node-server": "^1.19.15",
|
|
105
|
+
"fast-uri": "^3.1.8",
|
|
106
|
+
"hono": "^4.13.7",
|
|
107
|
+
"ip-address": "^10.7.1",
|
|
108
|
+
"qs": "^6.16.0",
|
|
109
|
+
"tar": "^7.5.21",
|
|
110
|
+
"undici": "^7.29.1"
|
|
104
111
|
},
|
|
105
112
|
"os": [
|
|
106
113
|
"darwin",
|
|
107
114
|
"linux"
|
|
108
115
|
],
|
|
109
116
|
"dependencies": {
|
|
110
|
-
"@electron/rebuild": "4.0
|
|
117
|
+
"@electron/rebuild": "4.2.0",
|
|
111
118
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
112
119
|
"@opentelemetry/api": "^1.9.0",
|
|
113
|
-
"@opentelemetry/exporter-trace-otlp-http": "^0.
|
|
114
|
-
"@opentelemetry/resources": "^
|
|
115
|
-
"@opentelemetry/sdk-trace-base": "^
|
|
116
|
-
"@opentelemetry/sdk-trace-node": "^
|
|
117
|
-
"@opentelemetry/semantic-conventions": "^1.
|
|
120
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.222.0",
|
|
121
|
+
"@opentelemetry/resources": "^2.11.0",
|
|
122
|
+
"@opentelemetry/sdk-trace-base": "^2.11.0",
|
|
123
|
+
"@opentelemetry/sdk-trace-node": "^2.11.0",
|
|
124
|
+
"@opentelemetry/semantic-conventions": "^1.43.0",
|
|
118
125
|
"chokidar": "^4.0.1",
|
|
119
|
-
"electron": "42.
|
|
126
|
+
"electron": "42.11.10",
|
|
120
127
|
"marked": "^14.0.0",
|
|
121
128
|
"node-pty": "^1.2.0-beta.12",
|
|
122
129
|
"zod": "^3.23.8"
|
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
* project_home_write({ cwd?, html }) -> POST /admin/project-home/write
|
|
15
15
|
* project_demo_video_write({ cwd?, html }) -> POST /admin/project-home/demo-video/write
|
|
16
16
|
*
|
|
17
|
+
* macro_list({ cwd? }) -> GET /admin/macros?cwd=<encoded>
|
|
18
|
+
* macro_save({ cwd?, id?, label, agentName, tag, prompt }) -> POST /admin/macros/save
|
|
19
|
+
*
|
|
17
20
|
* This is a separate process from the Electron app — it only ever reaches
|
|
18
21
|
* it over the token-authed loopback HTTP API in admin-api.json, never by
|
|
19
22
|
* requiring scheduler.cjs/localAdminHttp.cjs directly. The admin server IS the
|
|
@@ -395,6 +398,32 @@ const TOOLS = [
|
|
|
395
398
|
required: ['html'],
|
|
396
399
|
},
|
|
397
400
|
},
|
|
401
|
+
{
|
|
402
|
+
name: 'macro_list',
|
|
403
|
+
description: descriptionFor('macro_list'),
|
|
404
|
+
inputSchema: {
|
|
405
|
+
type: 'object',
|
|
406
|
+
properties: {
|
|
407
|
+
cwd: { type: 'string', description: "Optional: absolute path to the target project. Defaults to the calling session's own project root (SM_PROJECT_ROOT or process.cwd()) when omitted." },
|
|
408
|
+
},
|
|
409
|
+
},
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
name: 'macro_save',
|
|
413
|
+
description: descriptionFor('macro_save'),
|
|
414
|
+
inputSchema: {
|
|
415
|
+
type: 'object',
|
|
416
|
+
properties: {
|
|
417
|
+
cwd: { type: 'string', description: "Optional: absolute path to the target project. Defaults to the calling session's own project root (SM_PROJECT_ROOT or process.cwd()) when omitted." },
|
|
418
|
+
id: { type: 'string', description: 'Optional: id of an existing macro (already visible to this project) to update. Omit to create a new macro scoped to this project.' },
|
|
419
|
+
label: { type: 'string', description: 'Short label shown on the HOT KEYS button.' },
|
|
420
|
+
agentName: { type: 'string', description: 'Persona to run the macro as (e.g. "builder").' },
|
|
421
|
+
tag: { type: 'string', description: 'Mission tag for the macro.' },
|
|
422
|
+
prompt: { type: 'string', description: 'The opening prompt the macro sends.' },
|
|
423
|
+
},
|
|
424
|
+
required: ['label', 'agentName', 'tag', 'prompt'],
|
|
425
|
+
},
|
|
426
|
+
},
|
|
398
427
|
{
|
|
399
428
|
name: 'session_manager_help',
|
|
400
429
|
description: descriptionFor('session_manager_help'),
|
|
@@ -627,6 +656,24 @@ async function handleCallTool(request) {
|
|
|
627
656
|
const result = await adminRequest('POST', '/admin/project-home/demo-video/write', { cwd, html: args.html });
|
|
628
657
|
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
629
658
|
}
|
|
659
|
+
if (name === 'macro_list') {
|
|
660
|
+
const cwd = resolveCwdArg(args);
|
|
661
|
+
const result = await adminRequest('GET', `/admin/macros?cwd=${encodeURIComponent(cwd)}`);
|
|
662
|
+
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
663
|
+
}
|
|
664
|
+
if (name === 'macro_save') {
|
|
665
|
+
const missing = ['label', 'agentName', 'tag', 'prompt'].filter(
|
|
666
|
+
(field) => !args || typeof args[field] !== 'string',
|
|
667
|
+
);
|
|
668
|
+
if (missing.length > 0) {
|
|
669
|
+
return errorResult(`missing or invalid required argument(s): ${missing.join(', ')}`);
|
|
670
|
+
}
|
|
671
|
+
const cwd = resolveCwdArg(args);
|
|
672
|
+
const payload = { cwd, label: args.label, agentName: args.agentName, tag: args.tag, prompt: args.prompt };
|
|
673
|
+
if (typeof args.id === 'string' && args.id) payload.id = args.id;
|
|
674
|
+
const result = await adminRequest('POST', '/admin/macros/save', payload);
|
|
675
|
+
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
676
|
+
}
|
|
630
677
|
if (name === 'session_manager_help') {
|
|
631
678
|
const toolName = args && typeof args.tool === 'string' ? args.tool : null;
|
|
632
679
|
const topic = args && typeof args.topic === 'string' ? args.topic : null;
|
package/src/main/build-info.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
3
|
-
"gitSha": "
|
|
4
|
-
"gitShortSha": "
|
|
2
|
+
"version": "0.104.0",
|
|
3
|
+
"gitSha": "36272fc5173ad2015632696376d4cdee65c550d8",
|
|
4
|
+
"gitShortSha": "36272fc5",
|
|
5
5
|
"gitBranch": "HEAD",
|
|
6
|
-
"builtAt": "2026-10-
|
|
6
|
+
"builtAt": "2026-10-03T21:56:15.195Z",
|
|
7
7
|
"dirty": false
|
|
8
8
|
}
|
package/src/main/index.cjs
CHANGED
|
@@ -33,6 +33,7 @@ const { createAdminHttp } = require('./lib/localAdminHttp.cjs');
|
|
|
33
33
|
const prdCreate = require('./lib/prdCreate.cjs');
|
|
34
34
|
const prdAdminRoutes = require('./lib/prdAdminRoutes.cjs');
|
|
35
35
|
const projectHomeAdminRoutes = require('./lib/projectHomeAdminRoutes.cjs');
|
|
36
|
+
const macroAdminRoutes = require('./lib/macroAdminRoutes.cjs');
|
|
36
37
|
const { smfileResponseHeaders, shouldBlockFrameNavigation } = require('./lib/smfileHeaders.cjs');
|
|
37
38
|
const { appendAuditEvent } = require('./lib/auditLog.cjs');
|
|
38
39
|
const chatRunner = require('./chatRunner.cjs');
|
|
@@ -60,6 +61,7 @@ scheduler.registerAdminRoutes(adminHttp);
|
|
|
60
61
|
prdCreate.registerAdminRoute(adminHttp, scheduler.remote);
|
|
61
62
|
prdAdminRoutes.registerAdminRoute(adminHttp, scheduler.remote);
|
|
62
63
|
projectHomeAdminRoutes.registerAdminRoute(adminHttp);
|
|
64
|
+
macroAdminRoutes.registerAdminRoute(adminHttp, { onChanged: () => broadcastMacrosChanged() });
|
|
63
65
|
chatRunner.registerAdminRoute(adminHttp);
|
|
64
66
|
// Project-to-project feedback conduit — the app is the only process holding
|
|
65
67
|
// several projects' operations roots open, so it performs the cross-folder
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* macroAdminRoutes.cjs — loopback admin HTTP routes so an agent session (via
|
|
3
|
+
* the scheduler MCP, next PRD) can list and create/update a HOT KEYS macro
|
|
4
|
+
* for its own project, through the existing macroLibrary.cjs store:
|
|
5
|
+
* GET /admin/macros?cwd=… -> { ok, macros }
|
|
6
|
+
* POST /admin/macros/save {cwd, id?, label, agentName, tag, prompt}
|
|
7
|
+
*
|
|
8
|
+
* cwd resolution matches projectHomeAdminRoutes.cjs's resolveCwd exactly
|
|
9
|
+
* (reused, not copied). A create always stores `projects: [resolvedCwd]`,
|
|
10
|
+
* `surface: 'sessions'`; an update is refused (400) if the resolved cwd is
|
|
11
|
+
* not already in the macro's `projects` (no cross-project hijack), if `id`
|
|
12
|
+
* starts with `builtin-`, or if `id` is not found. Field validation reuses
|
|
13
|
+
* macroLibrary's `MacroSaveSchema`.
|
|
14
|
+
*
|
|
15
|
+
* A successful save calls `onChanged()` exactly once so the Sessions HOT
|
|
16
|
+
* KEYS strip updates live, matching the IPC handlers in index.cjs.
|
|
17
|
+
*/
|
|
18
|
+
'use strict';
|
|
19
|
+
|
|
20
|
+
const { readBody, sendJson } = require('./localAdminHttp.cjs');
|
|
21
|
+
const { resolveCwd } = require('./projectHomeAdminRoutes.cjs');
|
|
22
|
+
const macroLibrary = require('./macroLibrary.cjs');
|
|
23
|
+
|
|
24
|
+
function listHandler(onChanged, libOpts) {
|
|
25
|
+
return async (_req, res, query) => {
|
|
26
|
+
const resolved = resolveCwd(query.get('cwd'));
|
|
27
|
+
if (!resolved.ok) {
|
|
28
|
+
sendJson(res, resolved.status, { ok: false, error: resolved.error });
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const macros = await macroLibrary.listMacros(libOpts);
|
|
32
|
+
const visible = macros.filter(
|
|
33
|
+
(m) => m.projects.includes(resolved.cwd) || m.projects.includes(macroLibrary.ALL_PROJECTS),
|
|
34
|
+
);
|
|
35
|
+
sendJson(res, 200, { ok: true, macros: visible });
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function saveHandler(onChanged, libOpts) {
|
|
40
|
+
return async (req, res) => {
|
|
41
|
+
let raw;
|
|
42
|
+
try {
|
|
43
|
+
raw = await readBody(req);
|
|
44
|
+
} catch (e) {
|
|
45
|
+
sendJson(res, 400, { ok: false, error: `request body rejected: ${e?.message ?? 'unreadable'}` });
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
let body;
|
|
49
|
+
try {
|
|
50
|
+
body = raw ? JSON.parse(raw) : {};
|
|
51
|
+
} catch {
|
|
52
|
+
sendJson(res, 400, { ok: false, error: 'invalid JSON body' });
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const resolved = resolveCwd(body.cwd);
|
|
56
|
+
if (!resolved.ok) {
|
|
57
|
+
sendJson(res, resolved.status, { ok: false, error: resolved.error });
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (typeof body.id === 'string' && body.id.startsWith('builtin-')) {
|
|
61
|
+
sendJson(res, 400, { ok: false, error: 'built-in macros cannot be edited through this route' });
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
let input;
|
|
65
|
+
try {
|
|
66
|
+
input = macroLibrary.MacroSaveSchema.parse({
|
|
67
|
+
id: body.id,
|
|
68
|
+
label: body.label,
|
|
69
|
+
agentName: body.agentName,
|
|
70
|
+
tag: body.tag,
|
|
71
|
+
prompt: body.prompt,
|
|
72
|
+
});
|
|
73
|
+
} catch (e) {
|
|
74
|
+
sendJson(res, 400, { ok: false, error: e?.issues?.[0]?.message ?? e?.message ?? 'invalid payload' });
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (input.id) {
|
|
78
|
+
const macros = await macroLibrary.listMacros(libOpts);
|
|
79
|
+
const existing = macros.find((m) => m.id === input.id);
|
|
80
|
+
if (!existing) {
|
|
81
|
+
sendJson(res, 400, { ok: false, error: `macro not found: ${input.id}` });
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (!existing.projects.includes(resolved.cwd)) {
|
|
85
|
+
sendJson(res, 400, { ok: false, error: `macro ${input.id} is not visible to ${resolved.cwd}` });
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
} else {
|
|
89
|
+
input = { ...input, projects: [resolved.cwd], surface: 'sessions' };
|
|
90
|
+
}
|
|
91
|
+
let macro;
|
|
92
|
+
try {
|
|
93
|
+
macro = await macroLibrary.saveMacro(input, libOpts);
|
|
94
|
+
} catch (e) {
|
|
95
|
+
sendJson(res, 400, { ok: false, error: e?.message ?? 'save failed' });
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (onChanged) onChanged();
|
|
99
|
+
sendJson(res, 200, { ok: true, macro });
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function registerAdminRoute(adminHttp, { onChanged } = {}, opts = {}) {
|
|
104
|
+
const libOpts = opts.filePath ? { filePath: opts.filePath } : undefined;
|
|
105
|
+
adminHttp.registerRoute('GET', '/admin/macros', listHandler(onChanged, libOpts));
|
|
106
|
+
adminHttp.registerRoute('POST', '/admin/macros/save', saveHandler(onChanged, libOpts));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
module.exports = {
|
|
110
|
+
registerAdminRoute,
|
|
111
|
+
};
|
|
@@ -23,7 +23,7 @@ const { z } = require('zod');
|
|
|
23
23
|
|
|
24
24
|
const CatalogEntrySchema = z.object({
|
|
25
25
|
name: z.string().min(1),
|
|
26
|
-
group: z.enum(['scheduler', 'chat', 'feedback', 'help', 'project-home']),
|
|
26
|
+
group: z.enum(['scheduler', 'chat', 'feedback', 'help', 'project-home', 'macros']),
|
|
27
27
|
purpose: z.string().min(1),
|
|
28
28
|
whenToUse: z.string().min(1),
|
|
29
29
|
whenNotToUse: z.string().min(1),
|
|
@@ -293,6 +293,41 @@ const MCP_TOOL_CATALOG = [
|
|
|
293
293
|
notes: "cwd is optional — defaults to the calling session's own project root (SM_PROJECT_ROOT or process.cwd()) when omitted. "
|
|
294
294
|
+ 'The document is CSP-stamped after it is written, so the viewer sandbox is the real network fence — these checks are defence in depth.',
|
|
295
295
|
},
|
|
296
|
+
{
|
|
297
|
+
name: 'macro_list',
|
|
298
|
+
group: 'macros',
|
|
299
|
+
purpose: "List this project's HOT KEYS macros — the saved (agent, tag, prompt) one-click buttons shown "
|
|
300
|
+
+ "in the Sessions tab's HOT KEYS strip, via the session-manager app's admin API.",
|
|
301
|
+
whenToUse: 'Use to see what macros already exist for this project (including machine-wide `*` macros and '
|
|
302
|
+
+ 'built-ins) before deciding whether to add or update one.',
|
|
303
|
+
whenNotToUse: 'WHEN NOT TO USE IT: macros are scoped to the caller\'s own project — this only ever returns '
|
|
304
|
+
+ "macros visible to the resolved cwd, never another project's.",
|
|
305
|
+
exampleArgs: { cwd: '/home/bilko/Projects/session-manager' },
|
|
306
|
+
notes: "cwd is optional — defaults to the calling session's own project root (SM_PROJECT_ROOT or process.cwd()) when omitted.",
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
name: 'macro_save',
|
|
310
|
+
group: 'macros',
|
|
311
|
+
purpose: "Create or update one of this project's HOT KEYS macros — a saved (agentName, tag, prompt) "
|
|
312
|
+
+ 'one-click button — via the session-manager app\'s admin API, through the same macroLibrary.cjs store '
|
|
313
|
+
+ 'the Sessions HOT KEYS strip reads from.',
|
|
314
|
+
whenToUse: 'Pass `id` to update an existing macro already visible to this project; omit `id` to create a new '
|
|
315
|
+
+ 'one scoped to this project. Use for things like a "Publish git + npm" macro a human will press '
|
|
316
|
+
+ 'repeatedly, when they have asked for that macro to exist.',
|
|
317
|
+
whenNotToUse: 'WHEN NOT TO USE IT: macros are scoped to the caller\'s own project — this call is refused if '
|
|
318
|
+
+ '`id` resolves to a macro not visible to this project. Built-in macros (`id` starting with `builtin-`) '
|
|
319
|
+
+ "cannot be edited through this route. A macro is a HUMAN's one-click button, not a task runner — never "
|
|
320
|
+
+ 'create or update one unless the human has actually asked for that macro to exist.',
|
|
321
|
+
exampleArgs: {
|
|
322
|
+
cwd: '/home/bilko/Projects/session-manager',
|
|
323
|
+
label: 'Publish git + npm',
|
|
324
|
+
agentName: 'builder',
|
|
325
|
+
tag: 'feature',
|
|
326
|
+
prompt: 'Run the full publish flow: commit, bump version, gate, npm publish, push.',
|
|
327
|
+
},
|
|
328
|
+
notes: "cwd is optional — defaults to the calling session's own project root (SM_PROJECT_ROOT or "
|
|
329
|
+
+ 'process.cwd()) when omitted. label, agentName, tag and prompt are all required strings.',
|
|
330
|
+
},
|
|
296
331
|
{
|
|
297
332
|
name: 'session_manager_help',
|
|
298
333
|
group: 'help',
|
package/src/main/otel.cjs
CHANGED
|
@@ -35,9 +35,9 @@ function loadDeps() {
|
|
|
35
35
|
const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
|
|
36
36
|
const { BatchSpanProcessor } = require('@opentelemetry/sdk-trace-base');
|
|
37
37
|
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
|
|
38
|
-
const {
|
|
39
|
-
const {
|
|
40
|
-
return { api, NodeTracerProvider, BatchSpanProcessor, OTLPTraceExporter,
|
|
38
|
+
const { resourceFromAttributes } = require('@opentelemetry/resources');
|
|
39
|
+
const { ATTR_SERVICE_NAME } = require('@opentelemetry/semantic-conventions');
|
|
40
|
+
return { api, NodeTracerProvider, BatchSpanProcessor, OTLPTraceExporter, resourceFromAttributes, ATTR_SERVICE_NAME };
|
|
41
41
|
} catch (err) {
|
|
42
42
|
return { error: err };
|
|
43
43
|
}
|
|
@@ -83,7 +83,7 @@ async function init({ endpoint, headers, serviceName, includeContent: ic } = {})
|
|
|
83
83
|
return { ok: false, error: lastError };
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
const { NodeTracerProvider, BatchSpanProcessor, OTLPTraceExporter,
|
|
86
|
+
const { NodeTracerProvider, BatchSpanProcessor, OTLPTraceExporter, resourceFromAttributes, ATTR_SERVICE_NAME } = deps;
|
|
87
87
|
|
|
88
88
|
try {
|
|
89
89
|
const exporter = new OTLPTraceExporter({
|
|
@@ -91,11 +91,11 @@ async function init({ endpoint, headers, serviceName, includeContent: ic } = {})
|
|
|
91
91
|
headers: typeof headers === 'object' && headers ? headers : {},
|
|
92
92
|
});
|
|
93
93
|
const tp = new NodeTracerProvider({
|
|
94
|
-
resource:
|
|
95
|
-
[
|
|
94
|
+
resource: resourceFromAttributes({
|
|
95
|
+
[ATTR_SERVICE_NAME]: String(serviceName || 'session-manager'),
|
|
96
96
|
}),
|
|
97
|
+
spanProcessors: [new BatchSpanProcessor(exporter)],
|
|
97
98
|
});
|
|
98
|
-
tp.addSpanProcessor(new BatchSpanProcessor(exporter));
|
|
99
99
|
// Note: we deliberately do NOT call tp.register() — that installs a global
|
|
100
100
|
// tracer provider, which would intercept any other OTEL user in the
|
|
101
101
|
// process. We only want to emit our own spans, so we use the provider
|