qlogicagent 2.17.8 → 2.17.10

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.
Files changed (47) hide show
  1. package/dist/agent.js +21 -21
  2. package/dist/cli.js +1 -1566
  3. package/dist/index.js +419 -403
  4. package/dist/orchestration.js +7 -7
  5. package/dist/protocol.js +1 -1
  6. package/dist/skills/builtin/desktop-screenshot/SKILL.md +62 -0
  7. package/dist/skills/builtin/office-doc-reading/SKILL.md +19 -0
  8. package/dist/skills/mcp/astraclaw-native-mcp-server.js +6 -6
  9. package/dist/types/agent/tool-loop/artifact-final-contract.d.ts +18 -0
  10. package/dist/types/agent/tool-loop/loop-helpers.d.ts +9 -0
  11. package/dist/types/agent/tool-loop.d.ts +8 -5
  12. package/dist/types/cli/acp-session-handlers.d.ts +8 -1
  13. package/dist/types/cli/acp-session-host.d.ts +5 -1
  14. package/dist/types/cli/default-project-bootstrap.d.ts +33 -0
  15. package/dist/types/cli/handlers/session-handler.d.ts +6 -0
  16. package/dist/types/cli/handlers/turn-handler.d.ts +65 -0
  17. package/dist/types/cli/media-understanding.d.ts +45 -0
  18. package/dist/types/cli/session-context.d.ts +5 -1
  19. package/dist/types/cli/stdio-acp-request-host.d.ts +1 -1
  20. package/dist/types/cli/stdio-server.d.ts +1 -0
  21. package/dist/types/cli/tool-bootstrap-core-registration.d.ts +2 -0
  22. package/dist/types/orchestration/workflow/capability-catalog.d.ts +1 -1
  23. package/dist/types/orchestration/workflow/workflow-controller.d.ts +1 -1
  24. package/dist/types/orchestration/workflow/workflow-runtime.d.ts +1 -1
  25. package/dist/types/protocol/notifications.d.ts +1 -1
  26. package/dist/types/protocol/wire/agent-events.d.ts +2 -2
  27. package/dist/types/protocol/wire/index.d.ts +1 -1
  28. package/dist/types/protocol/wire/notification-payloads.d.ts +26 -0
  29. package/dist/types/runtime/execution/turn-progress-notifier.d.ts +16 -0
  30. package/dist/types/runtime/infra/acp-detector.d.ts +5 -1
  31. package/dist/types/runtime/infra/agent-process.d.ts +1 -0
  32. package/dist/types/runtime/infra/astraclaw-capabilities.d.ts +2 -2
  33. package/dist/types/runtime/infra/builtin-skills-seed.d.ts +31 -0
  34. package/dist/types/runtime/infra/project-data-gc.d.ts +7 -1
  35. package/dist/types/runtime/infra/skill-resolver.d.ts +15 -0
  36. package/dist/types/runtime/prompt/environment-context.d.ts +24 -2
  37. package/dist/types/runtime/prompt/identity-section.d.ts +17 -0
  38. package/dist/types/runtime/session/inbound-upload-persistence.d.ts +20 -0
  39. package/dist/types/runtime/session/session-recovery.d.ts +58 -0
  40. package/dist/types/runtime/session/session-types.d.ts +22 -0
  41. package/dist/types/skills/tools/exec-tool.d.ts +1 -1
  42. package/dist/types/skills/tools/shell/command-classification.d.ts +1 -0
  43. package/dist/types/skills/tools/shell/index.d.ts +3 -3
  44. package/dist/types/skills/tools/shell/powershell-provider.d.ts +8 -3
  45. package/dist/types/skills/tools/shell/shell-exec.d.ts +18 -0
  46. package/dist/types/skills/tools/shell/shell-provider.d.ts +67 -5
  47. package/package.json +4 -1
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import{createInterface as Qe}from"node:readline";import{existsSync as Ye,readFileSync as Ze}from"node:fs";import{readFileSync as be}from"node:fs";import{randomUUID as Te}from"node:crypto";import{readdirSync as le,readFileSync as ce,statSync as b,writeFileSync as ue}from"node:fs";import{join as d}from"node:path";import{homedir as ee}from"node:os";import{join as u,resolve as lt}from"node:path";import{existsSync as ut}from"node:fs";import{createHash as pt}from"node:crypto";var x=".qlogicagent";function te(){return process.env.QLOGICAGENT_HOME||u(ee(),x)}function oe(){let o=process.env.QLOGIC_LLMROUTER_USER_ID?.trim();if(o)return o;let e=process.env.QLOGIC_IMPLICIT_OWNER_ID?.trim();if(e)return e;let t=process.env.QLOGIC_DEVICE_ID?.trim();return t?`oc_${t}`:"oc_local"}function re(o){let e=o.trim();if(!e)throw new Error("ownerUserId is required for profile-scoped storage");return encodeURIComponent(e).replace(/\./g,"%2E")}function f(o=oe()){return u(te(),"profiles",re(o))}function y(){return u(f(),"skills")}function A(){return u(f(),"mcp.json")}function ne(o){if(!o)throw new Error("getProjectAgentDir: cwd is required (must not fall back to process.cwd())");return u(o,x)}function R(o){return u(ne(o),"skills-disabled.json")}import{readFileSync as se,writeFileSync as gt,mkdirSync as ht,renameSync as yt}from"node:fs";import{dirname as Tt,join as ie}from"node:path";function E(){return{version:1,disabled:[]}}function M(o){try{let e=JSON.parse(se(o,"utf8"));return!e||typeof e!="object"||!Array.isArray(e.disabled)?E():{version:1,disabled:[...new Set(e.disabled.filter(r=>typeof r=="string"&&r.trim().length>0))]}}catch{return E()}}function ae(){return ie(f(),"skills-disabled.json")}function D(){return new Set(M(ae()).disabled)}function I(o){return new Set(M(R(o)).disabled)}var de=["auto-skill-","test-skill-"],pe=".skills_prompt_snapshot.json";function me(o){return de.some(e=>o.startsWith(e))}function fe(o){let e=o.replace(/\r\n/g,`
3
- `),t=e.match(/^---\n[\s\S]*?^version:\s*(\S+)/m),r=e.match(/^---\n[\s\S]*?^description:\s*(.+)/m),n=e.match(/^---\n[\s\S]*?^category:\s*(.+)/m),s=e.match(/^---\n[\s\S]*?^author:\s*(.+)/m),i=e.match(/^---\n[\s\S]*?^requires:\s*(.+)/m),a=e.match(/^---\n[\s\S]*?^environments:\s*(.+)/m);return{version:t?.[1],description:r?.[1]?.trim(),category:n?.[1]?.trim()||void 0,author:s?.[1]?.trim()||void 0,requiredTools:j(i?.[1]),environments:j(a?.[1])}}function ge(o,e){let t=y(),r=D(),n=o?I(o):new Set,s=[],i;try{i=le(t,{withFileTypes:!0})}catch{i=[]}for(let a of i){if(!a.isDirectory()||a.name.startsWith("."))continue;let l=d(t,a.name),h=d(l,"SKILL.md"),k;try{if(!b(h).isFile())continue;k=ce(h,"utf8")}catch{continue}let P=r.has(a.name),C=n.has(a.name),c=fe(k),X=!he(c,e);s.push({name:a.name,filePath:h,baseDir:l,globallyDisabled:P,projectDisabled:C,active:!P&&!C&&!X,systemGenerated:me(a.name),description:c.description,version:c.version,category:c.category,author:c.author,requiredTools:c.requiredTools,environments:c.environments})}return ye(t,s),s}function L(o,e){return ge(o,e).filter(t=>t.active)}function O(o){let e=y(),t=d(e,o),r=d(t,"SKILL.md");try{if(b(r).isFile())return{baseDir:t,filePath:r}}catch{}return null}function j(o){if(!o)return;let e=o.replace(/^\[|\]$/g,"").split(/[,\s]+/).map(t=>t.replace(/^["']|["']$/g,"").trim()).filter(Boolean);return e.length>0?e:void 0}function he(o,e){if(o.environments&&e?.currentEnvironment&&!o.environments.includes(e.currentEnvironment))return!1;if(o.requiredTools){if(!e?.availableToolNames)return!1;let t=new Set(e.availableToolNames);return o.requiredTools.every(r=>t.has(r))}return!0}function ye(o,e){try{let r={version:1,entries:e.map(n=>{let s=b(n.filePath);return{name:n.name,size:s.size,mtimeMs:s.mtimeMs,description:n.description,version:n.version,requiredTools:n.requiredTools,environments:n.environments}})};ue(d(o,pe),JSON.stringify(r,null,2),"utf8")}catch{}}var N="astraclaw_capabilities";async function $(o){if(o.tool==="skills_list")return{handled:!0,result:{skills:L(o.projectRoot,{availableToolNames:o.availableToolNames,currentEnvironment:o.currentEnvironment??process.platform}).map(we)}};if(o.tool==="skill_view"){let e=typeof o.args.name=="string"?o.args.name.trim():"";if(!e)throw new Error("skill_view requires a skill name");let t=O(e);if(!t)throw new Error(`Skill not found: ${e}`);return{handled:!0,result:{name:e,content:be(t.filePath,"utf8")}}}if(o.tool==="mcp_connectors_list"){if(!o.toolCatalog)return{handled:!0,result:{tools:[],note:"AstraClaw MCP connector catalog is not attached to this capability server instance."}};let e=o.toolCatalog.getToolManifest().filter(t=>t.function.name.startsWith("mcp__")).map(t=>({toolName:t.function.name,server:Se(t.function.name),name:_e(t.function.name),description:t.function.description,inputSchema:t.function.parameters}));return{handled:!0,result:{tools:e,count:e.length}}}if(o.tool==="mcp_tool_call"){if(!o.toolCatalog)throw new Error("AstraClaw MCP connector catalog is not attached");let e=typeof o.args.toolName=="string"?o.args.toolName.trim():"";if(!e.startsWith("mcp__"))throw new Error("mcp_tool_call requires a connector toolName returned by mcp_connectors_list");let t=o.toolCatalog.findTool(e);if(!t?.execute)throw new Error(`MCP connector tool not found or not executable: ${e}`);let r=ve(o.args.args),n=`astraclaw_mcp_${Te().slice(0,8)}`,s=await t.execute(n,r);return{handled:!0,result:{toolName:e,content:s.content,details:s.details,imageUrls:s.imageUrls}}}return{handled:!1}}function we(o){return{name:o.name,description:o.description,version:o.version,category:o.category,requiredTools:o.requiredTools,environments:o.environments}}function ve(o){return typeof o=="object"&&o!==null&&!Array.isArray(o)?o:{}}function Se(o){let e=o.split("__");return e.length>=3?e[1]??"":""}function _e(o){let e=o.split("__");return e.length>=3?e.slice(2).join("__"):o}import p from"node:path";import{fileURLToPath as Ae}from"node:url";import{createRuntime as Re}from"mcporter";var U=new Set(["gateway","agents_list","session_status","sessions_send","sessions_list","sessions_history","sessions_spawn","cron","config","workflow"]),ke=new Set([...U,"agent"]);function q(o){return o?.riskLevel?o.riskLevel:o?.isDangerous?"system":o?.isReadOnly?"read":o?.isEgress?"external_egress":"write"}var T=class{toolPool=new Map;setTools(e){this.toolPool.clear();for(let t of e)this.toolPool.set(t.name,t)}addTool(e){this.toolPool.set(e.name,e)}addTools(e){for(let t of e)this.addTool(t)}removeTool(e){return this.toolPool.delete(e)}findTool(e){return this.toolPool.get(e)}hasTool(e){return this.toolPool.has(e)}getToolNames(){return Array.from(this.toolPool.keys())}getToolCount(){return this.toolPool.size}async executeTool(e,t,r,n){let s=this.toolPool.get(e);if(!s)throw new Error(`Tool not found: ${e}`);return s.execute(t,r,n)}getTools(){return Array.from(this.toolPool.values()).filter(e=>e.isEnabled?.()!==!1)}getToolManifest(){let e=[];for(let t of this.toolPool.values()){if(t.isEnabled?.()===!1)continue;let r=q(t);r==="write"&&(t.category==="media"||t.category==="web"||t.category==="mcp"?r="external_egress":(t.category==="system"||t.name==="exec"||t.name==="computer")&&(r="system")),e.push({type:"function",function:{name:t.name,description:t.description,parameters:t.parameters},meta:{category:t.category??"other",displayName:t.displayName??{key:`capability.tool.${t.name}.name`,fallback:t.label},displayDescription:t.displayDescription??{key:`capability.tool.${t.name}.description`,fallback:""},parallelSafe:t.isConcurrencySafe??!1,riskLevel:r,isReadOnly:r==="read",isDangerous:r==="system",isDelete:t.isDelete??!1,isEgress:t.isEgress??r==="external_egress",egressCarriesData:t.egressCarriesData??!1}})}return e}},W=new T;function F(o){W.addTools(o)}function G(o){return W.removeTool(o)}var Pe=new Set(["describe","fetch","find","get","inspect","list","query","read","search","stat"]),Ce=new Set(["append","copy","create","delete","edit","move","patch","remove","rename","set","update","upload","write"]);function B(o){let e=o.annotations,t=xe(o.name),r=t.some(l=>Ce.has(l)),n=t.some(l=>Pe.has(l)),s=e?.destructiveHint===!0||r,i=e?.readOnlyHint===!0||!s&&n,a=i||e?.idempotentHint===!0&&!s;return{isReadOnly:i,isConcurrencySafe:a,isDestructive:s}}function xe(o){return o.replace(/([a-z0-9])([A-Z])/g,"$1_$2").toLowerCase().split(/[^a-z0-9]+/).filter(Boolean)}var Ee=12e4,w=3,Me=1e3;async function De(o,e){let t=e.sleep??(s=>new Promise(i=>setTimeout(i,s))),r=Math.max(1,e.attempts),n;for(let s=1;s<=r;s++)try{return await o()}catch(i){n=i,s<r&&(e.onRetry?.(s,i),await t(e.baseDelayMs*s))}throw n}var g=class{runtime=null;definitions=[];toolsByServer=new Map;injectedNames=new Set;log;workspaceRoot;toolCatalog;serverToolFilters=new Map;serverOAuth=new Map;constructor(e){this.log=e.log??{info:()=>{},warn:()=>{}},this.workspaceRoot=e.workspaceRoot?p.resolve(e.workspaceRoot):void 0,this.toolCatalog=e.toolCatalog,this.definitions=e.servers.filter(t=>!t.disabled).filter(t=>{let r=ze(t);for(let n of r)this.log.warn(`[mcp] rejected server "${t.name}": ${n.message}`);return t.tools&&this.serverToolFilters.set(t.name,t.tools),t.oauth===!0&&this.serverOAuth.set(t.name,!0),r.length===0}).map(t=>this.toServerDefinition(t)).filter(t=>t!==null)}toServerDefinition(e){if((e.type??(e.url?"http":"stdio"))==="http"){if(!e.url)return this.log.warn(`[mcp] server "${e.name}" is type "http" but has no url, skipping`),null;let r;try{r=new URL(e.url)}catch{return this.log.warn(`[mcp] server "${e.name}" has an invalid url "${e.url}", skipping`),null}return{name:e.name,command:{kind:"http",url:r,headers:e.headers}}}return e.command?{name:e.name,command:{kind:"stdio",command:e.command,args:e.args??[],cwd:e.cwd??this.workspaceRoot??process.cwd()},env:e.env}:(this.log.warn(`[mcp] server "${e.name}" is type "stdio" but has no command, skipping`),null)}async connectAll(){this.definitions.length!==0&&(this.runtime=await Re({servers:this.definitions,clientInfo:{name:"qlogicagent",version:"1.0.0"},logger:{info:e=>this.log.info(`[mcp] ${e}`),warn:e=>this.log.warn(`[mcp] ${e}`),error:(e,t)=>this.log.warn(`[mcp] ${e}${t?` (${t instanceof Error?t.message:String(t)})`:""}`),debug:()=>{}}}),await Promise.allSettled(this.definitions.map(async e=>{try{let t=await De(()=>this.runtime.listTools(e.name,{includeSchema:!0,disableOAuth:this.serverOAuth.get(e.name)!==!0}),{attempts:w,baseDelayMs:Me,onRetry:(n,s)=>this.log.warn(`[mcp] connect attempt ${n}/${w} for ${e.name} failed, retrying: ${s instanceof Error?s.message:s}`)}),r=J(t,this.serverToolFilters.get(e.name));this.toolsByServer.set(e.name,r),this.log.info(`[mcp] connected to ${e.name} (${r.length}/${t.length} tools)`)}catch(t){this.log.warn(`[mcp] failed to connect to ${e.name} after ${w} attempts: ${t instanceof Error?t.message:t}`)}})))}injectTools(){for(let[e,t]of this.toolsByServer){let r=this.injectPortableTools(e,t);this.log.info(`[mcp] injected ${r.length} tools from ${e}`)}}async refreshServerTools(e){if(!this.runtime)throw new Error("MCP runtime is not connected");let t=await this.runtime.listTools(e,{includeSchema:!0,disableOAuth:this.serverOAuth.get(e)!==!0}),r=J(t,this.serverToolFilters.get(e));return this.toolsByServer.set(e,r),this.retractServerTools(e),this.injectPortableTools(e,r),r.length}getConnectedServers(){return Array.from(this.toolsByServer.keys())}getToolCount(){let e=0;for(let t of this.toolsByServer.values())e+=t.length;return e}async disconnectAll(){for(let t of this.injectedNames)this.removeRegisteredTool(t);this.injectedNames.clear(),this.toolsByServer.clear();let e=this.runtime;if(this.runtime=null,e)try{await e.close()}catch{}}toPortableTool(e,t){let r=B({name:t.name,description:t.description});return{name:`mcp__${H(e)}__${t.name}`,label:`[${e}] ${t.name}`,category:"mcp",description:t.description??`MCP tool from ${e}`,parameters:t.inputSchema??{type:"object",properties:{}},isConcurrencySafe:r.isConcurrencySafe,isReadOnly:r.isReadOnly,isDestructive:r.isDestructive,searchHint:`mcp ${e} ${t.name.replace(/[_-]+/g," ")}`,execute:async(n,s)=>{let i=this.runtime;if(!i)return{content:[{type:"text",text:`MCP server "${e}" is not connected.`}],details:{error:"mcp_not_connected"}};try{let a=await i.callTool(e,t.name,{args:s,timeoutMs:Ee});return Ie(a)}catch(a){let l=a instanceof Error?a.message:String(a);return{content:[{type:"text",text:`MCP tool error: ${l}`}],details:{error:l}}}}}}wrapToolsForWorkspaceBoundary(e){return this.workspaceRoot?e.map(t=>{if(!t.execute)return t;let r=t.execute;return{...t,execute:async(n,s,i)=>{let a=Le(t.name,s,this.workspaceRoot);return a?{content:[{type:"text",text:a}],details:{type:"mcp",error:"workspace_boundary"}}:r(n,s,i)}}}):e}injectPortableTools(e,t){let r=this.wrapToolsForWorkspaceBoundary(t.map(n=>this.toPortableTool(e,n)));this.registerTools(r);for(let n of r)this.injectedNames.add(n.name);return r}retractServerTools(e){let t=`mcp__${H(e)}__`;for(let r of[...this.injectedNames])r.startsWith(t)&&(this.removeRegisteredTool(r),this.injectedNames.delete(r))}registerTools(e){this.toolCatalog?this.toolCatalog.addTools(e):F(e)}removeRegisteredTool(e){return this.toolCatalog?.removeTool(e)??G(e)}};function Ie(o){let e=o&&typeof o=="object"?o:{};return{content:[{type:"text",text:(Array.isArray(e.content)?e.content:[]).filter(s=>!!s&&typeof s=="object").filter(s=>s.type==="text"&&typeof s.text=="string").map(s=>s.text).join(`
4
- `)||"(no text output)"}],...e.isError?{details:{error:"mcp_tool_error"}}:{}}}function H(o){return o.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}var je=/(?:^|_)(path|paths|file|files|filename|filenames|dir|dirs|directory|directories|folder|folders|cwd|root|uri)(?:$|_)/i;function Le(o,e,t){if(!t)return null;for(let r of S(e)){let n=$e(r.value,t);if(n&&!Ue(n.candidate,n.root,n.pathApi))return`Blocked: MCP tool "${o}" path "${r.value}" is outside the workspace boundary "${n.root}"`}return null}function S(o,e="",t=0){if(t>8)return[];if(typeof o=="string")return Oe(e,o)?[{key:e,value:o}]:[];if(Array.isArray(o))return o.flatMap(n=>S(n,e,t+1));if(!o||typeof o!="object")return[];let r=[];for(let[n,s]of Object.entries(o))r.push(...S(s,n,t+1));return r}function Oe(o,e){if(!je.test(o))return!1;let t=e.trim();return!t||/^https?:\/\//i.test(t)?!1:Ne(t)}function Ne(o){return p.isAbsolute(o)||/^[A-Za-z]:[\\/]/.test(o)||/^\\\\/.test(o)||/^file:\/\//i.test(o)||o.includes("../")||o.includes("..\\")||o.startsWith(".\\")||o.startsWith("./")||o.includes("/")||o.includes("\\")}function $e(o,e){let t=o.trim();if(/^file:\/\//i.test(t))try{t=Ae(t)}catch{return null}let r=z(t)||z(e)?p.win32:p,n=r.resolve(e);return{candidate:r.isAbsolute(t)?r.resolve(t):r.resolve(n,t),root:n,pathApi:r}}function Ue(o,e,t){let r=t.relative(e,o);return r===""||!r.startsWith("..")&&!t.isAbsolute(r)}function z(o){return/^[A-Za-z]:[\\/]/.test(o)||/^\\\\/.test(o)}function Q(o){if(!o||typeof o!="object")return[];let e=o,t=[],r=e.mcpServers??e.servers??e;for(let[n,s]of Object.entries(r)){if(!s||typeof s!="object")continue;let i=s;if(typeof i.url=="string"){t.push({name:n,type:"http",url:i.url,headers:i.headers&&typeof i.headers=="object"?i.headers:void 0,disabled:i.disabled===!0,oauth:i.oauth===!0,tools:V(i.tools)});continue}typeof i.command=="string"&&t.push({name:n,type:"stdio",command:i.command,args:Array.isArray(i.args)?i.args:void 0,env:i.env&&typeof i.env=="object"?i.env:void 0,cwd:typeof i.cwd=="string"?i.cwd:void 0,disabled:i.disabled===!0,oauth:i.oauth===!0,tools:V(i.tools)})}return t}function J(o,e){let t=new Set(e?.include??[]),r=new Set(e?.exclude??[]);return o.filter(n=>t.size>0&&!t.has(n.name)?!1:!r.has(n.name))}function V(o){if(!o||typeof o!="object")return;let e=o,t=K(e.include),r=K(e.exclude);if(!(!t&&!r))return{...t?{include:t}:{},...r?{exclude:r}:{}}}function K(o){if(!Array.isArray(o))return;let e=o.filter(t=>typeof t=="string"&&t.trim().length>0);return e.length>0?e:void 0}var qe=new Set(["bash","sh","zsh","fish","cmd","cmd.exe","powershell","powershell.exe","pwsh","pwsh.exe"]),We=new Set(["-c","/c","-command","-encodedcommand","-e"]),Fe=["curl","wget","invokewebrequest","invoke-restmethod","iwr","irm","nc","netcat"],Ge=["env","processenv","apikey","api_key","token","secret","credential","credentials","awsaccesskey","awssecret"],Be=["authorizedkeys","sshknownhosts","crontab","launchctl","schtasks","startup","runkey","runonce","bashrc","profile"],He=/\bssh-(?:rsa|ed25519|ecdsa-[^\s]+)\s+[A-Za-z0-9+/=]{40,}/i;function ze(o){let e=[],t=[o.command??"",...o.args??[],...Object.keys(o.env??{}),...Object.values(o.env??{})].join(`
5
- `);if(He.test(t)&&e.push({code:"ioc_public_key",message:"configuration contains an inline SSH public key IOC"}),(o.type??(o.url?"http":"stdio"))!=="stdio"||!Je(o.command))return e;let r=Ve(o.args??[]);if(!r)return e;let n=Ke(r);return v(n,Be)&&e.push({code:"persistence",message:"stdio shell command attempts a persistence write"}),v(n,Fe)&&v(n,Ge)&&e.push({code:"dangerous_egress",message:"stdio shell command combines network egress with likely secret access"}),e}function Je(o){if(!o)return!1;let e=p.basename(o).toLowerCase();return qe.has(e)}function Ve(o){for(let e=0;e<o.length;e++){let t=o[e]?.toLowerCase();if(t&&We.has(t))return o.slice(e+1).join(" ")}return""}function Ke(o){return o.toLowerCase().replace(/[^a-z0-9]+/g,"")}function v(o,e){return e.some(t=>o.includes(t))}var Xe=[{name:"skills_list",description:"List AstraClaw skills active for the current workspace.",inputSchema:{type:"object",properties:{},additionalProperties:!1}},{name:"skill_view",description:"Read the full SKILL.md instructions for one AstraClaw skill.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Skill name from skills_list."}},required:["name"],additionalProperties:!1}},{name:"mcp_connectors_list",description:"List MCP connector tools installed in AstraClaw's Plugins page and shared with this external agent.",inputSchema:{type:"object",properties:{},additionalProperties:!1}},{name:"mcp_tool_call",description:"Call one AstraClaw shared MCP connector tool by toolName from mcp_connectors_list.",inputSchema:{type:"object",properties:{toolName:{type:"string",description:"Connector tool name, for example mcp__filesystem__read_text_file."},args:{type:"object",description:"Arguments for the connector tool."}},required:["toolName"],additionalProperties:!1}}],_=class{tools=new Map;findTool(e){return this.tools.get(e)}getToolManifest(){return Array.from(this.tools.values()).map(e=>({type:"function",function:{name:e.name,description:e.description,parameters:e.parameters}}))}getToolNames(){return Array.from(this.tools.keys())}setTools(e){this.tools.clear(),this.addTools(e)}addTool(e){this.tools.set(e.name,e)}addTools(e){for(let t of e)this.addTool(t)}removeTool(e){return this.tools.delete(e)}},m=null,et=Qe({input:process.stdin,crlfDelay:Number.POSITIVE_INFINITY});et.on("line",o=>{tt(o)});async function tt(o){let e=o.trim();if(!e)return;let t;try{t=JSON.parse(e)}catch{return}if(t.id===void 0||t.id===null)return t.method==="notifications/initialized",void 0;try{let r=await ot(t);Z({jsonrpc:"2.0",id:t.id,result:r})}catch(r){Z({jsonrpc:"2.0",id:t.id,error:{code:-32603,message:r instanceof Error?r.message:String(r)}})}}async function ot(o){switch(o.method){case"initialize":return{protocolVersion:"2024-11-05",capabilities:{tools:{}},serverInfo:{name:N,version:"1.0.0"}};case"tools/list":return{tools:Xe};case"tools/call":{let e=Y(o.params),t=typeof e.name=="string"?e.name:"",r=Y(e.arguments),n=rt(),s=t==="mcp_connectors_list"||t==="mcp_tool_call"?await nt(n):void 0,i=await $({tool:t,args:r,projectRoot:n,toolCatalog:s});if(!i.handled)throw new Error(`Unknown tool: ${t}`);return{content:[{type:"text",text:JSON.stringify(i.result)}]}}default:throw new Error(`Unknown method: ${o.method}`)}}function rt(){return process.env.ASTRACLAW_PROJECT_ROOT||process.env.QLOGICAGENT_PROJECT_ROOT||process.cwd()}async function nt(o){if(m?.projectRoot===o)return await m.ready,m.catalog;m?.manager?.disconnectAll().catch(()=>{});let e=new _,t=new g({servers:st(),workspaceRoot:o,toolCatalog:e,log:{info:n=>process.stderr.write(`${n}
2
+ import{createInterface as Qe}from"node:readline";import{existsSync as Ye,readFileSync as Ze}from"node:fs";import{readFileSync as be}from"node:fs";import{randomUUID as ve}from"node:crypto";import{readdirSync as kt,readFileSync as Pt,statSync as ne,writeFileSync as _t}from"node:fs";import{readdir as se,readFile as ie,stat as ae,writeFile as le}from"node:fs/promises";import{join as u}from"node:path";import{homedir as Q}from"node:os";import{join as c,resolve as lt}from"node:path";import{existsSync as ut}from"node:fs";import{createHash as mt}from"node:crypto";var k=".qlogicagent";function Y(){return process.env.QLOGICAGENT_HOME||c(Q(),k)}function Z(){let t=process.env.QLOGIC_LLMROUTER_USER_ID?.trim();if(t)return t;let e=process.env.QLOGIC_IMPLICIT_OWNER_ID?.trim();if(e)return e;let o=process.env.QLOGIC_DEVICE_ID?.trim();return o?`oc_${o}`:"oc_local"}function X(t){let e=t.trim();if(!e)throw new Error("ownerUserId is required for profile-scoped storage");return encodeURIComponent(e).replace(/\./g,"%2E")}function p(t=Z()){return c(Y(),"profiles",X(t))}function h(){return c(p(),"skills")}function P(){return c(p(),"mcp.json")}function ee(t){if(!t)throw new Error("getProjectAgentDir: cwd is required (must not fall back to process.cwd())");return c(t,k)}function _(t){return c(ee(t),"skills-disabled.json")}import{readFileSync as te,writeFileSync as gt,mkdirSync as ht,renameSync as yt}from"node:fs";import{dirname as vt,join as oe}from"node:path";function C(){return{version:1,disabled:[]}}function x(t){try{let e=JSON.parse(te(t,"utf8"));return!e||typeof e!="object"||!Array.isArray(e.disabled)?C():{version:1,disabled:[...new Set(e.disabled.filter(r=>typeof r=="string"&&r.trim().length>0))]}}catch{return C()}}function re(){return oe(p(),"skills-disabled.json")}function A(){return new Set(x(re()).disabled)}function R(t){return new Set(x(_(t)).disabled)}var ce=["auto-skill-","test-skill-"],ue=".skills_prompt_snapshot.json";function de(t){return ce.some(e=>t.startsWith(e))}function me(t){let e=t.replace(/\r\n/g,`
3
+ `),o=e.match(/^---\n[\s\S]*?^version:\s*(\S+)/m),r=e.match(/^---\n[\s\S]*?^description:\s*(.+)/m),n=e.match(/^---\n[\s\S]*?^category:\s*(.+)/m),i=e.match(/^---\n[\s\S]*?^author:\s*(.+)/m),s=e.match(/^---\n[\s\S]*?^requires:\s*(.+)/m),a=e.match(/^---\n[\s\S]*?^environments:\s*(.+)/m);return{version:o?.[1],description:r?.[1]?.trim(),category:n?.[1]?.trim()||void 0,author:i?.[1]?.trim()||void 0,requiredTools:E(s?.[1]),environments:E(a?.[1])}}var M=new Map,y=new Map;function pe(t,e,o,r){let n=e.has(t.name),i=o.has(t.name),s=!he(t.meta,r);return{name:t.name,filePath:t.filePath,baseDir:t.baseDir,globallyDisabled:n,projectDisabled:i,active:!n&&!i&&!s,systemGenerated:t.systemGenerated,description:t.meta.description,version:t.meta.version,category:t.meta.category,author:t.meta.author,requiredTools:t.meta.requiredTools,environments:t.meta.environments}}async function fe(t){let e;try{e=await se(t,{withFileTypes:!0})}catch{e=[]}let o=[];for(let s of e){if(!s.isDirectory()||s.name.startsWith("."))continue;let a=u(t,s.name),l=u(a,"SKILL.md");try{let g=await ae(l);if(!g.isFile())continue;o.push({name:s.name,filePath:l,baseDir:a,mtimeMs:g.mtimeMs,size:g.size})}catch{continue}}o.sort((s,a)=>s.name.localeCompare(a.name));let r=o.map(s=>`${s.name}:${s.mtimeMs}:${s.size}`).join("|"),n=M.get(t);if(n&&n.fingerprint===r)return n.raw;let i=[];for(let s of o){let a;try{a=await ie(s.filePath,"utf8")}catch{continue}i.push({name:s.name,filePath:s.filePath,baseDir:s.baseDir,systemGenerated:de(s.name),mtimeMs:s.mtimeMs,size:s.size,meta:me(a)})}return M.set(t,{fingerprint:r,raw:i}),ye(t,i),i}async function ge(t,e){let o=h(),r=A(),n=t?R(t):new Set,i=y.get(o);return i||(i=fe(o).finally(()=>y.delete(o)),y.set(o,i)),(await i).map(a=>pe(a,r,n,e))}async function D(t,e){return(await ge(t,e)).filter(o=>o.active)}function I(t){let e=h(),o=u(e,t),r=u(o,"SKILL.md");try{if(ne(r).isFile())return{baseDir:o,filePath:r}}catch{}return null}function E(t){if(!t)return;let e=t.replace(/^\[|\]$/g,"").split(/[,\s]+/).map(o=>o.replace(/^["']|["']$/g,"").trim()).filter(Boolean);return e.length>0?e:void 0}function he(t,e){if(t.environments&&e?.currentEnvironment&&!t.environments.includes(e.currentEnvironment))return!1;if(t.requiredTools){if(!e?.availableToolNames)return!1;let o=new Set(e.availableToolNames);return t.requiredTools.every(r=>o.has(r))}return!0}async function ye(t,e){try{let r={version:1,entries:e.map(n=>({name:n.name,size:n.size,mtimeMs:n.mtimeMs,description:n.meta.description,version:n.meta.version,requiredTools:n.meta.requiredTools,environments:n.meta.environments}))};await le(u(t,ue),JSON.stringify(r,null,2),"utf8")}catch{}}var j="astraclaw_capabilities";async function L(t){if(t.tool==="skills_list")return{handled:!0,result:{skills:(await D(t.projectRoot,{availableToolNames:t.availableToolNames,currentEnvironment:t.currentEnvironment??process.platform})).map(we)}};if(t.tool==="skill_view"){let e=typeof t.args.name=="string"?t.args.name.trim():"";if(!e)throw new Error("skill_view requires a skill name");let o=I(e);if(!o)throw new Error(`Skill not found: ${e}`);return{handled:!0,result:{name:e,content:be(o.filePath,"utf8")}}}if(t.tool==="mcp_connectors_list"){if(!t.toolCatalog)return{handled:!0,result:{tools:[],note:"AstraClaw MCP connector catalog is not attached to this capability server instance."}};let e=t.toolCatalog.getToolManifest().filter(o=>o.function.name.startsWith("mcp__")).map(o=>({toolName:o.function.name,server:Se(o.function.name),name:ke(o.function.name),description:o.function.description,inputSchema:o.function.parameters}));return{handled:!0,result:{tools:e,count:e.length}}}if(t.tool==="mcp_tool_call"){if(!t.toolCatalog)throw new Error("AstraClaw MCP connector catalog is not attached");let e=typeof t.args.toolName=="string"?t.args.toolName.trim():"";if(!e.startsWith("mcp__"))throw new Error("mcp_tool_call requires a connector toolName returned by mcp_connectors_list");let o=t.toolCatalog.findTool(e);if(!o?.execute)throw new Error(`MCP connector tool not found or not executable: ${e}`);let r=Te(t.args.args),n=`astraclaw_mcp_${ve().slice(0,8)}`,i=await o.execute(n,r);return{handled:!0,result:{toolName:e,content:i.content,details:i.details,imageUrls:i.imageUrls}}}return{handled:!1}}function we(t){return{name:t.name,description:t.description,version:t.version,category:t.category,requiredTools:t.requiredTools,environments:t.environments}}function Te(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)?t:{}}function Se(t){let e=t.split("__");return e.length>=3?e[1]??"":""}function ke(t){let e=t.split("__");return e.length>=3?e.slice(2).join("__"):t}import d from"node:path";import{fileURLToPath as Ae}from"node:url";import{createRuntime as Re}from"mcporter";var O=new Set(["gateway","agents_list","session_status","sessions_send","sessions_list","sessions_history","sessions_spawn","cron","config","workflow"]),Pe=new Set([...O,"agent"]);function N(t){return t?.riskLevel?t.riskLevel:t?.isDangerous?"system":t?.isReadOnly?"read":t?.isEgress?"external_egress":"write"}var b=class{toolPool=new Map;setTools(e){this.toolPool.clear();for(let o of e)this.toolPool.set(o.name,o)}addTool(e){this.toolPool.set(e.name,e)}addTools(e){for(let o of e)this.addTool(o)}removeTool(e){return this.toolPool.delete(e)}findTool(e){return this.toolPool.get(e)}hasTool(e){return this.toolPool.has(e)}getToolNames(){return Array.from(this.toolPool.keys())}getToolCount(){return this.toolPool.size}async executeTool(e,o,r,n){let i=this.toolPool.get(e);if(!i)throw new Error(`Tool not found: ${e}`);return i.execute(o,r,n)}getTools(){return Array.from(this.toolPool.values()).filter(e=>e.isEnabled?.()!==!1)}getToolManifest(){let e=[];for(let o of this.toolPool.values()){if(o.isEnabled?.()===!1)continue;let r=N(o);r==="write"&&(o.category==="media"||o.category==="web"||o.category==="mcp"?r="external_egress":(o.category==="system"||o.name==="exec")&&(r="system")),e.push({type:"function",function:{name:o.name,description:o.description,parameters:o.parameters},meta:{category:o.category??"other",displayName:o.displayName??{key:`capability.tool.${o.name}.name`,fallback:o.label},displayDescription:o.displayDescription??{key:`capability.tool.${o.name}.description`,fallback:""},parallelSafe:o.isConcurrencySafe??!1,riskLevel:r,isReadOnly:r==="read",isDangerous:r==="system",isDelete:o.isDelete??!1,isEgress:o.isEgress??r==="external_egress",egressCarriesData:o.egressCarriesData??!1}})}return e}},$=new b;function q(t){$.addTools(t)}function U(t){return $.removeTool(t)}var _e=new Set(["describe","fetch","find","get","inspect","list","query","read","search","stat"]),Ce=new Set(["append","copy","create","delete","edit","move","patch","remove","rename","set","update","upload","write"]);function F(t){let e=t.annotations,o=xe(t.name),r=o.some(l=>Ce.has(l)),n=o.some(l=>_e.has(l)),i=e?.destructiveHint===!0||r,s=e?.readOnlyHint===!0||!i&&n,a=s||e?.idempotentHint===!0&&!i;return{isReadOnly:s,isConcurrencySafe:a,isDestructive:i}}function xe(t){return t.replace(/([a-z0-9])([A-Z])/g,"$1_$2").toLowerCase().split(/[^a-z0-9]+/).filter(Boolean)}var Me=12e4,v=3,Ee=1e3;async function De(t,e){let o=e.sleep??(i=>new Promise(s=>setTimeout(s,i))),r=Math.max(1,e.attempts),n;for(let i=1;i<=r;i++)try{return await t()}catch(s){n=s,i<r&&(e.onRetry?.(i,s),await o(e.baseDelayMs*i))}throw n}var f=class{runtime=null;definitions=[];toolsByServer=new Map;injectedNames=new Set;log;workspaceRoot;toolCatalog;serverToolFilters=new Map;serverOAuth=new Map;constructor(e){this.log=e.log??{info:()=>{},warn:()=>{}},this.workspaceRoot=e.workspaceRoot?d.resolve(e.workspaceRoot):void 0,this.toolCatalog=e.toolCatalog,this.definitions=e.servers.filter(o=>!o.disabled).filter(o=>{let r=He(o);for(let n of r)this.log.warn(`[mcp] rejected server "${o.name}": ${n.message}`);return o.tools&&this.serverToolFilters.set(o.name,o.tools),o.oauth===!0&&this.serverOAuth.set(o.name,!0),r.length===0}).map(o=>this.toServerDefinition(o)).filter(o=>o!==null)}toServerDefinition(e){if((e.type??(e.url?"http":"stdio"))==="http"){if(!e.url)return this.log.warn(`[mcp] server "${e.name}" is type "http" but has no url, skipping`),null;let r;try{r=new URL(e.url)}catch{return this.log.warn(`[mcp] server "${e.name}" has an invalid url "${e.url}", skipping`),null}return{name:e.name,command:{kind:"http",url:r,headers:e.headers}}}return e.command?{name:e.name,command:{kind:"stdio",command:e.command,args:e.args??[],cwd:e.cwd??this.workspaceRoot??process.cwd()},env:e.env}:(this.log.warn(`[mcp] server "${e.name}" is type "stdio" but has no command, skipping`),null)}async connectAll(){this.definitions.length!==0&&(this.runtime=await Re({servers:this.definitions,clientInfo:{name:"qlogicagent",version:"1.0.0"},logger:{info:e=>this.log.info(`[mcp] ${e}`),warn:e=>this.log.warn(`[mcp] ${e}`),error:(e,o)=>this.log.warn(`[mcp] ${e}${o?` (${o instanceof Error?o.message:String(o)})`:""}`),debug:()=>{}}}),await Promise.allSettled(this.definitions.map(async e=>{try{let o=await De(()=>this.runtime.listTools(e.name,{includeSchema:!0,disableOAuth:this.serverOAuth.get(e.name)!==!0}),{attempts:v,baseDelayMs:Ee,onRetry:(n,i)=>this.log.warn(`[mcp] connect attempt ${n}/${v} for ${e.name} failed, retrying: ${i instanceof Error?i.message:i}`)}),r=z(o,this.serverToolFilters.get(e.name));this.toolsByServer.set(e.name,r),this.log.info(`[mcp] connected to ${e.name} (${r.length}/${o.length} tools)`)}catch(o){this.log.warn(`[mcp] failed to connect to ${e.name} after ${v} attempts: ${o instanceof Error?o.message:o}`)}})))}injectTools(){for(let[e,o]of this.toolsByServer){let r=this.injectPortableTools(e,o);this.log.info(`[mcp] injected ${r.length} tools from ${e}`)}}async refreshServerTools(e){if(!this.runtime)throw new Error("MCP runtime is not connected");let o=await this.runtime.listTools(e,{includeSchema:!0,disableOAuth:this.serverOAuth.get(e)!==!0}),r=z(o,this.serverToolFilters.get(e));return this.toolsByServer.set(e,r),this.retractServerTools(e),this.injectPortableTools(e,r),r.length}getConnectedServers(){return Array.from(this.toolsByServer.keys())}getToolCount(){let e=0;for(let o of this.toolsByServer.values())e+=o.length;return e}async disconnectAll(){for(let o of this.injectedNames)this.removeRegisteredTool(o);this.injectedNames.clear(),this.toolsByServer.clear();let e=this.runtime;if(this.runtime=null,e)try{await e.close()}catch{}}toPortableTool(e,o){let r=F({name:o.name,description:o.description});return{name:`mcp__${G(e)}__${o.name}`,label:`[${e}] ${o.name}`,category:"mcp",description:o.description??`MCP tool from ${e}`,parameters:o.inputSchema??{type:"object",properties:{}},isConcurrencySafe:r.isConcurrencySafe,isReadOnly:r.isReadOnly,isDestructive:r.isDestructive,searchHint:`mcp ${e} ${o.name.replace(/[_-]+/g," ")}`,execute:async(n,i)=>{let s=this.runtime;if(!s)return{content:[{type:"text",text:`MCP server "${e}" is not connected.`}],details:{error:"mcp_not_connected"}};try{let a=await s.callTool(e,o.name,{args:i,timeoutMs:Me});return Ie(a)}catch(a){let l=a instanceof Error?a.message:String(a);return{content:[{type:"text",text:`MCP tool error: ${l}`}],details:{error:l}}}}}}wrapToolsForWorkspaceBoundary(e){return this.workspaceRoot?e.map(o=>{if(!o.execute)return o;let r=o.execute;return{...o,execute:async(n,i,s)=>{let a=Le(o.name,i,this.workspaceRoot);return a?{content:[{type:"text",text:a}],details:{type:"mcp",error:"workspace_boundary"}}:r(n,i,s)}}}):e}injectPortableTools(e,o){let r=this.wrapToolsForWorkspaceBoundary(o.map(n=>this.toPortableTool(e,n)));this.registerTools(r);for(let n of r)this.injectedNames.add(n.name);return r}retractServerTools(e){let o=`mcp__${G(e)}__`;for(let r of[...this.injectedNames])r.startsWith(o)&&(this.removeRegisteredTool(r),this.injectedNames.delete(r))}registerTools(e){this.toolCatalog?this.toolCatalog.addTools(e):q(e)}removeRegisteredTool(e){return this.toolCatalog?.removeTool(e)??U(e)}};function Ie(t){let e=t&&typeof t=="object"?t:{};return{content:[{type:"text",text:(Array.isArray(e.content)?e.content:[]).filter(i=>!!i&&typeof i=="object").filter(i=>i.type==="text"&&typeof i.text=="string").map(i=>i.text).join(`
4
+ `)||"(no text output)"}],...e.isError?{details:{error:"mcp_tool_error"}}:{}}}function G(t){return t.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}var je=/(?:^|_)(path|paths|file|files|filename|filenames|dir|dirs|directory|directories|folder|folders|cwd|root|uri)(?:$|_)/i;function Le(t,e,o){if(!o)return null;for(let r of T(e)){let n=$e(r.value,o);if(n&&!qe(n.candidate,n.root,n.pathApi))return`Blocked: MCP tool "${t}" path "${r.value}" is outside the workspace boundary "${n.root}"`}return null}function T(t,e="",o=0){if(o>8)return[];if(typeof t=="string")return Oe(e,t)?[{key:e,value:t}]:[];if(Array.isArray(t))return t.flatMap(n=>T(n,e,o+1));if(!t||typeof t!="object")return[];let r=[];for(let[n,i]of Object.entries(t))r.push(...T(i,n,o+1));return r}function Oe(t,e){if(!je.test(t))return!1;let o=e.trim();return!o||/^https?:\/\//i.test(o)?!1:Ne(o)}function Ne(t){return d.isAbsolute(t)||/^[A-Za-z]:[\\/]/.test(t)||/^\\\\/.test(t)||/^file:\/\//i.test(t)||t.includes("../")||t.includes("..\\")||t.startsWith(".\\")||t.startsWith("./")||t.includes("/")||t.includes("\\")}function $e(t,e){let o=t.trim();if(/^file:\/\//i.test(o))try{o=Ae(o)}catch{return null}let r=W(o)||W(e)?d.win32:d,n=r.resolve(e);return{candidate:r.isAbsolute(o)?r.resolve(o):r.resolve(n,o),root:n,pathApi:r}}function qe(t,e,o){let r=o.relative(e,t);return r===""||!r.startsWith("..")&&!o.isAbsolute(r)}function W(t){return/^[A-Za-z]:[\\/]/.test(t)||/^\\\\/.test(t)}function J(t){if(!t||typeof t!="object")return[];let e=t,o=[],r=e.mcpServers??e.servers??e;for(let[n,i]of Object.entries(r)){if(!i||typeof i!="object")continue;let s=i;if(typeof s.url=="string"){o.push({name:n,type:"http",url:s.url,headers:s.headers&&typeof s.headers=="object"?s.headers:void 0,disabled:s.disabled===!0,oauth:s.oauth===!0,tools:B(s.tools)});continue}typeof s.command=="string"&&o.push({name:n,type:"stdio",command:s.command,args:Array.isArray(s.args)?s.args:void 0,env:s.env&&typeof s.env=="object"?s.env:void 0,cwd:typeof s.cwd=="string"?s.cwd:void 0,disabled:s.disabled===!0,oauth:s.oauth===!0,tools:B(s.tools)})}return o}function z(t,e){let o=new Set(e?.include??[]),r=new Set(e?.exclude??[]);return t.filter(n=>o.size>0&&!o.has(n.name)?!1:!r.has(n.name))}function B(t){if(!t||typeof t!="object")return;let e=t,o=H(e.include),r=H(e.exclude);if(!(!o&&!r))return{...o?{include:o}:{},...r?{exclude:r}:{}}}function H(t){if(!Array.isArray(t))return;let e=t.filter(o=>typeof o=="string"&&o.trim().length>0);return e.length>0?e:void 0}var Ue=new Set(["bash","sh","zsh","fish","cmd","cmd.exe","powershell","powershell.exe","pwsh","pwsh.exe"]),Fe=new Set(["-c","/c","-command","-encodedcommand","-e"]),Ge=["curl","wget","invokewebrequest","invoke-restmethod","iwr","irm","nc","netcat"],We=["env","processenv","apikey","api_key","token","secret","credential","credentials","awsaccesskey","awssecret"],ze=["authorizedkeys","sshknownhosts","crontab","launchctl","schtasks","startup","runkey","runonce","bashrc","profile"],Be=/\bssh-(?:rsa|ed25519|ecdsa-[^\s]+)\s+[A-Za-z0-9+/=]{40,}/i;function He(t){let e=[],o=[t.command??"",...t.args??[],...Object.keys(t.env??{}),...Object.values(t.env??{})].join(`
5
+ `);if(Be.test(o)&&e.push({code:"ioc_public_key",message:"configuration contains an inline SSH public key IOC"}),(t.type??(t.url?"http":"stdio"))!=="stdio"||!Je(t.command))return e;let r=Ve(t.args??[]);if(!r)return e;let n=Ke(r);return w(n,ze)&&e.push({code:"persistence",message:"stdio shell command attempts a persistence write"}),w(n,Ge)&&w(n,We)&&e.push({code:"dangerous_egress",message:"stdio shell command combines network egress with likely secret access"}),e}function Je(t){if(!t)return!1;let e=d.basename(t).toLowerCase();return Ue.has(e)}function Ve(t){for(let e=0;e<t.length;e++){let o=t[e]?.toLowerCase();if(o&&Fe.has(o))return t.slice(e+1).join(" ")}return""}function Ke(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"")}function w(t,e){return e.some(o=>t.includes(o))}var Xe=[{name:"skills_list",description:"List AstraClaw skills active for the current workspace.",inputSchema:{type:"object",properties:{},additionalProperties:!1}},{name:"skill_view",description:"Read the full SKILL.md instructions for one AstraClaw skill.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Skill name from skills_list."}},required:["name"],additionalProperties:!1}},{name:"mcp_connectors_list",description:"List MCP connector tools installed in AstraClaw's Plugins page and shared with this external agent.",inputSchema:{type:"object",properties:{},additionalProperties:!1}},{name:"mcp_tool_call",description:"Call one AstraClaw shared MCP connector tool by toolName from mcp_connectors_list.",inputSchema:{type:"object",properties:{toolName:{type:"string",description:"Connector tool name, for example mcp__filesystem__read_text_file."},args:{type:"object",description:"Arguments for the connector tool."}},required:["toolName"],additionalProperties:!1}}],S=class{tools=new Map;findTool(e){return this.tools.get(e)}getToolManifest(){return Array.from(this.tools.values()).map(e=>({type:"function",function:{name:e.name,description:e.description,parameters:e.parameters}}))}getToolNames(){return Array.from(this.tools.keys())}setTools(e){this.tools.clear(),this.addTools(e)}addTool(e){this.tools.set(e.name,e)}addTools(e){for(let o of e)this.addTool(o)}removeTool(e){return this.tools.delete(e)}},m=null,et=Qe({input:process.stdin,crlfDelay:Number.POSITIVE_INFINITY});et.on("line",t=>{tt(t)});async function tt(t){let e=t.trim();if(!e)return;let o;try{o=JSON.parse(e)}catch{return}if(o.id===void 0||o.id===null)return o.method==="notifications/initialized",void 0;try{let r=await ot(o);K({jsonrpc:"2.0",id:o.id,result:r})}catch(r){K({jsonrpc:"2.0",id:o.id,error:{code:-32603,message:r instanceof Error?r.message:String(r)}})}}async function ot(t){switch(t.method){case"initialize":return{protocolVersion:"2024-11-05",capabilities:{tools:{}},serverInfo:{name:j,version:"1.0.0"}};case"tools/list":return{tools:Xe};case"tools/call":{let e=V(t.params),o=typeof e.name=="string"?e.name:"",r=V(e.arguments),n=rt(),i=o==="mcp_connectors_list"||o==="mcp_tool_call"?await nt(n):void 0,s=await L({tool:o,args:r,projectRoot:n,toolCatalog:i});if(!s.handled)throw new Error(`Unknown tool: ${o}`);return{content:[{type:"text",text:JSON.stringify(s.result)}]}}default:throw new Error(`Unknown method: ${t.method}`)}}function rt(){return process.env.ASTRACLAW_PROJECT_ROOT||process.env.QLOGICAGENT_PROJECT_ROOT||process.cwd()}async function nt(t){if(m?.projectRoot===t)return await m.ready,m.catalog;m?.manager?.disconnectAll().catch(()=>{});let e=new S,o=new f({servers:st(),workspaceRoot:t,toolCatalog:e,log:{info:n=>process.stderr.write(`${n}
6
6
  `),warn:n=>process.stderr.write(`${n}
7
- `)}}),r=t.connectAll().then(()=>t.injectTools());return m={projectRoot:o,catalog:e,manager:t,ready:r},await r,e}function st(){let o=process.env.ASTRACLAW_MCP_CONFIG_PATH||A();if(!Ye(o))return[];try{let e=Ze(o,"utf8").replace(/^\uFEFF/,"");return Q(JSON.parse(e))}catch(e){return process.stderr.write(`[astraclaw-native-mcp] failed to read MCP config: ${e instanceof Error?e.message:String(e)}
8
- `),[]}}function Y(o){return typeof o=="object"&&o!==null&&!Array.isArray(o)?o:{}}function Z(o){process.stdout.write(`${JSON.stringify(o)}
7
+ `)}}),r=o.connectAll().then(()=>o.injectTools());return m={projectRoot:t,catalog:e,manager:o,ready:r},await r,e}function st(){let t=process.env.ASTRACLAW_MCP_CONFIG_PATH||P();if(!Ye(t))return[];try{let e=Ze(t,"utf8").replace(/^\uFEFF/,"");return J(JSON.parse(e))}catch(e){return process.stderr.write(`[astraclaw-native-mcp] failed to read MCP config: ${e instanceof Error?e.message:String(e)}
8
+ `),[]}}function V(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)?t:{}}function K(t){process.stdout.write(`${JSON.stringify(t)}
9
9
  `)}
@@ -122,6 +122,18 @@ export interface FinalStatusReconciliation {
122
122
  /** A ```final-status block was present but not valid schema-1 JSON (treated as absent). */
123
123
  malformedBlock: boolean;
124
124
  }
125
+ /**
126
+ * Locale for engine-authored final-status content. Only the fixed wording skeleton is localized;
127
+ * dynamic data (paths, tool names, counts, blocker reasons, evidence) is always verbatim.
128
+ * Model-authored claims are untouched — they already follow the conversation language.
129
+ */
130
+ export type EngineStatusLocale = "zh" | "en";
131
+ /**
132
+ * Derive the conversation locale from the LAST user message's text. Han characters → "zh",
133
+ * otherwise "en" (including when no string-content user message exists). Only the newest user
134
+ * turn matters, so engine status follows the language the user is currently writing in.
135
+ */
136
+ export declare function deriveConversationLocale(messages: readonly ChatMessage[]): EngineStatusLocale;
125
137
  export declare function reconcileFinalStatus(params: {
126
138
  content: string;
127
139
  /** From finalStatusContractApplies() over the turn's tool surface; inactive turns pass through untouched. */
@@ -138,4 +150,10 @@ export declare function reconcileFinalStatus(params: {
138
150
  activeTasks?: readonly TaskContractItem[];
139
151
  /** The turn ended on a forced/failure terminal rather than a clean model stop. */
140
152
  forcedStop?: boolean;
153
+ /**
154
+ * Conversation language for engine-authored content. Defaults to "en" so existing tests and
155
+ * non-Chinese sessions are unaffected. Model-authored claims ignore this — they already follow
156
+ * the conversation language.
157
+ */
158
+ locale?: EngineStatusLocale;
141
159
  }): FinalStatusReconciliation;
@@ -3,6 +3,7 @@ export { isEmptyToolResult } from "./tool-result-classification.js";
3
3
  export declare function findLastToolError(messages: unknown[], _toolName: string): string | undefined;
4
4
  export declare function looksLikeBuildRequest(messages?: readonly ChatMessage[]): boolean;
5
5
  export declare function isBareIntentPreamble(text: string): boolean;
6
+ export declare function isCapabilityDenial(text: string): boolean;
6
7
  export declare function resolveToolLoopBudget(requested?: number, messages?: readonly ChatMessage[]): number;
7
8
  export declare function countExplicitOutputArtifacts(messages?: readonly ChatMessage[]): number;
8
9
  export declare function resolveTotalToolCallBudget(requested?: number, messages?: readonly ChatMessage[]): number;
@@ -29,4 +30,12 @@ export declare function buildRepeatedToolFailureStopContent(messages: ChatMessag
29
30
  * the error put in front of it once. Returns null when there is no tool error to correct from.
30
31
  */
31
32
  export declare function buildToolFailureCorrectionNudge(messages: ChatMessage[]): ChatMessage | null;
33
+ /**
34
+ * exec 命令的"族"标识:程序名 + 子命令/脚本名(最多两段),用于 churn/变体失败
35
+ * 计数。审计 CASE2:按精确命令串 keying 时,每轮换一个转换/安装命令即可永远绕过
36
+ * 阈值 —— 按族计数后 "pip install A" / "pip install B" 归并为同一目标。
37
+ */
38
+ export declare function execCommandFamily(command: string): string;
39
+ export declare function isIterativeRunnerFamily(family: string): boolean;
40
+ export declare function isSetupOnlyExecCommand(command: string | null): boolean;
32
41
  export declare function summarizeToolInput(rawArgs: string): string | undefined;
@@ -109,19 +109,22 @@ export interface ToolLoopParams {
109
109
  /** Crossing this many actions on the SAME target within a turn flags a no-progress candidate. */
110
110
  export declare const NO_PROGRESS_TARGET_THRESHOLD = 4;
111
111
  /**
112
- * [lever 3 — observe-only] Identify the "target" a tool call acts on, for churn counting:
113
- * the file path for write/edit/patch, the normalized command for exec. Returns null for
112
+ * [lever 3] Identify the "target" a tool call acts on, for churn counting: the file path
113
+ * for write/edit/patch, the command FAMILY (program + subcommand/script) for exec with
114
+ * iterate-by-design runner families (test/build/lint/git) exempted, since repeatedly
115
+ * re-running those is a normal fix-verify cycle, not churn. Crossing the threshold now
116
+ * feeds an acting once-per-family nudge (plus recoveryTrace telemetry). Returns null for
114
117
  * tools whose repetition isn't a stuck-signal (read, search, etc.). Exported for testing.
115
118
  */
116
119
  export declare function noProgressTargetKey(toolName: string, rawArguments: string): string | null;
117
- export declare function buildBenchmarkStateMaintenanceInstruction(documents: ReadonlyMap<string, MaintainedDocumentIndex>, turn: number): string | null;
118
- export declare function benchmarkStateMaintenanceWriteValidation(maintainedDocuments: ReadonlyMap<string, MaintainedDocumentIndex>, filePath: string, rawArguments: string): {
120
+ export declare function buildLongHorizonStateMaintenanceInstruction(documents: ReadonlyMap<string, MaintainedDocumentIndex>, turn: number): string | null;
121
+ export declare function longHorizonStateMaintenanceWriteValidation(maintainedDocuments: ReadonlyMap<string, MaintainedDocumentIndex>, filePath: string, rawArguments: string): {
119
122
  ok: true;
120
123
  } | {
121
124
  ok: false;
122
125
  reason: string;
123
126
  };
124
- export declare function benchmarkStateHashIntegrityViolations(maintainedDocuments: ReadonlyMap<string, MaintainedDocumentIndex>): {
127
+ export declare function longHorizonStateHashIntegrityViolations(maintainedDocuments: ReadonlyMap<string, MaintainedDocumentIndex>): {
125
128
  path: string;
126
129
  reason: string;
127
130
  }[];
@@ -1,6 +1,13 @@
1
1
  import type { AcpSessionHost } from "./acp-session-host.js";
2
- import { type AcpInitializeParams, type AcpInitializeResult, type AcpSessionCloseParams, type AcpSessionLoadParams, type AcpSessionNewParams, type AcpSessionNewResult, type AcpSessionPromptParams, type AcpSessionPromptResult, type AcpSessionSetConfigParams } from "../protocol/wire/index.js";
2
+ import { type AcpInitializeParams, type AcpInitializeResult, type AcpSessionCloseParams, type AcpSessionLoadParams, type AcpSessionMeta, type AcpSessionNewParams, type AcpSessionNewResult, type AcpSessionPromptParams, type AcpSessionPromptResult, type AcpSessionSetConfigParams } from "../protocol/wire/index.js";
3
3
  export type { AcpSessionHost };
4
+ /**
5
+ * Resolve the _meta a prompt must inherit: prefer the meta registered for THIS session (session/new)
6
+ * over the per-connection singleton, so multiplexed sessions (desktop × WeChat on one connection)
7
+ * never swap each other's config. Falls back to the legacy singleton for unregistered sessions
8
+ * (old-gateway compat), then to an empty bag.
9
+ */
10
+ export declare function resolveSessionMetaForPrompt(host: AcpSessionHost, sessionId: string): AcpSessionMeta;
4
11
  export declare function handleAcpInitialize(host: AcpSessionHost, params: AcpInitializeParams, packageVersion: string): Promise<AcpInitializeResult>;
5
12
  export declare function handleAcpSessionNew(host: AcpSessionHost, params: AcpSessionNewParams): Promise<AcpSessionNewResult>;
6
13
  /**
@@ -19,8 +19,12 @@ export interface SessionLlmConfig {
19
19
  baseUrl?: string;
20
20
  }
21
21
  export interface AcpSessionHost {
22
- /** Gateway-supplied per-session context (_meta from session/new); inherited by every prompt. */
22
+ /** Gateway-supplied per-session context (_meta from session/new).
23
+ * LEGACY fallback: a per-CONNECTION singleton overwritten by the last session/new — kept only
24
+ * for old-gateway compat. Multiplexed connections must read via acpSessionMetaBySession instead. */
23
25
  acpSessionMeta: AcpSessionMeta | null;
26
+ /** Per-session gateway _meta(session/new 注册;prompt 按 sessionId 取,消除跨会话串扰)。 */
27
+ acpSessionMetaBySession: Map<string, AcpSessionMeta>;
24
28
  /** Host-pinned per-session LLM config; overlaid into every prompt's turn config. */
25
29
  sessionLlmConfig: SessionLlmConfig;
26
30
  currentHooks: HookRegistry | null;
@@ -5,4 +5,37 @@ export interface DefaultProjectBootstrapDeps {
5
5
  projectMemoryStoreFactory: ProjectMemoryStoreFactory;
6
6
  sendNotification<M extends keyof NotificationMethodMap>(method: M, params: NotificationMethodMap[M]): void;
7
7
  }
8
+ /**
9
+ * Slow, non-essential startup chores split OUT of the synchronous initialize path. Deferring these
10
+ * off the sync response of `initialize` is what keeps a concurrent `session.list` from being starved
11
+ * (T17-class bug: sync fs on Node's single thread blocks RPC dispatch until it finishes — here
12
+ * `gcOrphanProjectData`'s work is unbounded in the count of project dirs ever created on the box).
13
+ * Mirrors the AcpDetector.scanAsync precedent: move the blocking work off the hot path (here via one
14
+ * deferral to a later event-loop turn — not per-iteration setImmediate slicing). None of this is
15
+ * needed before session.list/session.prompt can be served —
16
+ * the default project already exists and is registered/active (that stays synchronous below), the
17
+ * seeded builtin skills only enrich the lazy progressive-disclosure catalog, and GC only reclaims
18
+ * orphaned companion dirs (never live data).
19
+ */
20
+ interface DeferredHeavyWork {
21
+ /** A default project was freshly created this run → its starter templates still need seeding. */
22
+ freshDefaultDir?: string;
23
+ }
24
+ /** Resolves once the most recently scheduled deferred heavy work has settled (never rejects). */
25
+ export declare function getDefaultProjectHeavyWorkPromise(): Promise<void>;
8
26
  export declare function ensureDefaultProjectBootstrap(deps: DefaultProjectBootstrapDeps): ProjectMemoryStore;
27
+ /**
28
+ * Schedule (fire-and-forget) the deferred heavy work so it runs off the synchronous initialize path.
29
+ * Exposed for tests; production calls it from ensureDefaultProjectBootstrap. Records a gate promise on
30
+ * `heavyWorkPromise` so a caller that must wait can, without any synchronous blocking of startup.
31
+ *
32
+ * Uses a single `setImmediate` — NOT setImmediate *slicing*: the entire block is deferred once to a
33
+ * later event-loop turn (the check phase after the next poll phase), so a `session.list` that was
34
+ * already queued on stdin is read and dispatched BEFORE this synchronous-fs block runs. A microtask
35
+ * would drain before returning to the poll phase and so would not let session.list through first.
36
+ * The block still starts with bounded synchronous fs (builtin-skill seed + template copy), so the
37
+ * macrotask boundary is what lets the queued session.list run before it; the unbounded orphan GC
38
+ * inside is itself async and yields between directories.
39
+ */
40
+ export declare function scheduleDefaultProjectHeavyWork(heavy: DeferredHeavyWork): void;
41
+ export {};
@@ -39,6 +39,12 @@ export declare function handleSessionUpdate(this: SessionHandlerHost, msg: Agent
39
39
  export declare function handleSessionDelete(this: SessionHandlerHost, msg: AgentRpcRequest): Promise<void>;
40
40
  export declare function handleSessionDeleteAll(this: SessionHandlerHost, msg: AgentRpcRequest): Promise<void>;
41
41
  export declare function handleSessionArchive(this: SessionHandlerHost, msg: AgentRpcRequest): Promise<void>;
42
+ /**
43
+ * L2 优雅关闭清标记:清所有 session 残留的 in-flight 标记(== hermes .clean_shutdown 语义)。
44
+ * gateway 优雅退出时在 adapter.dispose() 前调用,据此区分"优雅关闭"与"崩溃"——
45
+ * 启动扫描(L3)看到的残留标记因此一定是崩溃残留,不误报。无参、幂等。
46
+ */
47
+ export declare function handleSessionMarkCleanShutdown(this: SessionHandlerHost, msg: AgentRpcRequest): Promise<void>;
42
48
  export declare function handleSessionResume(this: SessionHandlerHost, msg: AgentRpcRequest): Promise<void>;
43
49
  export declare function handleSessionGetInfo(this: SessionHandlerHost, msg: AgentRpcRequest): void;
44
50
  export declare function handleSessionSwitchProject(this: SessionHandlerHost, msg: AgentRpcRequest): void;
@@ -2,6 +2,8 @@
2
2
  * Turn execution handlers — extracted from StdioServer.
3
3
  * Handles: the shared turn pipeline (runTurnPipeline) + thread.user_response (ask-user answers).
4
4
  */
5
+ import { type ModelPurpose } from "../../runtime/infra/model-registry.js";
6
+ import { type UnderstandMediaClient, type UnderstandMediaKind } from "../media-understanding.js";
5
7
  import type { PermissionMetadataResolver, ToolCatalog } from "../../runtime/ports/index.js";
6
8
  import type { ChatMessage, TokenUsage, ToolDefinition, TurnConfig } from "../../agent/types.js";
7
9
  import type { AgentRpcRequest } from "../../protocol/wire/agent-rpc.js";
@@ -17,6 +19,34 @@ export interface TurnControlHandlerHost {
17
19
  log(message: string): void;
18
20
  sendResponse(id: string | number, result?: unknown, error?: unknown): void;
19
21
  }
22
+ /**
23
+ * First-turn session-title generation, extracted so the caller can run it
24
+ * fire-and-forget (see run()). Behavior is identical to the previous inline
25
+ * block; the only change is that the LLM round-trip inside `generateTitle`
26
+ * no longer sits on the critical path before executeTurnCore.
27
+ *
28
+ * Dependencies are injected so this is a pure, testable unit:
29
+ * - `generateTitle` wraps generateSessionTitle (which keeps the deterministic
30
+ * fast-path internally — it is NOT bypassed here).
31
+ * - `fallbackTitle` wraps titleFromPromptFallback (applied when generation
32
+ * yields nothing).
33
+ * - `persistTitle` wraps updateSessionMetadata (swallowing its own errors).
34
+ *
35
+ * Returns a promise for the async work; callers that want fire-and-forget
36
+ * should `void` it (with a `.catch(() => {})` guard).
37
+ */
38
+ export interface FirstTurnTitleGenerationDeps {
39
+ existingTitle: string | undefined;
40
+ firstUserText: string;
41
+ sessionId: string;
42
+ projectId: string | undefined;
43
+ generateTitle(firstUserText: string): Promise<string | null>;
44
+ fallbackTitle(firstUserText: string): string;
45
+ persistTitle(title: string): Promise<void>;
46
+ sendNotification(method: string, params: Record<string, unknown>): void;
47
+ log(message: string): void;
48
+ }
49
+ export declare function runFirstTurnTitleGeneration(deps: FirstTurnTitleGenerationDeps): Promise<void>;
20
50
  export declare function hydrateTurnConfigFromModelMetadata(config: TurnConfig): TurnConfig;
21
51
  export declare function hydrateAttachmentReferenceUrlsForTurn(messages: ChatMessage[]): ChatMessage[];
22
52
  export declare function getFocusedAttachmentToolNamesForTurn(messages: ChatMessage[]): Set<string> | null;
@@ -47,6 +77,41 @@ export declare function getFocusedAttachmentModelPurposeForTurn(messages: ChatMe
47
77
  export declare function requiresPreToolPreambleForTurn(messages: readonly ChatMessage[]): boolean;
48
78
  export declare function refreshPermissionCheckerToolMeta(permissionChecker: PermissionMetadataResolver | null | undefined, tools: ToolDefinition[]): void;
49
79
  export declare function handleUserResponse(this: TurnControlHandlerHost, msg: AgentRpcRequest): void;
80
+ /**
81
+ * Pure: assemble the text appended to the user message after modality routing.
82
+ * `descriptorsByKind` are the successfully understood texts (in order per modality);
83
+ * `fallbackStripped` are the "X 张图片"-style labels for media that was dropped without
84
+ * understanding. Returns "" when there is nothing to inject.
85
+ *
86
+ * The understood blocks lead with a note stating they are model transcriptions; the
87
+ * "media omitted" note is appended ONLY for the fallback set, so a successful transcription
88
+ * is never contradicted by a blanket "media omitted" line.
89
+ */
90
+ export declare function buildUnderstoodInjection(descriptorsByKind: Record<UnderstandMediaKind, string[]>, fallbackStripped: string[]): string;
91
+ interface ModalityRegistryView {
92
+ acceptsInputModality(modality: string, purpose: ModelPurpose): boolean;
93
+ isAvailable(purpose: ModelPurpose): boolean;
94
+ }
95
+ interface RouteUnsupportedModalitiesDeps {
96
+ lastUserMsg: ChatMessage;
97
+ purpose: ModelPurpose;
98
+ registry: ModalityRegistryView;
99
+ resolveClient(purpose: ModelPurpose): UnderstandMediaClient | null;
100
+ signal?: AbortSignal;
101
+ log(message: string): void;
102
+ }
103
+ /**
104
+ * For each modality the resolved main model can't consume, route the media to its
105
+ * understanding model (image→imageUnderstanding, audio→stt, video→videoUnderstanding)
106
+ * and fold the returned text into the user message; media that can't be understood
107
+ * (model unavailable / call failed / empty / over the cap) degrades to the previous
108
+ * behavior (field dropped + omission note). The media field is ALWAYS deleted afterward
109
+ * — the main model still can't consume it, so leaving it would 400 the turn.
110
+ *
111
+ * Mutates `lastUserMsg` in place. Injection only touches string content (array content is
112
+ * left as-is, matching the prior behavior). Best-effort: never throws for a per-item failure.
113
+ */
114
+ export declare function routeUnsupportedModalitiesToUnderstanding(deps: RouteUnsupportedModalitiesDeps): Promise<void>;
50
115
  export interface TurnPipelineInput {
51
116
  turnId: string;
52
117
  sessionId: string;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Shared media-understanding — single source of truth for turning a non-text medium
3
+ * (image / audio / video) into plain text via the matching understanding model.
4
+ *
5
+ * Used by BOTH pipelines:
6
+ * - memory candidates (memory-candidate-service.ts): passes a base64 `data:` URL built
7
+ * from persisted attachment bytes.
8
+ * - the turn gate (handlers/turn-handler.ts): passes the local media-proxy URL already
9
+ * stamped onto the user message, so a medium the main model can't consume is routed
10
+ * to the understanding model and its description injected instead of dropped.
11
+ *
12
+ * The function is URL-agnostic on purpose: it just places whatever URL string it is given
13
+ * onto the modality-correct message field and streams the reply. It never reads attachment
14
+ * bytes and never persists anything — callers own storage/injection.
15
+ */
16
+ export type UnderstandMediaKind = "image" | "audio" | "video";
17
+ /** Maps each medium to the ModelPurpose that understands it. */
18
+ export declare const PURPOSE_BY_KIND: Record<UnderstandMediaKind, "imageUnderstanding" | "stt" | "videoUnderstanding">;
19
+ /** Maps each medium to the ChatMessage field the transport reads media URLs from. */
20
+ export declare const URL_FIELD_BY_KIND: Record<UnderstandMediaKind, "imageUrls" | "audioUrls" | "videoUrls">;
21
+ /** Per-medium instruction. Every kind is normalized to plain text so callers only swap a label. */
22
+ export declare const PROMPT_BY_KIND: Record<UnderstandMediaKind, string>;
23
+ /**
24
+ * A resolved understanding client. Structurally compatible with both the real LLMTransport
25
+ * (whose `stream` takes an optional third `signal` arg) and the memory client. Deliberately
26
+ * loose on the request/chunk shapes so it composes with either caller without import cycles.
27
+ */
28
+ export interface UnderstandMediaClient {
29
+ model: string;
30
+ apiKey: string;
31
+ transport: {
32
+ stream(request: Record<string, unknown>, apiKey: string, signal?: AbortSignal): AsyncIterable<{
33
+ type: string;
34
+ text?: string;
35
+ }>;
36
+ };
37
+ }
38
+ /**
39
+ * Understand a single medium at `url` and return the model's trimmed text (may be empty
40
+ * if the model produced nothing). Never throws for an empty reply — an empty string is a
41
+ * valid "no text" result the caller degrades on.
42
+ */
43
+ export declare function understandMediaUrl(client: UnderstandMediaClient, kind: UnderstandMediaKind, url: string, opts?: {
44
+ signal?: AbortSignal;
45
+ }): Promise<string>;
@@ -24,6 +24,10 @@ export declare class SessionContext {
24
24
  /** Host-pinned per-session LLM config (session/set_config_option · set_model · /model).
25
25
  * NEVER wiped by ModelRegistry churn — distinct from the DERIVED ResolvedAgentCache. */
26
26
  llmConfig: SessionLlmConfig;
27
- /** ACP session-level context supplement (_meta from session/new), inherited by every prompt. */
27
+ /** ACP session-level context supplement (_meta from session/new), inherited by every prompt.
28
+ * LEGACY per-connection singleton — kept for old-gateway fallback; multiplexed prompts read
29
+ * acpMetaBySession by sessionId instead. */
28
30
  acpMeta: Record<string, unknown> | null;
31
+ /** Per-session gateway _meta(按 sessionId 存,消除跨会话串扰)。 */
32
+ acpMetaBySession: Map<string, Record<string, unknown>>;
29
33
  }
@@ -6,7 +6,7 @@ import type { CliAcpRequestHandlerHost } from "./cli-acp-request-handler.js";
6
6
  * (`this: any`), so members it touches must be forwarded here explicitly;
7
7
  * see TURN_PIPELINE_HOST_MEMBERS for the regression-tested list.
8
8
  */
9
- export type StdioAcpRequestHostSource = Pick<CliAcpRequestHandlerHost, "activeTurn" | "acpSessionMeta" | "currentHooks" | "currentSessionId" | "currentTurnId" | "memoryPrefetchState" | "permissionChecker" | "sessionHistory" | "sessionLlmConfig" | "sessionState" | "cancelIdleDreamTimer" | "disposeSessionRuntime" | "enableIdleDream" | "ensureDefaultProject" | "ensureModelRegistryHydrated" | "getActiveProjectRoot" | "log" | "sendNotification" | "setActiveWorkdir"> & {
9
+ export type StdioAcpRequestHostSource = Pick<CliAcpRequestHandlerHost, "activeTurn" | "acpSessionMeta" | "acpSessionMetaBySession" | "currentHooks" | "currentSessionId" | "currentTurnId" | "memoryPrefetchState" | "permissionChecker" | "sessionHistory" | "sessionLlmConfig" | "sessionState" | "cancelIdleDreamTimer" | "disposeSessionRuntime" | "enableIdleDream" | "ensureDefaultProject" | "ensureModelRegistryHydrated" | "getActiveProjectRoot" | "log" | "sendNotification" | "setActiveWorkdir"> & {
10
10
  currentModel: string | undefined;
11
11
  lastAssistantMessageForExtract: string | undefined;
12
12
  lastUserMessageForAutoExtract: string | undefined;
@@ -117,6 +117,7 @@ export declare class StdioServer {
117
117
  set sessionLlmConfig(v: SessionLlmConfig);
118
118
  get acpSessionMeta(): Record<string, unknown> | null;
119
119
  set acpSessionMeta(v: Record<string, unknown> | null);
120
+ get acpSessionMetaBySession(): Map<string, Record<string, unknown>>;
120
121
  get currentHooks(): import("../contracts/hooks.js").HookRegistry | null;
121
122
  get permissionChecker(): AgentRuntimeSessionState["permissionChecker"];
122
123
  private set permissionChecker(value);
@@ -30,3 +30,5 @@ export declare function setGroupSecurityMode(enabled: boolean): void;
30
30
  export declare const localCoreToolRegistrationModule: import("../runtime/ports/tool-contracts.js").ToolRegistrationModule<LocalCoreToolRegistrationContext>;
31
31
  export declare function registerLocalCoreTools(context: LocalCoreToolRegistrationContext): void;
32
32
  export declare function validateExecCommand(command: string, workdir: string, groupMode?: boolean): string | null;
33
+ /** office/pdf 文档扩展名 → mime;非文档返回 undefined。导出仅为单测。 */
34
+ export declare function documentMimeForExtension(ext: string): string | undefined;
@@ -35,7 +35,7 @@ export interface CapabilityCatalogDeps {
35
35
  projectRoot: string;
36
36
  }
37
37
  /** Enumerate every capability a workflow in `projectRoot` can reference right now. */
38
- export declare function buildCapabilityCatalog(deps: CapabilityCatalogDeps): CapabilityEntry[];
38
+ export declare function buildCapabilityCatalog(deps: CapabilityCatalogDeps): Promise<CapabilityEntry[]>;
39
39
  /**
40
40
  * Compact catalog text for the AI graph builder's system prompt: category headers + `id — desc`
41
41
  * lines, hard-capped per category so huge tool sets don't blow the prompt (the agent uses the
@@ -215,5 +215,5 @@ export declare function defaultRuntimeFactory(opts: {
215
215
  checkpoint?: (workflowId: string, runId: string) => RunCheckpoint | undefined;
216
216
  now?: () => Date;
217
217
  /** Per-node lifecycle for live canvas coloring; workflowId comes from the run ctx. */
218
- emitNodeStatus?: (workflowId: string, nodeId: string, status: NodeRunStatus) => void;
218
+ emitNodeStatus?: (workflowId: string, nodeId: string, status: NodeRunStatus, error?: string) => void;
219
219
  }): RuntimeFactory;
@@ -96,7 +96,7 @@ export interface WorkflowRuntimeOptions {
96
96
  */
97
97
  preserveCheckpoint?: boolean;
98
98
  /** Per-node lifecycle callback for live status (canvas coloring). Fire-and-forget, not durable. */
99
- onNodeStatus?: (nodeId: string, status: "running" | "completed" | "failed") => void;
99
+ onNodeStatus?: (nodeId: string, status: "running" | "completed" | "failed", error?: string) => void;
100
100
  }
101
101
  export declare class WorkflowRuntime {
102
102
  private def;
@@ -6,4 +6,4 @@
6
6
  * This file re-exports the wire types.
7
7
  * Internal consumers import from this file — zero churn.
8
8
  */
9
- export type { AgentSource, AgentsErrorNotification, AgentsStatusNotification, ArtifactType, MediaResultType, MemoryDecayCompletedNotification, MemoryUpdatedNotification, NotificationMethod, NotificationMethodMap, NotificationThreadItem, PermissionRuleUpdatedNotification, PlanInterruptedNotification, PongNotification, ProductAgentActivityNotification, ProductBudgetUpdateNotification, ProductBudgetWarningNotification, ProductCheckpointedNotification, ProductCompletedNotification, ProductDagTopologyNotification, ProductMembersNotification, ProductPlanFailedNotification, ProductPlanningDeltaNotification, ProductPlanReadyNotification, ProductTaskCompletedNotification, ProductTaskFailedNotification, ProductTaskOutputDeltaNotification, ProductTaskStartedNotification, ProjectArchivedNotification, ProjectCreatedNotification, ProjectDeletedNotification, ProjectRenamedNotification, ProjectSwitchedNotification, ProjectUnarchivedNotification, SessionInfoNotification, SoloAgentDeltaNotification, SoloAgentUsageNotification, SoloEvaluationNotification, SoloProgressNotification, TeamMemberNotification, ToolApprovalRequestNotification, TurnAnnotationsNotification, TurnArtifactNotification, TurnAskUserNotification, TurnDeltaNotification, TurnEndNotification, TurnErrorNotification, TurnExecProgressNotification, TurnHeartbeatNotification, TurnMediaPersistedNotification, TurnMediaProgressNotification, TurnMediaResultNotification, TurnPlanUpdateNotification, TurnReasoningDeltaNotification, TurnRecoveryNotification, TurnSidechainCompletedNotification, TurnSidechainStartedNotification, TurnSkillInstructionNotification, TurnStartNotification, TurnSubagentDeltaNotification, TurnSuggestionsNotification, TurnTaskUpdatedNotification, TurnTodosUpdatedNotification, TurnToolBlockedNotification, TurnToolCallNotification, TurnToolResultNotification, TurnToolUseSummaryNotification, TurnUsageUpdateNotification, WireTokenUsage, } from "./wire/index.js";
9
+ export type { AgentSource, AgentsErrorNotification, AgentsStatusNotification, ArtifactType, MediaResultType, MemoryDecayCompletedNotification, MemoryUpdatedNotification, NotificationMethod, NotificationMethodMap, NotificationThreadItem, PermissionRuleUpdatedNotification, PlanInterruptedNotification, PongNotification, ProductAgentActivityNotification, ProductBudgetUpdateNotification, ProductBudgetWarningNotification, ProductCheckpointedNotification, ProductCompletedNotification, ProductDagTopologyNotification, ProductMembersNotification, ProductPlanFailedNotification, ProductPlanningDeltaNotification, ProductPlanReadyNotification, ProductTaskCompletedNotification, ProductTaskFailedNotification, ProductTaskOutputDeltaNotification, ProductTaskStartedNotification, ProjectArchivedNotification, ProjectCreatedNotification, ProjectDeletedNotification, ProjectRenamedNotification, ProjectSwitchedNotification, ProjectUnarchivedNotification, SessionInfoNotification, SessionRecoveryPendingNotification, SoloAgentDeltaNotification, SoloAgentUsageNotification, SoloEvaluationNotification, SoloProgressNotification, TeamMemberNotification, ToolApprovalRequestNotification, TurnAnnotationsNotification, TurnArtifactNotification, TurnAskUserNotification, TurnDeltaNotification, TurnEndNotification, TurnErrorNotification, TurnExecProgressNotification, TurnHeartbeatNotification, TurnMediaPersistedNotification, TurnMediaProgressNotification, TurnMediaResultNotification, TurnPlanUpdateNotification, TurnProgressNotification, TurnReasoningDeltaNotification, TurnRecoveryNotification, TurnSidechainCompletedNotification, TurnSidechainStartedNotification, TurnSkillInstructionNotification, TurnStartNotification, TurnSubagentDeltaNotification, TurnSuggestionsNotification, TurnTaskUpdatedNotification, TurnTodosUpdatedNotification, TurnToolBlockedNotification, TurnToolCallNotification, TurnToolResultNotification, TurnToolUseSummaryNotification, TurnUsageUpdateNotification, WireTokenUsage, } from "./wire/index.js";
@@ -13,7 +13,7 @@
13
13
  * Turn-lifecycle events relayed to the Control UI WebSocket.
14
14
  * These are the "chat session" events that every UI client needs.
15
15
  */
16
- export declare const AGENT_WS_EVENT_NAMES: readonly ["turn.start", "turn.delta", "turn.end", "turn.error", "turn.recovery", "turn.file_changes", "turn.tool_call", "turn.tool_result", "turn.tool_blocked", "turn.reasoning_delta", "turn.approval_request", "turn.skill_instruction", "turn.ask_user", "turn.media_result", "turn.media_progress", "turn.media_usage", "turn.media_capability_check", "turn.plan_update", "turn.suggestions", "turn.sidechain_started", "turn.subagent_started", "turn.subagent_delta", "turn.subagent_ended", "turn.sidechain_completed", "turn.task_updated", "turn.todos_updated", "turn.exec_progress", "turn.tool_use_summary", "turn.tool_selection_policy", "turn.lifecycle", "turn.document_maintenance", "turn.artifact_contract", "turn.usage_update", "team.member.notification", "session.info", "memory.updated", "skills.updated", "pet.soul_ready", "pet.reaction", "pet.growth", "pet.state", "pet.confirm", "pet.asset.updated", "system.activity", "workflow.created", "workflow.updated", "workflow.deleted", "workflow.runStarted", "workflow.runCompleted", "workflow.runFailed", "workflow.nodeStatus", "workflow.triggerDropped", "workflow.alert", "workflow.approvalRequested"];
16
+ export declare const AGENT_WS_EVENT_NAMES: readonly ["turn.start", "turn.delta", "turn.end", "turn.error", "turn.recovery", "turn.file_changes", "turn.tool_call", "turn.tool_result", "turn.tool_blocked", "turn.reasoning_delta", "turn.approval_request", "turn.skill_instruction", "turn.ask_user", "turn.media_result", "turn.media_progress", "turn.media_usage", "turn.media_capability_check", "turn.plan_update", "turn.suggestions", "turn.sidechain_started", "turn.subagent_started", "turn.subagent_delta", "turn.subagent_ended", "turn.sidechain_completed", "turn.task_updated", "turn.todos_updated", "turn.exec_progress", "turn.progress", "turn.tool_use_summary", "turn.tool_selection_policy", "turn.lifecycle", "turn.document_maintenance", "turn.artifact_contract", "turn.usage_update", "team.member.notification", "session.info", "session.recovery_pending", "memory.updated", "skills.updated", "pet.soul_ready", "pet.reaction", "pet.growth", "pet.state", "pet.confirm", "pet.asset.updated", "system.activity", "workflow.created", "workflow.updated", "workflow.deleted", "workflow.runStarted", "workflow.runCompleted", "workflow.runFailed", "workflow.nodeStatus", "workflow.triggerDropped", "workflow.alert", "workflow.approvalRequested"];
17
17
  /**
18
18
  * Agent Team events (Solo Mode, Product Mode, Plan lifecycle).
19
19
  * Relayed to the UI's team/orchestration panel.
@@ -23,7 +23,7 @@ export declare const AGENT_TEAM_WS_EVENT_NAMES: readonly ["solo.progress", "solo
23
23
  * All agent notifications that Gateway should relay to WS clients.
24
24
  * Union of session events + team events.
25
25
  */
26
- export declare const ALL_AGENT_WS_EVENT_NAMES: readonly ["turn.start", "turn.delta", "turn.end", "turn.error", "turn.recovery", "turn.file_changes", "turn.tool_call", "turn.tool_result", "turn.tool_blocked", "turn.reasoning_delta", "turn.approval_request", "turn.skill_instruction", "turn.ask_user", "turn.media_result", "turn.media_progress", "turn.media_usage", "turn.media_capability_check", "turn.plan_update", "turn.suggestions", "turn.sidechain_started", "turn.subagent_started", "turn.subagent_delta", "turn.subagent_ended", "turn.sidechain_completed", "turn.task_updated", "turn.todos_updated", "turn.exec_progress", "turn.tool_use_summary", "turn.tool_selection_policy", "turn.lifecycle", "turn.document_maintenance", "turn.artifact_contract", "turn.usage_update", "team.member.notification", "session.info", "memory.updated", "skills.updated", "pet.soul_ready", "pet.reaction", "pet.growth", "pet.state", "pet.confirm", "pet.asset.updated", "system.activity", "workflow.created", "workflow.updated", "workflow.deleted", "workflow.runStarted", "workflow.runCompleted", "workflow.runFailed", "workflow.nodeStatus", "workflow.triggerDropped", "workflow.alert", "workflow.approvalRequested", "solo.progress", "solo.specProgress", "solo.agentDelta", "solo.agentActivity", "solo.agentUsage", "solo.evaluation", "product.taskStarted", "product.taskOutput", "product.members", "product.agentActivity", "product.taskCompleted", "product.taskFailed", "product.budgetUpdate", "product.budgetWarning", "product.checkpointed", "product.completed", "product.dagTopology", "plan.interrupted", "goal.run_state_changed", "goal.phase_boundary", "goal.goal_edited", "goal.message_queued", "goal.acceptance_updated"];
26
+ export declare const ALL_AGENT_WS_EVENT_NAMES: readonly ["turn.start", "turn.delta", "turn.end", "turn.error", "turn.recovery", "turn.file_changes", "turn.tool_call", "turn.tool_result", "turn.tool_blocked", "turn.reasoning_delta", "turn.approval_request", "turn.skill_instruction", "turn.ask_user", "turn.media_result", "turn.media_progress", "turn.media_usage", "turn.media_capability_check", "turn.plan_update", "turn.suggestions", "turn.sidechain_started", "turn.subagent_started", "turn.subagent_delta", "turn.subagent_ended", "turn.sidechain_completed", "turn.task_updated", "turn.todos_updated", "turn.exec_progress", "turn.progress", "turn.tool_use_summary", "turn.tool_selection_policy", "turn.lifecycle", "turn.document_maintenance", "turn.artifact_contract", "turn.usage_update", "team.member.notification", "session.info", "session.recovery_pending", "memory.updated", "skills.updated", "pet.soul_ready", "pet.reaction", "pet.growth", "pet.state", "pet.confirm", "pet.asset.updated", "system.activity", "workflow.created", "workflow.updated", "workflow.deleted", "workflow.runStarted", "workflow.runCompleted", "workflow.runFailed", "workflow.nodeStatus", "workflow.triggerDropped", "workflow.alert", "workflow.approvalRequested", "solo.progress", "solo.specProgress", "solo.agentDelta", "solo.agentActivity", "solo.agentUsage", "solo.evaluation", "product.taskStarted", "product.taskOutput", "product.members", "product.agentActivity", "product.taskCompleted", "product.taskFailed", "product.budgetUpdate", "product.budgetWarning", "product.checkpointed", "product.completed", "product.dagTopology", "plan.interrupted", "goal.run_state_changed", "goal.phase_boundary", "goal.goal_edited", "goal.message_queued", "goal.acceptance_updated"];
27
27
  /** Type-level event name for session events. */
28
28
  export type AgentWsEventName = (typeof AGENT_WS_EVENT_NAMES)[number];
29
29
  /** Type-level event name for team events. */
@@ -6,7 +6,7 @@ export { type ChatMessage, type ChatMessageRole, type LocalizedToolText, type Th
6
6
  export { type AgentCapabilities, type AgentCategory, type AgentConfig, type AgentDescriptor, type AgentProtocol, type AgentRpcMethodMap, type AgentStatus, type CustomAgentDef, type ProductInstanceDef, type ProductPhase, type ProductStatus, type ProductSummary, type ProductTaskDef, type ProductTaskStatus, type SoloAgentResult, type SoloAgentState, type SoloState, type SoloStatus, } from "./agent-methods.js";
7
7
  export type * from "./acp-agent-management.js";
8
8
  export { AGENT_TEAM_WS_EVENT_NAMES, AGENT_WS_EVENT_NAMES, ALL_AGENT_WS_EVENT_NAMES, type AgentTeamWsEventName, type AgentWsEventName, type AllAgentWsEventName, } from "./agent-events.js";
9
- export { type AgentSource, type AgentsErrorNotification, type AgentsStatusNotification, type ArtifactType, type MediaResultType, type MemoryDecayCompletedNotification, type MemoryUpdatedNotification, type NotificationMethod, type NotificationMethodMap, type NotificationThreadItem, type PermissionRuleUpdatedNotification, type PlanInterruptedNotification, type PongNotification, type ProductBudgetUpdateNotification, type ProductBudgetWarningNotification, type ProductCheckpointedNotification, type ProductCompletedNotification, type ProductDagTopologyNotification, type ProductTaskCompletedNotification, type ProductTaskFailedNotification, type ProductTaskOutputDeltaNotification, type ProductMembersNotification, type ProductAgentActivityNotification, type ProductTaskStartedNotification, type ProjectArchivedNotification, type ProjectCreatedNotification, type ProjectDeletedNotification, type ProjectRenamedNotification, type ProjectSwitchedNotification, type ProjectUnarchivedNotification, type SessionInfoNotification, type SoloAgentDeltaNotification, type SoloAgentUsageNotification, type SoloEvaluationNotification, type SoloProgressNotification, type TeamMemberNotification, type ToolApprovalRequestNotification, type TurnAnnotationsNotification, type TurnArtifactContractNotification, type TurnArtifactNotification, type TurnAskUserNotification, type TurnDeltaNotification, type TurnEndNotification, type TurnErrorNotification, type TurnExecProgressNotification, type TurnHeartbeatNotification, type TurnMediaPersistedNotification, type TurnMediaProgressNotification, type TurnMediaResultNotification, type TurnPlanUpdateNotification, type TurnReasoningDeltaNotification, type TurnRecoveryNotification, type TurnSidechainCompletedNotification, type TurnSidechainStartedNotification, type TurnSkillAcquisitionNeededNotification, type TurnSkillInstructionNotification, type TurnStartNotification, type TurnSubagentDeltaNotification, type TurnSubagentEndedNotification, type TurnSubagentStartedNotification, type TurnSuggestionsNotification, type TurnTaskUpdatedNotification, type TurnTodosUpdatedNotification, type TurnToolBlockedNotification, type TurnToolCallNotification, type TurnToolResultNotification, type TurnToolUseSummaryNotification, type TurnUsageUpdateNotification, type WireTokenUsage, type ProductPlanReadyNotification, type ProductPlanFailedNotification, type ProductPlanningDeltaNotification, type PetSoulReadyNotification, type PetReactionNotification, type PetGrowthNotification, type PetStateNotification, type PetConfirmNotification, type WorkflowDeletedNotification, type WorkflowRecordNotification, type WorkflowRunCompletedNotification, type WorkflowRunFailedNotification, type WorkflowRunStartedNotification, } from "./notification-payloads.js";
9
+ export { type AgentSource, type AgentsErrorNotification, type AgentsStatusNotification, type ArtifactType, type MediaResultType, type MemoryDecayCompletedNotification, type MemoryUpdatedNotification, type NotificationMethod, type NotificationMethodMap, type NotificationThreadItem, type PermissionRuleUpdatedNotification, type PlanInterruptedNotification, type PongNotification, type ProductBudgetUpdateNotification, type ProductBudgetWarningNotification, type ProductCheckpointedNotification, type ProductCompletedNotification, type ProductDagTopologyNotification, type ProductTaskCompletedNotification, type ProductTaskFailedNotification, type ProductTaskOutputDeltaNotification, type ProductMembersNotification, type ProductAgentActivityNotification, type ProductTaskStartedNotification, type ProjectArchivedNotification, type ProjectCreatedNotification, type ProjectDeletedNotification, type ProjectRenamedNotification, type ProjectSwitchedNotification, type ProjectUnarchivedNotification, type SessionInfoNotification, type SessionRecoveryPendingNotification, type SoloAgentDeltaNotification, type SoloAgentUsageNotification, type SoloEvaluationNotification, type SoloProgressNotification, type TeamMemberNotification, type ToolApprovalRequestNotification, type TurnAnnotationsNotification, type TurnArtifactContractNotification, type TurnArtifactNotification, type TurnAskUserNotification, type TurnDeltaNotification, type TurnEndNotification, type TurnErrorNotification, type TurnExecProgressNotification, type TurnHeartbeatNotification, type TurnMediaPersistedNotification, type TurnMediaProgressNotification, type TurnMediaResultNotification, type TurnPlanUpdateNotification, type TurnProgressNotification, type TurnReasoningDeltaNotification, type TurnRecoveryNotification, type TurnSidechainCompletedNotification, type TurnSidechainStartedNotification, type TurnSkillAcquisitionNeededNotification, type TurnSkillInstructionNotification, type TurnStartNotification, type TurnSubagentDeltaNotification, type TurnSubagentEndedNotification, type TurnSubagentStartedNotification, type TurnSuggestionsNotification, type TurnTaskUpdatedNotification, type TurnTodosUpdatedNotification, type TurnToolBlockedNotification, type TurnToolCallNotification, type TurnToolResultNotification, type TurnToolUseSummaryNotification, type TurnUsageUpdateNotification, type WireTokenUsage, type ProductPlanReadyNotification, type ProductPlanFailedNotification, type ProductPlanningDeltaNotification, type PetSoulReadyNotification, type PetReactionNotification, type PetGrowthNotification, type PetStateNotification, type PetConfirmNotification, type WorkflowDeletedNotification, type WorkflowRecordNotification, type WorkflowRunCompletedNotification, type WorkflowRunFailedNotification, type WorkflowRunStartedNotification, } from "./notification-payloads.js";
10
10
  export { ACP_EXTENDED_METHODS, ACP_EXTENDED_SESSION_UPDATE_TYPES, ACP_METHODS, ACP_PROTOCOL_VERSION, ACP_SESSION_UPDATE_TYPES, isAcpJsonRpcNotification, isAcpJsonRpcRequest, isAcpJsonRpcResponse, isExtendedSessionUpdateType, isStandardSessionUpdateType, parseAcpMessage, type AcpAgentCapabilities, type AcpAgentMessageChunkPayload, type AcpAgentThoughtChunkPayload, type AcpConfigOptionDescriptor, type AcpConfigOptionUpdatePayload, type AcpContentBlock, type AcpEndTurnPayload, type AcpExtendedMethod, type AcpExtendedSessionUpdateType, type AcpFsReadTextFileParams, type AcpFsReadTextFileResult, type AcpFsWriteTextFileParams, type AcpFsWriteTextFileResult, type AcpHostCapabilities, type AcpInitializeParams, type AcpInitializeResult, type AcpJsonRpcError, type AcpJsonRpcMessage, type AcpJsonRpcNotification, type AcpJsonRpcRequest, type AcpJsonRpcResponse, type AcpMode, type AcpPermissionOption, type AcpPermissionRequestParams, type AcpPermissionRequestResult, type AcpPlanPayload, type AcpSessionCancelParams, type AcpSessionCloseParams, type AcpSessionMeta, type AcpSessionLoadParams, type AcpSessionModeState, type AcpSessionNewParams, type AcpSessionNewResult, type AcpSessionPromptParams, type AcpSessionPromptResult, type AcpSessionSetConfigParams, type AcpSessionUpdateNotification, type AcpSessionUpdateType, type AcpStandardMethod, type AcpStandardSessionUpdateType, type AcpStopReason, type AcpToolCallPayload, type AcpToolCallUpdatePayload, type AcpUsage, type AcpUsageUpdatePayload, type AcpXSessionInfoPayload, type AcpXSkillInstructionPayload, } from "./acp-protocol.js";
11
11
  export { type ApprovalRequiredToolContract, type ModelSelectionReason, type PendingPromptContract, type RuntimeCapabilitySummaryContract, type RuntimeSessionContract, type SessionIdentityContract, } from "./session.js";
12
12
  export { type GatewayChannelExecutionEgressContract, type GatewayChannelExecutionEgressKind, type GatewayChannelExecutionIngressBindingContract, type GatewayChannelExecutionIngressSource, } from "./channel-ingress.js";