@keepur/hive 0.1.6 → 0.1.7
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/package.json +1 -1
- package/pkg/mcp/admin.min.js +1 -1
- package/pkg/server.min.js +2 -2
package/package.json
CHANGED
package/pkg/mcp/admin.min.js
CHANGED
|
@@ -48,7 +48,7 @@ ${r.soul??"(not set)"}`),i.push(`
|
|
|
48
48
|
--- System Prompt ---
|
|
49
49
|
${r.systemPrompt??"(not set)"}`);let o=r.updatedAt instanceof Date?r.updatedAt.toISOString():String(r.updatedAt??"");return i.push(`
|
|
50
50
|
Updated: ${o} by ${r.updatedBy??"unknown"}`),{content:[{type:"text",text:i.join(`
|
|
51
|
-
`)}]}});B.registerTool("agent_create",{title:"Create Agent",description:"Create a new agent definition. Required: _id, name, model, homeBase. Archetype is optional \u2014 pass it when the role is a discipline with shared infrastructure (see list_archetypes). Soul/systemPrompt shape the agent's voice and role; if omitted they default to empty strings. Additional tuning (channels, schedule, budget, autonomy, archetypeConfig, etc.) goes in `fields`.",inputSchema:{_id:z.string().describe("Agent ID (lowercase with hyphens, e.g. 'my-agent')"),name:z.string().describe("Display name for the agent"),model:z.string().describe("Model to use (e.g. 'claude-sonnet-4-6', 'claude-haiku-4-5')"),homeBase:z.string().describe("Primary Slack channel for scheduler delivery and default identity (e.g. 'agent-<id>'). The channel must exist in Slack."),soul:z.string().optional().describe("Personality / voice / character definition (5-15 lines). Shapes how the agent talks."),systemPrompt:z.string().optional().describe("Role definition and guardrails. Concise. Instance-specific flavor \u2014 archetype framing layers underneath."),archetype:z.string().optional().describe("Discipline id from list_archetypes (e.g. 'software-engineer'). Omit for plain unstructured agents."),title:z.string().optional().describe("Customer-facing title (e.g. 'VP Engineering'). Typically paired with archetype."),fields:z.record(z.string(),z.any()).optional().describe("Additional fields (channels, passiveChannels, schedule, coreServers override, delegateServers, plugins, autonomy, archetypeConfig, budgetUsd, maxTurns, etc.)")}},async({_id:e,name:r,model:i,homeBase:o,soul:t,systemPrompt:n,archetype:a,title:c,fields:u})=>{if(await N.findOne({_id:e}))return{content:[{type:"text",text:`Agent '${e}' already exists. Use agent_update to modify it.`}],isError:!0};if(!o||o.trim()==="")return{content:[{type:"text",text:`Missing required field: homeBase (primary channel for scheduled delivery, e.g. 'agent-${e}').`}],isError:!0};if(a!==void 0&&!zn(a)){let _=Sn().join(", ")||"(none registered)";return{content:[{type:"text",text:`Unknown archetype: "${a}". Known: ${_}.`}],isError:!0}}let l=u??{},p=new Date,$={_id:e,name:r,model:i,icon:l.icon??T.icon,channels:l.channels??[],homeBase:o.trim(),passiveChannels:l.passiveChannels??[...T.passiveChannels],keywords:l.keywords??[...T.keywords],isDefault:l.isDefault??!1,coreServers:l.coreServers??[...T.coreServers],delegateServers:l.delegateServers??[...T.delegateServers],delegatePrompts:l.delegatePrompts??{...T.delegatePrompts},plugins:l.plugins,metadata:l.metadata,soul:t??l.soul??"",systemPrompt:n??l.systemPrompt??"",archetype:a,title:c,archetypeConfig:l.archetypeConfig,schedule:l.schedule??[...T.schedule],subscribe:l.subscribe,budgetUsd:l.budgetUsd??T.budgetUsd,maxTurns:l.maxTurns??T.maxTurns,maxConcurrent:l.maxConcurrent??T.maxConcurrent,timeoutMs:l.timeoutMs??T.timeoutMs,disabled:l.disabled??!1,slackBot:l.slackBot,autonomy:l.autonomy,resourceTiers:l.resourceTiers,betas:l.betas,catches:l.catches,createdAt:p,updatedAt:p,updatedBy:Tt};return await N.insertOne($),{content:[{type:"text",text:`Agent '${e}' (${r}) created with model ${i}${a?` \u2014 archetype ${a}`:""}. Change will take effect within 30 seconds.`}]}});B.registerTool("agent_update",{title:"Update Agent",description:"Update fields on an existing agent definition. Saves a version snapshot before mutation. Cannot change _id. Creation-boundary fields (homeBase, archetype, title, soul, systemPrompt) are promoted to top-level for discoverability; everything else goes in `fields`.",inputSchema:{agent_id:z.string().describe("The agent ID to update"),homeBase:z.string().optional().describe("Primary Slack channel for scheduler delivery."),soul:z.string().optional().describe("Personality / voice / character definition."),systemPrompt:z.string().optional().describe("Role definition and guardrails."),archetype:z.string().optional().describe("Discipline id from list_archetypes. Pass null-style empty string to clear (note: fields.archetype: null also works via the fields bag)."),title:z.string().optional().describe("Customer-facing title."),fields:z.record(z.string(),z.any()).optional().describe("Additional fields (channels, schedule, autonomy, archetypeConfig, budgetUsd, model, etc.)")}},async({agent_id:e,homeBase:r,soul:i,systemPrompt:o,archetype:t,title:n,fields:a})=>{if(!await N.findOne({_id:e}))return{content:[{type:"text",text:`Agent '${e}' not found.`}],isError:!0};let u={...a??{}};if(r!==void 0&&(u.homeBase=r),i!==void 0&&(u.soul=i),o!==void 0&&(u.systemPrompt=o),t!==void 0&&(u.archetype=t),n!==void 0&&(u.title=n),"_id"in u)return{content:[{type:"text",text:"Cannot change _id. Create a new agent instead."}],isError:!0};if(delete u.createdAt,typeof u.archetype=="string"&&u.archetype.length>0&&!zn(u.archetype)){let l=Sn().join(", ")||"(none registered)";return{content:[{type:"text",text:`Unknown archetype: "${u.archetype}". Known: ${l}.`}],isError:!0}}let s=Object.keys(u);return s.length===0?{content:[{type:"text",text:`No fields to update for '${e}'.`}],isError:!0}:(await Nt(e,s),await N.updateOne({_id:e},{$set:{...u,updatedAt:new Date,updatedBy:Tt}}),{content:[{type:"text",text:`Agent '${e}' updated: ${s.join(", ")}. Version saved. Change will take effect within 30 seconds.`}]})});B.registerTool("agent_delete",{title:"Delete Agent",description:"Delete an agent definition. Saves a version snapshot before deletion. Requires confirm=true.",inputSchema:{agent_id:z.string().describe("The agent ID to delete"),confirm:z.boolean().describe("Must be true to confirm deletion")}},async({agent_id:e,confirm:r})=>r?await N.findOne({_id:e})?(await Nt(e,["DELETED"]),await N.deleteOne({_id:e}),{content:[{type:"text",text:`Agent '${e}' deleted. Version snapshot saved. Change will take effect within 30 seconds.`}]}):{content:[{type:"text",text:`Agent '${e}' not found.`}],isError:!0}:{content:[{type:"text",text:"Deletion not confirmed. Set confirm=true to proceed."}],isError:!0});B.registerTool("agent_enable",{title:"Enable Agent",description:"Bring a disabled agent back online (sets disabled=false).",inputSchema:{agent_id:z.string().describe("The agent ID to enable")}},async({agent_id:e})=>await N.findOne({_id:e})?(await Nt(e,["disabled"]),await N.updateOne({_id:e},{$set:{disabled:!1,updatedAt:new Date,updatedBy:Tt}}),{content:[{type:"text",text:`Agent '${e}' enabled. Version saved. Change will take effect within 30 seconds.`}]}):{content:[{type:"text",text:`Agent '${e}' not found.`}],isError:!0});B.registerTool("agent_disable",{title:"Disable Agent",description:"Take an agent offline (sets disabled=true). The agent stops receiving messages and active sessions are aborted.",inputSchema:{agent_id:z.string().describe("The agent ID to disable")}},async({agent_id:e})=>await N.findOne({_id:e})?(await Nt(e,["disabled"]),await N.updateOne({_id:e},{$set:{disabled:!0,updatedAt:new Date,updatedBy:Tt}}),{content:[{type:"text",text:`Agent '${e}' disabled. Version saved. Change will take effect within 30 seconds.`}]}):{content:[{type:"text",text:`Agent '${e}' not found.`}],isError:!0});B.registerTool("agent_history",{title:"Agent Version History",description:"List version history for an agent definition, sorted newest first.",inputSchema:{agent_id:z.string().describe("The agent ID"),limit:z.number().optional().describe("Max entries to return (default 10)")}},async({agent_id:e,limit:r})=>{let i=r??10,o=await wn.find({agentId:e}).sort({createdAt:-1}).limit(i).toArray();if(o.length===0)return{content:[{type:"text",text:`No version history for '${e}'.`}]};let t=o.map((n,a)=>{let c=n.createdAt instanceof Date?n.createdAt.toISOString():String(n.createdAt),u=n.changedFields.join(", "),s=n.snapshot?.updatedBy?` (by ${n.snapshot.updatedBy})`:"";return`[${a}] ${c} \u2014 changed: ${u}${s}`});return{content:[{type:"text",text:`Version history for '${e}' (${o.length} entries):
|
|
51
|
+
`)}]}});B.registerTool("agent_create",{title:"Create Agent",description:"Create a new agent definition. Required: _id, name, model, homeBase. Archetype is optional \u2014 pass it when the role is a discipline with shared infrastructure (see list_archetypes). Soul/systemPrompt shape the agent's voice and role; if omitted they default to empty strings. Additional tuning (channels, schedule, budget, autonomy, archetypeConfig, etc.) goes in `fields`.",inputSchema:{_id:z.string().describe("Agent ID (lowercase with hyphens, e.g. 'my-agent')"),name:z.string().describe("Display name for the agent"),model:z.string().describe("Model to use (e.g. 'claude-sonnet-4-6', 'claude-haiku-4-5')"),homeBase:z.string().describe("Primary Slack channel for scheduler delivery and default identity (e.g. 'agent-<id>'). The channel must exist in Slack."),soul:z.string().optional().describe("Personality / voice / character definition (5-15 lines). Shapes how the agent talks."),systemPrompt:z.string().optional().describe("Role definition and guardrails. Concise. Instance-specific flavor \u2014 archetype framing layers underneath."),archetype:z.string().optional().describe("Discipline id from list_archetypes (e.g. 'software-engineer'). Omit for plain unstructured agents."),title:z.string().optional().describe("Customer-facing title (e.g. 'VP Engineering'). Typically paired with archetype."),fields:z.record(z.string(),z.any()).optional().describe("Additional fields (channels, passiveChannels, schedule, coreServers override, delegateServers, plugins, autonomy, archetypeConfig, budgetUsd, maxTurns, etc.)")}},async({_id:e,name:r,model:i,homeBase:o,soul:t,systemPrompt:n,archetype:a,title:c,fields:u})=>{if(await N.findOne({_id:e}))return{content:[{type:"text",text:`Agent '${e}' already exists. Use agent_update to modify it.`}],isError:!0};if(!o||o.trim()==="")return{content:[{type:"text",text:`Missing required field: homeBase (primary channel for scheduled delivery, e.g. 'agent-${e}').`}],isError:!0};if(a!==void 0&&!zn(a)){let _=Sn().join(", ")||"(none registered)";return{content:[{type:"text",text:`Unknown archetype: "${a}". Known: ${_}.`}],isError:!0}}let l=u??{},p=new Date,$={_id:e,name:r,aliases:l.aliases,model:i,icon:l.icon??T.icon,channels:l.channels??[],homeBase:o.trim(),passiveChannels:l.passiveChannels??[...T.passiveChannels],keywords:l.keywords??[...T.keywords],isDefault:l.isDefault??!1,coreServers:l.coreServers??[...T.coreServers],delegateServers:l.delegateServers??[...T.delegateServers],delegatePrompts:l.delegatePrompts??{...T.delegatePrompts},plugins:l.plugins,metadata:l.metadata,soul:t??l.soul??"",systemPrompt:n??l.systemPrompt??"",archetype:a,title:c,archetypeConfig:l.archetypeConfig,schedule:l.schedule??[...T.schedule],subscribe:l.subscribe,budgetUsd:l.budgetUsd??T.budgetUsd,maxTurns:l.maxTurns??T.maxTurns,maxConcurrent:l.maxConcurrent??T.maxConcurrent,timeoutMs:l.timeoutMs??T.timeoutMs,disabled:l.disabled??!1,slackBot:l.slackBot,autonomy:l.autonomy,resourceTiers:l.resourceTiers,betas:l.betas,catches:l.catches,createdAt:p,updatedAt:p,updatedBy:Tt};return await N.insertOne($),{content:[{type:"text",text:`Agent '${e}' (${r}) created with model ${i}${a?` \u2014 archetype ${a}`:""}. Change will take effect within 30 seconds.`}]}});B.registerTool("agent_update",{title:"Update Agent",description:"Update fields on an existing agent definition. Saves a version snapshot before mutation. Cannot change _id. Creation-boundary fields (homeBase, archetype, title, soul, systemPrompt) are promoted to top-level for discoverability; everything else goes in `fields`.",inputSchema:{agent_id:z.string().describe("The agent ID to update"),homeBase:z.string().optional().describe("Primary Slack channel for scheduler delivery."),soul:z.string().optional().describe("Personality / voice / character definition."),systemPrompt:z.string().optional().describe("Role definition and guardrails."),archetype:z.string().optional().describe("Discipline id from list_archetypes. Pass null-style empty string to clear (note: fields.archetype: null also works via the fields bag)."),title:z.string().optional().describe("Customer-facing title."),fields:z.record(z.string(),z.any()).optional().describe("Additional fields (channels, schedule, autonomy, archetypeConfig, budgetUsd, model, etc.)")}},async({agent_id:e,homeBase:r,soul:i,systemPrompt:o,archetype:t,title:n,fields:a})=>{if(!await N.findOne({_id:e}))return{content:[{type:"text",text:`Agent '${e}' not found.`}],isError:!0};let u={...a??{}};if(r!==void 0&&(u.homeBase=r),i!==void 0&&(u.soul=i),o!==void 0&&(u.systemPrompt=o),t!==void 0&&(u.archetype=t),n!==void 0&&(u.title=n),"_id"in u)return{content:[{type:"text",text:"Cannot change _id. Create a new agent instead."}],isError:!0};if(delete u.createdAt,typeof u.archetype=="string"&&u.archetype.length>0&&!zn(u.archetype)){let l=Sn().join(", ")||"(none registered)";return{content:[{type:"text",text:`Unknown archetype: "${u.archetype}". Known: ${l}.`}],isError:!0}}let s=Object.keys(u);return s.length===0?{content:[{type:"text",text:`No fields to update for '${e}'.`}],isError:!0}:(await Nt(e,s),await N.updateOne({_id:e},{$set:{...u,updatedAt:new Date,updatedBy:Tt}}),{content:[{type:"text",text:`Agent '${e}' updated: ${s.join(", ")}. Version saved. Change will take effect within 30 seconds.`}]})});B.registerTool("agent_delete",{title:"Delete Agent",description:"Delete an agent definition. Saves a version snapshot before deletion. Requires confirm=true.",inputSchema:{agent_id:z.string().describe("The agent ID to delete"),confirm:z.boolean().describe("Must be true to confirm deletion")}},async({agent_id:e,confirm:r})=>r?await N.findOne({_id:e})?(await Nt(e,["DELETED"]),await N.deleteOne({_id:e}),{content:[{type:"text",text:`Agent '${e}' deleted. Version snapshot saved. Change will take effect within 30 seconds.`}]}):{content:[{type:"text",text:`Agent '${e}' not found.`}],isError:!0}:{content:[{type:"text",text:"Deletion not confirmed. Set confirm=true to proceed."}],isError:!0});B.registerTool("agent_enable",{title:"Enable Agent",description:"Bring a disabled agent back online (sets disabled=false).",inputSchema:{agent_id:z.string().describe("The agent ID to enable")}},async({agent_id:e})=>await N.findOne({_id:e})?(await Nt(e,["disabled"]),await N.updateOne({_id:e},{$set:{disabled:!1,updatedAt:new Date,updatedBy:Tt}}),{content:[{type:"text",text:`Agent '${e}' enabled. Version saved. Change will take effect within 30 seconds.`}]}):{content:[{type:"text",text:`Agent '${e}' not found.`}],isError:!0});B.registerTool("agent_disable",{title:"Disable Agent",description:"Take an agent offline (sets disabled=true). The agent stops receiving messages and active sessions are aborted.",inputSchema:{agent_id:z.string().describe("The agent ID to disable")}},async({agent_id:e})=>await N.findOne({_id:e})?(await Nt(e,["disabled"]),await N.updateOne({_id:e},{$set:{disabled:!0,updatedAt:new Date,updatedBy:Tt}}),{content:[{type:"text",text:`Agent '${e}' disabled. Version saved. Change will take effect within 30 seconds.`}]}):{content:[{type:"text",text:`Agent '${e}' not found.`}],isError:!0});B.registerTool("agent_history",{title:"Agent Version History",description:"List version history for an agent definition, sorted newest first.",inputSchema:{agent_id:z.string().describe("The agent ID"),limit:z.number().optional().describe("Max entries to return (default 10)")}},async({agent_id:e,limit:r})=>{let i=r??10,o=await wn.find({agentId:e}).sort({createdAt:-1}).limit(i).toArray();if(o.length===0)return{content:[{type:"text",text:`No version history for '${e}'.`}]};let t=o.map((n,a)=>{let c=n.createdAt instanceof Date?n.createdAt.toISOString():String(n.createdAt),u=n.changedFields.join(", "),s=n.snapshot?.updatedBy?` (by ${n.snapshot.updatedBy})`:"";return`[${a}] ${c} \u2014 changed: ${u}${s}`});return{content:[{type:"text",text:`Version history for '${e}' (${o.length} entries):
|
|
52
52
|
${t.join(`
|
|
53
53
|
`)}`}]}});B.registerTool("agent_rollback",{title:"Rollback Agent",description:"Rollback an agent definition to a previous version. Saves current state first, then replaces with the snapshot. Use agent_history to see available versions.",inputSchema:{agent_id:z.string().describe("The agent ID to rollback"),version_index:z.number().describe("Version index from agent_history (0 = most recent version)")}},async({agent_id:e,version_index:r})=>{if(r<0||!Number.isInteger(r))return{content:[{type:"text",text:"version_index must be a non-negative integer."}],isError:!0};let i=await wn.find({agentId:e}).sort({createdAt:-1}).limit(r+1).toArray();if(i.length<=r)return{content:[{type:"text",text:`Version index ${r} not found for '${e}'. Only ${i.length} versions available.`}],isError:!0};let o=i[r];if(!await N.findOne({_id:e}))return{content:[{type:"text",text:`Agent '${e}' not found \u2014 cannot rollback a deleted agent.`}],isError:!0};await Nt(e,["ROLLBACK"]);let{_id:n,...a}=o.snapshot;await N.updateOne({_id:e},{$set:{...a,updatedAt:new Date,updatedBy:Tt}});let c=o.createdAt instanceof Date?o.createdAt.toISOString():String(o.createdAt);return{content:[{type:"text",text:`Agent '${e}' rolled back to version from ${c}. Current state saved first. Change will take effect within 30 seconds.`}]}});var yf={instanceId:"unknown",servers:{configured:[],unconfigured:[]}},Zt=yf;try{if(process.env.INSTANCE_CAPABILITIES){let e=JSON.parse(process.env.INSTANCE_CAPABILITIES);e&&typeof e=="object"&&"servers"in e&&(Zt=e)}}catch(e){console.error("[hive-admin] Failed to parse INSTANCE_CAPABILITIES, using fallback:",e)}B.registerTool("instance_capabilities",{title:"Instance Capabilities",description:"Report what servers, integrations, and channels are configured on this Hive instance. Use this before creating agents to check what capabilities are available.",inputSchema:{}},async()=>{let e=await N.find({},{projection:{channels:1,passiveChannels:1}}).toArray(),r=new Set;for(let o of e){for(let t of o.channels??[])r.add(t);for(let t of o.passiveChannels??[])r.add(t)}return{content:[{type:"text",text:[`Instance: ${Zt.instanceId}`,`Agents: ${e.length}`,"","## Configured Servers",...Zt.servers.configured.map(o=>` \u2713 ${o}`),"","## Unconfigured Servers (missing credentials)",...Zt.servers.unconfigured.length>0?Zt.servers.unconfigured.map(o=>` \u2717 ${o}`):[" (none \u2014 all servers configured)"],"","## Active Channels",...r.size>0?[...r].sort().map(o=>` #${o}`):[" (no channels assigned)"]].join(`
|
|
54
54
|
`)}]}});B.registerTool("list_archetypes",{title:"List Archetypes",description:"List registered agent archetypes with self-descriptions. Use this to decide whether an agent you are creating is a discipline-bound archetype (e.g. software-engineer) or a plain unstructured agent.",inputSchema:{}},async()=>{let r=Sn().map(i=>{let o=zn(i);return o?{id:o.id,description:o.description??null,whenToUse:o.whenToUse??null,configSchema:o.configSchema??null}:null}).filter(i=>i!==null);return{content:[{type:"text",text:JSON.stringify(r,null,2)}]}});B.registerTool("verify_path",{title:"Verify Filesystem Path",description:"Check that an absolute filesystem path exists and is a directory. Used by the agent-builder skill to validate archetype-config paths (e.g. software-engineer `workshop`) before agent creation, so the caller catches typos at creation time instead of at agent-load time.",inputSchema:{path:z.string().describe("Absolute filesystem path to verify. Must start with '/'. Tilde (~) is not expanded \u2014 callers must pre-expand.")}},async({path:e})=>{if(typeof e!="string"||e.length===0)return{content:[{type:"text",text:JSON.stringify({exists:!1,isDirectory:!1,error:"path must be a non-empty string"})}],isError:!0};if(!vf(e))return{content:[{type:"text",text:JSON.stringify({exists:!1,isDirectory:!1,error:`path must be absolute (start with '/'); got "${e}"`})}],isError:!0};let r=hf(e);try{let i=gf(r);return{content:[{type:"text",text:JSON.stringify({exists:!0,isDirectory:i.isDirectory(),resolved:r})}]}}catch{return{content:[{type:"text",text:JSON.stringify({exists:!1,isDirectory:!1,resolved:r})}]}}});process.on("SIGTERM",()=>In.close());process.on("SIGINT",()=>In.close());var xf=new pf;await B.connect(xf);
|
package/pkg/server.min.js
CHANGED
|
@@ -239,7 +239,7 @@ data: [DONE]
|
|
|
239
239
|
`+i.map(o=>` - ${o}`).join(`
|
|
240
240
|
`)+`
|
|
241
241
|
Reinstall with: npm install @keepur/hive@<version>`);return{ok:!0,warnings:[]}}function pc(n){let e=["skills","plugins",".hive",".env","hive.yaml","hive-"],t=new Set(["dist","node_modules","package.json","package-lock.json","pkg","seeds","templates"]);try{let s=Mp(n),r=[];for(let i of s)t.has(i)||i.startsWith(".")&&i!==".hive"||e.some(o=>i.startsWith(o.replace("/","")))||r.push(i);r.length>0&&gi.warn("Unexpected files in instance directory",{files:r})}catch{}}O();import{existsSync as yi,readFileSync as Lp,writeFileSync as Pp,mkdirSync as $p}from"node:fs";import{resolve as wi}from"node:path";var mc=T("upgrade-notice");function gc(n,e){let t=wi(n,"upgrade-notice-emitted");if(yi(t))return;let s=wi(n,"previous-snapshot.json");if(yi(s))try{let r=JSON.parse(Lp(s,"utf-8")),i=[];for(let l of r)if(typeof l.path=="string"&&l.path.startsWith("skills/")&&l.path.endsWith("SKILL.md")){let c=l.path.match(/^skills\/([^/]+)\//);c&&!yi(wi(e,c[1]))&&i.push(c[1])}if(i.length===0)return;let o=[...new Set(i)],a=["","=".repeat(72),"Your previous version of hive shipped the following skills in its tarball:",...o.map(l=>` - ${l}`),"","These are no longer part of the hive core package. You can re-install any of","them from the default Keepur registry with:",""," hive skill add <name>","","Agent-authored skills you or your agents wrote on this hive are unaffected and","continue to work. This notice only appears once.","=".repeat(72),""].join(`
|
|
242
|
-
`);mc.info(a),$p(n,{recursive:!0}),Pp(t,new Date().toISOString())}catch(r){mc.warn("Failed to check upgrade notice",{error:String(r)})}}Oe();O();O();sa();var z={maxConcurrent:3,timeoutMs:3e5,budgetUsd:10,maxTurns:200,icon:"",keywords:[],passiveChannels:[],delegatePrompts:{},schedule:[],coreServers:["memory","structured-memory","keychain","event-bus","contacts"],delegateServers:[]};function wu(n,e){return{id:n._id,name:n.name,model:n.model,channels:n.channels??[],homeBase:n.homeBase,catches:n.catches,passiveChannels:n.passiveChannels??z.passiveChannels,keywords:n.keywords??z.keywords,isDefault:n.isDefault??!1,schedule:n.schedule??z.schedule,budgetUsd:n.budgetUsd??z.budgetUsd,maxTurns:n.maxTurns??z.maxTurns,icon:n.icon??z.icon,slackBot:n.slackBot,coreServers:n.coreServers??[...z.coreServers],delegateServers:n.delegateServers??[...z.delegateServers],plugins:n.plugins,maxConcurrent:n.maxConcurrent??z.maxConcurrent,timeoutMs:n.timeoutMs??z.timeoutMs,betas:n.betas,metadata:n.metadata,disabled:n.disabled??!1,subscribe:n.subscribe??[],resourceTiers:n.resourceTiers,delegatePrompts:n.delegatePrompts??z.delegatePrompts,soul:n.soul??"",systemPrompt:n.systemPrompt??"",archetype:n.archetype,title:n.title,archetypeConfig:n.archetypeConfig,autonomy:du(e,n.autonomy)}}Oe();or();or();import{statSync as xS}from"node:fs";import{normalize as _u,resolve as ku}from"node:path";var vu=new Set(["linear","github","clickup"]);function Iu(n){if(!n||typeof n!="object")throw new Error("software-engineer archetypeConfig must be an object");let e=n;if(typeof e.workshop!="string"||!e.workshop.startsWith("/"))throw new Error("workshop must be an absolute path");let t=_u(e.workshop);Tu(t,"workshop");let s=e.workspaces??[];if(!Array.isArray(s))throw new Error("workspaces must be an array");let r=new Set,i=s.map((o,a)=>{if(!o||typeof o!="object")throw new Error(`workspaces[${a}]: must be an object`);let l=o;if(typeof l.name!="string"||l.name.length===0)throw new Error(`workspaces[${a}]: name is required`);if(r.has(l.name))throw new Error(`workspaces[${a}]: duplicate workspace name "${l.name}"`);if(r.add(l.name),typeof l.path!="string"||!l.path.startsWith("/"))throw new Error(`workspaces[${a}] (${l.name}): path must be an absolute path`);let c=_u(l.path);Tu(c,`workspaces[${a}] (${l.name})`);let d=ku(c),u=ku(t);if(!d.startsWith(u+"/"))throw new Error(`workspaces[${a}] (${l.name}): path must be inside workshop (${t}), got ${c}`);if(!l.tracker||typeof l.tracker!="object")throw new Error(`workspaces[${a}] (${l.name}): tracker is required`);let h=l.tracker;if(typeof h.type!="string"||!vu.has(h.type))throw new Error(`workspaces[${a}] (${l.name}): tracker.type must be one of: ${[...vu].join(", ")}`);return MS(h,a,l.name),{name:l.name,path:c,tracker:h,...l.primary===!0?{primary:!0}:{}}});return{workshop:t,workspaces:i}}function Tu(n,e){let t;try{t=xS(n)}catch{throw new Error(`${e}: path does not exist: ${n}`)}if(!t.isDirectory())throw new Error(`${e}: path is not a directory: ${n}`)}function MS(n,e,t){switch(n.type){case"linear":if(typeof n.project!="string"||n.project.length===0)throw new Error(`workspaces[${e}] (${t}): linear tracker requires project`);break;case"github":if(typeof n.repo!="string"||n.repo.length===0)throw new Error(`workspaces[${e}] (${t}): github tracker requires repo`);break;case"clickup":if(typeof n.list!="string"||n.list.length===0)throw new Error(`workspaces[${e}] (${t}): clickup tracker requires list`);break}}function Au(n){let e=n.archetypeConfig,t=n.agentConfig.title||n.agentConfig.name,s=[];s.push(`# Software Engineer
|
|
242
|
+
`);mc.info(a),$p(n,{recursive:!0}),Pp(t,new Date().toISOString())}catch(r){mc.warn("Failed to check upgrade notice",{error:String(r)})}}Oe();O();O();sa();var z={maxConcurrent:3,timeoutMs:3e5,budgetUsd:10,maxTurns:200,icon:"",keywords:[],passiveChannels:[],delegatePrompts:{},schedule:[],coreServers:["memory","structured-memory","keychain","event-bus","contacts"],delegateServers:[]};function wu(n,e){return{id:n._id,name:n.name,aliases:n.aliases??[],model:n.model,channels:n.channels??[],homeBase:n.homeBase,catches:n.catches,passiveChannels:n.passiveChannels??z.passiveChannels,keywords:n.keywords??z.keywords,isDefault:n.isDefault??!1,schedule:n.schedule??z.schedule,budgetUsd:n.budgetUsd??z.budgetUsd,maxTurns:n.maxTurns??z.maxTurns,icon:n.icon??z.icon,slackBot:n.slackBot,coreServers:n.coreServers??[...z.coreServers],delegateServers:n.delegateServers??[...z.delegateServers],plugins:n.plugins,maxConcurrent:n.maxConcurrent??z.maxConcurrent,timeoutMs:n.timeoutMs??z.timeoutMs,betas:n.betas,metadata:n.metadata,disabled:n.disabled??!1,subscribe:n.subscribe??[],resourceTiers:n.resourceTiers,delegatePrompts:n.delegatePrompts??z.delegatePrompts,soul:n.soul??"",systemPrompt:n.systemPrompt??"",archetype:n.archetype,title:n.title,archetypeConfig:n.archetypeConfig,autonomy:du(e,n.autonomy)}}Oe();or();or();import{statSync as xS}from"node:fs";import{normalize as _u,resolve as ku}from"node:path";var vu=new Set(["linear","github","clickup"]);function Iu(n){if(!n||typeof n!="object")throw new Error("software-engineer archetypeConfig must be an object");let e=n;if(typeof e.workshop!="string"||!e.workshop.startsWith("/"))throw new Error("workshop must be an absolute path");let t=_u(e.workshop);Tu(t,"workshop");let s=e.workspaces??[];if(!Array.isArray(s))throw new Error("workspaces must be an array");let r=new Set,i=s.map((o,a)=>{if(!o||typeof o!="object")throw new Error(`workspaces[${a}]: must be an object`);let l=o;if(typeof l.name!="string"||l.name.length===0)throw new Error(`workspaces[${a}]: name is required`);if(r.has(l.name))throw new Error(`workspaces[${a}]: duplicate workspace name "${l.name}"`);if(r.add(l.name),typeof l.path!="string"||!l.path.startsWith("/"))throw new Error(`workspaces[${a}] (${l.name}): path must be an absolute path`);let c=_u(l.path);Tu(c,`workspaces[${a}] (${l.name})`);let d=ku(c),u=ku(t);if(!d.startsWith(u+"/"))throw new Error(`workspaces[${a}] (${l.name}): path must be inside workshop (${t}), got ${c}`);if(!l.tracker||typeof l.tracker!="object")throw new Error(`workspaces[${a}] (${l.name}): tracker is required`);let h=l.tracker;if(typeof h.type!="string"||!vu.has(h.type))throw new Error(`workspaces[${a}] (${l.name}): tracker.type must be one of: ${[...vu].join(", ")}`);return MS(h,a,l.name),{name:l.name,path:c,tracker:h,...l.primary===!0?{primary:!0}:{}}});return{workshop:t,workspaces:i}}function Tu(n,e){let t;try{t=xS(n)}catch{throw new Error(`${e}: path does not exist: ${n}`)}if(!t.isDirectory())throw new Error(`${e}: path is not a directory: ${n}`)}function MS(n,e,t){switch(n.type){case"linear":if(typeof n.project!="string"||n.project.length===0)throw new Error(`workspaces[${e}] (${t}): linear tracker requires project`);break;case"github":if(typeof n.repo!="string"||n.repo.length===0)throw new Error(`workspaces[${e}] (${t}): github tracker requires repo`);break;case"clickup":if(typeof n.list!="string"||n.list.length===0)throw new Error(`workspaces[${e}] (${t}): clickup tracker requires list`);break}}function Au(n){let e=n.archetypeConfig,t=n.agentConfig.title||n.agentConfig.name,s=[];s.push(`# Software Engineer
|
|
243
243
|
|
|
244
244
|
You are a software engineer. Your title is ${t}. Your discipline is owning codebases and shipping production code through disciplined delivery.`);let r=[`Your workshop is \`${e.workshop}\`. This is your working directory.`];if(e.workspaces.length>0){r.push(`
|
|
245
245
|
Workspaces:`);for(let i of e.workspaces){let o=DS(i.tracker),a=i.primary?" (primary)":"";r.push(`- **${i.name}**${a}: \`${i.path}\` \u2014 tracker: ${o}`)}}else r.push(`
|
|
@@ -269,7 +269,7 @@ A task is done when ALL of these are true:
|
|
|
269
269
|
- **Always** verify PR + CI status before closing a ticket
|
|
270
270
|
- **Always** file a ticket before delegating work`),s.join(`
|
|
271
271
|
|
|
272
|
-
`)}function DS(n){switch(n.type){case"linear":return`Linear (project: ${n.project})`;case"github":return`GitHub Issues (repo: ${n.repo})`;case"clickup":return`ClickUp (list: ${n.list})`;default:return n.type}}import{resolve as LS}from"node:path";import{normalize as Cu,resolve as Eu}from"node:path";function ia(n){if(typeof n!="string"||!n.startsWith("/"))throw new Error(`claudeProjectSlug: path must be absolute, got ${String(n)}`);return n.replace(/\/+$/,"").replace(/[/_.]/g,"-").replace(/-+/g,"-")}function Nu(n,e){let t=Cu(Eu(n));return e.workspaces.find(s=>{let r=Cu(Eu(s.path));return t===r||t.startsWith(r+"/")})}function Ou(n){return ia(n.workshop)}function xu(n){return ia(n.path)}var PS=new Set(["Edit","Write","MultiEdit","NotebookEdit"]);function $S(n,e){return n==="NotebookEdit"?e.notebook_path??e.file_path:e.file_path}function Mu(n){let e=n.archetypeConfig;return e.workspaces.length===0?[]:[{hooks:[async t=>{try{let s=t,r=s.tool_name??"";if(!PS.has(r))return{continue:!0};let i=$S(r,s.tool_input??{});if(typeof i!="string"||i.length===0)return{continue:!0};let o=LS(e.workshop,i),a=Nu(o,e);return a?{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:`${r} blocked: \`${o}\` is inside workspace \`${a.name}\`. Code changes inside workspaces flow through \`code_task\`, not direct edits \u2014 this preserves the spec \u2192 plan \u2192 PR \u2192 CI discipline. If you're drafting a prototype, work inside the workshop outside any workspace. If you're ready to implement against a ticket, use \`code_task\` with the ticket ID.`}}:{continue:!0}}catch(s){return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:`Software-engineer hook internal error: ${String(s)}. All file mutations blocked until the archetype is fixed.`}}}}]}]}import{homedir as RS}from"node:os";import{join as Du}from"node:path";function Lu(n){let e=n.archetypeConfig,t=RS(),s=[];s.push({id:"workshop",backing:"filesystem",dir:Du(t,".claude/projects",Ou(e),"memory")});for(let r of e.workspaces)s.push({id:`workspace:${r.name}`,backing:"filesystem",dir:Du(t,".claude/projects",xu(r),"memory")});return s}function Pu(n){return{cwd:n.archetypeConfig.workshop,settingSources:["project"]}}bu({id:"software-engineer",description:"Owns codebases and ships production code through disciplined delivery (ticket \u2192 spec \u2192 PR \u2192 CI \u2192 close).",whenToUse:"Pick this when the agent's core job is writing, reviewing, or shipping production code. For product strategists, marketers, or anyone where code is incidental, use a plain agent.",configSchema:{workshop:{type:"string",required:!0,description:"Absolute filesystem path \u2014 the engineer's bounded root directory (e.g. /Users/you/dev)."},workspaces:{type:"array",required:!1,description:"Registered codebases inside the workshop. Do NOT prompt for these at creation time \u2014 workspace registration is a separate admin flow. Start with an empty array."}},validateConfig:Iu,systemPromptCard:Au,preToolUseHooks:Mu,memoryScopes:Lu,sessionOptions:Pu});var he=T("agent-registry"),$u=3e4,ar=class{agents=new Map;originToAgent=new Map;disabledAgents=[];agentDefs;changeStream=null;pollTimer=null;lastPollTime=new Date(0);onReload;constructor(e,t){this.agentDefs=e,this.onReload=t}async load(){let e=await this.agentDefs.find().toArray(),t=new Set(this.agents.keys()),s=new Set,r=[],i=[],o=[],a=[];for(let l of e){let c=wu(l,m.autonomy);if(s.add(c.id),c.disabled){a.push(c),this.agents.has(c.id)&&(this.agents.delete(c.id),o.push(c.id),he.info("Disabled agent removed from active map",{id:c.id}));continue}if(c.archetype){let d=ir(c.archetype);if(!d)he.warn("Unknown archetype \u2014 loading agent as unstructured",{id:c.id,archetype:c.archetype}),c.archetype=void 0,c.archetypeConfig=void 0;else try{c.archetypeConfig=d.validateConfig(c.archetypeConfig)}catch(u){he.error("Archetype config validation failed \u2014 agent will not load",{id:c.id,archetype:c.archetype,error:String(u)}),this.agents.has(c.id)&&(this.agents.delete(c.id),o.push(c.id),he.warn("Evicted previously-loaded agent due to archetype validation failure",{id:c.id}));continue}}t.has(c.id)?i.push(c.id):r.push(c.id),this.agents.set(c.id,c),he.info("Loaded agent",{id:c.id,name:c.name})}this.disabledAgents=a;for(let l of t)s.has(l)||(this.agents.delete(l),o.push(l),he.info("Removed agent",{id:l}));return this.lastPollTime=new Date,this.rebuildOriginIndex(),{added:r,updated:i,removed:o}}async startWatching(){try{this.changeStream=this.agentDefs.watch([],{fullDocument:"updateLookup"}),this.changeStream.on("change",()=>{he.info("Agent definition changed (change stream), triggering reload"),this.onReload?.()}),this.changeStream.on("error",e=>{he.warn("Change stream error, falling back to polling",{error:String(e)}),this.changeStream=null,this.startPolling()}),he.info("Agent registry watching via change stream")}catch{he.info("Change stream not available, using polling fallback"),this.startPolling()}}startPolling(){this.pollTimer=setInterval(async()=>{try{let e=await this.agentDefs.countDocuments({updatedAt:{$gt:this.lastPollTime}});e>0&&(he.info("Agent definitions changed (poll), triggering reload",{changed:e}),this.onReload?.())}catch(e){he.error("Poll check failed",{error:String(e)})}},$u),he.info("Agent registry watching via polling",{intervalMs:$u})}rebuildOriginIndex(){this.originToAgent.clear();let e=[...this.agents.values()].sort((t,s)=>t.id.localeCompare(s.id));for(let t of e)for(let s of t.catches??[]){if(this.originToAgent.has(s)){he.error("Origin conflict \u2014 first sorted agent wins",{origin:s,winner:this.originToAgent.get(s),loser:t.id});continue}this.originToAgent.set(s,t.id)}}stopWatching(){this.changeStream&&(this.changeStream.close().catch(()=>{}),this.changeStream=null),this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null)}get(e){return this.agents.get(e)}getAll(){return Array.from(this.agents.values())}async getAllDefinitions(){return this.agentDefs.find().toArray()}listIds(){return Array.from(this.agents.keys())}findByChannel(e){return this.getAll().find(t=>!t.disabled&&t.channels.includes(e))}findByOrigin(e){let t=this.originToAgent.get(e);return t?this.agents.get(t):void 0}isPassiveChannel(e){return this.getAll().some(t=>!t.disabled&&t.passiveChannels.includes(e))}findByKeyword(e){let t=e.toLowerCase();return this.getAll().find(s=>!s.disabled&&s.keywords.some(r=>{let i=r.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`\\b${i}\\b`).test(t)}))}findByName(e){return this.findAllByName(e)[0]}findAllByName(e){return this.getAll().filter(t=>{if(t.disabled)return!1;let s=t.name.
|
|
272
|
+
`)}function DS(n){switch(n.type){case"linear":return`Linear (project: ${n.project})`;case"github":return`GitHub Issues (repo: ${n.repo})`;case"clickup":return`ClickUp (list: ${n.list})`;default:return n.type}}import{resolve as LS}from"node:path";import{normalize as Cu,resolve as Eu}from"node:path";function ia(n){if(typeof n!="string"||!n.startsWith("/"))throw new Error(`claudeProjectSlug: path must be absolute, got ${String(n)}`);return n.replace(/\/+$/,"").replace(/[/_.]/g,"-").replace(/-+/g,"-")}function Nu(n,e){let t=Cu(Eu(n));return e.workspaces.find(s=>{let r=Cu(Eu(s.path));return t===r||t.startsWith(r+"/")})}function Ou(n){return ia(n.workshop)}function xu(n){return ia(n.path)}var PS=new Set(["Edit","Write","MultiEdit","NotebookEdit"]);function $S(n,e){return n==="NotebookEdit"?e.notebook_path??e.file_path:e.file_path}function Mu(n){let e=n.archetypeConfig;return e.workspaces.length===0?[]:[{hooks:[async t=>{try{let s=t,r=s.tool_name??"";if(!PS.has(r))return{continue:!0};let i=$S(r,s.tool_input??{});if(typeof i!="string"||i.length===0)return{continue:!0};let o=LS(e.workshop,i),a=Nu(o,e);return a?{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:`${r} blocked: \`${o}\` is inside workspace \`${a.name}\`. Code changes inside workspaces flow through \`code_task\`, not direct edits \u2014 this preserves the spec \u2192 plan \u2192 PR \u2192 CI discipline. If you're drafting a prototype, work inside the workshop outside any workspace. If you're ready to implement against a ticket, use \`code_task\` with the ticket ID.`}}:{continue:!0}}catch(s){return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:`Software-engineer hook internal error: ${String(s)}. All file mutations blocked until the archetype is fixed.`}}}}]}]}import{homedir as RS}from"node:os";import{join as Du}from"node:path";function Lu(n){let e=n.archetypeConfig,t=RS(),s=[];s.push({id:"workshop",backing:"filesystem",dir:Du(t,".claude/projects",Ou(e),"memory")});for(let r of e.workspaces)s.push({id:`workspace:${r.name}`,backing:"filesystem",dir:Du(t,".claude/projects",xu(r),"memory")});return s}function Pu(n){return{cwd:n.archetypeConfig.workshop,settingSources:["project"]}}bu({id:"software-engineer",description:"Owns codebases and ships production code through disciplined delivery (ticket \u2192 spec \u2192 PR \u2192 CI \u2192 close).",whenToUse:"Pick this when the agent's core job is writing, reviewing, or shipping production code. For product strategists, marketers, or anyone where code is incidental, use a plain agent.",configSchema:{workshop:{type:"string",required:!0,description:"Absolute filesystem path \u2014 the engineer's bounded root directory (e.g. /Users/you/dev)."},workspaces:{type:"array",required:!1,description:"Registered codebases inside the workshop. Do NOT prompt for these at creation time \u2014 workspace registration is a separate admin flow. Start with an empty array."}},validateConfig:Iu,systemPromptCard:Au,preToolUseHooks:Mu,memoryScopes:Lu,sessionOptions:Pu});var he=T("agent-registry"),$u=3e4,ar=class{agents=new Map;originToAgent=new Map;disabledAgents=[];agentDefs;changeStream=null;pollTimer=null;lastPollTime=new Date(0);onReload;constructor(e,t){this.agentDefs=e,this.onReload=t}async load(){let e=await this.agentDefs.find().toArray(),t=new Set(this.agents.keys()),s=new Set,r=[],i=[],o=[],a=[];for(let l of e){let c=wu(l,m.autonomy);if(s.add(c.id),c.disabled){a.push(c),this.agents.has(c.id)&&(this.agents.delete(c.id),o.push(c.id),he.info("Disabled agent removed from active map",{id:c.id}));continue}if(c.archetype){let d=ir(c.archetype);if(!d)he.warn("Unknown archetype \u2014 loading agent as unstructured",{id:c.id,archetype:c.archetype}),c.archetype=void 0,c.archetypeConfig=void 0;else try{c.archetypeConfig=d.validateConfig(c.archetypeConfig)}catch(u){he.error("Archetype config validation failed \u2014 agent will not load",{id:c.id,archetype:c.archetype,error:String(u)}),this.agents.has(c.id)&&(this.agents.delete(c.id),o.push(c.id),he.warn("Evicted previously-loaded agent due to archetype validation failure",{id:c.id}));continue}}t.has(c.id)?i.push(c.id):r.push(c.id),this.agents.set(c.id,c),he.info("Loaded agent",{id:c.id,name:c.name})}this.disabledAgents=a;for(let l of t)s.has(l)||(this.agents.delete(l),o.push(l),he.info("Removed agent",{id:l}));return this.lastPollTime=new Date,this.rebuildOriginIndex(),{added:r,updated:i,removed:o}}async startWatching(){try{this.changeStream=this.agentDefs.watch([],{fullDocument:"updateLookup"}),this.changeStream.on("change",()=>{he.info("Agent definition changed (change stream), triggering reload"),this.onReload?.()}),this.changeStream.on("error",e=>{he.warn("Change stream error, falling back to polling",{error:String(e)}),this.changeStream=null,this.startPolling()}),he.info("Agent registry watching via change stream")}catch{he.info("Change stream not available, using polling fallback"),this.startPolling()}}startPolling(){this.pollTimer=setInterval(async()=>{try{let e=await this.agentDefs.countDocuments({updatedAt:{$gt:this.lastPollTime}});e>0&&(he.info("Agent definitions changed (poll), triggering reload",{changed:e}),this.onReload?.())}catch(e){he.error("Poll check failed",{error:String(e)})}},$u),he.info("Agent registry watching via polling",{intervalMs:$u})}rebuildOriginIndex(){this.originToAgent.clear();let e=[...this.agents.values()].sort((t,s)=>t.id.localeCompare(s.id));for(let t of e)for(let s of t.catches??[]){if(this.originToAgent.has(s)){he.error("Origin conflict \u2014 first sorted agent wins",{origin:s,winner:this.originToAgent.get(s),loser:t.id});continue}this.originToAgent.set(s,t.id)}}stopWatching(){this.changeStream&&(this.changeStream.close().catch(()=>{}),this.changeStream=null),this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null)}get(e){return this.agents.get(e)}getAll(){return Array.from(this.agents.values())}async getAllDefinitions(){return this.agentDefs.find().toArray()}listIds(){return Array.from(this.agents.keys())}findByChannel(e){return this.getAll().find(t=>!t.disabled&&t.channels.includes(e))}findByOrigin(e){let t=this.originToAgent.get(e);return t?this.agents.get(t):void 0}isPassiveChannel(e){return this.getAll().some(t=>!t.disabled&&t.passiveChannels.includes(e))}findByKeyword(e){let t=e.toLowerCase();return this.getAll().find(s=>!s.disabled&&s.keywords.some(r=>{let i=r.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`\\b${i}\\b`).test(t)}))}findByName(e){return this.findAllByName(e)[0]}findAllByName(e){return this.getAll().filter(t=>{if(t.disabled)return!1;if(this.matchesName(t.name,e))return!0;if(t.name.includes(" ")){let s=t.name.split(" ")[0];if(this.matchesName(s,e))return!0}for(let s of t.aliases)if(this.matchesName(s,e))return!0;return!1})}matchesName(e,t){let s=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`(?:^|hey\\s+|@)${s}\\b|\\b${s}[,:]`,"i").test(t)}getDefault(){return this.getAll().find(e=>!e.disabled&&e.isDefault)}getDisabled(){return this.disabledAgents}getSubscriberMap(){let e={};for(let t of this.getAll())if(!t.disabled)for(let s of t.subscribe??[]){let r=s.includes(":")?s.split(":")[0]:s;e[r]||(e[r]=[]),e[r].includes(t.id)||e[r].push(t.id)}return e}};O();pa();qs();O();Oe();import{query as l0}from"@anthropic-ai/claude-agent-sdk";var js=T("model-router"),d0={haiku:{timeoutMs:12e4,maxTurns:20,budgetUsd:1},sonnet:{timeoutMs:3e5,maxTurns:50,budgetUsd:5},opus:{timeoutMs:6e5,maxTurns:200,budgetUsd:50}};function pr(n,e){let t=d0[n],s=e?.[n];return s?{timeoutMs:s.timeoutMs??t.timeoutMs,maxTurns:s.maxTurns??t.maxTurns,budgetUsd:s.budgetUsd??t.budgetUsd}:{...t}}var ct={haiku:0,sonnet:1,opus:2},mr={haiku:"claude-haiku-4-5-20251001",sonnet:"claude-sonnet-4-6",opus:"claude-opus-4-6"};function u0(n){return n.includes("opus")?"opus":n.includes("haiku")?"haiku":"sonnet"}var h0=`You are a model router. Your job is to classify the complexity of a user message and decide which AI model tier should handle it.
|
|
273
273
|
|
|
274
274
|
Tiers:
|
|
275
275
|
- **haiku**: Greetings, simple factual questions, acknowledgments, status checks, yes/no answers, brief lookups, routine updates. Fast and cheap.
|