superclawd 0.1.0 → 0.1.2
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 +71 -29
- package/dist/hook-helper.mjs +61 -4
- package/dist/index.js +154 -112
- package/dist/mcp-server.mjs +45 -37
- package/package.json +8 -3
package/dist/index.js
CHANGED
|
@@ -1,22 +1,30 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire as __cr } from 'module'; const require = __cr(import.meta.url);
|
|
3
|
-
import{spawn as
|
|
4
|
-
`,{mode:384});try{
|
|
5
|
-
`)}catch{}}function
|
|
3
|
+
import{spawn as tn,spawnSync as Dr,execSync as Or}from"node:child_process";import{fileURLToPath as en}from"node:url";import{existsSync as nn}from"node:fs";import{resolve as Tr,dirname as Ur,join as Wr}from"node:path";import{homedir as on}from"node:os";import{join as Z}from"node:path";import{randomBytes as sn}from"node:crypto";import{readFileSync as an,writeFileSync as Oe,mkdirSync as Te,chmodSync as cn,existsSync as Ue}from"node:fs";var H=(process.env.SUPERCLAWD_BACKEND||"real").toLowerCase(),k=H==="mock",B=process.env.SUPERCLAWD_MCP_API_URL||"https://mcp-api.superclawd.com",ee=process.env.SUPERCLAWD_API_URL||"https://api.superclawd.com",U=process.env.SUPERCLAWD_HOME||Z(on(),".superclawd"),te=Z(U,"sessions"),Q=Z(U,"config.json");function ln(e){if(!e||typeof e!="object")return{};let t=e,n=t.credentials??{...typeof t.keyId=="string"?{keyId:t.keyId}:{},...typeof t.secret=="string"?{secret:t.secret}:{},...typeof t.workspace=="string"?{workspace:t.workspace}:{}},r=t.preferences??{...typeof t.skipPermissions=="boolean"?{skipPermissions:t.skipPermissions}:{},...typeof t.notifications=="boolean"?{notifications:t.notifications}:{},...typeof t.chooseWorkspaceAtStartup=="boolean"?{chooseWorkspaceAtStartup:t.chooseWorkspaceAtStartup}:{},...typeof t.experimental=="boolean"?{experimental:t.experimental}:{}},o={};return Object.keys(n).length&&(o.credentials=n),Object.keys(r).length&&(o.preferences=r),typeof t.machineId=="string"&&(o.machineId=t.machineId),o}function We(){let e=P()??{};if(e.machineId)return e.machineId;let t=sn(16).toString("hex");return G({...e,machineId:t}),t}function P(){try{return ln(JSON.parse(an(Q,"utf8")))}catch{return null}}function G(e){Te(U,{recursive:!0}),Oe(Q,`${JSON.stringify(e,null,2)}
|
|
4
|
+
`,{mode:384});try{cn(Q,384)}catch{}}function Ne(){return P()?.preferences?.skipPermissions===!0}function un(){return P()?.preferences?.notifications===!0}function Ge(){return P()?.preferences?.chooseWorkspaceAtStartup!==!1}function we(e){let t=P()??{};G({...t,credentials:{...t.credentials,workspace:e}})}function ne(){let e=P();e?.credentials?.workspace&&G({...e,credentials:{...e.credentials,workspace:""}})}function je(){return P()?.preferences?.experimental===!0}function Fe(){return P()?.preferences?.keepAwake===!0}function Ke(){return P()?.preferences?.privateMemory!==!1}function Ye(){return P()?.preferences?.pipelinesMcp===!0}function Be(e){return Z(e,"config.json")}function pn(e,t){try{Te(e,{recursive:!0}),Oe(Be(e),`${JSON.stringify(t,null,2)}
|
|
5
|
+
`)}catch{}}function He(e,t){Ue(Be(e))||pn(e,{notifications:un(),...t?{workspace:t}:{}})}function qe(){Ue(Q)||G({credentials:{keyId:"",secret:"",workspace:""},preferences:{notifications:!1,skipPermissions:!1,chooseWorkspaceAtStartup:!0,privateMemory:!0}})}var Ve=1e3*60*60*24*3;function Je(){if(k)return{ok:!0,session:{keyId:process.env.SUPERCLAWD_MCP_KEY||"mock-key",secret:process.env.SUPERCLAWD_MCP_SECRET||"mock-secret",workspace:process.env.SUPERCLAWD_MCP_WORKSPACE||"mock-workspace",apiUrl:B}};let e=P()?.credentials??{},t=process.env.SUPERCLAWD_MCP_KEY||e.keyId,n=process.env.SUPERCLAWD_MCP_SECRET||e.secret,r=process.env.SUPERCLAWD_MCP_WORKSPACE||e.workspace||"";return!t||!n?{ok:!1,error:"Not authenticated. Run `superclawd login` (or set SUPERCLAWD_MCP_KEY + SUPERCLAWD_MCP_SECRET)."}:{ok:!0,session:{keyId:t,secret:n,workspace:r,apiUrl:B}}}import{spawn as Se}from"node:child_process";var Xe=e=>{process.env.SUPERCLAWD_DEBUG&&process.stderr.write(`keep-awake: ${e}
|
|
6
|
+
`)};function dn(){try{switch(process.platform){case"darwin":return Se("caffeinate",["-i","-w",String(process.pid)],{stdio:"ignore"});case"linux":return Se("systemd-inhibit",["--what=sleep:idle","--who=SuperClawd","--why=SuperClawd session running","--mode=block","cat"],{stdio:["pipe","ignore","ignore"]});case"win32":{let e=[`$p = Add-Type -MemberDefinition '[DllImport("kernel32.dll")] public static extern uint SetThreadExecutionState(uint e);' -Name P -Namespace W -PassThru;`,"$p::SetThreadExecutionState(0x80000000 -bor 0x00000001) | Out-Null;","[void][Console]::In.ReadToEnd();"].join(" ");return Se("powershell",["-NoProfile","-NonInteractive","-Command",e],{stdio:["pipe","ignore","ignore"]})}default:return null}}catch{return null}}function ze(){let e=dn();if(!e)return Xe(`unsupported platform ${process.platform}`),null;e.unref(),e.on("error",n=>Xe(n.message));let t=!1;return{stop(){if(!t){t=!0;try{e.kill()}catch{}}}}}import{spawnSync as Qe}from"node:child_process";var fn="https://registry.npmjs.org/superclawd",mn=1500;function gn(e,t){let n=s=>s.split("-")[0].split(".").map(i=>parseInt(i,10)||0),r=n(e),o=n(t);for(let s=0;s<3;s++){let i=r[s]??0,a=o[s]??0;if(i!==a)return i>a}return!1}async function hn(){let e=new AbortController,t=setTimeout(()=>e.abort(),mn);try{let n=await fetch(fn,{headers:{accept:"application/vnd.npm.install-v1+json"},signal:e.signal});return n.ok?(await n.json())["dist-tags"]?.latest??null:null}catch{return null}finally{clearTimeout(t)}}async function Ze(e,t){if(process.env.SUPERCLAWD_NO_UPDATE||process.env.SUPERCLAWD_BACKEND==="mock"||process.env.SUPERCLAWD_UPDATED)return{};let n=await hn();if(!n||!gn(n,e))return{};process.stderr.write(`SuperClawd ${e} is outdated (latest ${n}). Updating\u2026
|
|
7
|
+
`);let r=Qe("npm install -g superclawd@latest",{stdio:"inherit",shell:!0});if(r.status!==0)return process.stderr.write(`
|
|
8
|
+
\u2717 Couldn't auto-update to ${n} (npm exited ${r.status??"?"}).
|
|
9
|
+
SuperClawd won't launch an outdated version. Update manually, then re-run:
|
|
10
|
+
npm install -g superclawd@latest
|
|
11
|
+
`),{exitCode:1};let o=Qe("superclawd",t,{stdio:"inherit",env:{...process.env,SUPERCLAWD_UPDATED:"1"}});return o.error?(process.stderr.write(`
|
|
12
|
+
\u2713 Updated to ${n}. Re-run your command.
|
|
13
|
+
`),{exitCode:0}):{exitCode:o.status??0}}import{randomUUID as et}from"node:crypto";function tt(e){let t={"content-type":"application/json","x-mcp-key-id":e.keyId,"x-mcp-secret":e.secret,"x-workspace-slug":e.workspace,"x-request-id":et()};return process.env.SUPERCLAWD_EXPERIMENTAL==="true"&&(t["x-experimental"]="true"),t}async function re(e,t,n){let r=`${e.apiUrl}${t}`;if(n){let i=new URLSearchParams;for(let[l,c]of Object.entries(n))c!==void 0&&c!==""&&i.set(l,c);let a=i.toString();a&&(r+=(r.includes("?")?"&":"?")+a)}let o=await fetch(r,{headers:tt(e)}),s=await o.json().catch(()=>null);return{status:o.status,ok:o.ok,body:s}}async function nt(e,t,n){try{let r=await fetch(`${e}/api/prompt/workspaces`,{headers:{"content-type":"application/json","x-mcp-key-id":t,"x-mcp-secret":n,"x-request-id":et()}}),o=await r.json().catch(()=>null);return{ok:r.ok,status:r.status,workspaces:o?.workspaces??[]}}catch{return{ok:!1,status:0,workspaces:[]}}}async function rt(e,t,n,r={}){let o=await fetch(`${e.apiUrl}${t}`,{method:"POST",headers:{...tt(e),...r},body:JSON.stringify(n)}),s=await o.json().catch(()=>null);return{status:o.status,ok:o.ok,body:s}}async function ke(e,t){e.message("Loading your workspaces\u2026");let n=await nt(B,t.keyId,t.secret);if(!n.ok||n.workspaces.length===0)return{};let r=new Set(n.workspaces.map(i=>i.slug)),o=t.workspace&&r.has(t.workspace)?t.workspace:void 0;if(t.workspace&&!r.has(t.workspace)&&ne(),n.workspaces.length===1){let i=n.workspaces[0].slug;return i!==o&&we(i),{workspace:i}}let s=await e.selectWorkspace(n.workspaces,{currentSlug:o,defaultSlug:o,onSetDefault:i=>we(i)});return s===null?{cancelled:!0}:{workspace:s}}async function ye(e){if(k)return{ok:!0};try{let t=await re(e,"/api/prompt/catalog");return t.ok?{ok:!0}:t.status===401?{ok:!1,error:"Your credentials are invalid or expired. Run `superclawd login` again."}:t.status===404?{ok:!1,workspaceInvalid:!0,error:"Workspace not found. Run `superclawd` and pick a workspace."}:t.status===403?{ok:!1,workspaceInvalid:!0,error:"You are not a member of this workspace."}:t.status===502||t.status===503||t.status===504?{ok:!1,error:`SuperClawd backend is unreachable or starting up (HTTP ${t.status}). Try again in a moment.`}:{ok:!1,error:`Auth check failed (HTTP ${t.status}).`}}catch(t){return{ok:!1,error:`Cannot reach SuperClawd backend (${String(t)}).`}}}var Ee=[{id:"skill-backend-001",name:"backend-api-conventions",action:"code",executionMode:"auto",description:"writing, creating, modifying, or reviewing backend API code \u2014 HTTP endpoints, routes, controllers, request handlers, or server-side validation and security",categories:[{name:"endpoint-design",instructions:["Name routes with plural nouns and kebab-case (e.g. /user-profiles).","Return RFC-7807 problem+json on errors, never bare strings.","Validate and sanitize every request body against a schema before use."]},{name:"security",instructions:["Use parameterized queries only; never string-concatenate SQL.","Rate-limit auth endpoints to 5 requests/minute per IP."]}]},{id:"skill-testing-001",name:"testing-standards",action:"test",executionMode:"auto",description:"writing or updating automated tests \u2014 unit tests, integration tests, test files, assertions, mocks, or test coverage",categories:[{name:"unit",instructions:["One behavioral assertion per test; name tests as should_<expectation>.","Mock only at process boundaries (network, fs, clock)."]}]},{id:"skill-always-001",name:"repo-foundations",action:"behave",executionMode:"always",description:"foundational rules that always apply in this repository",categories:[{name:"house-rules",instructions:["Every source file must start with a one-line header comment describing its purpose.","Prefer clarity over cleverness; match the surrounding code's style."]}]}];var ot=[{id:"guardrail-no-rm-rf",match:{tools:["Bash"],commandPatterns:["\\brm\\s+-rf\\b","\\brm\\s+-fr\\b"]},action:"deny",message:"Destructive 'rm -rf' is blocked by a workspace guardrail. Remove paths explicitly and deliberately instead."},{id:"guardrail-payments-edits",match:{tools:["Edit","Write","MultiEdit","NotebookEdit"],pathGlobs:["**/payments/**"]},action:"ask",message:"Edits under payments/ touch billing-critical code \u2014 confirm before proceeding (workspace guardrail)."}],st=[{id:"agent-reviewer-001",name:"code-reviewer",description:"Reviews a diff for correctness and security issues. Use after writing code.",vendor:"anthropic",model:"claude-sonnet-4-6",prompt:"You are a meticulous senior code reviewer. Examine the change for correctness, security, and clarity. Report concrete findings with file:line; do not rewrite the code unless asked.",mode:"subagent",tools:{read:"allow",glob:"allow",grep:"allow",edit:"deny",write:"deny",bash:"deny",webfetch:"deny",task:"deny"},steps:null,inheritWorkspaceContext:!1},{id:"agent-orchestrator-001",name:"orchestrator",description:"Coordinates multi-step coding tasks and delegates focused work. Use when a task spans several files or steps.",vendor:"anthropic",model:"claude-sonnet-4-6",prompt:"You are an orchestrator. Break the request into concrete steps, perform the edits directly, and keep changes minimal and focused on what was asked.",mode:"subagent",tools:{read:"allow",glob:"allow",grep:"allow",edit:"allow",write:"allow",bash:"deny",webfetch:"deny",task:"allow"},steps:null,inheritWorkspaceContext:!0}],it=[{name:"ship-checklist",description:"Run this team's pre-merge checklist.",arguments:[{name:"scope",description:"what is being shipped",required:!1}],content:`Pre-merge checklist for $ARGUMENTS:
|
|
6
14
|
1. Tests pass and cover new behavior.
|
|
7
15
|
2. No secrets or debug logging left in.
|
|
8
16
|
3. Public APIs documented.
|
|
9
|
-
4. Changelog updated.`}],
|
|
17
|
+
4. Changelog updated.`}],at=[{name:"error-codes",description:"Canonical list of this platform's error codes.",content:`E1001 invalid_input
|
|
10
18
|
E1002 unauthorized
|
|
11
19
|
E1003 rate_limited
|
|
12
|
-
E2001 upstream_unavailable`}];var
|
|
20
|
+
E2001 upstream_unavailable`}];var ct=[{id:"workflow-deploy-001",name:"production-deploy",description:"deploying to production, cutting a release, or shipping to prod",itemCount:6,content:`Production deploy workflow:
|
|
13
21
|
1. Confirm CI is green on main.
|
|
14
22
|
2. Bump version + update changelog.
|
|
15
23
|
3. Tag the release.
|
|
16
24
|
4. Run db migrations.
|
|
17
25
|
5. Deploy and watch error rate for 10m.
|
|
18
|
-
6. Announce in #releases.`}];function
|
|
19
|
-
`);return{skills:e,agents:
|
|
26
|
+
6. Announce in #releases.`}];function wn(){let e=Ee.filter(n=>n.executionMode==="auto").map(n=>({id:n.id,name:n.name,action:n.action,executionMode:n.executionMode,description:n.description})),t=Ee.filter(n=>n.executionMode==="always").flatMap(n=>n.categories.flatMap(r=>r.instructions)).map((n,r)=>`${r+1}. ${n}`).join(`
|
|
27
|
+
`);return{skills:e,agents:st,agentTeams:[],commands:it.map(({name:n,description:r,arguments:o,team:s})=>({name:n,description:r,arguments:o,team:s??null})),resources:at.map(({name:n,description:r})=>({name:n,description:r})),workflows:ct.map(({id:n,name:r,description:o})=>({id:n,name:r,description:o})),mcpServers:[],guardrails:ot,policyGuardrails:[],foundational:{text:t},teamMemoryEnabled:!0,repoMemoryEnabled:!0,agentMemoryEnabled:!0}}async function lt(e){if(k)return wn();let t=await re(e,"/api/prompt/catalog",{repoFingerprint:process.env.SUPERCLAWD_REPO_FINGERPRINT});if(!t.ok||!t.body)throw new Error(`Failed to fetch catalog (HTTP ${t.status}).`);return{skills:(t.body.skills??[]).filter(r=>r.executionMode==="auto"),agents:(t.body.agents??[]).map(r=>({...r,learnedMemories:r.learnedMemories??[]})),agentTeams:(t.body.agentTeams??[]).map(r=>({...r,linkedWorkflows:r.linkedWorkflows??[]})),commands:t.body.commands??[],resources:t.body.resources??[],workflows:t.body.workflows??[],mcpServers:t.body.mcpServers??[],guardrails:t.body.guardrails??[],policyGuardrails:t.body.policyGuardrails??[],foundational:{text:t.body.foundational?.text??""},teamMemoryEnabled:t.body.teamMemoryEnabled??!0,repoMemoryEnabled:t.body.repoMemoryEnabled??!0,agentMemoryEnabled:t.body.agentMemoryEnabled??!0}}async function ut(e,t){if(k)return!0;try{return(await rt(e,"/api/prompt/inspector",{ide:!0,platform:"claude-code",llm_model:"claude",x_session_request_id:t,notify_on_checkpoint:!0,enable_session_files:!1},{"x-session-request-id":t})).ok}catch{return!1}}import{mkdirSync as ar,writeFileSync as cr,chmodSync as lr}from"node:fs";import{dirname as Ot,join as Tt}from"node:path";function x(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,64)||"skill"}function Sn(e){return`${(e.description??e.name).trim().replace(/\.$/,"")}. SuperClawd-managed "${e.name}" guidance for ${e.action} tasks.`}function kn(e){return`# ${e.name} (SuperClawd-managed)
|
|
20
28
|
|
|
21
29
|
The authoritative instructions for this skill are managed in SuperClawd and
|
|
22
30
|
are **not** included here. You must fetch them before acting.
|
|
@@ -30,13 +38,13 @@ are **not** included here. You must fetch them before acting.
|
|
|
30
38
|
|
|
31
39
|
Do not proceed using only this description \u2014 it is a pointer, not the rules.
|
|
32
40
|
If \`get_directives\` returns an error, tell the user and stop.
|
|
33
|
-
`}function
|
|
34
|
-
name: ${
|
|
41
|
+
`}function yn(e){let t=Sn(e).replace(/"/g,'\\"');return`---
|
|
42
|
+
name: ${x(e.name)}
|
|
35
43
|
description: "${t}"
|
|
36
44
|
user-invocable: false
|
|
37
45
|
---
|
|
38
46
|
|
|
39
|
-
`}function
|
|
47
|
+
`}function pt(e){let t=new Set,n=[];for(let r of e){let o=x(r.name),s=2;for(;t.has(o);)o=`${x(r.name)}-${s++}`;t.add(o),n.push({relPath:`skills/${o}/SKILL.md`,content:yn(r)+kn(r)})}return n}var En=`SUPERCLAWD \u2014 operating manual (always in effect):
|
|
40
48
|
- The ALWAYS rules below are ALREADY LOADED and active for this entire session.
|
|
41
49
|
Apply them directly to all work. Do NOT call any tool to fetch them \u2014 you
|
|
42
50
|
already have them in full.
|
|
@@ -45,24 +53,52 @@ user-invocable: false
|
|
|
45
53
|
the \`get_directives\` tool with that file's skillId (a UUID) BEFORE acting,
|
|
46
54
|
and apply what it returns. Those skill files are pointers, not the rules.
|
|
47
55
|
- Only call \`get_directives\` with a UUID skillId taken from an activated skill
|
|
48
|
-
file. Never call it for the ALWAYS rules, and never pass a skill name
|
|
56
|
+
file. Never call it for the ALWAYS rules, and never pass a skill name.
|
|
57
|
+
- MEMORY: when the user states something durable \u2014 a fact, preference, or standing
|
|
58
|
+
rule, ESPECIALLY phrased as "remember\u2026", "from now on", "always", or "going
|
|
59
|
+
forward" \u2014 call \`record_memory\` RIGHT AWAY to persist it (silently; it picks the
|
|
60
|
+
scope on its own: the user's PRIVATE memory, the TEAM's, or the REPO's). Acknowledging
|
|
61
|
+
a durable instruction is NOT persisting it \u2014 you must actually record it. But do NOT
|
|
62
|
+
record one-off chit-chat or personal trivia that won't shape future work (e.g. "I love
|
|
63
|
+
candies") \u2014 just acknowledge those and move on. Still NEVER
|
|
64
|
+
ask where to store it, present a "how should I remember this?" menu, or offer to edit
|
|
65
|
+
an agent definition to save a preference \u2014 just record it silently. Be ACCURATE about
|
|
66
|
+
what you saved: only say something is saved/remembered AFTER you've actually called
|
|
67
|
+
\`record_memory\` for it; never claim a preference is "already" a saved convention, or
|
|
68
|
+
that it "will persist", unless you just recorded it (or confirmed it via
|
|
69
|
+
\`list_memories\`). A background pass also captures durable facts at session end as a
|
|
70
|
+
backstop \u2014 but never rely on it for an explicit request; record that now.`;function Ce(e){let t=En,n=(e||"").trim();return n&&(t+=`
|
|
49
71
|
|
|
50
72
|
ALWAYS \u2014 foundational rules (already loaded & active for this whole session; apply directly, never fetch):
|
|
51
|
-
${
|
|
73
|
+
${n}`),t}function Cn(e){return e.inheritWorkspaceContext!==!1}function Rn(e){return Ce(e).trim()}function _n(e){return`You are SuperClawd agent \`${e.id}\`. SuperClawd automatically remembers the durable, reusable lessons from your work and applies them on your future runs \u2014 you do NOT need to save anything yourself.`}function Pn(e){let t=(e.learnedMemories??[]).filter(r=>r.trim());return t.length===0?"":`AGENT MEMORY \u2014 lessons you've learned in past work (apply by default; a more specific instruction wins):
|
|
74
|
+
`+t.map(r=>`- ${r.trim()}`).join(`
|
|
75
|
+
`)}function Re(e,t){let n=[];if(Cn(e)){let o=Rn(t);o&&n.push(o)}n.push(_n(e));let r=Pn(e);return r&&n.push(r),n.push(e.prompt),n.join(`
|
|
52
76
|
|
|
53
77
|
---
|
|
54
78
|
|
|
55
|
-
${e
|
|
56
|
-
${
|
|
79
|
+
`)}var q="superclawd",oe="core",se=`mcp__plugin_${q}_${oe}__`,_e=e=>`${se}${e}`,dt=`${se}*`,vn=`${q}:`,ie=e=>`${vn}${e}`;var ae={read:"Read",glob:"Glob",grep:"Grep",edit:"Edit",write:"Write",bash:"Bash",webfetch:"WebFetch",task:"Task"};function bn(e){return e==="allow"||e==="ask"||e===!0}var Pe=_e("get_workflow"),ft=_e("get_directives"),An=e=>ie(e);function Mn(e,t=!1,n=!1,r=!1){let o=e.tools??{},s=Object.keys(ae).filter(i=>bn(o[i])).map(i=>ae[i]);return t&&!s.includes(ae.task)&&s.push(ae.task),n&&!s.includes(Pe)&&s.push(Pe),r&&!s.includes(ft)&&s.push(ft),s}function xn(e,t=!1,n=!1){let r=[`name: ${x(e.name)}`,`description: "${(e.description??e.name).replace(/"/g,'\\"')}"`];e.vendor==="anthropic"&&e.model&&e.model!=="default"&&r.push(`model: ${JSON.stringify(e.model)}`);let o=(e.skills?.length??0)>0,s=Mn(e,t,n,o);return s.length&&r.push(`tools: ${s.join(", ")}`),e.skills?.length&&r.push(`skills: ${e.skills.join(", ")}`),`---
|
|
80
|
+
${r.join(`
|
|
57
81
|
`)}
|
|
58
82
|
---
|
|
59
83
|
|
|
60
|
-
`}function
|
|
84
|
+
`}function ce(e){let t=new Set;return e.map(n=>{let r=x(n.name),o=2;for(;t.has(r);)r=`${x(n.name)}-${o++}`;return t.add(r),{slug:r,agent:n}})}function mt(e){let t={};for(let{slug:n,agent:r}of ce(e))t[n]=r.id;return t}function $n(e,t){let n=t.map(s=>`- \`${An(s.slug)}\` \u2014 ${s.description??s.slug}`).join(`
|
|
85
|
+
`),r=`## Team Lead \u2014 ${e.name}
|
|
86
|
+
You lead the **${e.name}** agent team. When given a task, decompose it and **delegate to your team members via the Agent tool** \u2014 then **synthesize** their outputs into one consolidated answer. Delegate using the EXACT agent name shown below (including the \`superclawd:\` prefix). Call the Agent tool and use the result it returns directly \u2014 it returns the member's full output when that member finishes. To run members in parallel, issue multiple Agent calls in a single step; they run concurrently and each returns its own result. Do NOT run members as background agents, and NEVER poll for a "\`.done\`"/completion file or run a \`sleep\`/\`until\` wait loop \u2014 there is no such marker, so it will hang forever; just read the Agent tool's returned result. Your members:
|
|
87
|
+
${n}`,o=e.linkedWorkflows??[];if(o.length){let s=o.map(i=>`- ${i.name} (workflowId: ${i.id}) \u2014 ${i.description??""}`).join(`
|
|
88
|
+
`);r+=`
|
|
89
|
+
|
|
90
|
+
### Linked workflows
|
|
91
|
+
You **MAY** run any of these linked workflows if (and only if) one is relevant to the task \u2014 there is **no obligation** to run any. To run one, call the \`${Pe}\` MCP tool with its \`workflowId\`, then follow the returned steps in order.
|
|
92
|
+
${s}`}return r}function gt(e,t={},n=[]){let r=t.foundationalText??"",o=ce(e),s=new Map;for(let{slug:l,agent:c}of o)s.set(c.id,{slug:l,description:c.description});let i=new Map,a=new Set;for(let l of n){let c=l.memberAgentIds.map(w=>s.get(w)).filter(w=>!!w),g=$n(l,c),E=i.get(l.leadAgentId)??[];E.push(g),i.set(l.leadAgentId,E),l.linkedWorkflows?.length&&a.add(l.leadAgentId)}return o.map(({slug:l,agent:c})=>{let g=i.get(c.id),E=!!g&&g.length>0,w=a.has(c.id),p=E?[Re(c,r),...g].join(`
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
`):Re(c,r);return{relPath:`agents/${l}.md`,content:xn(c,E,w)+p}})}function Ln(e){return e.arguments.length?e.arguments.map(t=>t.required?`<${t.name}>`:`[${t.name}]`).join(" "):""}function In(e){let t=[`description: "${e.description.replace(/"/g,'\\"')}"`],n=Ln(e);return n&&t.push(`argument-hint: ${n}`),`---
|
|
61
97
|
${t.join(`
|
|
62
98
|
`)}
|
|
63
99
|
---
|
|
64
100
|
|
|
65
|
-
`}function
|
|
101
|
+
`}function Dn(e,t){let n=`This is the SuperClawd command **${e.name}**. Its content is managed in
|
|
66
102
|
SuperClawd and fetched on use.
|
|
67
103
|
|
|
68
104
|
**REQUIRED \u2014 do this now:**
|
|
@@ -71,7 +107,20 @@ SuperClawd and fetched on use.
|
|
|
71
107
|
2. Execute the returned command content, substituting these arguments: $ARGUMENTS
|
|
72
108
|
|
|
73
109
|
Do not improvise the command from this description.
|
|
74
|
-
|
|
110
|
+
`,r=e.team;if(r&&t.has(r.leadAgentId)){let o=t.get(r.leadAgentId);return`## Team: ${r.name}
|
|
111
|
+
Run this command WITH the **${r.name}** agent team. Delegate the task to its lead \`${ie(o)}\` via the Agent tool \u2014 the lead will decompose it, fan out to its members, and synthesize \u2014 then return the lead's result. Do the work through the team rather than alone. Call the Agent tool and use the result it returns directly; do NOT run the lead as a background agent or poll for a "\`.done\`"/completion file (there is none \u2014 it will hang).
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
`+n}return n}function ht(e,t){let n=new Map(ce(t).map(({slug:s,agent:i})=>[i.id,s])),r=new Set,o=[];for(let s of e){let i=x(s.name),a=2;for(;r.has(i);)i=`${x(s.name)}-${a++}`;r.add(i),o.push({relPath:`commands/${i}.md`,content:In(s)+Dn(s,n)})}return o}function On(e,t){let n=e.mode==="reference",r=(e.description??e.name).trim().replace(/\.$/,""),o=(n?`${r}. Read the '${e.name}' SuperClawd reference workflow to understand how this works (do not execute it).`:`${r}. Runs the '${e.name}' SuperClawd workflow.`).replace(/"/g,'\\"'),s=n?`# ${e.name} (SuperClawd workflow \u2014 REFERENCE)
|
|
116
|
+
|
|
117
|
+
This is a **structured explanation** of how a system or flow works \u2014 NOT a procedure to run.
|
|
118
|
+
|
|
119
|
+
**When this is relevant to the task:**
|
|
120
|
+
|
|
121
|
+
1. Call the \`get_workflow\` tool with \`workflowId\`: \`${e.id}\`.
|
|
122
|
+
2. **Read** the returned steps to understand the flow. Do **not** execute them as actions.
|
|
123
|
+
`:`# ${e.name} (SuperClawd workflow)
|
|
75
124
|
|
|
76
125
|
This is a managed multi-step workflow. Fetch its steps before starting.
|
|
77
126
|
|
|
@@ -83,19 +132,23 @@ This is a managed multi-step workflow. Fetch its steps before starting.
|
|
|
83
132
|
Do not improvise the process from this description.
|
|
84
133
|
`;return{relPath:`skills/${t}/SKILL.md`,content:`---
|
|
85
134
|
name: ${t}
|
|
86
|
-
description: "${
|
|
135
|
+
description: "${o}"
|
|
87
136
|
user-invocable: false
|
|
88
137
|
---
|
|
89
138
|
|
|
90
|
-
${
|
|
139
|
+
${s}`}}function Tn(e,t){let n=e.mode==="reference",r=n?`Read the SuperClawd reference workflow **${e.name}** to understand how it works:
|
|
140
|
+
|
|
141
|
+
1. Call the \`get_workflow\` tool with \`workflowId\`: \`${e.id}\`.
|
|
142
|
+
2. **Read** the returned steps to understand the flow \u2014 do not execute them.
|
|
143
|
+
`:`Run the SuperClawd workflow **${e.name}**:
|
|
91
144
|
|
|
92
145
|
1. Call the \`get_workflow\` tool with \`workflowId\`: \`${e.id}\`.
|
|
93
146
|
2. Follow the returned steps in order, using any arguments: $ARGUMENTS
|
|
94
|
-
`,n
|
|
95
|
-
description: "${
|
|
147
|
+
`,o=(n?`Read how '${e.name}' works.`:`Run the '${e.name}' workflow.`).replace(/"/g,'\\"');return{relPath:`commands/${t}.md`,content:`---
|
|
148
|
+
description: "${o}"
|
|
96
149
|
---
|
|
97
150
|
|
|
98
|
-
${
|
|
151
|
+
${r}`}}function wt(e){let t=new Set,n=[];for(let r of e){let o=x(r.name),s=2;for(;t.has(o);)o=`${x(r.name)}-${s++}`;t.add(o),n.push(On(r,o)),n.push(Tn(r,o))}return n}var Un=`---
|
|
99
152
|
description: Audit this session against your active SuperClawd directives.
|
|
100
153
|
---
|
|
101
154
|
|
|
@@ -107,7 +160,7 @@ Audit the work done so far in this session against your active SuperClawd direct
|
|
|
107
160
|
4. Flag anything relevant you may have skipped \u2014 and if so, fetch and apply/run it now.
|
|
108
161
|
|
|
109
162
|
Be concise; this is a compliance check, not a code review.
|
|
110
|
-
`,
|
|
163
|
+
`,Wn=`---
|
|
111
164
|
description: Show SuperClawd service status, workspace info, and credit balance.
|
|
112
165
|
---
|
|
113
166
|
|
|
@@ -118,14 +171,14 @@ Give me a concise SuperClawd status overview. Call these tools and summarize the
|
|
|
118
171
|
3. \`check_balance\` \u2014 current credit balance.
|
|
119
172
|
|
|
120
173
|
Present it as a tidy summary; do not take any other action.
|
|
121
|
-
`,
|
|
174
|
+
`,Nn=`---
|
|
122
175
|
description: Toggle SuperClawd notifications for this session.
|
|
123
176
|
---
|
|
124
177
|
|
|
125
178
|
The user wants to flip SuperClawd notifications for this session.
|
|
126
179
|
|
|
127
180
|
Call the \`notifications\` tool (no arguments \u2014 it toggles the current on/off state), then report the resulting state in one short line. Do not take any other action.
|
|
128
|
-
`,
|
|
181
|
+
`,Gn=`---
|
|
129
182
|
description: Apply maximum extended thinking (ultrathink) to the work at hand.
|
|
130
183
|
argument-hint: "[task or question]"
|
|
131
184
|
---
|
|
@@ -133,104 +186,93 @@ argument-hint: "[task or question]"
|
|
|
133
186
|
To perform this work, please ultrathink \u2014 reason as deeply and carefully as you can before acting. Surface edge cases, weigh alternatives, and check your assumptions.
|
|
134
187
|
|
|
135
188
|
$ARGUMENTS
|
|
136
|
-
`;function
|
|
137
|
-
${
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
${
|
|
144
|
-
`),o(null)):
|
|
145
|
-
|
|
146
|
-
`)
|
|
147
|
-
|
|
148
|
-
`),{
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
`),process.stdout.write(
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
`);let
|
|
160
|
-
|
|
161
|
-
`)
|
|
162
|
-
`),
|
|
163
|
-
Default workspace is already "${n}".
|
|
164
|
-
|
|
165
|
-
`),{ok:!0}):(I({...e,credentials:{...t,workspace:n}}),process.stdout.write(`
|
|
166
|
-
\u2713 Default workspace set to "${n}".
|
|
167
|
-
|
|
168
|
-
`),{ok:!0}):{ok:!1,error:"A workspace is required."}}function Ze(){if(g){process.stdout.write(`Mock mode \u2014 credentials are not used.
|
|
169
|
-
`);return}let e=x()?.credentials??{},t=(o,n,r,s=!1)=>{let i=process.env[n],d=i||r,p=i?"env":r?"config file":"\u2014",u=d?s?Je(d):d:"(not set)";process.stdout.write(` ${o.padEnd(12)} ${u.padEnd(28)} (${p})
|
|
170
|
-
`)};process.stdout.write(`SuperClawd configuration:
|
|
171
|
-
`),t("Key ID","MCP_KEY_ID",e.keyId,!0),t("Secret","MCP_SECRET",e.secret,!0),t("Workspace","MCP_WORKSPACE",e.workspace),process.stdout.write(`
|
|
172
|
-
Env vars override the config file.
|
|
173
|
-
`)}function et(){try{Qt(W),process.stdout.write(`Cleared your SuperClawd configuration.
|
|
174
|
-
`)}catch{process.stdout.write(`No stored configuration to remove.
|
|
175
|
-
`)}}var h="\x1B",q=[{key:"notifications",label:"Notifications",description:"Default for new sessions \u2014 ping when Claude needs you or finishes",defaultOn:!1},{key:"skipPermissions",label:"Dangerously skip permissions",description:"Launch Claude Code with --dangerously-skip-permissions (no approval prompts)",defaultOn:!1},{key:"chooseWorkspaceAtStartup",label:"Choose workspace at startup",description:"Pick the workspace to boot into each time you run superclawd",defaultOn:!1}].sort((e,t)=>e.label.localeCompare(t.label)),re=(e,t)=>e.preferences?.[t.key]??t.defaultOn;async function tt(){let e=x()??{},t=process.stdin;if(!t.isTTY){process.stdout.write(`SuperClawd options:
|
|
176
|
-
`);for(let o of q)process.stdout.write(` ${re(e,o)?"on ":"off"} ${o.label}
|
|
177
|
-
`);return}await new Promise(o=>{let n=q.length,r=n+2,s=0,i=u=>{u||process.stdout.write(`${h}[${r}A`);for(let a=0;a<n;a++){let l=q[a],E=a===s?`${h}[38;5;208m\u276F `:" ",D=re(e,l)?`${h}[38;5;208m[\u2713]${h}[0m`:"[ ]";process.stdout.write(`${h}[2K${E}${D} ${l.label}${h}[0m ${h}[2m${l.description}${h}[0m
|
|
178
|
-
`)}process.stdout.write(`${h}[2K
|
|
179
|
-
`),process.stdout.write(`${h}[2K${h}[2mPress Esc (or Ctrl-C) to exit${h}[0m
|
|
189
|
+
`;function St(){return[{relPath:"commands/audit-work.md",content:Un},{relPath:"commands/status.md",content:Wn},{relPath:"commands/notifications.md",content:Nn},{relPath:"commands/ultrathink.md",content:Gn}]}import{existsSync as jn,readFileSync as Fn,writeFileSync as Kn,chmodSync as Yn,mkdirSync as Bn}from"node:fs";import{execSync as Hn}from"node:child_process";import{dirname as qn,join as kt}from"node:path";function Ct(e){let t="hooks/foundational-fallback.txt",n=`${e.pluginDir}/${t}`,r=`${e.pluginDir}/hooks/reminder-context.txt`,o=`${e.pluginDir}/stepcount`,s=h=>({type:"command",command:`node "${e.helperPath}" ${h}`}),i=h=>({...s(h),async:!0}),a={SessionStart:[{hooks:[s(`foundational "${n}" SessionStart`)]}],Notification:[{matcher:"permission_prompt|elicitation_dialog|elicitation_complete|elicitation_response|auth_success",hooks:[i(`notify-local attention "${e.launchId}"`),i(`notify attention "${e.launchId}"`)]}],Stop:[{hooks:[i(`notify-local stop "${e.launchId}"`)]}],SessionEnd:[{hooks:[i(`notify completion "${e.launchId}"`)]}]},l=[{relPath:t,content:e.foundational.text??""}],c=Number(process.env.SUPERCLAWD_REMIND_EVERY??8),g=process.env.SUPERCLAWD_REPO_MEMORY!=="0",E=process.env.SUPERCLAWD_AGENT_MEMORY!=="0",w=process.env.SUPERCLAWD_PRIVATE_MEMORY==="1",p=process.env.SUPERCLAWD_NO_CAPTURE==="1",f=!p&&!!process.env.SUPERCLAWD_REPO_FINGERPRINT&&(g||w),d=(e.foundational.text??"").trim(),A=d?`REMINDER \u2014 these SuperClawd always-rules remain in effect:
|
|
190
|
+
${d}`:"";if(c>0&&A&&(a.PostToolUse=[{matcher:"*",hooks:[s(`remind "${r}" "${o}"`)]}],l.push({relPath:"hooks/reminder-context.txt",content:A})),f){let h={hooks:[i(`capture "${e.launchId}"`)]};a.Stop.push(h),a.SessionEnd.push(h)}let u=e.agents??[];if(!p&&E&&u.length){let h="hooks/agent-map.json",m=`${e.pluginDir}/${h}`;l.push({relPath:h,content:JSON.stringify(mt(u))}),a.SubagentStop=[{hooks:[i(`capture-agent "${m}" "${e.launchId}"`)]}]}let S=[];if(e.gate&&S.push({matcher:`${se}.*`,hooks:[s("gate")]}),e.guardrails?.length){let h="hooks/guardrails.json",m=`${e.pluginDir}/${h}`;l.push({relPath:h,content:JSON.stringify(e.guardrails,null,2)}),S.push({matcher:"*",hooks:[s(`guardrails "${m}"`)]})}if(e.policyGuardrails?.length){let h="hooks/policy-guardrails.json",m=`${e.pluginDir}/${h}`;l.push({relPath:h,content:JSON.stringify(e.policyGuardrails,null,2)}),S.push({matcher:"Bash",hooks:[s(`policy "${m}"`)]})}return process.env.SUPERCLAWD_AUTO_RETRIEVE!=="0"&&(a.UserPromptSubmit=[{hooks:[s("retrieve prompt")]}],S.push({matcher:"Read",hooks:[s("retrieve file")]})),S.length&&(a.PreToolUse=S),l.push({relPath:"hooks/hooks.json",content:JSON.stringify({hooks:a},null,2)}),l}var yt="# superclawd-report-commit";function Et(e){return`'${String(e).replace(/'/g,"'\\''")}'`}function Rt(e){let{cwd:t,helperPath:n,env:r}=e,o="";try{let c=Hn("git rev-parse --git-path hooks",{cwd:t,encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();c&&(o=c.startsWith("/")?c:kt(t,c))}catch{return{installed:!1,reason:"not a git repo"}}if(!o)return{installed:!1,reason:"no hooks dir"};let s=kt(o,"post-commit");if(jn(s)){let c="";try{c=Fn(s,"utf8")}catch{return{installed:!1,reason:"post-commit unreadable; skipped"}}if(!c.includes(yt))return{installed:!1,reason:"existing user post-commit hook; skipped"}}let a=["SUPERCLAWD_BACKEND","SUPERCLAWD_MCP_API_URL","SUPERCLAWD_REPO_FINGERPRINT","SUPERCLAWD_MCP_KEY","SUPERCLAWD_MCP_SECRET","SUPERCLAWD_MCP_WORKSPACE","NODE_EXTRA_CA_CERTS","SUPERCLAWD_HOME","SUPERCLAWD_CLAUDE_BIN","SUPERCLAWD_POLICY_MODEL"].filter(c=>r[c]!==void 0&&r[c]!=="").map(c=>`export ${c}=${Et(r[c])}`).join(`
|
|
191
|
+
`),l=`#!/bin/sh
|
|
192
|
+
${yt}
|
|
193
|
+
# Auto-generated by superclawd \u2014 reports Learned Memory staleness after each
|
|
194
|
+
# commit. Safe to delete; superclawd will not recreate it if you replace it.
|
|
195
|
+
${a}
|
|
196
|
+
node ${Et(n)} report-commit >/dev/null 2>&1 &
|
|
197
|
+
`;try{Bn(qn(s),{recursive:!0}),Kn(s,l),Yn(s,493)}catch(c){return{installed:!1,reason:`write failed: ${String(c)}`}}return{installed:!0,reason:"installed"}}import{spawn as ve,spawnSync as Vn}from"node:child_process";import b from"node:fs";import v from"node:path";import{fileURLToPath as Jn}from"node:url";import{createRequire as Xn}from"node:module";var Ae=v.join(U,"pipelines.pid"),Me=v.join(U,"pipelines.port"),_t=v.join(U,"pipelines.log"),zn=v.join(U,"pipelines-mcp.json"),xt=63210,$t=2e4;function Qn(e){let t="",n=null,r=!1;for(let o=0;o<e.length;o++){let s=e[o],i=e[o+1];if(s==="--port"||s==="-p"){let a=Number(i);i&&Number.isInteger(a)&&a>0&&a<65536&&(n=a,o++)}else s==="-d"||s==="--detach"?r=!0:!s.startsWith("-")&&!t&&(t=s)}return{sub:t,port:n,detach:r}}function be(e){try{return process.kill(e,0),!0}catch(t){return t.code==="EPERM"}}function Pt(e){try{let t=Number(b.readFileSync(e,"utf8").trim());return Number.isInteger(t)&&t>0?t:null}catch{return null}}function le(){let e=Pt(Ae),t=Pt(Me);return{pid:e,port:t,alive:e!==null&&be(e)}}function Zn(){try{let e=JSON.parse(b.readFileSync(zn,"utf8"));return e&&typeof e=="object"?e:null}catch{return null}}function Lt(){if(!Ye())return null;let e=Zn(),t=e?.port??xt,n=e?.token;return{name:"pipelines",type:"http",url:`http://127.0.0.1:${t}/mcp`,...n?{headers:{Authorization:`Bearer ${n}`}}:{}}}function vt(e,t){b.mkdirSync(U,{recursive:!0}),b.writeFileSync(Ae,String(e)),b.writeFileSync(Me,String(t))}function V(){for(let e of[Ae,Me])try{b.unlinkSync(e)}catch{}}function er(){let e=process.env.SUPERCLAWD_PIPELINES_DIR;if(e)return b.existsSync(e)?e:null;let t=v.dirname(Jn(import.meta.url));for(let n=0;n<8;n++){let r=v.join(t,"apps","pipelines");if(b.existsSync(v.join(r,"server","index.ts"))||b.existsSync(v.join(r,"dist-server","index.mjs")))return r;let o=v.dirname(t);if(o===t)break;t=o}try{let n=Xn(import.meta.url),r=v.dirname(n.resolve("@superclawd-ai/pipelines/package.json"));if(b.existsSync(v.join(r,"dist-server","index.mjs")))return r}catch{}return null}function tr(e){let t=[v.join(e,"node_modules",".bin","tsx"),v.join(e,"..","..","node_modules",".bin","tsx")];for(let n of t)if(b.existsSync(n))return n;return"tsx"}function nr(){let e=er();if(!e)return null;let t=v.join(e,"dist-server","index.mjs");if(b.existsSync(t))return{cmd:process.execPath,args:[t],cwd:e};let n=v.join(e,"server","index.ts");return b.existsSync(n)?{cmd:tr(e),args:[n],cwd:e}:null}async function bt(e,t=$t){let n=Date.now()+t;for(;Date.now()<n;){if(await It(e))return!0;await new Promise(r=>setTimeout(r,250))}return!1}async function It(e){let t=new AbortController,n=setTimeout(()=>t.abort(),1e3);try{return(await fetch(`http://localhost:${e}/api/session`,{signal:t.signal})).ok}catch{return!1}finally{clearTimeout(n)}}function At(e){let t=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";try{ve(t,[e],{stdio:"ignore",detached:!0,shell:process.platform==="win32"}).unref()}catch{}}function O(e){process.stdout.write(e+`
|
|
198
|
+
`)}function F(e){process.stderr.write(e+`
|
|
199
|
+
`)}async function rr(e){let t=le(),n=a=>`http://localhost:${a}`;if(t.alive&&t.port)return O(`Pipelines is already running (pid ${t.pid}) at ${n(t.port)}`),e.detach||At(n(t.port)),0;t.pid&&!t.alive&&V();let r=nr();if(!r)return F(`\u2717 Couldn't locate the Pipelines app.
|
|
200
|
+
Set SUPERCLAWD_PIPELINES_DIR to its directory (the one containing server/index.ts).`),1;let o=e.port??xt,s={...process.env,PIPELINES_PORT:String(o)};if(e.detach){b.mkdirSync(U,{recursive:!0});let a=b.openSync(_t,"a"),l=ve(r.cmd,r.args,{cwd:r.cwd,env:s,detached:!0,stdio:["ignore",a,a]});return l.unref(),l.pid?(vt(l.pid,o),await bt(o)?(O(`\u2713 Pipelines started (pid ${l.pid}) at ${n(o)}`),0):(F(`\u2717 Daemon didn't become ready within ${$t/1e3}s. See ${_t}`),1)):(F("\u2717 Failed to spawn the Pipelines daemon."),1)}O(`Starting Pipelines at ${n(o)} \u2026 (Ctrl-C to stop)`);let i=ve(r.cmd,r.args,{cwd:r.cwd,env:s,stdio:"inherit"});return i.pid&&vt(i.pid,o),bt(o).then(a=>{a&&At(n(o))}),await new Promise(a=>{i.on("error",l=>{F(`\u2717 Could not launch the daemon: ${l.message}`),V(),a(1)}),i.on("close",l=>{V(),a(l??0)})})}async function or(){let e=le();if(!e.pid||!e.alive)return O("Pipelines is not running."),V(),0;let t=n=>{try{process.kill(-e.pid,n)}catch{try{process.kill(e.pid,n)}catch{}}};t("SIGTERM");for(let n=0;n<40&&be(e.pid);n++)await new Promise(r=>setTimeout(r,100));return be(e.pid)&&t("SIGKILL"),V(),O("\u2713 Pipelines stopped."),0}async function sr(){let e=le();if(!e.alive)return O("Pipelines: stopped."),0;let t=e.port?await It(e.port):!1;return O(`Pipelines: running (pid ${e.pid}) on port ${e.port??"?"} \u2014 `+(t?"responding \u2713":"not responding yet")),0}function ir(){if(le().alive)return F("\u2717 Stop the daemon first: superclawd pipelines stop"),1;O("Updating superclawd (npm i -g superclawd@latest) \u2026");let t=Vn("npm install -g superclawd@latest",{stdio:"inherit",shell:!0});return t.status!==0?(F(`\u2717 Update failed (npm exited ${t.status??"?"}).`),t.status??1):(O("\u2713 Updated. Start again with: superclawd pipelines start"),0)}function Mt(){return["superclawd pipelines \u2014 run the local Pipelines app",""," start [--port <n>] [-d] Start the daemon (foreground; -d detaches). Opens the browser."," stop Stop the running daemon."," status Show whether the daemon is running."," update Update superclawd (daemon must be stopped)."].join(`
|
|
201
|
+
`)}async function Dt(e){let t=Qn(e);switch(t.sub){case"start":return rr(t);case"stop":return or();case"status":return sr();case"update":return ir();case"":case"help":return O(Mt()),0;default:return F(`Unknown pipelines command: ${t.sub}`),O(Mt()),1}}function ur(e){let t={},n=[];for(let r of e){if(!r.name||r.name===oe||r.name===q||t[r.name])continue;let o={};r.type==="http"?(o.type="http",o.url=r.url,r.headers&&Object.keys(r.headers).length&&(o.headers=r.headers)):(o.command=r.command,r.args&&r.args.length&&(o.args=r.args)),r.env&&Object.keys(r.env).length&&(o.env=r.env),t[r.name]=o,n.push(r.name)}return{map:t,names:n}}function pr(e,t,n,r,o){let s={SUPERCLAWD_BACKEND:H,SUPERCLAWD_MCP_API_URL:B,SUPERCLAWD_SESSION_ID:n};return k||(s.SUPERCLAWD_MCP_KEY=e.keyId,s.SUPERCLAWD_MCP_SECRET=e.secret,s.SUPERCLAWD_MCP_WORKSPACE=e.workspace),process.env.NODE_EXTRA_CA_CERTS&&(s.NODE_EXTRA_CA_CERTS=process.env.NODE_EXTRA_CA_CERTS),process.env.SUPERCLAWD_HOME&&(s.SUPERCLAWD_HOME=process.env.SUPERCLAWD_HOME),process.env.SUPERCLAWD_LOG_FILE&&(s.SUPERCLAWD_LOG_FILE=process.env.SUPERCLAWD_LOG_FILE),process.env.SUPERCLAWD_DEBUG&&(s.SUPERCLAWD_DEBUG=process.env.SUPERCLAWD_DEBUG),process.env.SUPERCLAWD_MOCK_TIER&&(s.SUPERCLAWD_MOCK_TIER=process.env.SUPERCLAWD_MOCK_TIER),process.env.SUPERCLAWD_MOCK_BALANCE&&(s.SUPERCLAWD_MOCK_BALANCE=process.env.SUPERCLAWD_MOCK_BALANCE),process.env.SUPERCLAWD_EXPERIMENTAL&&(s.SUPERCLAWD_EXPERIMENTAL=process.env.SUPERCLAWD_EXPERIMENTAL),process.env.SUPERCLAWD_REPO_FINGERPRINT&&(s.SUPERCLAWD_REPO_FINGERPRINT=process.env.SUPERCLAWD_REPO_FINGERPRINT),process.env.SUPERCLAWD_TEAM_MEMORY&&(s.SUPERCLAWD_TEAM_MEMORY=process.env.SUPERCLAWD_TEAM_MEMORY),process.env.SUPERCLAWD_REPO_MEMORY&&(s.SUPERCLAWD_REPO_MEMORY=process.env.SUPERCLAWD_REPO_MEMORY),process.env.SUPERCLAWD_AGENT_MEMORY&&(s.SUPERCLAWD_AGENT_MEMORY=process.env.SUPERCLAWD_AGENT_MEMORY),process.env.SUPERCLAWD_PRIVATE_MEMORY&&(s.SUPERCLAWD_PRIVATE_MEMORY=process.env.SUPERCLAWD_PRIVATE_MEMORY),process.env.SUPERCLAWD_PIPELINES_TOOLS&&(s.SUPERCLAWD_PIPELINES_TOOLS=process.env.SUPERCLAWD_PIPELINES_TOOLS),process.env.SUPERCLAWD_PIPELINES_URL&&(s.SUPERCLAWD_PIPELINES_URL=process.env.SUPERCLAWD_PIPELINES_URL),process.env.SUPERCLAWD_PIPELINES_TICKET&&(s.SUPERCLAWD_PIPELINES_TICKET=process.env.SUPERCLAWD_PIPELINES_TICKET),r.length&&(s.SUPERCLAWD_RESOURCES=JSON.stringify(r.map(a=>({name:a.name,description:a.description})))),{relPath:".claude-plugin/plugin.json",content:JSON.stringify({name:q,description:"SuperClawd skills + live, metered directives for Claude Code.",mcpServers:{[oe]:{command:"node",args:[t],env:s},...o}},null,2)}}function Ut(e){let{pluginDir:t,session:n,catalog:r,serverPath:o,launchId:s}=e,i=Tt(Ot(o),"hook-helper.mjs"),a=process.env.SUPERCLAWD_GATE==="1",l=ur(r.mcpServers),c=Lt();if(c&&!l.map[c.name]){let w={type:"http",url:c.url};c.headers&&(w.headers=c.headers),l.map[c.name]=w,l.names.push(c.name)}let g=[pr(n,o,s,r.resources,l.map),...pt(r.skills),...gt(r.agents,{foundationalText:r.foundational.text},r.agentTeams),...ht(r.commands,r.agents),...wt(r.workflows),...St(),...Ct({foundational:r.foundational,helperPath:i,pluginDir:t,launchId:s,gate:a,guardrails:r.guardrails,policyGuardrails:r.policyGuardrails,agents:r.agents})],E=[];for(let w of g){let p=Tt(t,w.relPath);ar(Ot(p),{recursive:!0}),cr(p,w.content),w.executable&&lr(p,493),E.push(w.relPath)}return{pluginDir:t,skillCount:r.skills.length,agentCount:r.agents.length,commandCount:r.commands.length,workflowCount:r.workflows.length,mcpServerNames:l.names,files:E}}import{mkdirSync as dr,rmSync as Wt,readdirSync as fr,statSync as mr}from"node:fs";import{join as xe}from"node:path";import{randomBytes as gr}from"node:crypto";function Nt(){let e=`${Date.now().toString(36)}-${gr(4).toString("hex")}`,t=xe(te,e),n=xe(t,"plugin");return dr(n,{recursive:!0}),{id:e,dir:t,pluginDir:n}}function Gt(e){try{Wt(e.dir,{recursive:!0,force:!0})}catch{}}function jt(e=Date.now()){let t=0,n=[];try{n=fr(te)}catch{return 0}for(let r of n){let o=xe(te,r);try{e-mr(o).mtimeMs>Ve&&(Wt(o,{recursive:!0,force:!0}),t++)}catch{}}return t}import{hostname as hr}from"node:os";import{spawn as wr}from"node:child_process";var Sr=e=>new Promise(t=>setTimeout(t,e));function kr(e){try{let t=process.platform,o=wr(t==="darwin"?"open":t==="win32"?"cmd":"xdg-open",t==="win32"?["/c","start","",e]:[e],{stdio:"ignore",detached:!0});o.on("error",()=>{}),o.unref()}catch{}}async function Ft(){if(k)return process.stdout.write(`Mock mode \u2014 login is not needed.
|
|
202
|
+
`),{ok:!0};let e=We(),t=hr()||"Unknown device",n;try{let c=await fetch(`${ee}/api/auth/cli/device/start`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({machineId:e,hostname:t})});if(!c.ok)return{ok:!1,error:`Couldn't start login (HTTP ${c.status}).`};n=await c.json()}catch{return{ok:!1,error:`Couldn't reach ${ee}.`}}let r=n.verification_uri_complete||n.verification_uri;process.stdout.write(`
|
|
203
|
+
To authorize this machine, open:
|
|
204
|
+
${r}
|
|
205
|
+
|
|
206
|
+
and confirm this code matches: ${n.user_code}
|
|
207
|
+
|
|
208
|
+
`),kr(r),process.stdout.write(`Waiting for approval\u2026 (Ctrl-C to cancel)
|
|
209
|
+
`);let o=(n.interval||5)*1e3,s=Date.now()+(n.expires_in||600)*1e3,i,a;for(;Date.now()<s;){await Sr(o);let c;try{c=await(await fetch(`${ee}/api/auth/cli/device/token`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({deviceCode:n.device_code})})).json()}catch{continue}if(c.status==="approved"){i=c.key_id,a=c.secret;break}if(c.status==="denied")return{ok:!1,error:"Request was denied in the browser."};if(c.status==="expired")return{ok:!1,error:"Login request expired. Run `superclawd login` again."}}if(!i||!a)return{ok:!1,error:"Login timed out. Run `superclawd login` again."};process.stdout.write(`\u2713 Authorized.
|
|
210
|
+
|
|
211
|
+
`);let l=P()??{};return G({...l,credentials:{...l.credentials,keyId:i,secret:a}}),process.stdout.write("\u2713 Logged in. Run `superclawd` to choose a workspace and start.\n\n"),{ok:!0}}var C="\x1B",ue=[{key:"notifications",label:"Notifications",description:"Default for new sessions \u2014 ping when Claude needs you or finishes",defaultOn:!1},{key:"skipPermissions",label:"Dangerously skip permissions",description:"Launch Claude Code with --dangerously-skip-permissions (no approval prompts)",defaultOn:!1},{key:"chooseWorkspaceAtStartup",label:"Choose workspace at startup",description:"Pick the workspace to boot into each time you run superclawd",defaultOn:!0},{key:"experimental",label:"Experimental mode",description:"Run the latest unpublished (draft) versions instead of the stable release",defaultOn:!1},{key:"keepAwake",label:"Keep Awake",description:"Prevent your computer from sleeping while a session is running",defaultOn:!1},{key:"privateMemory",label:"Private Memory",description:"Remember your personal preferences across all your sessions (private to you, never shared)",defaultOn:!0},{key:"pipelinesMcp",label:"Pipelines MCP",description:"Let Claude Code drive your Pipelines board (requires SuperClawd Pipelines running)",defaultOn:!1}].sort((e,t)=>e.label.localeCompare(t.label)),$e=(e,t)=>e.preferences?.[t.key]??t.defaultOn;async function Kt(){let e=P()??{},t=process.stdin;if(!t.isTTY){process.stdout.write(`SuperClawd options:
|
|
212
|
+
`);for(let n of ue)process.stdout.write(` ${$e(e,n)?"on ":"off"} ${n.label}
|
|
213
|
+
`);return}await new Promise(n=>{let r=ue.length,o=r+2,s=0,i=f=>{f||process.stdout.write(`${C}[${o}A`);for(let d=0;d<r;d++){let A=ue[d],u=d===s?`${C}[38;5;208m\u276F `:" ",S=$e(e,A)?`${C}[38;5;208m[\u2713]${C}[0m`:"[ ]";process.stdout.write(`${C}[2K${u}${S} ${A.label}${C}[0m ${C}[2m${A.description}${C}[0m
|
|
214
|
+
`)}process.stdout.write(`${C}[2K
|
|
215
|
+
`),process.stdout.write(`${C}[2K${C}[2mPress Esc (or Ctrl-C) to exit${C}[0m
|
|
180
216
|
`)};process.stdout.write(`
|
|
181
|
-
SuperClawd options ${
|
|
182
|
-
${
|
|
183
|
-
`)},p=
|
|
184
|
-
`||
|
|
185
|
-
`)}function
|
|
186
|
-
`)}${
|
|
187
|
-
|
|
188
|
-
`),{async phase(
|
|
189
|
-
`)},message(
|
|
190
|
-
`)},async selectWorkspace(
|
|
191
|
-
`)},fail(
|
|
192
|
-
`)},note(
|
|
193
|
-
`)},handoff(){},finish(){}}}function
|
|
194
|
-
`.repeat(
|
|
195
|
-
`;
|
|
196
|
-
`;let
|
|
197
|
-
|
|
198
|
-
`;let X=Math.max(0,Math.floor((
|
|
199
|
-
`;let
|
|
200
|
-
`.repeat(
|
|
201
|
-
`;
|
|
202
|
-
`;for(let
|
|
203
|
-
`;let
|
|
204
|
-
`?(process.stdin.off("data",
|
|
205
|
-
`)},note(){},handoff(){s&&(process.stdin.off("data",i),process.stdin.pause(),s=!1),
|
|
217
|
+
SuperClawd options ${C}[2m(\u2191/\u2193 move \xB7 Space/Enter to toggle)${C}[0m
|
|
218
|
+
${C}[?7l${C}[?25l`),i(!0),t.setRawMode(!0),t.resume();let a=!1,l=()=>{if(!a){a=!0;try{t.setRawMode(!1)}catch{}process.stdout.write(`${C}[?7h${C}[?25h`)}},c=["SIGINT","SIGTERM","SIGHUP"],g=()=>l(),E=f=>{l(),process.kill(process.pid,f)};process.once("exit",g);for(let f of c)process.once(f,E);let w=()=>{t.off("data",p),process.off("exit",g);for(let f of c)process.off(f,E);t.pause(),l(),process.stdout.write(`
|
|
219
|
+
`)},p=f=>{let d=f.toString();if(d===""||d===C)w(),n();else if(d==="\r"||d===`
|
|
220
|
+
`||d===" "){let A=ue[s];e.preferences={...e.preferences,[A.key]:!$e(e,A)},G(e),i(!1)}else d===`${C}[A`||d==="k"?(s=(s-1+r)%r,i(!1)):(d===`${C}[B`||d==="j")&&(s=(s+1)%r,i(!1))};t.on("data",p)})}import{execSync as Vt}from"node:child_process";var y="\x1B",W=`${y}[38;5;208m`,Y=`${y}[2m`,fe=`${y}[31m`,R=`${y}[0m`,yr=`${y}[?1049h`,Yt=`${y}[?1049l`,Er=`${y}[?25l`,Le=`${y}[?25h`,Cr=`${y}[?1007l`,Bt=`${y}[?1007h`,Rr=`${y}[?1000l${y}[?1002l${y}[?1003l${y}[?1004l${y}[?1006l${y}[?1015l`,Ie=`${y}[2J${y}[H`,pe=[" _ _"," ____ _ _ __ ___ _ _ __| |__ ___ __ ____| |","(_-< || | '_ \\/ -_) '_/ _| / _` \\ V V / _` |","/__/\\_,_| .__/\\___|_| \\__|_\\__,_|\\_/\\_/\\__,_|"," |_|"],Ht=45,J=36,_r=140,Pr=350,I=e=>void process.stdout.write(e),vr=e=>new Promise(t=>setTimeout(t,e)),K=e=>e>0?" ".repeat(e):"",Jt=process.platform!=="win32";function br(){if(!Jt)return null;try{return Vt("stty -g </dev/tty",{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return null}}function qt(e){if(Jt)try{Vt(`stty ${e} </dev/tty`,{stdio:"ignore"})}catch{}}var de=null;function Xt(e){de?.(),de=null,process.stderr.write(`${fe}\u2717 ${e}${R}
|
|
221
|
+
`)}function Ar(e,t){return I(`${W}${pe.join(`
|
|
222
|
+
`)}${R} ${Y}v${t}${R}
|
|
223
|
+
|
|
224
|
+
`),{async phase(n,r){I(`${Y} \xB7 ${r}${R}
|
|
225
|
+
`)},message(n){I(`${Y} \xB7 ${n}${R}
|
|
226
|
+
`)},async selectWorkspace(n,r){return r?.currentSlug??n[0]?.slug??null},async ready(n){I(`${W} \u2713 ${n}${R}
|
|
227
|
+
`)},fail(n){I(`${fe} \u2717 ${n}${R}
|
|
228
|
+
`)},note(n){I(` ${n}
|
|
229
|
+
`)},handoff(){},finish(){}}}function Mr(e,t){let n=br(),r=0,o=!0,s=!1,i=u=>{u.includes(3)&&g()},a=()=>{let u=process.stdin;if(u.isTTY){try{u.setRawMode(!0)}catch{}u.resume(),u.on("data",i),s=!0}},l=()=>{if(!s)return;let u=process.stdin;u.off("data",i);try{u.setRawMode(!1)}catch{}u.pause(),s=!1},c=()=>{l();try{process.stdin.isTTY&&process.stdin.setRawMode(!1)}catch{}I(Le+Bt+Yt),n&&qt(n)},g=()=>{o&&c(),o=!1,process.exit(130)},E=()=>{l(),o&&I(Le+Bt+Yt)},w=()=>{process.off("SIGINT",g),process.off("SIGTERM",g),process.off("exit",E),de=null};qt("-echo"),I(yr+Er+Cr+Rr),a(),process.on("SIGINT",g),process.on("SIGTERM",g),process.on("exit",E),de=c;let p=(u,S)=>{let _=process.stdout.columns||80,h=process.stdout.rows||24,m=Math.floor(u*J/e);m<0&&(m=0),m>J&&(m=J);let $="\u2588".repeat(m)+"\u2591".repeat(J-m),T=Math.floor(u*100/e),D=J+6,M=Math.max(0,Math.floor((h-9)/2)),N=Ie+`
|
|
230
|
+
`.repeat(M),L=Math.max(0,Math.floor((_-Ht)/2));for(let rn of pe)N+=`${K(L)}${W}${rn}${R}
|
|
231
|
+
`;N+=`
|
|
232
|
+
`;let j=Math.max(0,Math.floor((_-S.length)/2));N+=`${K(j)}${Y}${S}${R}
|
|
233
|
+
|
|
234
|
+
`;let X=Math.max(0,Math.floor((_-D)/2));N+=`${K(X)}${W}${$}${R} ${String(T).padStart(3)}%
|
|
235
|
+
`;let z=`v${t}`,ge=Math.max(1,h-1),he=Math.max(1,_-z.length-1);N+=`${y}[${ge};${he}H${W}${z}${R}`,I(N)},f=async(u,S,_)=>{let h=_-(Date.now()-r);h>0&&await vr(h),p(u,S),r=Date.now()},d=u=>{let S=process.stdout.columns||80,_=process.stdout.rows||24,h=Math.max(0,Math.floor((_-(pe.length+1+u.length))/2)),m=Ie+`
|
|
236
|
+
`.repeat(h),$=Math.max(0,Math.floor((S-Ht)/2));for(let D of pe)m+=`${K($)}${W}${D}${R}
|
|
237
|
+
`;m+=`
|
|
238
|
+
`;for(let D of u)m+=`${D}
|
|
239
|
+
`;let T=`v${t}`;m+=`${y}[${Math.max(1,_-1)};${Math.max(1,S-T.length-1)}H${W}${T}${R}`,I(m)},A=(u,S,_)=>{let h=process.stdout.columns||80,m="Select your workspace \u2191/\u2193 \xB7 enter launches \xB7 d sets default \xB7 esc cancels",$=Math.max(0,Math.floor((h-m.length)/2)),T=L=>` ${L.name} ${L.slug} \xB7 ${L.role}`,D=Math.max(...u.map(L=>T(L).length)),M=Math.max(0,Math.floor((h-D)/2)),N=[`${K($)}${Y}${m}${R}`,""];for(let L=0;L<u.length;L++){let j=u[L],X=L===S,z=X?`${W}\u276F `:" ",ge=X?`${W}${j.name}${R}`:j.name,he=j.slug===_?` ${W}\u2605 default${R}`:"";N.push(`${K(M)}${z}${ge} ${Y}${j.slug} \xB7 ${j.role}${R}${he}`)}d(N)};return{phase:(u,S)=>f(u-1,S,_r),ready:u=>f(e,u,Pr),message(u){let S=process.stdout.columns||80,_=Math.max(0,Math.floor((S-u.length)/2));d([`${K(_)}${Y}${u}${R}`]),r=Date.now()},selectWorkspace(u,S){return new Promise(_=>{let h=S?.currentSlug?u.findIndex(D=>D.slug===S.currentSlug):-1,m=h>=0?h:0,$=S?.defaultSlug;s&&process.stdin.off("data",i),A(u,m,$);let T=D=>{let M=D.toString();M===""||M===y?(process.stdin.off("data",T),_(null)):M==="\r"||M===`
|
|
240
|
+
`?(process.stdin.off("data",T),process.stdin.on("data",i),_(u[m].slug)):M==="d"||M==="D"?($=u[m].slug,S?.onSetDefault?.($),A(u,m,$)):M===`${y}[A`||M==="k"?(m=(m-1+u.length)%u.length,A(u,m,$)):(M===`${y}[B`||M==="j")&&(m=(m+1)%u.length,A(u,m,$))};process.stdin.on("data",T)})},fail(u){o&&c(),o=!1,w(),process.stderr.write(`${fe}\u2717 ${u}${R}
|
|
241
|
+
`)},note(){},handoff(){s&&(process.stdin.off("data",i),process.stdin.pause(),s=!1),I(Ie+Le),process.off("SIGINT",g),process.off("SIGTERM",g)},finish(){o&&c(),o=!1,w()}}}function xr(){return process.platform!=="win32"?!0:!!(process.env.WT_SESSION||process.env.TERM_PROGRAM||process.env.TERM)}function $r(){return{async phase(){},message(){},async selectWorkspace(e,t){return t?.currentSlug??e[0]?.slug??null},async ready(){},fail(e){process.stderr.write(`${fe}\u2717 ${e}${R}
|
|
242
|
+
`)},note(){},handoff(){},finish(){}}}function zt(e){if(e.quiet)return $r();let t=process.stdout.isTTY===!0,n=e.version??"";return e.plain||!t||!xr()?Ar(e.total,n):Mr(e.total,n)}var Lr=["low","medium","high","xhigh","max"];function Qt(e){let t=!1,n="",r=null,o=!1,s=!1,i=null,a=!1,l=!1,c="board",g=null,E=null,w=null;for(let p=0;p<e.length;p++){let f=e[p],d=e[p+1];f==="-p"||f==="--print"?(t=!0,d&&!d.startsWith("-")&&(n=d,p++)):f==="--workspace"||f==="-w"?d&&!d.startsWith("-")&&(r=d,p++):f==="--no-capture"?o=!0:f==="--resume"||f==="-r"?(s=!0,d&&!d.startsWith("-")&&(i=d,p++)):f==="--pipelines"?a=!0:f==="--pipelines-tools"?l=!0:f.startsWith("--pipelines-tools=")?(l=!0,c=f.slice(18)==="restricted"?"restricted":"board"):f==="--session-id"?d&&!d.startsWith("-")&&(g=d,p++):f==="--model"?d&&!d.startsWith("-")&&(E=d,p++):f==="--effort"&&d&&Lr.includes(d)&&(w=d,p++)}return{printMode:t,printPrompt:n,workspace:r,noCapture:o,resume:s,resumeSessionId:i,pipelines:a,pipelinesTools:l,pipelinesToolsMode:c,sessionId:g,model:E,effort:w}}var Zt={name:"superclawd",version:"0.1.2",description:"Claude Code, supercharged \u2014 your team's standards, every session. The superclawd CLI loads your workspace's skills, agents, commands, workflows, and live directives into Claude Code as a plugin.",author:"SuperClawd <support@superclawd.com>",license:"SEE LICENSE IN LICENSE",homepage:"https://superclawd.com",repository:{type:"git",url:"https://github.com/superclawd-ai/superclawd"},bugs:{url:"https://github.com/superclawd-ai/superclawd/issues"},keywords:["superclawd","claude-code","claude","plugin","skills","agents","mcp","ai-assistant","coding-standards","model-context-protocol"],engines:{node:">=20"},type:"module",main:"dist/index.js",bin:{superclawd:"dist/index.js"},files:["dist","README.md","LICENSE"],scripts:{build:"node build.mjs",dev:"node build.mjs && tsx src/index.ts",typecheck:"tsc --noEmit",lint:"eslint 'src/**/*.{ts,tsx}'","lint:fix":"eslint 'src/**/*.{ts,tsx}' --fix",format:"prettier --check 'src/**/*.{ts,tsx}'","format:fix":"prettier --write 'src/**/*.{ts,tsx}'",selftest:"tsx test/mcp-selftest.ts","test:guardrails":"tsx test/guardrails-eval.test.ts",test:"node build.mjs && tsx test/mcp-selftest.ts && tsx test/pipelines-tools.test.ts && tsx test/guardrails-eval.test.ts && tsx test/hooks-capture.test.ts && tsx test/translator-teams.test.ts && tsx test/run-args.test.ts && tsx test/pipelines.test.ts && tsx test/update-check.test.ts && tsx test/retrieve.test.ts && tsx test/config-private-memory.test.ts && tsx test/config-choose-workspace.test.ts && tsx test/config.test.ts && tsx test/translator-basics.test.ts && tsx test/hook-helper-guardrails.test.ts && tsx test/capture-prompts.test.ts && tsx test/mcp-backend-real.test.ts && tsx test/catalog.test.ts",prepublishOnly:"npm run build","publish:npm":"npm publish","version:bump":"npm version patch --no-git-tag-version"},dependencies:{"@modelcontextprotocol/sdk":"^1.7.0",zod:"^3.24.2"},devDependencies:{"@eslint/js":"^9.39.1","@types/node":"^22.10.0","@typescript-eslint/eslint-plugin":"^8.44.1","@typescript-eslint/parser":"^8.44.1",esbuild:"^0.24.0",eslint:"^9.36.0","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.4",prettier:"^3.6.2",tsx:"^4.19.0",typescript:"^5.7.0"}};var De=Zt.version,me=process.env.SUPERCLAWD_DRY_RUN==="1"||process.argv.includes("--dry-run");function Nr(){try{let e=Or("git remote get-url origin",{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();if(e)return e.replace(/\.git$/,"").toLowerCase()}catch{}return`dir:${Tr(process.cwd())}`}function Gr(){if(process.env.SUPERCLAWD_MCP_SERVER_PATH)return process.env.SUPERCLAWD_MCP_SERVER_PATH;let e=en(new URL("./mcp-server.mjs",import.meta.url));return nn(e)?e:en(new URL("../dist/mcp-server.mjs",import.meta.url))}function jr(){return`superclawd \u2014 Claude Code, supercharged with your SuperClawd workspace.
|
|
206
243
|
|
|
207
244
|
Usage:
|
|
208
245
|
superclawd Launch Claude with your skills/agents/directives loaded
|
|
209
|
-
superclawd
|
|
210
|
-
superclawd
|
|
246
|
+
superclawd --resume [session-id] Resume a prior Claude Code conversation (-r; picker if no id)
|
|
247
|
+
superclawd -p "<prompt>" Run one prompt non-interactively (claude -p) and print the result
|
|
248
|
+
(slash commands work: namespace yours as "/superclawd:<command>")
|
|
249
|
+
superclawd login Sign in via your browser
|
|
211
250
|
superclawd config Toggle launch options + default notifications preference
|
|
212
251
|
superclawd update Update to the latest version (npm i -g superclawd)
|
|
252
|
+
superclawd pipelines [start|stop|status|update] Run the local Pipelines app (start opens your browser)
|
|
213
253
|
superclawd version
|
|
214
254
|
superclawd help
|
|
215
255
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
256
|
+
Run flags:
|
|
257
|
+
--workspace <id> Workspace for the run (highest precedence: flag \u2192 SUPERCLAWD_MCP_WORKSPACE \u2192 stored default).
|
|
258
|
+
Interactive with none set \u2192 prompts; print mode with none \u2192 errors.
|
|
259
|
+
Print-mode flags (with -p):
|
|
260
|
+
--model <alias> Model for the run (e.g. haiku, sonnet, opus) \u2014 forwarded to claude
|
|
261
|
+
--effort <level> Reasoning effort: low | medium | high | xhigh | max
|
|
262
|
+
--no-capture Don't write learned memories for this run (handy for behavior tests)
|
|
263
|
+
|
|
264
|
+
Not authenticated yet? Run \`superclawd login\` first.
|
|
265
|
+
`}function Fr(){try{return!Dr("claude",["--version"],{stdio:"ignore"}).error}catch{return!1}}function Kr(e,t=[],n,r,o,s,i){let a=["--plugin-dir",e.pluginDir];a.push("--allowedTools",dt);for(let l of t)a.push("--allowedTools",`mcp__plugin_superclawd_${l}__*`);return(Ne()||n)&&a.push("--dangerously-skip-permissions"),r?(a.push("--resume"),r.sessionId&&a.push(r.sessionId)):o&&a.push("--session-id",o),s&&a.push("--model",s),i&&a.push("--effort",i),n&&a.push("-p",n.prompt),new Promise(l=>{let c=tn("claude",a,{stdio:"inherit",env:{...process.env,CLAUDE_CODE_DISABLE_AUTO_MEMORY:"1"}});c.on("error",g=>l({code:127,error:`Could not launch claude: ${g.message}. Is Claude Code installed and on PATH?`})),c.on("close",g=>l({code:g??0}))})}function Yr(){return process.stdout.write(`Updating superclawd (npm i -g superclawd@latest)\u2026
|
|
266
|
+
`),new Promise(e=>{let t=tn("npm install -g superclawd@latest",{stdio:"inherit",shell:!0});t.on("error",n=>{process.stderr.write(`\u2717 Could not run npm: ${n.message}. Is npm on your PATH?
|
|
267
|
+
`),e(127)}),t.on("close",n=>{n===0?process.stdout.write("\u2713 Updated. Run `superclawd version` to confirm.\n"):process.stderr.write(`\u2717 Update failed (npm exited ${n}).
|
|
268
|
+
`),e(n??1)})})}async function Br(e){if(e.printMode&&!e.printPrompt.trim())return process.stderr.write(`Provide a prompt: superclawd -p "<your prompt>"
|
|
269
|
+
`),1;if(e.pipelines&&(process.env.SUPERCLAWD_NO_UPDATE="1"),e.pipelinesTools&&(process.env.SUPERCLAWD_PIPELINES_TOOLS=e.pipelinesToolsMode),!me){let p=await Ze(De,process.argv.slice(2));if(p.exitCode!==void 0)return p.exitCode}if(e.noCapture&&(process.env.SUPERCLAWD_NO_CAPTURE="1"),!me&&!Fr())return process.stderr.write(`\u2717 Claude Code isn't installed (or isn't on your PATH).
|
|
224
270
|
|
|
225
271
|
SuperClawd supercharges Claude Code, so you'll need it first:
|
|
226
272
|
\u2192 https://claude.com/code
|
|
227
273
|
|
|
228
274
|
Once it's installed, run \`superclawd\` again.
|
|
229
|
-
`),1;
|
|
230
|
-
`),1;let t=e.
|
|
231
|
-
`),
|
|
232
|
-
`),0):
|
|
233
|
-
`),0):(process.stderr.write(`\u2717 ${n.error??"Configuration failed."}
|
|
234
|
-
`),1)}async function $o(){let e=await Qe();return e.cancelled?(process.stdout.write(`Cancelled.
|
|
235
|
-
`),0):e.ok?0:(process.stderr.write(`\u2717 ${e.error??"Workspace switch failed."}
|
|
236
|
-
`),1)}async function _o(){let[e]=process.argv.slice(2).filter(t=>t!=="--dry-run");switch(e){case"configure":process.exit(await So());return;case"switch":process.exit(await $o());return;case"config":await tt(),process.exit(0);return;case"update":process.exit(await Co());return;case"version":case"--version":case"-v":console.log(mt);return;case"help":case"--help":case"-h":console.log(ho());return;default:process.exit(await yo())}}_o().catch(e=>{ct(String(e)),process.exit(1)});
|
|
275
|
+
`),1;k||qe(),!k&&je()&&(process.env.SUPERCLAWD_EXPERIMENTAL="true"),process.env.SUPERCLAWD_REPO_FINGERPRINT=Nr();let t=Je();if(!t.ok&&!k)return process.stderr.write(`${t.error??"Could not resolve credentials."}
|
|
276
|
+
`),1;let n=t.session;e.workspace&&(n={...n,workspace:e.workspace});let r=zt({total:5,plain:me,quiet:e.printMode,version:De});if(!k&&!e.printMode&&!e.workspace&&process.stdin.isTTY&&(!n.workspace||Ge())){let p=await ke(r,n);if(p.cancelled)return r.finish(),130;p.workspace&&(n={...n,workspace:p.workspace})}if(!k&&!n.workspace)return r.finish(),process.stderr.write("No workspace selected. Pass --workspace <id>, set SUPERCLAWD_MCP_WORKSPACE, or run `superclawd` interactively once to pick a default.\n"),1;await r.phase(1,"Resolving credentials\u2026"),await r.phase(2,"Authenticating\u2026");let o=await ye(n);if(o.workspaceInvalid&&!k&&!e.printMode&&!e.workspace&&process.stdin.isTTY){ne();let p=await ke(r,{...n,workspace:""});if(p.cancelled)return r.finish(),130;p.workspace&&(n={...n,workspace:p.workspace},await r.phase(2,"Authenticating\u2026"),o=await ye(n))}if(!o.ok)return r.fail(o.error??"Authentication failed."),1;await r.phase(3,k?"Loading mock catalog\u2026":"Fetching your workspace\u2026");let s;try{s=await lt(n)}catch(p){return r.fail(`Catalog fetch failed: ${String(p)}`),1}process.env.SUPERCLAWD_TEAM_MEMORY=s.teamMemoryEnabled?"1":"0",process.env.SUPERCLAWD_REPO_MEMORY=s.repoMemoryEnabled?"1":"0",process.env.SUPERCLAWD_AGENT_MEMORY=s.agentMemoryEnabled?"1":"0",process.env.SUPERCLAWD_PRIVATE_MEMORY=k||Ke()?"1":"0",await r.phase(4,"Establishing session\u2026"),jt();let i=Nt();He(i.dir,n.workspace);let a=Gr();if(!nn(a))return r.fail(`Bundled MCP server not found at ${a}. Run \`npm run build\` first.`),1;await ut(n,i.id),await r.phase(5,"Generating plugin\u2026");let l=Ut({pluginDir:i.pluginDir,session:n,catalog:s,serverPath:a,launchId:i.id});if(!k)try{let p=Wr(Ur(a),"hook-helper.mjs"),f=Rt({cwd:process.cwd(),helperPath:p,env:{SUPERCLAWD_BACKEND:H,SUPERCLAWD_MCP_API_URL:n.apiUrl,SUPERCLAWD_REPO_FINGERPRINT:process.env.SUPERCLAWD_REPO_FINGERPRINT,SUPERCLAWD_MCP_KEY:n.keyId,SUPERCLAWD_MCP_SECRET:n.secret,SUPERCLAWD_MCP_WORKSPACE:n.workspace,NODE_EXTRA_CA_CERTS:process.env.NODE_EXTRA_CA_CERTS,SUPERCLAWD_HOME:process.env.SUPERCLAWD_HOME,SUPERCLAWD_CLAUDE_BIN:process.env.SUPERCLAWD_CLAUDE_BIN,SUPERCLAWD_POLICY_MODEL:process.env.SUPERCLAWD_POLICY_MODEL}});!f.installed&&f.reason!=="not a git repo"&&r.note(`Post-commit hook: ${f.reason}`)}catch{}let c=k?"mock":n.workspace;if(await r.ready(`${c} \xB7 ${l.skillCount} skills \xB7 ${l.commandCount} commands \xB7 ${l.workflowCount} workflows`),me){r.note("Dry run \u2014 not launching Claude. Generated files:");for(let p of l.files)r.note(` ${p}`);return 0}r.handoff();let g=!k&&Fe()?ze():null,{code:E,error:w}=await Kr(i,l.mcpServerNames,e.printMode?{prompt:e.printPrompt}:void 0,e.resume?{sessionId:e.resumeSessionId}:void 0,e.sessionId,e.model,e.effort);return g?.stop(),r.finish(),Gt(i),w&&process.stderr.write(`${w}
|
|
277
|
+
`),w?127:E}async function Hr(){let e=await Ft();return e.cancelled||e.ok?0:(process.stderr.write(`\u2717 ${e.error??"Login failed."}
|
|
278
|
+
`),1)}async function qr(){let[e]=process.argv.slice(2).filter(t=>t!=="--dry-run");switch(e){case"login":process.exit(await Hr());return;case"config":await Kt(),process.exit(0);return;case"update":process.exit(await Yr());return;case"pipelines":{let t=process.argv.slice(2).filter(n=>n!=="--dry-run");process.exit(await Dt(t.slice(t.indexOf("pipelines")+1)));return}case"version":case"--version":case"-v":console.log(De);return;case"help":case"--help":case"-h":console.log(jr());return;default:process.exit(await Br(Qt(process.argv.slice(2))))}}qr().catch(e=>{Xt(String(e)),process.exit(1)});
|