@agimon-ai/doompi-team 0.0.1-alpha.39 → 0.0.1-alpha.40

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 (32) hide show
  1. package/README.md +5 -5
  2. package/dist/src/adapters/intercom/nativeTeamChannel.cjs +4 -4
  3. package/dist/src/adapters/intercom/nativeTeamChannel.mjs +2 -2
  4. package/dist/src/adapters/pi/commands/slash/slashCommands.cjs +1 -1
  5. package/dist/src/adapters/pi/commands/slash/slashCommands.cjs.map +1 -1
  6. package/dist/src/adapters/pi/commands/slash/slashCommands.mjs +1 -1
  7. package/dist/src/adapters/pi/commands/slash/slashCommands.mjs.map +1 -1
  8. package/dist/src/adapters/pi/extension.cjs +1 -1
  9. package/dist/src/adapters/pi/extension.mjs +1 -1
  10. package/dist/src/adapters/pi/extension.mjs.map +1 -1
  11. package/dist/src/adapters/pi/extensions/spawnPlan.cjs +3 -3
  12. package/dist/src/adapters/pi/extensions/spawnPlan.mjs +3 -3
  13. package/dist/src/adapters/pi/extensions/subagentPromptRuntime.cjs +3 -3
  14. package/dist/src/adapters/pi/extensions/subagentPromptRuntime.mjs +5 -5
  15. package/dist/src/adapters/pi/extensions/subagentPromptRuntime.mjs.map +1 -1
  16. package/dist/src/adapters/pi/extensions/subagentTool.cjs +4 -4
  17. package/dist/src/adapters/pi/extensions/subagentTool.mjs +4 -4
  18. package/dist/src/adapters/pi/promptRuntime.cjs +1 -1
  19. package/dist/src/adapters/pi/promptRuntime.mjs +1 -1
  20. package/dist/src/adapters/pi/teamRuntime.cjs +1 -1
  21. package/dist/src/adapters/pi/teamRuntime.mjs +1 -1
  22. package/dist/src/adapters/runs/background/asyncExecution.cjs +1 -1
  23. package/dist/src/adapters/runs/background/asyncExecution.mjs +1 -1
  24. package/dist/src/adapters/runs/background/asyncExecution.mjs.map +1 -1
  25. package/dist/src/adapters/runs/shared/piArgs.cjs +1 -1
  26. package/dist/src/adapters/runs/shared/piArgs.mjs +1 -1
  27. package/package.json +8 -8
  28. package/web/AgentCatalogDrawer.tsx +1 -1
  29. package/web/AgentThreadPanel.tsx +30 -3
  30. package/web/LaunchAgentDialog.tsx +13 -7
  31. package/web/SubagentsPanel.tsx +14 -7
  32. package/web/subagentsStore.ts +7 -1
package/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # @agimon-ai/doompi-team
2
2
 
3
- An asynchronous subagent runtime for Pi: agent discovery, background runs, membership, intercom,
4
- and model and tool policy.
3
+ Discover agents, run them in the background, exchange messages, and enforce model and tool policy.
5
4
 
6
5
  Part of the [DoomPi distribution](https://www.npmjs.com/package/@agimon-ai/doompi).
7
6
 
@@ -55,14 +54,15 @@ Slash commands include:
55
54
  /run
56
55
  /parallel
57
56
  /subagents-doctor
57
+ /subagents-steer <run-id> <message>
58
58
  /subagents-stop
59
59
  /subagents-list
60
60
  /subagents-fleet
61
61
  ```
62
62
 
63
- Use `/run` for one agent, `/parallel` for several, `/subagents-doctor` for diagnostics,
64
- `/subagents-stop` to stop work, `/subagents-list` for available agents, and `/subagents-fleet` for
65
- current runs.
63
+ Use `/run` for one agent and `/parallel` for several. `/subagents-doctor` reports diagnostics,
64
+ `/subagents-steer` sends guidance to a running agent, and `/subagents-stop` requests a stop.
65
+ `/subagents-list` shows available agents, and `/subagents-fleet` shows current runs.
66
66
 
67
67
  The `subagent` tool exposes `agents`, `run`, `status`, `steer`, `stop`, `suspended`, and `restore`.
68
68
  The `intercom` tool exposes `members`, `send`, `ask`, `pending`, and `reply`.
@@ -1,5 +1,5 @@
1
- const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../types/environment.cjs"),n=require("../../services/support/lruCache.cjs"),r=require("../atomicJson.cjs"),i=require("../filesystem/paths.cjs"),a=require("../../services/support/errors.cjs"),o=require("../../services/support/boundedKeySet.cjs"),s=require("../../services/support/versioned.cjs");let c=require("node:fs");c=e.__toESM(c,1);let l=require("node:path");l=e.__toESM(l,1);let u=require("node:crypto");const d=`intercom`,f=`subagent.team.message`,p=`subagent.team.reply`,m=`members`,ee=`heartbeats`,h=`inboxes`,g=`replies`,te=`receipts`,ne=`team.json`,_=`.json`,v=`main`,y=`agent`,b=65536,x=4096,re=[`members`,`send`,`ask`,`reply`,`pending`],ie=/^[A-Za-z0-9._-]{1,256}$/,ae=/[^a-z0-9._-]+/g,S=/^[-.]+|[-.]+$/g,oe=`sha256`,C=`delivered`,se=`failed`,ce={oneOf:[...[`members`,`pending`].map(e=>({type:`object`,properties:{action:{const:e}},required:[`action`],additionalProperties:!1})),{type:`object`,properties:{action:{const:`send`},to:{type:`string`},message:{type:`string`}},required:[`action`,`to`,`message`],additionalProperties:!1},{type:`object`,properties:{action:{const:`ask`},to:{type:`string`},message:{type:`string`},timeoutMs:{type:`integer`,minimum:1}},required:[`action`,`to`,`message`],additionalProperties:!1},{type:`object`,properties:{action:{const:`reply`},requestId:{type:`string`},message:{type:`string`}},required:[`action`,`requestId`,`message`],additionalProperties:!1}]};function w(e){return typeof e==`string`&&ie.test(e)}function T(e){return typeof e==`number`&&Number.isInteger(e)}function E(e){return typeof e==`number`&&Number.isFinite(e)}function D(e){return typeof e==`string`&&e.trim().length>0}function O(e){return e===void 0||typeof e==`string`}function le(e){return e===void 0||T(e)}function ue(e){return e===`main`||e===`subagent`}function de(e){return e===`send`||e===`ask`}function k(e,t){return Buffer.byteLength(e,`utf-8`)<=t}function fe(e){return e instanceof Error?e.message:String(e)}function A(e){return process.env[e]?.trim()||void 0}function j(e){return(0,u.createHash)(oe).update(e).digest(`hex`)}function pe(){return(0,u.randomBytes)(32).toString(`base64url`)}function me(e){return`session-${j(e).slice(0,32)}`}function M(e){return e.trim().toLowerCase().replace(ae,`-`).replace(S,``).slice(0,48).replace(S,``)||y}function he(e,t){let n=`-${t+1}`,r=48-n.length;return`${e.slice(0,Math.max(r,0)).replace(S,``)||y}${n}`}function ge(e,t){if(e!==v)return e;if(t)throw Error(`Native team member name '${v}' is reserved for the root session.`);return`main-agent`}function N(e){if(!w(e))throw Error(`Invalid native team id.`);return l.join(i.scopeTeamDir(i.requireCurrentSessionScope()),e)}function P(e,t){if(!w(t))throw Error(`Invalid native team member id.`);return l.join(N(e.teamId),m,`${t}${_}`)}function F(e,t){if(!w(t))throw Error(`Invalid native team member id.`);return l.join(N(e.teamId),ee,`${t}${_}`)}function I(e,t){if(!w(t))throw Error(`Invalid native team member id.`);return l.join(N(e.teamId),h,t)}function L(e){return`${e}${_}`}function R(e,t,n){if(!w(n))throw Error(`Invalid native team message id.`);return l.join(I(e,t),L(n))}function _e(e,t){if(!w(t))throw Error(`Invalid native team request id.`);return l.join(N(e.teamId),g,`${t}${_}`)}function z(e,t,n){if(!w(t)||!w(n))throw Error(`Invalid intercom receipt identity.`);return l.join(N(e.teamId),te,t,`${n}${_}`)}function ve(e,t){return(0,u.createHash)(oe).update(`${e}:${t}`).digest(`hex`)}function ye(e){let t=N(e.teamId);for(let e of[m,ee,h,g,te])c.mkdirSync(l.join(t,e),{recursive:!0,mode:448})}function B(e){try{let t=JSON.parse(c.readFileSync(e,`utf-8`));return t&&typeof t==`object`&&!Array.isArray(t)?t:void 0}catch{return}}function V(e){try{return c.rmSync(e,{force:!0}),!0}catch(e){return e.code===`ENOENT`}}function be(e){try{return c.rmSync(e,{recursive:!0,force:!0}),!0}catch{return!1}}function xe(e){if(!(!s.parseVersioned(e,[1]).ok||!e)&&!(!w(e.teamId)||!D(e.rootSessionId)||e.mainMemberId!==v||!E(e.createdAt)||!E(e.updatedAt)))return{version:1,teamId:e.teamId,rootSessionId:e.rootSessionId,mainMemberId:v,createdAt:e.createdAt,updatedAt:e.updatedAt}}function Se(e){if(!e||typeof e!=`object`||Array.isArray(e))return;let t=e;if(!(!D(t.id)||!D(t.subject))&&!(!k(t.id,256)||!k(t.subject,x)))return{id:t.id,subject:t.subject}}function Ce(e){if(!s.parseVersioned(e,[1]).ok||!e||!w(e.teamId)||!D(e.rootSessionId)||!D(e.mainMemberId)||!w(e.memberId)||!ue(e.role)||!D(e.tokenHash)||!T(e.pid)||typeof e.active!=`boolean`||!E(e.joinedAt)||!O(e.agent)||!O(e.runId)||!le(e.childIndex)||!O(e.parentMemberId))return;let t=e.task===void 0?void 0:Se(e.task);if(!(e.task!==void 0&&!t))return{version:1,teamId:e.teamId,rootSessionId:e.rootSessionId,mainMemberId:e.mainMemberId,memberId:e.memberId,role:e.role,tokenHash:e.tokenHash,pid:e.pid,active:e.active,joinedAt:e.joinedAt,...E(e.leftAt)?{leftAt:e.leftAt}:{},...e.agent===void 0?{}:{agent:e.agent},...e.runId===void 0?{}:{runId:e.runId},...e.childIndex===void 0?{}:{childIndex:e.childIndex},...e.parentMemberId===void 0?{}:{parentMemberId:e.parentMemberId},...t?{task:t}:{}}}function we(e){if(!(!s.parseVersioned(e,[1]).ok||!e)&&!(!w(e.memberId)||!D(e.tokenHash)||!T(e.pid)||!E(e.heartbeatAt)))return{version:1,memberId:e.memberId,tokenHash:e.tokenHash,pid:e.pid,heartbeatAt:e.heartbeatAt}}function Te(e){if(!(!s.parseVersioned(e,[2]).ok||!e)&&!(e.type!==f||!w(e.id)||!w(e.teamId)||!de(e.kind)||!w(e.fromMemberId)||!w(e.toMemberId)||!D(e.senderTokenHash)||!T(e.seq)||typeof e.message!=`string`||!k(e.message,b)||!E(e.createdAt)||!E(e.expiresAt)))return{type:f,version:2,id:e.id,teamId:e.teamId,kind:e.kind,fromMemberId:e.fromMemberId,toMemberId:e.toMemberId,senderTokenHash:e.senderTokenHash,seq:e.seq,message:e.message,createdAt:e.createdAt,expiresAt:e.expiresAt}}function Ee(e){if(!(!s.parseVersioned(e,[2]).ok||!e)&&!(e.type!==p||!w(e.requestId)||!w(e.teamId)||!w(e.fromMemberId)||!w(e.toMemberId)||!D(e.senderTokenHash)||typeof e.message!=`string`||!k(e.message,b)||!E(e.createdAt)))return{type:p,version:2,requestId:e.requestId,teamId:e.teamId,fromMemberId:e.fromMemberId,toMemberId:e.toMemberId,senderTokenHash:e.senderTokenHash,message:e.message,createdAt:e.createdAt}}function De(e){if(!e||typeof e!=`object`||Array.isArray(e))throw a.invalidRequest(`Intercom params must be an object.`,`Use one documented intercom action shape.`);let t=e,n=re.find(e=>e===t.action);if(!n)throw new a.DoomTeamExpectedError(`unsupported_operation`,`Unsupported intercom action: ${String(t.action)}.`,!1,`Use members, send, ask, pending, or reply.`);if(!O(t.to)||!O(t.message)||!O(t.requestId))throw a.invalidRequest(`Intercom to, message and requestId values must be strings.`,`Correct the action fields and retry.`);if(t.timeoutMs!==void 0&&(!T(t.timeoutMs)||t.timeoutMs<1))throw a.invalidRequest(`Intercom timeoutMs must be a positive integer.`,`Correct timeoutMs and retry.`);let r=new Set(n===`members`||n===`pending`?[`action`]:n===`reply`?[`action`,`requestId`,`message`]:n===`ask`?[`action`,`to`,`message`,`timeoutMs`]:[`action`,`to`,`message`]),i=Object.keys(t).filter(e=>!r.has(e));if(i.length)throw a.invalidRequest(`Intercom action '${n}' does not accept: ${i.join(`, `)}.`,`Remove unknown fields and retry.`);return{action:n,...t.to===void 0?{}:{to:t.to},...t.message===void 0?{}:{message:t.message},...t.requestId===void 0?{}:{requestId:t.requestId},...t.timeoutMs===void 0?{}:{timeoutMs:t.timeoutMs}}}function H(e,t){return Ce(B(P(e,t)))}function U(e,t){let n=we(B(F(e,t.memberId)));if(!(!n||n.memberId!==t.memberId||n.tokenHash!==t.tokenHash))return n}function Oe(e){if(e===process.pid)return!0;try{return process.kill(e,0),!0}catch(e){return e.code===`EPERM`}}function ke(e,t){return U(e,t)?.heartbeatAt??t.leftAt??t.joinedAt}function W(e,t,n){return t.active&&Oe(t.pid)&&n-ke(e,t)<=3e4}function Ae(e){c.mkdirSync(I(e,e.memberId),{recursive:!0,mode:448}),r.writePrivateAtomicJson(P(e,e.memberId),e)}function G(e,t,n){let i={version:1,memberId:t.memberId,tokenHash:t.tokenHash,pid:t.pid,heartbeatAt:n};r.writePrivateAtomicJson(F(e,t.memberId),i)}function K(e){let t=l.join(N(e.teamId),m),n;try{n=c.readdirSync(t,{withFileTypes:!0})}catch{return[]}return n.filter(e=>e.isFile()&&e.name.endsWith(_)).map(e=>Ce(B(l.join(t,e.name)))).filter(e=>!!e).filter(t=>t.teamId===e.teamId&&t.rootSessionId===e.rootSessionId)}function q(e,t){return K(e).filter(n=>W(e,n,t)).sort((e,t)=>e.joinedAt-t.joinedAt||e.memberId.localeCompare(t.memberId))}function je(e=Date.now()){let t=Y();if(t)return{members:q(t,e).map($)}}function Me(e,t,n){let r=0;for(let i of K(e))i.memberId!==t&&(W(e,i,n)||n-ke(e,i)<=33e4||(be(I(e,i.memberId)),V(F(e,i.memberId)),V(P(e,i.memberId)),r+=1));return r}function Ne(e){let t=e.trim();if(!t)throw Error(`A root session id is required for native team communication.`);let n={version:1,teamId:me(t),rootSessionId:t,mainMemberId:v};ye(n);let i=l.join(N(n.teamId),ne),a=xe(B(i));if(a&&a.rootSessionId!==t)throw Error(`Native team identity collision detected.`);let o=Date.now(),s={...n,createdAt:a?.createdAt??o,updatedAt:o};return r.writePrivateAtomicJson(i,s),n}function J(e){return{[t.SUBAGENT_TEAM_ID_ENV]:e.teamId,[t.SUBAGENT_TEAM_ROOT_SESSION_ENV]:e.rootSessionId,[t.SUBAGENT_TEAM_MAIN_MEMBER_ENV]:e.mainMemberId}}function Pe(e){return{...J(e),[t.SUBAGENT_TEAM_MEMBER_ID_ENV]:e.memberId,[t.SUBAGENT_TEAM_MEMBER_TOKEN_ENV]:e.token}}function Fe(){return{[t.SUBAGENT_TEAM_MEMBER_ID_ENV]:void 0,[t.SUBAGENT_TEAM_MEMBER_TOKEN_ENV]:void 0}}function Ie(e){Object.assign(process.env,J(e))}function Le(e){e&&process.env.PI_SUBAGENT_TEAM_ID!==e.teamId||(delete process.env[t.SUBAGENT_TEAM_ID_ENV],delete process.env[t.SUBAGENT_TEAM_ROOT_SESSION_ENV],delete process.env[t.SUBAGENT_TEAM_MAIN_MEMBER_ENV])}function Y(){let e=A(t.SUBAGENT_TEAM_ID_ENV),n=A(t.SUBAGENT_TEAM_ROOT_SESSION_ENV),r=A(t.SUBAGENT_TEAM_MAIN_MEMBER_ENV);if(!e||!w(e)||!n||r!==v||e!==me(n))return;let i=xe(B(l.join(N(e),ne)));if(!(!i||i.rootSessionId!==n||i.teamId!==e))return{version:1,teamId:e,rootSessionId:n,mainMemberId:r}}function Re(e){if(!e)return;let t=e.id.trim(),n=e.subject.trim();if(!t||!k(t,256))throw Error(`Native team task id must be between 1 and 256 bytes.`);if(!n||!k(n,x))throw Error(`Native team task subject must be between 1 and ${x} bytes.`);return{id:t,subject:n}}function ze(e){if(e.role===`main`)return e.root.mainMemberId;let t=e.name!==void 0;if(!t&&!e.agent)throw Error(`An intercom member needs a name or an agent to derive one from.`);let n=ge(M(e.name??e.agent??y),t);if(e.runId){let t=M(e.runId).slice(0,8),r=48-t.length-1;return`${n.slice(0,r).replace(S,``)||y}-${t}`}return e.fanoutIndex===void 0?n:he(n,e.fanoutIndex)}function Be(e){let t=ze(e);if(!w(t))throw Error(`A safe native team member id is required.`);let n=pe(),r=j(n),i=Date.now(),a=Re(e.task),o={...e.root,memberId:t,token:n,role:e.role,...e.agent?{agent:e.agent}:{},...e.runId?{runId:e.runId}:{},...e.childIndex===void 0?{}:{childIndex:e.childIndex},...e.parentMemberId?{parentMemberId:e.parentMemberId}:{},...a?{task:a}:{}},s=H(e.root,t);s&&s.tokenHash!==r&&be(I(e.root,t));let{token:c,version:l,...u}=o,d={...u,version:1,tokenHash:r,pid:e.pid??process.pid,active:!0,joinedAt:i};Ae(d),G(e.root,d,i);let f=!1;return{context:o,dispose:()=>{if(f)return;f=!0;let n=H(e.root,t);if(!n||n.tokenHash!==r)return;let i=Date.now();Ae({...n,active:!1,leftAt:i}),G(e.root,n,i)}}}function X(){let e=Y(),n=A(t.SUBAGENT_TEAM_MEMBER_ID_ENV),r=A(t.SUBAGENT_TEAM_MEMBER_TOKEN_ENV);if(!e||!n||!w(n)||!r)return;let i=H(e,n);if(!(!i||i.teamId!==e.teamId||i.rootSessionId!==e.rootSessionId)&&!(i.tokenHash!==j(r)||!i.active))return{...e,memberId:n,token:r,role:i.role,...i.agent?{agent:i.agent}:{},...i.runId?{runId:i.runId}:{},...i.childIndex===void 0?{}:{childIndex:i.childIndex},...i.parentMemberId?{parentMemberId:i.parentMemberId}:{},...i.task?{task:i.task}:{}}}function Z(e,t){let n=H(e,e.memberId);if(!n||n.tokenHash!==j(e.token)||!W(e,n,t))throw Error(`This native team member is no longer active.`);return n}function Ve(e,t,n){let r=t?.trim();if(!r)throw a.invalidRequest(`to is required for intercom send and ask.`,`Provide an explicit recipient.`);let i=q(e,n).filter(t=>t.memberId!==e.memberId),o=M(r),s=i.find(e=>e.memberId===r||e.memberId===o);if(s)return s;let c=r.toLowerCase(),l=i.filter(e=>e.agent?.toLowerCase()===c||e.runId?.toLowerCase()===c||c===v&&e.role===`main`);if(l.length===1)return l[0];throw l.length>1?new a.DoomTeamExpectedError(`recipient_ambiguous`,`Multiple active intercom members match '${r}': ${l.map(e=>e.memberId).join(`, `)}.`,!1,`Retry with one exact member id.`):new a.DoomTeamExpectedError(`recipient_not_found`,`Active intercom member '${r}' was not found.`,!0,`Call intercom({"action":"members"}) and retry with an active member id.`)}function He(e){let t=e?.trim();if(!t)throw a.invalidRequest(`message is required for intercom communication.`,`Provide a nonblank message.`);if(!k(t,b))throw a.invalidRequest(`Intercom message exceeds 64 KiB.`,`Shorten the message and retry.`);return t}function Q(e,t,n){let r=H(e,t);return!!(r&&r.tokenHash===n)}function Ue(e,t,n){let r=I(e,e.memberId),i;try{i=c.readdirSync(r,{withFileTypes:!0})}catch{return{messages:[],foreignFiles:[]}}let a=[],o=[];for(let s of i){if(!s.isFile()||!s.name.endsWith(_)||n?.(s.name))continue;let i=l.join(r,s.name),c=Te(B(i));if(!c){V(i);continue}if(c.teamId!==e.teamId||c.toMemberId!==e.memberId){o.push(s.name);continue}if(c.expiresAt<t||!Q(e,c.fromMemberId,c.senderTokenHash)){V(i);continue}a.push(c)}return{messages:We(a),foreignFiles:o}}function We(e){let t=new Map;for(let n of e){let e=t.get(n.fromMemberId);e?e.push(n):t.set(n.fromMemberId,[n])}let n=[];for(let e of t.values())e.sort((e,t)=>e.seq-t.seq),n.push(e);let r=[];for(;;){let e,t;for(let r of n){let n=r[0];n&&(!t||n.createdAt<t.createdAt||n.createdAt===t.createdAt&&n.fromMemberId<t.fromMemberId)&&(e=r,t=n)}if(!e||!t)break;e.shift(),r.push(t)}return r}function Ge(e){let t=e.role===`main`?v:e.agent??e.memberId,n=e.runId?` [${e.runId}]`:``,r=e.task?`, task ${e.task.id}: ${e.task.subject}`:``;return`- ${e.memberId}: ${t}${n}${r}`}function $(e){return{name:e.memberId,role:e.role,...e.agent?{agent:e.agent}:{},...e.runId?{runId:e.runId}:{},...e.task?{task:e.task}:{}}}function Ke(e,t){return new Promise((n,r)=>{if(t?.aborted){r(Error(`Native team request cancelled.`));return}let i,a=()=>{i&&clearTimeout(i),t?.removeEventListener(`abort`,o)},o=()=>{a(),r(Error(`Native team request cancelled.`))};i=setTimeout(()=>{a(),n()},e),t?.addEventListener(`abort`,o,{once:!0})})}function qe(e,t){let n=H(e,t.fromMemberId),r=`${t.fromMemberId}${n?.agent?` (${n.agent})`:``}`,i=n?.task?`, task ${n.task.id}`:``,a=[`${t.kind===`ask`?`Question`:`Message`} from ${r}${i}.`];return a.push(``,t.message),t.kind===`ask`&&a.push(``,`Reply with ${d}({ action: "reply", requestId: "${t.id}", message: "..." }).`),a.join(`
2
- `)}function Je(e,t){try{return e.getAllTools().some(e=>e.name===t)}catch{return!1}}var Ye=class{pi;options;context;ownedMembershipDispose;poller;lastHeartbeatAt=0;lastGcAt=0;seenFiles=new o.BoundedKeySet(1024);deliveryAttempts=new n.LruCache(256);undeliverableMessages=[];outboundSeq=0;constructor(e,t){if(this.pi=e,this.options=t,Je(e,`intercom`))throw Error(`[tool_conflict] A foreign '${d}' tool is already registered. Recovery: disable the competing extension and reload Doom Team.`);e.registerTool(this.buildTool())}current(){return this.context}undeliverable(){return this.undeliverableMessages}bindMainSession(e){let t=Ne(e);Ie(t);let n=Be({root:t,role:`main`});return this.startBinding(n.context,n.dispose)}bindChildFromEnvironment(){let e=X();if(e)return this.context?.memberId===e.memberId&&this.context.token===e.token?this.context:this.startBinding(e)}dispose(){let e=this.context;this.stopBinding(),e?.role===`main`&&Le(e)}startBinding(e,t){return this.stopBinding(),this.context=e,this.ownedMembershipDispose=t,this.poll(),this.poller=setInterval(()=>{this.poll()},this.options.pollIntervalMs),this.poller.unref?.(),e}stopBinding(){this.poller&&clearInterval(this.poller),this.poller=void 0,this.ownedMembershipDispose?.(),this.ownedMembershipDispose=void 0,this.seenFiles.clear(),this.deliveryAttempts.clear(),this.lastHeartbeatAt=0,this.lastGcAt=0,this.outboundSeq=0,this.context=void 0}poll(){let e=this.context;if(!e)return;let t=this.options.now();this.heartbeat(e,t),this.collectGarbageIfDue(e,t);let n=Ue(e,t,e=>this.seenFiles.has(e));for(let e of n.foreignFiles)this.seenFiles.add(e);for(let t of n.messages)this.deliverOnce(e,t)}deliverOnce(e,t){let n=L(t.id);try{this.deliver(e,t)}catch(r){let i=(this.deliveryAttempts.get(n)??0)+1;if(i<this.options.maxDeliveryAttempts){this.deliveryAttempts.set(n,i);return}this.deliveryAttempts.delete(n),this.seenFiles.add(n),this.reportUndeliverable(e,t,i,r);return}this.seenFiles.add(n),this.deliveryAttempts.delete(n),r.writePrivateAtomicJson(z(e,t.fromMemberId,t.id),{version:1,messageId:t.id,state:C,deliveredAt:this.options.now()}),t.kind===`send`&&V(R(e,e.memberId,t.id))}deliver(e,t){let n=qe(e,t);if(e.role===`subagent`){this.pi.sendUserMessage(n,{deliverAs:`steer`});return}this.pi.sendMessage({customType:`intercom_message`,content:n,display:!0,details:{id:t.id,kind:t.kind,from:t.fromMemberId,to:t.toMemberId,seq:t.seq}},{triggerTurn:!0,deliverAs:`steer`})}reportUndeliverable(e,t,n,i){let a={messageId:t.id,fromMemberId:t.fromMemberId,kind:t.kind,attempts:n,reason:fe(i),at:this.options.now()};for(this.undeliverableMessages.push(a),r.writePrivateAtomicJson(z(e,t.fromMemberId,t.id),{version:1,messageId:t.id,state:se,reason:a.reason,failedAt:a.at});this.undeliverableMessages.length>32;)this.undeliverableMessages.shift();try{return this.pi.sendMessage({customType:`intercom_undeliverable`,content:`Native team message ${t.id} from ${t.fromMemberId} could not be delivered after ${n} attempts: ${a.reason}`,display:!0,details:{...a}},{triggerTurn:!0,deliverAs:`steer`}),!0}catch{return!1}}heartbeat(e,t){if(t-this.lastHeartbeatAt<this.options.heartbeatIntervalMs)return;let n=H(e,e.memberId);!n||n.tokenHash!==j(e.token)||!n.active||(this.lastHeartbeatAt=t,G(e,n,t))}collectGarbageIfDue(e,t){if(!(t-this.lastGcAt<this.options.gcIntervalMs)){this.lastGcAt=t;try{Me(e,e.memberId,t)}catch(n){for(this.undeliverableMessages.push({messageId:``,fromMemberId:e.memberId,kind:`send`,attempts:0,reason:`Native team directory sweep failed: ${fe(n)}`,at:t});this.undeliverableMessages.length>32;)this.undeliverableMessages.shift()}}}nextSeq(){return this.outboundSeq+=1,this.outboundSeq}queueMessage(e,t,n,i,a,o){if(Z(e,a),!W(e,t,a))throw Error(`Native team member '${t.memberId}' is no longer active.`);let s={type:f,version:2,id:o,teamId:e.teamId,kind:n,fromMemberId:e.memberId,toMemberId:t.memberId,senderTokenHash:j(e.token),seq:this.nextSeq(),message:i,createdAt:a,expiresAt:a+864e5};return c.mkdirSync(I(e,t.memberId),{recursive:!0,mode:448}),r.writePrivateAtomicJson(R(e,t.memberId,s.id),s),s}replyToRequest(e,t,n,i){if(!t||!w(t))throw Error(`requestId must be a valid intercom request id.`);Z(e,i);let o=R(e,e.memberId,t),s=Te(B(o));if(!s||s.kind!==`ask`||s.teamId!==e.teamId||s.toMemberId!==e.memberId||!Q(e,s.fromMemberId,s.senderTokenHash))throw new a.DoomTeamExpectedError(`recipient_not_found`,`No pending intercom ask matches requestId '${t}'.`,!1,`Call intercom({"action":"pending"}) and retry with an exact requestId.`);let c={type:p,version:2,requestId:t,teamId:e.teamId,fromMemberId:e.memberId,toMemberId:s.fromMemberId,senderTokenHash:j(e.token),message:n,createdAt:i};return r.writePrivateAtomicJson(_e(e,t),c),V(o),this.seenFiles.delete(L(t)),c}async waitForReply(e,t,n,r,i){let o=_e(e,n.id),s=this.options.now()+(i??this.options.askTimeoutMs);for(;this.options.now()<=s;){if(r?.aborted)throw Error(`Native team request cancelled.`);let i=Ee(B(o));if(i&&i.teamId===e.teamId&&i.requestId===n.id&&i.fromMemberId===t.memberId&&i.toMemberId===e.memberId&&Q(e,i.fromMemberId,i.senderTokenHash))return V(o),i;let s=H(e,t.memberId);if(!s||!W(e,s,this.options.now()))throw new a.DoomTeamExpectedError(`communication_unavailable`,`Intercom member '${t.memberId}' became unreachable before replying.`,!0,`Call intercom({"action":"members"}) and decide whether to retry with an active member.`);await Ke(this.options.replyPollIntervalMs,r)}throw new a.DoomTeamExpectedError(`reply_timeout`,`Timed out waiting for intercom member '${t.memberId}' to reply.`,!0,`Check member status before deciding whether to ask again.`)}buildTool(){return{name:d,label:`Intercom`,description:`Communicate with active agents in this root session. Use members, send, ask, pending, or reply. The stable root identity is main.`,promptGuidelines:[`Send only new progress, blockers, or decisions. Do not repeat the task brief, sender task, or delegation instructions because the recipient already has them.`],parameters:ce,execute:async(e,t,n,r)=>{let i=this.context;if(!i)throw new a.DoomTeamExpectedError(`communication_unavailable`,`Intercom is not active for this session.`,!0,`Wait for session startup or reload Doom Team.`);let o=De(t),s=this.options.now();if(Z(i,s),o.action===`members`){let e=q(i,s);return{content:[{type:`text`,text:e.length?e.map(Ge).join(`
3
- `):`No active members.`}],details:{members:e.map($)}}}if(o.action===`pending`){let e=Ue(i,s).messages.filter(e=>e.kind===`ask`),t=e.map(e=>`- ${e.id}: from ${e.fromMemberId}. Reply with ${d}({ action: "reply", requestId: "${e.id}", message: "..." }).`);return{content:[{type:`text`,text:t.length?t.join(`
4
- `):`No pending native team asks.`}],details:{pending:e.map(e=>({id:e.id,from:e.fromMemberId,message:e.message}))}}}let c=He(o.message);if(o.action===`reply`){let e=this.replyToRequest(i,o.requestId,c,s);return{content:[{type:`text`,text:`Replied to native team request ${e.requestId}.`}],details:{requestId:e.requestId,to:e.toMemberId}}}let l=Ve(i,o.to,s);o.action===`ask`&&r?.({content:[{type:`text`,text:`Waiting for ${l.memberId} to reply...`}],details:{action:`ask`,to:l.memberId,partial:!0}});let u=ve(i.memberId,e),f=B(z(i,i.memberId,u));if(f?.state===se){let e=typeof f.reason==`string`?f.reason:`unknown error`;throw new a.DoomTeamExpectedError(`delivery_unconfirmed`,`Intercom message ${u} failed: ${e}`,!1,`Call intercom({"action":"members"}) and do not resend automatically.`)}if(o.action===`send`&&f?.state===C)return{content:[{type:`text`,text:`Message ${u} delivered to ${l.memberId}.`}],details:{state:C,delivered:!0,messageId:u,to:l.memberId}};let p=this.queueMessage(i,l,o.action,c,s,u);if(o.action===`send`)return{content:[{type:`text`,text:`Message ${p.id} queued for ${l.memberId}; delivery is not yet confirmed. Do not resend.`}],details:{state:`queued`,delivered:!1,messageId:p.id,to:l.memberId,seq:p.seq}};try{let e=await this.waitForReply(i,l,p,n,o.timeoutMs);return{content:[{type:`text`,text:`Reply from ${l.memberId}:\n${e.message}`}],details:{requestId:p.id,from:l.memberId,reply:e.message}}}finally{V(R(i,l.memberId,p.id))}}}}},Xe=class{runtimes=new WeakMap;pollIntervalMs=250;replyPollIntervalMs=250;heartbeatIntervalMs=5e3;gcIntervalMs=6e4;askTimeoutMs=6e5;maxDeliveryAttempts=5;now(){return Date.now()}createRuntime(e){let t=this.runtimes.get(e);if(t)return t;let n=new Ye(e,{pollIntervalMs:this.pollIntervalMs,replyPollIntervalMs:this.replyPollIntervalMs,heartbeatIntervalMs:this.heartbeatIntervalMs,gcIntervalMs:this.gcIntervalMs,askTimeoutMs:this.askTimeoutMs,maxDeliveryAttempts:this.maxDeliveryAttempts,now:()=>this.now()});return this.runtimes.set(e,n),e.on(`session_shutdown`,()=>{this.runtimes.get(e)?.dispose()}),n}registerClient(e){i.tryCurrentSessionScope()&&X()&&this.createRuntime(e).bindChildFromEnvironment()}};exports.HEARTBEAT_STALE_MS=3e4,exports.NATIVE_TEAM_TOOL_NAME=d,exports.NativeTeamChannelService=Xe,exports.applyNativeTeamRootEnvironment=Ie,exports.clearNativeTeamMemberEnvironment=Fe,exports.clearNativeTeamRootEnvironment=Le,exports.ensureNativeTeamRoot=Ne,exports.listMemberRecords=K,exports.nativeTeamMemberEnvironment=Pe,exports.nativeTeamRootEnvironment=J,exports.normalizeTeamMemberName=M,exports.processAlive=Oe,exports.readActiveNativeTeamSnapshot=je,exports.readHeartbeat=U,exports.readMember=H,exports.readNativeTeamMemberFromEnvironment=X,exports.readNativeTeamRootFromEnvironment=Y,exports.registerNativeTeamMember=Be,exports.teamDir=N;
1
+ const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../types/environment.cjs"),n=require("../../services/support/lruCache.cjs"),r=require("../atomicJson.cjs"),i=require("../filesystem/paths.cjs"),a=require("../../services/support/boundedKeySet.cjs"),o=require("../../services/support/errors.cjs"),s=require("../../services/support/versioned.cjs");let c=require("node:fs");c=e.__toESM(c,1);let l=require("node:path");l=e.__toESM(l,1);let u=require("node:crypto");const d=`intercom`,f=`subagent.team.message`,p=`subagent.team.reply`,m=`members`,ee=`heartbeats`,h=`inboxes`,g=`replies`,te=`receipts`,ne=`team.json`,_=`.json`,v=`main`,y=`agent`,b=65536,x=4096,re=[`members`,`send`,`ask`,`reply`,`pending`],ie=/^[A-Za-z0-9._-]{1,256}$/,ae=/[^a-z0-9._-]+/g,S=/^[-.]+|[-.]+$/g,oe=`sha256`,C=`delivered`,se=`failed`,ce={oneOf:[...[`members`,`pending`].map(e=>({type:`object`,properties:{action:{const:e}},required:[`action`],additionalProperties:!1})),{type:`object`,properties:{action:{const:`send`},to:{type:`string`},message:{type:`string`}},required:[`action`,`to`,`message`],additionalProperties:!1},{type:`object`,properties:{action:{const:`ask`},to:{type:`string`},message:{type:`string`},timeoutMs:{type:`integer`,minimum:1}},required:[`action`,`to`,`message`],additionalProperties:!1},{type:`object`,properties:{action:{const:`reply`},requestId:{type:`string`},message:{type:`string`}},required:[`action`,`requestId`,`message`],additionalProperties:!1}]};function w(e){return typeof e==`string`&&ie.test(e)}function T(e){return typeof e==`number`&&Number.isInteger(e)}function E(e){return typeof e==`number`&&Number.isFinite(e)}function D(e){return typeof e==`string`&&e.trim().length>0}function O(e){return e===void 0||typeof e==`string`}function le(e){return e===void 0||T(e)}function ue(e){return e===`main`||e===`subagent`}function de(e){return e===`send`||e===`ask`}function k(e,t){return Buffer.byteLength(e,`utf-8`)<=t}function fe(e){return e instanceof Error?e.message:String(e)}function A(e){return process.env[e]?.trim()||void 0}function j(e){return(0,u.createHash)(oe).update(e).digest(`hex`)}function pe(){return(0,u.randomBytes)(32).toString(`base64url`)}function me(e){return`session-${j(e).slice(0,32)}`}function M(e){return e.trim().toLowerCase().replace(ae,`-`).replace(S,``).slice(0,48).replace(S,``)||y}function he(e,t){let n=`-${t+1}`,r=48-n.length;return`${e.slice(0,Math.max(r,0)).replace(S,``)||y}${n}`}function ge(e,t){if(e!==v)return e;if(t)throw Error(`Native team member name '${v}' is reserved for the root session.`);return`main-agent`}function N(e){if(!w(e))throw Error(`Invalid native team id.`);return l.join(i.scopeTeamDir(i.requireCurrentSessionScope()),e)}function P(e,t){if(!w(t))throw Error(`Invalid native team member id.`);return l.join(N(e.teamId),m,`${t}${_}`)}function F(e,t){if(!w(t))throw Error(`Invalid native team member id.`);return l.join(N(e.teamId),ee,`${t}${_}`)}function I(e,t){if(!w(t))throw Error(`Invalid native team member id.`);return l.join(N(e.teamId),h,t)}function L(e){return`${e}${_}`}function R(e,t,n){if(!w(n))throw Error(`Invalid native team message id.`);return l.join(I(e,t),L(n))}function _e(e,t){if(!w(t))throw Error(`Invalid native team request id.`);return l.join(N(e.teamId),g,`${t}${_}`)}function z(e,t,n){if(!w(t)||!w(n))throw Error(`Invalid intercom receipt identity.`);return l.join(N(e.teamId),te,t,`${n}${_}`)}function ve(e,t){return(0,u.createHash)(oe).update(`${e}:${t}`).digest(`hex`)}function ye(e){let t=N(e.teamId);for(let e of[m,ee,h,g,te])c.mkdirSync(l.join(t,e),{recursive:!0,mode:448})}function B(e){try{let t=JSON.parse(c.readFileSync(e,`utf-8`));return t&&typeof t==`object`&&!Array.isArray(t)?t:void 0}catch{return}}function V(e){try{return c.rmSync(e,{force:!0}),!0}catch(e){return e.code===`ENOENT`}}function be(e){try{return c.rmSync(e,{recursive:!0,force:!0}),!0}catch{return!1}}function xe(e){if(!(!s.parseVersioned(e,[1]).ok||!e)&&!(!w(e.teamId)||!D(e.rootSessionId)||e.mainMemberId!==v||!E(e.createdAt)||!E(e.updatedAt)))return{version:1,teamId:e.teamId,rootSessionId:e.rootSessionId,mainMemberId:v,createdAt:e.createdAt,updatedAt:e.updatedAt}}function Se(e){if(!e||typeof e!=`object`||Array.isArray(e))return;let t=e;if(!(!D(t.id)||!D(t.subject))&&!(!k(t.id,256)||!k(t.subject,x)))return{id:t.id,subject:t.subject}}function Ce(e){if(!s.parseVersioned(e,[1]).ok||!e||!w(e.teamId)||!D(e.rootSessionId)||!D(e.mainMemberId)||!w(e.memberId)||!ue(e.role)||!D(e.tokenHash)||!T(e.pid)||typeof e.active!=`boolean`||!E(e.joinedAt)||!O(e.agent)||!O(e.runId)||!le(e.childIndex)||!O(e.parentMemberId))return;let t=e.task===void 0?void 0:Se(e.task);if(!(e.task!==void 0&&!t))return{version:1,teamId:e.teamId,rootSessionId:e.rootSessionId,mainMemberId:e.mainMemberId,memberId:e.memberId,role:e.role,tokenHash:e.tokenHash,pid:e.pid,active:e.active,joinedAt:e.joinedAt,...E(e.leftAt)?{leftAt:e.leftAt}:{},...e.agent===void 0?{}:{agent:e.agent},...e.runId===void 0?{}:{runId:e.runId},...e.childIndex===void 0?{}:{childIndex:e.childIndex},...e.parentMemberId===void 0?{}:{parentMemberId:e.parentMemberId},...t?{task:t}:{}}}function we(e){if(!(!s.parseVersioned(e,[1]).ok||!e)&&!(!w(e.memberId)||!D(e.tokenHash)||!T(e.pid)||!E(e.heartbeatAt)))return{version:1,memberId:e.memberId,tokenHash:e.tokenHash,pid:e.pid,heartbeatAt:e.heartbeatAt}}function Te(e){if(!(!s.parseVersioned(e,[2]).ok||!e)&&!(e.type!==f||!w(e.id)||!w(e.teamId)||!de(e.kind)||!w(e.fromMemberId)||!w(e.toMemberId)||!D(e.senderTokenHash)||!T(e.seq)||typeof e.message!=`string`||!k(e.message,b)||!E(e.createdAt)||!E(e.expiresAt)))return{type:f,version:2,id:e.id,teamId:e.teamId,kind:e.kind,fromMemberId:e.fromMemberId,toMemberId:e.toMemberId,senderTokenHash:e.senderTokenHash,seq:e.seq,message:e.message,createdAt:e.createdAt,expiresAt:e.expiresAt}}function Ee(e){if(!(!s.parseVersioned(e,[2]).ok||!e)&&!(e.type!==p||!w(e.requestId)||!w(e.teamId)||!w(e.fromMemberId)||!w(e.toMemberId)||!D(e.senderTokenHash)||typeof e.message!=`string`||!k(e.message,b)||!E(e.createdAt)))return{type:p,version:2,requestId:e.requestId,teamId:e.teamId,fromMemberId:e.fromMemberId,toMemberId:e.toMemberId,senderTokenHash:e.senderTokenHash,message:e.message,createdAt:e.createdAt}}function De(e){if(!e||typeof e!=`object`||Array.isArray(e))throw o.invalidRequest(`Intercom params must be an object.`,`Use one documented intercom action shape.`);let t=e,n=re.find(e=>e===t.action);if(!n)throw new o.DoomTeamExpectedError(`unsupported_operation`,`Unsupported intercom action: ${String(t.action)}.`,!1,`Use members, send, ask, pending, or reply.`);if(!O(t.to)||!O(t.message)||!O(t.requestId))throw o.invalidRequest(`Intercom to, message and requestId values must be strings.`,`Correct the action fields and retry.`);if(t.timeoutMs!==void 0&&(!T(t.timeoutMs)||t.timeoutMs<1))throw o.invalidRequest(`Intercom timeoutMs must be a positive integer.`,`Correct timeoutMs and retry.`);let r=new Set(n===`members`||n===`pending`?[`action`]:n===`reply`?[`action`,`requestId`,`message`]:n===`ask`?[`action`,`to`,`message`,`timeoutMs`]:[`action`,`to`,`message`]),i=Object.keys(t).filter(e=>!r.has(e));if(i.length)throw o.invalidRequest(`Intercom action '${n}' does not accept: ${i.join(`, `)}.`,`Remove unknown fields and retry.`);return{action:n,...t.to===void 0?{}:{to:t.to},...t.message===void 0?{}:{message:t.message},...t.requestId===void 0?{}:{requestId:t.requestId},...t.timeoutMs===void 0?{}:{timeoutMs:t.timeoutMs}}}function H(e,t){return Ce(B(P(e,t)))}function U(e,t){let n=we(B(F(e,t.memberId)));if(!(!n||n.memberId!==t.memberId||n.tokenHash!==t.tokenHash))return n}function Oe(e){if(e===process.pid)return!0;try{return process.kill(e,0),!0}catch(e){return e.code===`EPERM`}}function ke(e,t){return U(e,t)?.heartbeatAt??t.leftAt??t.joinedAt}function W(e,t,n){return t.active&&Oe(t.pid)&&n-ke(e,t)<=3e4}function Ae(e){c.mkdirSync(I(e,e.memberId),{recursive:!0,mode:448}),r.writePrivateAtomicJson(P(e,e.memberId),e)}function G(e,t,n){let i={version:1,memberId:t.memberId,tokenHash:t.tokenHash,pid:t.pid,heartbeatAt:n};r.writePrivateAtomicJson(F(e,t.memberId),i)}function K(e){let t=l.join(N(e.teamId),m),n;try{n=c.readdirSync(t,{withFileTypes:!0})}catch{return[]}return n.filter(e=>e.isFile()&&e.name.endsWith(_)).map(e=>Ce(B(l.join(t,e.name)))).filter(e=>!!e).filter(t=>t.teamId===e.teamId&&t.rootSessionId===e.rootSessionId)}function q(e,t){return K(e).filter(n=>W(e,n,t)).sort((e,t)=>e.joinedAt-t.joinedAt||e.memberId.localeCompare(t.memberId))}function je(e=Date.now()){let t=Y();if(t)return{members:q(t,e).map($)}}function Me(e,t,n){let r=0;for(let i of K(e))i.memberId!==t&&(W(e,i,n)||n-ke(e,i)<=33e4||(be(I(e,i.memberId)),V(F(e,i.memberId)),V(P(e,i.memberId)),r+=1));return r}function Ne(e){let t=e.trim();if(!t)throw Error(`A root session id is required for native team communication.`);let n={version:1,teamId:me(t),rootSessionId:t,mainMemberId:v};ye(n);let i=l.join(N(n.teamId),ne),a=xe(B(i));if(a&&a.rootSessionId!==t)throw Error(`Native team identity collision detected.`);let o=Date.now(),s={...n,createdAt:a?.createdAt??o,updatedAt:o};return r.writePrivateAtomicJson(i,s),n}function J(e){return{[t.SUBAGENT_TEAM_ID_ENV]:e.teamId,[t.SUBAGENT_TEAM_ROOT_SESSION_ENV]:e.rootSessionId,[t.SUBAGENT_TEAM_MAIN_MEMBER_ENV]:e.mainMemberId}}function Pe(e){return{...J(e),[t.SUBAGENT_TEAM_MEMBER_ID_ENV]:e.memberId,[t.SUBAGENT_TEAM_MEMBER_TOKEN_ENV]:e.token}}function Fe(){return{[t.SUBAGENT_TEAM_MEMBER_ID_ENV]:void 0,[t.SUBAGENT_TEAM_MEMBER_TOKEN_ENV]:void 0}}function Ie(e){Object.assign(process.env,J(e))}function Le(e){e&&process.env.PI_SUBAGENT_TEAM_ID!==e.teamId||(delete process.env[t.SUBAGENT_TEAM_ID_ENV],delete process.env[t.SUBAGENT_TEAM_ROOT_SESSION_ENV],delete process.env[t.SUBAGENT_TEAM_MAIN_MEMBER_ENV])}function Y(){let e=A(t.SUBAGENT_TEAM_ID_ENV),n=A(t.SUBAGENT_TEAM_ROOT_SESSION_ENV),r=A(t.SUBAGENT_TEAM_MAIN_MEMBER_ENV);if(!e||!w(e)||!n||r!==v||e!==me(n))return;let i=xe(B(l.join(N(e),ne)));if(!(!i||i.rootSessionId!==n||i.teamId!==e))return{version:1,teamId:e,rootSessionId:n,mainMemberId:r}}function Re(e){if(!e)return;let t=e.id.trim(),n=e.subject.trim();if(!t||!k(t,256))throw Error(`Native team task id must be between 1 and 256 bytes.`);if(!n||!k(n,x))throw Error(`Native team task subject must be between 1 and ${x} bytes.`);return{id:t,subject:n}}function ze(e){if(e.role===`main`)return e.root.mainMemberId;let t=e.name!==void 0;if(!t&&!e.agent)throw Error(`An intercom member needs a name or an agent to derive one from.`);let n=ge(M(e.name??e.agent??y),t);if(e.runId){let t=M(e.runId).slice(0,8),r=48-t.length-1;return`${n.slice(0,r).replace(S,``)||y}-${t}`}return e.fanoutIndex===void 0?n:he(n,e.fanoutIndex)}function Be(e){let t=ze(e);if(!w(t))throw Error(`A safe native team member id is required.`);let n=pe(),r=j(n),i=Date.now(),a=Re(e.task),o={...e.root,memberId:t,token:n,role:e.role,...e.agent?{agent:e.agent}:{},...e.runId?{runId:e.runId}:{},...e.childIndex===void 0?{}:{childIndex:e.childIndex},...e.parentMemberId?{parentMemberId:e.parentMemberId}:{},...a?{task:a}:{}},s=H(e.root,t);s&&s.tokenHash!==r&&be(I(e.root,t));let{token:c,version:l,...u}=o,d={...u,version:1,tokenHash:r,pid:e.pid??process.pid,active:!0,joinedAt:i};Ae(d),G(e.root,d,i);let f=!1;return{context:o,dispose:()=>{if(f)return;f=!0;let n=H(e.root,t);if(!n||n.tokenHash!==r)return;let i=Date.now();Ae({...n,active:!1,leftAt:i}),G(e.root,n,i)}}}function X(){let e=Y(),n=A(t.SUBAGENT_TEAM_MEMBER_ID_ENV),r=A(t.SUBAGENT_TEAM_MEMBER_TOKEN_ENV);if(!e||!n||!w(n)||!r)return;let i=H(e,n);if(!(!i||i.teamId!==e.teamId||i.rootSessionId!==e.rootSessionId)&&!(i.tokenHash!==j(r)||!i.active))return{...e,memberId:n,token:r,role:i.role,...i.agent?{agent:i.agent}:{},...i.runId?{runId:i.runId}:{},...i.childIndex===void 0?{}:{childIndex:i.childIndex},...i.parentMemberId?{parentMemberId:i.parentMemberId}:{},...i.task?{task:i.task}:{}}}function Z(e,t){let n=H(e,e.memberId);if(!n||n.tokenHash!==j(e.token)||!W(e,n,t))throw Error(`This native team member is no longer active.`);return n}function Ve(e,t,n){let r=t?.trim();if(!r)throw o.invalidRequest(`to is required for intercom send and ask.`,`Provide an explicit recipient.`);let i=q(e,n).filter(t=>t.memberId!==e.memberId),a=M(r),s=i.find(e=>e.memberId===r||e.memberId===a);if(s)return s;let c=r.toLowerCase(),l=i.filter(e=>e.agent?.toLowerCase()===c||e.runId?.toLowerCase()===c||c===v&&e.role===`main`);if(l.length===1)return l[0];throw l.length>1?new o.DoomTeamExpectedError(`recipient_ambiguous`,`Multiple active intercom members match '${r}': ${l.map(e=>e.memberId).join(`, `)}.`,!1,`Retry with one exact member id.`):new o.DoomTeamExpectedError(`recipient_not_found`,`Active intercom member '${r}' was not found.`,!0,`Call intercom({"action":"members"}) and retry with an active member id.`)}function He(e){let t=e?.trim();if(!t)throw o.invalidRequest(`message is required for intercom communication.`,`Provide a nonblank message.`);if(!k(t,b))throw o.invalidRequest(`Intercom message exceeds 64 KiB.`,`Shorten the message and retry.`);return t}function Q(e,t,n){let r=H(e,t);return!!(r&&r.tokenHash===n)}function Ue(e,t,n){let r=I(e,e.memberId),i;try{i=c.readdirSync(r,{withFileTypes:!0})}catch{return{messages:[],foreignFiles:[]}}let a=[],o=[];for(let s of i){if(!s.isFile()||!s.name.endsWith(_)||n?.(s.name))continue;let i=l.join(r,s.name),c=Te(B(i));if(!c){V(i);continue}if(c.teamId!==e.teamId||c.toMemberId!==e.memberId){o.push(s.name);continue}if(c.expiresAt<t||!Q(e,c.fromMemberId,c.senderTokenHash)){V(i);continue}a.push(c)}return{messages:We(a),foreignFiles:o}}function We(e){let t=new Map;for(let n of e){let e=t.get(n.fromMemberId);e?e.push(n):t.set(n.fromMemberId,[n])}let n=[];for(let e of t.values())e.sort((e,t)=>e.seq-t.seq),n.push(e);let r=[];for(;;){let e,t;for(let r of n){let n=r[0];n&&(!t||n.createdAt<t.createdAt||n.createdAt===t.createdAt&&n.fromMemberId<t.fromMemberId)&&(e=r,t=n)}if(!e||!t)break;e.shift(),r.push(t)}return r}function Ge(e){let t=e.role===`main`?v:e.agent??e.memberId,n=e.runId?` [${e.runId}]`:``,r=e.task?`, task ${e.task.id}: ${e.task.subject}`:``;return`- ${e.memberId}: ${t}${n}${r}`}function $(e){return{name:e.memberId,role:e.role,...e.agent?{agent:e.agent}:{},...e.runId?{runId:e.runId}:{},...e.task?{task:e.task}:{}}}function Ke(e,t){return new Promise((n,r)=>{if(t?.aborted){r(Error(`Native team request cancelled.`));return}let i,a=()=>{i&&clearTimeout(i),t?.removeEventListener(`abort`,o)},o=()=>{a(),r(Error(`Native team request cancelled.`))};i=setTimeout(()=>{a(),n()},e),t?.addEventListener(`abort`,o,{once:!0})})}function qe(e,t){let n=H(e,t.fromMemberId),r=`${t.fromMemberId}${n?.agent?` (${n.agent})`:``}`,i=n?.task?`, task ${n.task.id}`:``,a=[`${t.kind===`ask`?`Question`:`Message`} from ${r}${i}.`];return a.push(``,t.message),t.kind===`ask`&&a.push(``,`Reply with ${d}({ action: "reply", requestId: "${t.id}", message: "..." }).`),a.join(`
2
+ `)}function Je(e,t){try{return e.getAllTools().some(e=>e.name===t)}catch{return!1}}var Ye=class{pi;options;context;ownedMembershipDispose;poller;lastHeartbeatAt=0;lastGcAt=0;seenFiles=new a.BoundedKeySet(1024);deliveryAttempts=new n.LruCache(256);undeliverableMessages=[];outboundSeq=0;constructor(e,t){if(this.pi=e,this.options=t,Je(e,`intercom`))throw Error(`[tool_conflict] A foreign '${d}' tool is already registered. Recovery: disable the competing extension and reload Doom Team.`);e.registerTool(this.buildTool())}current(){return this.context}undeliverable(){return this.undeliverableMessages}bindMainSession(e){let t=Ne(e);Ie(t);let n=Be({root:t,role:`main`});return this.startBinding(n.context,n.dispose)}bindChildFromEnvironment(){let e=X();if(e)return this.context?.memberId===e.memberId&&this.context.token===e.token?this.context:this.startBinding(e)}dispose(){let e=this.context;this.stopBinding(),e?.role===`main`&&Le(e)}startBinding(e,t){return this.stopBinding(),this.context=e,this.ownedMembershipDispose=t,this.poll(),this.poller=setInterval(()=>{this.poll()},this.options.pollIntervalMs),this.poller.unref?.(),e}stopBinding(){this.poller&&clearInterval(this.poller),this.poller=void 0,this.ownedMembershipDispose?.(),this.ownedMembershipDispose=void 0,this.seenFiles.clear(),this.deliveryAttempts.clear(),this.lastHeartbeatAt=0,this.lastGcAt=0,this.outboundSeq=0,this.context=void 0}poll(){let e=this.context;if(!e)return;let t=this.options.now();this.heartbeat(e,t),this.collectGarbageIfDue(e,t);let n=Ue(e,t,e=>this.seenFiles.has(e));for(let e of n.foreignFiles)this.seenFiles.add(e);for(let t of n.messages)this.deliverOnce(e,t)}deliverOnce(e,t){let n=L(t.id);try{this.deliver(e,t)}catch(r){let i=(this.deliveryAttempts.get(n)??0)+1;if(i<this.options.maxDeliveryAttempts){this.deliveryAttempts.set(n,i);return}this.deliveryAttempts.delete(n),this.seenFiles.add(n),this.reportUndeliverable(e,t,i,r);return}this.seenFiles.add(n),this.deliveryAttempts.delete(n),r.writePrivateAtomicJson(z(e,t.fromMemberId,t.id),{version:1,messageId:t.id,state:C,deliveredAt:this.options.now()}),t.kind===`send`&&V(R(e,e.memberId,t.id))}deliver(e,t){let n=qe(e,t);if(e.role===`subagent`){this.pi.sendUserMessage(n,{deliverAs:`steer`});return}this.pi.sendMessage({customType:`intercom_message`,content:n,display:!0,details:{id:t.id,kind:t.kind,from:t.fromMemberId,to:t.toMemberId,seq:t.seq}},{triggerTurn:!0,deliverAs:`steer`})}reportUndeliverable(e,t,n,i){let a={messageId:t.id,fromMemberId:t.fromMemberId,kind:t.kind,attempts:n,reason:fe(i),at:this.options.now()};for(this.undeliverableMessages.push(a),r.writePrivateAtomicJson(z(e,t.fromMemberId,t.id),{version:1,messageId:t.id,state:se,reason:a.reason,failedAt:a.at});this.undeliverableMessages.length>32;)this.undeliverableMessages.shift();try{return this.pi.sendMessage({customType:`intercom_undeliverable`,content:`Native team message ${t.id} from ${t.fromMemberId} could not be delivered after ${n} attempts: ${a.reason}`,display:!0,details:{...a}},{triggerTurn:!0,deliverAs:`steer`}),!0}catch{return!1}}heartbeat(e,t){if(t-this.lastHeartbeatAt<this.options.heartbeatIntervalMs)return;let n=H(e,e.memberId);!n||n.tokenHash!==j(e.token)||!n.active||(this.lastHeartbeatAt=t,G(e,n,t))}collectGarbageIfDue(e,t){if(!(t-this.lastGcAt<this.options.gcIntervalMs)){this.lastGcAt=t;try{Me(e,e.memberId,t)}catch(n){for(this.undeliverableMessages.push({messageId:``,fromMemberId:e.memberId,kind:`send`,attempts:0,reason:`Native team directory sweep failed: ${fe(n)}`,at:t});this.undeliverableMessages.length>32;)this.undeliverableMessages.shift()}}}nextSeq(){return this.outboundSeq+=1,this.outboundSeq}queueMessage(e,t,n,i,a,o){if(Z(e,a),!W(e,t,a))throw Error(`Native team member '${t.memberId}' is no longer active.`);let s={type:f,version:2,id:o,teamId:e.teamId,kind:n,fromMemberId:e.memberId,toMemberId:t.memberId,senderTokenHash:j(e.token),seq:this.nextSeq(),message:i,createdAt:a,expiresAt:a+864e5};return c.mkdirSync(I(e,t.memberId),{recursive:!0,mode:448}),r.writePrivateAtomicJson(R(e,t.memberId,s.id),s),s}replyToRequest(e,t,n,i){if(!t||!w(t))throw Error(`requestId must be a valid intercom request id.`);Z(e,i);let a=R(e,e.memberId,t),s=Te(B(a));if(!s||s.kind!==`ask`||s.teamId!==e.teamId||s.toMemberId!==e.memberId||!Q(e,s.fromMemberId,s.senderTokenHash))throw new o.DoomTeamExpectedError(`recipient_not_found`,`No pending intercom ask matches requestId '${t}'.`,!1,`Call intercom({"action":"pending"}) and retry with an exact requestId.`);let c={type:p,version:2,requestId:t,teamId:e.teamId,fromMemberId:e.memberId,toMemberId:s.fromMemberId,senderTokenHash:j(e.token),message:n,createdAt:i};return r.writePrivateAtomicJson(_e(e,t),c),V(a),this.seenFiles.delete(L(t)),c}async waitForReply(e,t,n,r,i){let a=_e(e,n.id),s=this.options.now()+(i??this.options.askTimeoutMs);for(;this.options.now()<=s;){if(r?.aborted)throw Error(`Native team request cancelled.`);let i=Ee(B(a));if(i&&i.teamId===e.teamId&&i.requestId===n.id&&i.fromMemberId===t.memberId&&i.toMemberId===e.memberId&&Q(e,i.fromMemberId,i.senderTokenHash))return V(a),i;let s=H(e,t.memberId);if(!s||!W(e,s,this.options.now()))throw new o.DoomTeamExpectedError(`communication_unavailable`,`Intercom member '${t.memberId}' became unreachable before replying.`,!0,`Call intercom({"action":"members"}) and decide whether to retry with an active member.`);await Ke(this.options.replyPollIntervalMs,r)}throw new o.DoomTeamExpectedError(`reply_timeout`,`Timed out waiting for intercom member '${t.memberId}' to reply.`,!0,`Check member status before deciding whether to ask again.`)}buildTool(){return{name:d,label:`Intercom`,description:`Communicate with active agents in this root session. Use members, send, ask, pending, or reply. The stable root identity is main.`,promptGuidelines:[`Send only new progress, blockers, or decisions. Do not repeat the task brief, sender task, or delegation instructions because the recipient already has them.`],parameters:ce,execute:async(e,t,n,r)=>{let i=this.context;if(!i)throw new o.DoomTeamExpectedError(`communication_unavailable`,`Intercom is not active for this session.`,!0,`Wait for session startup or reload Doom Team.`);let a=De(t),s=this.options.now();if(Z(i,s),a.action===`members`){let e=q(i,s);return{content:[{type:`text`,text:e.length?e.map(Ge).join(`
3
+ `):`No active members.`}],details:{members:e.map($)}}}if(a.action===`pending`){let e=Ue(i,s).messages.filter(e=>e.kind===`ask`),t=e.map(e=>`- ${e.id}: from ${e.fromMemberId}. Reply with ${d}({ action: "reply", requestId: "${e.id}", message: "..." }).`);return{content:[{type:`text`,text:t.length?t.join(`
4
+ `):`No pending native team asks.`}],details:{pending:e.map(e=>({id:e.id,from:e.fromMemberId,message:e.message}))}}}let c=He(a.message);if(a.action===`reply`){let e=this.replyToRequest(i,a.requestId,c,s);return{content:[{type:`text`,text:`Replied to native team request ${e.requestId}.`}],details:{requestId:e.requestId,to:e.toMemberId}}}let l=Ve(i,a.to,s);a.action===`ask`&&r?.({content:[{type:`text`,text:`Waiting for ${l.memberId} to reply...`}],details:{action:`ask`,to:l.memberId,partial:!0}});let u=ve(i.memberId,e),f=B(z(i,i.memberId,u));if(f?.state===se){let e=typeof f.reason==`string`?f.reason:`unknown error`;throw new o.DoomTeamExpectedError(`delivery_unconfirmed`,`Intercom message ${u} failed: ${e}`,!1,`Call intercom({"action":"members"}) and do not resend automatically.`)}if(a.action===`send`&&f?.state===C)return{content:[{type:`text`,text:`Message ${u} delivered to ${l.memberId}.`}],details:{state:C,delivered:!0,messageId:u,to:l.memberId}};let p=this.queueMessage(i,l,a.action,c,s,u);if(a.action===`send`)return{content:[{type:`text`,text:`Message ${p.id} queued for ${l.memberId}; delivery is not yet confirmed. Do not resend.`}],details:{state:`queued`,delivered:!1,messageId:p.id,to:l.memberId,seq:p.seq}};try{let e=await this.waitForReply(i,l,p,n,a.timeoutMs);return{content:[{type:`text`,text:`Reply from ${l.memberId}:\n${e.message}`}],details:{requestId:p.id,from:l.memberId,reply:e.message}}}finally{V(R(i,l.memberId,p.id))}}}}},Xe=class{runtimes=new WeakMap;pollIntervalMs=250;replyPollIntervalMs=250;heartbeatIntervalMs=5e3;gcIntervalMs=6e4;askTimeoutMs=6e5;maxDeliveryAttempts=5;now(){return Date.now()}createRuntime(e){let t=this.runtimes.get(e);if(t)return t;let n=new Ye(e,{pollIntervalMs:this.pollIntervalMs,replyPollIntervalMs:this.replyPollIntervalMs,heartbeatIntervalMs:this.heartbeatIntervalMs,gcIntervalMs:this.gcIntervalMs,askTimeoutMs:this.askTimeoutMs,maxDeliveryAttempts:this.maxDeliveryAttempts,now:()=>this.now()});return this.runtimes.set(e,n),e.on(`session_shutdown`,()=>{this.runtimes.get(e)?.dispose()}),n}registerClient(e){i.tryCurrentSessionScope()&&X()&&this.createRuntime(e).bindChildFromEnvironment()}};exports.HEARTBEAT_STALE_MS=3e4,exports.NATIVE_TEAM_TOOL_NAME=d,exports.NativeTeamChannelService=Xe,exports.applyNativeTeamRootEnvironment=Ie,exports.clearNativeTeamMemberEnvironment=Fe,exports.clearNativeTeamRootEnvironment=Le,exports.ensureNativeTeamRoot=Ne,exports.listMemberRecords=K,exports.nativeTeamMemberEnvironment=Pe,exports.nativeTeamRootEnvironment=J,exports.normalizeTeamMemberName=M,exports.processAlive=Oe,exports.readActiveNativeTeamSnapshot=je,exports.readHeartbeat=U,exports.readMember=H,exports.readNativeTeamMemberFromEnvironment=X,exports.readNativeTeamRootFromEnvironment=Y,exports.registerNativeTeamMember=Be,exports.teamDir=N;
5
5
  //# sourceMappingURL=nativeTeamChannel.cjs.map
@@ -1,5 +1,5 @@
1
- import{__esmMin as e}from"../../../_virtual/_rolldown/runtime.mjs";import{SUBAGENT_TEAM_ID_ENV as t,SUBAGENT_TEAM_MAIN_MEMBER_ENV as n,SUBAGENT_TEAM_MEMBER_ID_ENV as r,SUBAGENT_TEAM_MEMBER_TOKEN_ENV as i,SUBAGENT_TEAM_ROOT_SESSION_ENV as a,init_environment as o}from"../../types/environment.mjs";import{LruCache as s,init_lruCache as c}from"../../services/support/lruCache.mjs";import{init_atomicJson as l,writePrivateAtomicJson as u}from"../atomicJson.mjs";import{init_paths as d,requireCurrentSessionScope as ee,scopeTeamDir as te,tryCurrentSessionScope as ne}from"../filesystem/paths.mjs";import{DoomTeamExpectedError as f,init_errors as re,invalidRequest as p}from"../../services/support/errors.mjs";import{BoundedKeySet as ie,init_boundedKeySet as ae}from"../../services/support/boundedKeySet.mjs";import{init_versioned as oe,parseVersioned as m}from"../../services/support/versioned.mjs";import*as h from"node:fs";import*as g from"node:path";import{createHash as se,randomBytes as ce}from"node:crypto";function _(e){return typeof e==`string`&&At.test(e)}function v(e){return typeof e==`number`&&Number.isInteger(e)}function y(e){return typeof e==`number`&&Number.isFinite(e)}function b(e){return typeof e==`string`&&e.trim().length>0}function x(e){return e===void 0||typeof e==`string`}function le(e){return e===void 0||v(e)}function ue(e){return e===`main`||e===`subagent`}function de(e){return e===`send`||e===`ask`}function S(e,t){return Buffer.byteLength(e,`utf-8`)<=t}function fe(e){return e instanceof Error?e.message:String(e)}function C(e){return process.env[e]?.trim()||void 0}function w(e){return se(Q).update(e).digest(`hex`)}function pe(){return ce(Nt).toString(`base64url`)}function me(e){return`${It}${w(e).slice(0,Mt)}`}function T(e){return e.trim().toLowerCase().replace(jt,ht).replace(Z,``).slice(0,H).replace(Z,``)||V}function he(e,t){let n=`${ht}${t+gt}`,r=H-n.length;return`${e.slice(0,Math.max(r,0)).replace(Z,``)||V}${n}`}function ge(e,t){if(e!==B)return e;if(t)throw Error(`Native team member name '${B}' is reserved for the root session.`);return mt}function E(e){if(!_(e))throw Error(`Invalid native team id.`);return g.join(te(ee()),e)}function _e(e,t){if(!_(t))throw Error(`Invalid native team member id.`);return g.join(E(e.teamId),I,`${t}${z}`)}function ve(e,t){if(!_(t))throw Error(`Invalid native team member id.`);return g.join(E(e.teamId),dt,`${t}${z}`)}function D(e,t){if(!_(t))throw Error(`Invalid native team member id.`);return g.join(E(e.teamId),ft,t)}function ye(e){return`${e}${z}`}function O(e,t,n){if(!_(n))throw Error(`Invalid native team message id.`);return g.join(D(e,t),ye(n))}function be(e,t){if(!_(t))throw Error(`Invalid native team request id.`);return g.join(E(e.teamId),pt,`${t}${z}`)}function xe(e,t,n){if(!_(t)||!_(n))throw Error(`Invalid intercom receipt identity.`);return g.join(E(e.teamId),L,t,`${n}${z}`)}function Se(e,t){return se(Q).update(`${e}:${t}`).digest(`hex`)}function Ce(e){let t=E(e.teamId);for(let e of[I,dt,ft,pt,L])h.mkdirSync(g.join(t,e),{recursive:!0,mode:U})}function k(e){try{let t=JSON.parse(h.readFileSync(e,`utf-8`));return t&&typeof t==`object`&&!Array.isArray(t)?t:void 0}catch{return}}function A(e){try{return h.rmSync(e,{force:!0}),!0}catch(e){return e.code===`ENOENT`}}function we(e){try{return h.rmSync(e,{recursive:!0,force:!0}),!0}catch{return!1}}function Te(e){if(!(!m(e,[q]).ok||!e)&&!(!_(e.teamId)||!b(e.rootSessionId)||e.mainMemberId!==B||!y(e.createdAt)||!y(e.updatedAt)))return{version:q,teamId:e.teamId,rootSessionId:e.rootSessionId,mainMemberId:B,createdAt:e.createdAt,updatedAt:e.updatedAt}}function Ee(e){if(!e||typeof e!=`object`||Array.isArray(e))return;let t=e;if(!(!b(t.id)||!b(t.subject))&&!(!S(t.id,G)||!S(t.subject,K)))return{id:t.id,subject:t.subject}}function De(e){if(!m(e,[J]).ok||!e||!_(e.teamId)||!b(e.rootSessionId)||!b(e.mainMemberId)||!_(e.memberId)||!ue(e.role)||!b(e.tokenHash)||!v(e.pid)||typeof e.active!=`boolean`||!y(e.joinedAt)||!x(e.agent)||!x(e.runId)||!le(e.childIndex)||!x(e.parentMemberId))return;let t=e.task===void 0?void 0:Ee(e.task);if(!(e.task!==void 0&&!t))return{version:J,teamId:e.teamId,rootSessionId:e.rootSessionId,mainMemberId:e.mainMemberId,memberId:e.memberId,role:e.role,tokenHash:e.tokenHash,pid:e.pid,active:e.active,joinedAt:e.joinedAt,...y(e.leftAt)?{leftAt:e.leftAt}:{},...e.agent===void 0?{}:{agent:e.agent},...e.runId===void 0?{}:{runId:e.runId},...e.childIndex===void 0?{}:{childIndex:e.childIndex},...e.parentMemberId===void 0?{}:{parentMemberId:e.parentMemberId},...t?{task:t}:{}}}function Oe(e){if(!(!m(e,[Y]).ok||!e)&&!(!_(e.memberId)||!b(e.tokenHash)||!v(e.pid)||!y(e.heartbeatAt)))return{version:Y,memberId:e.memberId,tokenHash:e.tokenHash,pid:e.pid,heartbeatAt:e.heartbeatAt}}function ke(e){if(!(!m(e,[X]).ok||!e)&&!(e.type!==P||!_(e.id)||!_(e.teamId)||!de(e.kind)||!_(e.fromMemberId)||!_(e.toMemberId)||!b(e.senderTokenHash)||!v(e.seq)||typeof e.message!=`string`||!S(e.message,W)||!y(e.createdAt)||!y(e.expiresAt)))return{type:P,version:X,id:e.id,teamId:e.teamId,kind:e.kind,fromMemberId:e.fromMemberId,toMemberId:e.toMemberId,senderTokenHash:e.senderTokenHash,seq:e.seq,message:e.message,createdAt:e.createdAt,expiresAt:e.expiresAt}}function Ae(e){if(!(!m(e,[X]).ok||!e)&&!(e.type!==F||!_(e.requestId)||!_(e.teamId)||!_(e.fromMemberId)||!_(e.toMemberId)||!b(e.senderTokenHash)||typeof e.message!=`string`||!S(e.message,W)||!y(e.createdAt)))return{type:F,version:X,requestId:e.requestId,teamId:e.teamId,fromMemberId:e.fromMemberId,toMemberId:e.toMemberId,senderTokenHash:e.senderTokenHash,message:e.message,createdAt:e.createdAt}}function je(e){if(!e||typeof e!=`object`||Array.isArray(e))throw p(`Intercom params must be an object.`,`Use one documented intercom action shape.`);let t=e,n=kt.find(e=>e===t.action);if(!n)throw new f(`unsupported_operation`,`Unsupported intercom action: ${String(t.action)}.`,!1,`Use members, send, ask, pending, or reply.`);if(!x(t.to)||!x(t.message)||!x(t.requestId))throw p(`Intercom to, message and requestId values must be strings.`,`Correct the action fields and retry.`);if(t.timeoutMs!==void 0&&(!v(t.timeoutMs)||t.timeoutMs<1))throw p(`Intercom timeoutMs must be a positive integer.`,`Correct timeoutMs and retry.`);let r=new Set(n===`members`||n===`pending`?[`action`]:n===`reply`?[`action`,`requestId`,`message`]:n===`ask`?[`action`,`to`,`message`,`timeoutMs`]:[`action`,`to`,`message`]),i=Object.keys(t).filter(e=>!r.has(e));if(i.length)throw p(`Intercom action '${n}' does not accept: ${i.join(`, `)}.`,`Remove unknown fields and retry.`);return{action:n,...t.to===void 0?{}:{to:t.to},...t.message===void 0?{}:{message:t.message},...t.requestId===void 0?{}:{requestId:t.requestId},...t.timeoutMs===void 0?{}:{timeoutMs:t.timeoutMs}}}function j(e,t){return De(k(_e(e,t)))}function Me(e,t){let n=Oe(k(ve(e,t.memberId)));if(!(!n||n.memberId!==t.memberId||n.tokenHash!==t.tokenHash))return n}function Ne(e){if(e===process.pid)return!0;try{return process.kill(e,0),!0}catch(e){return e.code===`EPERM`}}function Pe(e,t){return Me(e,t)?.heartbeatAt??t.leftAt??t.joinedAt}function M(e,t,n){return t.active&&Ne(t.pid)&&n-Pe(e,t)<=3e4}function Fe(e){h.mkdirSync(D(e,e.memberId),{recursive:!0,mode:U}),u(_e(e,e.memberId),e)}function Ie(e,t,n){let r={version:Y,memberId:t.memberId,tokenHash:t.tokenHash,pid:t.pid,heartbeatAt:n};u(ve(e,t.memberId),r)}function Le(e){let t=g.join(E(e.teamId),I),n;try{n=h.readdirSync(t,{withFileTypes:!0})}catch{return[]}return n.filter(e=>e.isFile()&&e.name.endsWith(z)).map(e=>De(k(g.join(t,e.name)))).filter(e=>!!e).filter(t=>t.teamId===e.teamId&&t.rootSessionId===e.rootSessionId)}function Re(e,t){return Le(e).filter(n=>M(e,n,t)).sort((e,t)=>e.joinedAt-t.joinedAt||e.memberId.localeCompare(t.memberId))}function ze(e=Date.now()){let t=qe();if(t)return{members:Re(t,e).map(at)}}function Be(e,t,n){let r=0;for(let i of Le(e))i.memberId!==t&&(M(e,i,n)||n-Pe(e,i)<=33e4||(we(D(e,i.memberId)),A(ve(e,i.memberId)),A(_e(e,i.memberId)),r+=1));return r}function Ve(e){let t=e.trim();if(!t)throw Error(`A root session id is required for native team communication.`);let n={version:q,teamId:me(t),rootSessionId:t,mainMemberId:B};Ce(n);let r=g.join(E(n.teamId),R),i=Te(k(r));if(i&&i.rootSessionId!==t)throw Error(`Native team identity collision detected.`);let a=Date.now(),o={...n,createdAt:i?.createdAt??a,updatedAt:a};return u(r,o),n}function He(e){return{[t]:e.teamId,[a]:e.rootSessionId,[n]:e.mainMemberId}}function Ue(e){return{...He(e),[r]:e.memberId,[i]:e.token}}function We(){return{[r]:void 0,[i]:void 0}}function Ge(e){Object.assign(process.env,He(e))}function Ke(e){e&&process.env.PI_SUBAGENT_TEAM_ID!==e.teamId||(delete process.env[t],delete process.env[a],delete process.env[n])}function qe(){let e=C(t),r=C(a),i=C(n);if(!e||!_(e)||!r||i!==B||e!==me(r))return;let o=Te(k(g.join(E(e),R)));if(!(!o||o.rootSessionId!==r||o.teamId!==e))return{version:q,teamId:e,rootSessionId:r,mainMemberId:i}}function Je(e){if(!e)return;let t=e.id.trim(),n=e.subject.trim();if(!t||!S(t,G))throw Error(`Native team task id must be between 1 and ${G} bytes.`);if(!n||!S(n,K))throw Error(`Native team task subject must be between 1 and ${K} bytes.`);return{id:t,subject:n}}function Ye(e){if(e.role===`main`)return e.root.mainMemberId;let t=e.name!==void 0;if(!t&&!e.agent)throw Error(`An intercom member needs a name or an agent to derive one from.`);let n=ge(T(e.name??e.agent??V),t);if(e.runId){let t=T(e.runId).slice(0,8),r=H-t.length-1;return`${n.slice(0,r).replace(Z,``)||V}-${t}`}return e.fanoutIndex===void 0?n:he(n,e.fanoutIndex)}function Xe(e){let t=Ye(e);if(!_(t))throw Error(`A safe native team member id is required.`);let n=pe(),r=w(n),i=Date.now(),a=Je(e.task),o={...e.root,memberId:t,token:n,role:e.role,...e.agent?{agent:e.agent}:{},...e.runId?{runId:e.runId}:{},...e.childIndex===void 0?{}:{childIndex:e.childIndex},...e.parentMemberId?{parentMemberId:e.parentMemberId}:{},...a?{task:a}:{}},s=j(e.root,t);s&&s.tokenHash!==r&&we(D(e.root,t));let{token:c,version:l,...u}=o,d={...u,version:J,tokenHash:r,pid:e.pid??process.pid,active:!0,joinedAt:i};Fe(d),Ie(e.root,d,i);let ee=!1;return{context:o,dispose:()=>{if(ee)return;ee=!0;let n=j(e.root,t);if(!n||n.tokenHash!==r)return;let i=Date.now();Fe({...n,active:!1,leftAt:i}),Ie(e.root,n,i)}}}function Ze(){let e=qe(),t=C(r),n=C(i);if(!e||!t||!_(t)||!n)return;let a=j(e,t);if(!(!a||a.teamId!==e.teamId||a.rootSessionId!==e.rootSessionId)&&!(a.tokenHash!==w(n)||!a.active))return{...e,memberId:t,token:n,role:a.role,...a.agent?{agent:a.agent}:{},...a.runId?{runId:a.runId}:{},...a.childIndex===void 0?{}:{childIndex:a.childIndex},...a.parentMemberId?{parentMemberId:a.parentMemberId}:{},...a.task?{task:a.task}:{}}}function Qe(e,t){let n=j(e,e.memberId);if(!n||n.tokenHash!==w(e.token)||!M(e,n,t))throw Error(`This native team member is no longer active.`);return n}function $e(e,t,n){let r=t?.trim();if(!r)throw p(`to is required for intercom send and ask.`,`Provide an explicit recipient.`);let i=Re(e,n).filter(t=>t.memberId!==e.memberId),a=T(r),o=i.find(e=>e.memberId===r||e.memberId===a);if(o)return o;let s=r.toLowerCase(),c=i.filter(e=>e.agent?.toLowerCase()===s||e.runId?.toLowerCase()===s||s===B&&e.role===`main`);if(c.length===1)return c[0];throw c.length>1?new f(`recipient_ambiguous`,`Multiple active intercom members match '${r}': ${c.map(e=>e.memberId).join(`, `)}.`,!1,`Retry with one exact member id.`):new f(`recipient_not_found`,`Active intercom member '${r}' was not found.`,!0,`Call intercom({"action":"members"}) and retry with an active member id.`)}function et(e){let t=e?.trim();if(!t)throw p(`message is required for intercom communication.`,`Provide a nonblank message.`);if(!S(t,W))throw p(`Intercom message exceeds 64 KiB.`,`Shorten the message and retry.`);return t}function tt(e,t,n){let r=j(e,t);return!!(r&&r.tokenHash===n)}function nt(e,t,n){let r=D(e,e.memberId),i;try{i=h.readdirSync(r,{withFileTypes:!0})}catch{return{messages:[],foreignFiles:[]}}let a=[],o=[];for(let s of i){if(!s.isFile()||!s.name.endsWith(z)||n?.(s.name))continue;let i=g.join(r,s.name),c=ke(k(i));if(!c){A(i);continue}if(c.teamId!==e.teamId||c.toMemberId!==e.memberId){o.push(s.name);continue}if(c.expiresAt<t||!tt(e,c.fromMemberId,c.senderTokenHash)){A(i);continue}a.push(c)}return{messages:rt(a),foreignFiles:o}}function rt(e){let t=new Map;for(let n of e){let e=t.get(n.fromMemberId);e?e.push(n):t.set(n.fromMemberId,[n])}let n=[];for(let e of t.values())e.sort((e,t)=>e.seq-t.seq),n.push(e);let r=[];for(;;){let e,t;for(let r of n){let n=r[0];n&&(!t||n.createdAt<t.createdAt||n.createdAt===t.createdAt&&n.fromMemberId<t.fromMemberId)&&(e=r,t=n)}if(!e||!t)break;e.shift(),r.push(t)}return r}function it(e){let t=e.role===`main`?B:e.agent??e.memberId,n=e.runId?` [${e.runId}]`:``,r=e.task?`, task ${e.task.id}: ${e.task.subject}`:``;return`- ${e.memberId}: ${t}${n}${r}`}function at(e){return{name:e.memberId,role:e.role,...e.agent?{agent:e.agent}:{},...e.runId?{runId:e.runId}:{},...e.task?{task:e.task}:{}}}function ot(e,t){return new Promise((n,r)=>{if(t?.aborted){r(Error(`Native team request cancelled.`));return}let i,a=()=>{i&&clearTimeout(i),t?.removeEventListener(`abort`,o)},o=()=>{a(),r(Error(`Native team request cancelled.`))};i=setTimeout(()=>{a(),n()},e),t?.addEventListener(`abort`,o,{once:!0})})}function st(e,t){let n=j(e,t.fromMemberId),r=`${t.fromMemberId}${n?.agent?` (${n.agent})`:``}`,i=n?.task?`, task ${n.task.id}`:``,a=[`${t.kind===`ask`?`Question`:`Message`} from ${r}${i}.`];return a.push(``,t.message),t.kind===`ask`&&a.push(``,`Reply with ${N}({ action: "reply", requestId: "${t.id}", message: "..." }).`),a.join(`
2
- `)}function ct(e,t){try{return e.getAllTools().some(e=>e.name===t)}catch{return!1}}var N,P,F,lt,ut,I,dt,ft,pt,L,R,z,B,mt,V,H,ht,gt,U,W,G,K,_t,vt,yt,bt,xt,St,Ct,wt,Tt,Et,Dt,Ot,q,J,Y,X,kt,At,jt,Z,Mt,Nt,Q,Pt,$,Ft,It,Lt,Rt,zt,Bt=e((()=>{o(),l(),ae(),re(),c(),d(),oe(),N=`intercom`,P=`subagent.team.message`,F=`subagent.team.reply`,lt=`intercom_message`,ut=`intercom_undeliverable`,I=`members`,dt=`heartbeats`,ft=`inboxes`,pt=`replies`,L=`receipts`,R=`team.json`,z=`.json`,B=`main`,mt=`main-agent`,V=`agent`,H=48,ht=`-`,gt=1,U=448,W=65536,G=256,K=4096,_t=864e5,vt=6e5,yt=5e3,bt=3e4,xt=250,St=250,Ct=5,wt=1,Tt=1024,Et=256,Dt=32,Ot=6e4,q=1,J=1,Y=1,X=2,kt=[`members`,`send`,`ask`,`reply`,`pending`],At=/^[A-Za-z0-9._-]{1,256}$/,jt=/[^a-z0-9._-]+/g,Z=/^[-.]+|[-.]+$/g,Mt=32,Nt=32,Q=`sha256`,Pt=1,$=`delivered`,Ft=`failed`,It=`session-`,Lt={oneOf:[...[`members`,`pending`].map(e=>({type:`object`,properties:{action:{const:e}},required:[`action`],additionalProperties:!1})),{type:`object`,properties:{action:{const:`send`},to:{type:`string`},message:{type:`string`}},required:[`action`,`to`,`message`],additionalProperties:!1},{type:`object`,properties:{action:{const:`ask`},to:{type:`string`},message:{type:`string`},timeoutMs:{type:`integer`,minimum:1}},required:[`action`,`to`,`message`],additionalProperties:!1},{type:`object`,properties:{action:{const:`reply`},requestId:{type:`string`},message:{type:`string`}},required:[`action`,`requestId`,`message`],additionalProperties:!1}]},Rt=class{pi;options;context;ownedMembershipDispose;poller;lastHeartbeatAt=0;lastGcAt=0;seenFiles=new ie(Tt);deliveryAttempts=new s(Et);undeliverableMessages=[];outboundSeq=0;constructor(e,t){if(this.pi=e,this.options=t,ct(e,`intercom`))throw Error(`[tool_conflict] A foreign '${N}' tool is already registered. Recovery: disable the competing extension and reload Doom Team.`);e.registerTool(this.buildTool())}current(){return this.context}undeliverable(){return this.undeliverableMessages}bindMainSession(e){let t=Ve(e);Ge(t);let n=Xe({root:t,role:`main`});return this.startBinding(n.context,n.dispose)}bindChildFromEnvironment(){let e=Ze();if(e)return this.context?.memberId===e.memberId&&this.context.token===e.token?this.context:this.startBinding(e)}dispose(){let e=this.context;this.stopBinding(),e?.role===`main`&&Ke(e)}startBinding(e,t){return this.stopBinding(),this.context=e,this.ownedMembershipDispose=t,this.poll(),this.poller=setInterval(()=>{this.poll()},this.options.pollIntervalMs),this.poller.unref?.(),e}stopBinding(){this.poller&&clearInterval(this.poller),this.poller=void 0,this.ownedMembershipDispose?.(),this.ownedMembershipDispose=void 0,this.seenFiles.clear(),this.deliveryAttempts.clear(),this.lastHeartbeatAt=0,this.lastGcAt=0,this.outboundSeq=0,this.context=void 0}poll(){let e=this.context;if(!e)return;let t=this.options.now();this.heartbeat(e,t),this.collectGarbageIfDue(e,t);let n=nt(e,t,e=>this.seenFiles.has(e));for(let e of n.foreignFiles)this.seenFiles.add(e);for(let t of n.messages)this.deliverOnce(e,t)}deliverOnce(e,t){let n=ye(t.id);try{this.deliver(e,t)}catch(r){let i=(this.deliveryAttempts.get(n)??0)+wt;if(i<this.options.maxDeliveryAttempts){this.deliveryAttempts.set(n,i);return}this.deliveryAttempts.delete(n),this.seenFiles.add(n),this.reportUndeliverable(e,t,i,r);return}this.seenFiles.add(n),this.deliveryAttempts.delete(n),u(xe(e,t.fromMemberId,t.id),{version:Pt,messageId:t.id,state:$,deliveredAt:this.options.now()}),t.kind===`send`&&A(O(e,e.memberId,t.id))}deliver(e,t){let n=st(e,t);if(e.role===`subagent`){this.pi.sendUserMessage(n,{deliverAs:`steer`});return}this.pi.sendMessage({customType:lt,content:n,display:!0,details:{id:t.id,kind:t.kind,from:t.fromMemberId,to:t.toMemberId,seq:t.seq}},{triggerTurn:!0,deliverAs:`steer`})}reportUndeliverable(e,t,n,r){let i={messageId:t.id,fromMemberId:t.fromMemberId,kind:t.kind,attempts:n,reason:fe(r),at:this.options.now()};for(this.undeliverableMessages.push(i),u(xe(e,t.fromMemberId,t.id),{version:Pt,messageId:t.id,state:Ft,reason:i.reason,failedAt:i.at});this.undeliverableMessages.length>Dt;)this.undeliverableMessages.shift();try{return this.pi.sendMessage({customType:ut,content:`Native team message ${t.id} from ${t.fromMemberId} could not be delivered after ${n} attempts: ${i.reason}`,display:!0,details:{...i}},{triggerTurn:!0,deliverAs:`steer`}),!0}catch{return!1}}heartbeat(e,t){if(t-this.lastHeartbeatAt<this.options.heartbeatIntervalMs)return;let n=j(e,e.memberId);!n||n.tokenHash!==w(e.token)||!n.active||(this.lastHeartbeatAt=t,Ie(e,n,t))}collectGarbageIfDue(e,t){if(!(t-this.lastGcAt<this.options.gcIntervalMs)){this.lastGcAt=t;try{Be(e,e.memberId,t)}catch(n){for(this.undeliverableMessages.push({messageId:``,fromMemberId:e.memberId,kind:`send`,attempts:0,reason:`Native team directory sweep failed: ${fe(n)}`,at:t});this.undeliverableMessages.length>Dt;)this.undeliverableMessages.shift()}}}nextSeq(){return this.outboundSeq+=1,this.outboundSeq}queueMessage(e,t,n,r,i,a){if(Qe(e,i),!M(e,t,i))throw Error(`Native team member '${t.memberId}' is no longer active.`);let o={type:P,version:X,id:a,teamId:e.teamId,kind:n,fromMemberId:e.memberId,toMemberId:t.memberId,senderTokenHash:w(e.token),seq:this.nextSeq(),message:r,createdAt:i,expiresAt:i+_t};return h.mkdirSync(D(e,t.memberId),{recursive:!0,mode:U}),u(O(e,t.memberId,o.id),o),o}replyToRequest(e,t,n,r){if(!t||!_(t))throw Error(`requestId must be a valid intercom request id.`);Qe(e,r);let i=O(e,e.memberId,t),a=ke(k(i));if(!a||a.kind!==`ask`||a.teamId!==e.teamId||a.toMemberId!==e.memberId||!tt(e,a.fromMemberId,a.senderTokenHash))throw new f(`recipient_not_found`,`No pending intercom ask matches requestId '${t}'.`,!1,`Call intercom({"action":"pending"}) and retry with an exact requestId.`);let o={type:F,version:X,requestId:t,teamId:e.teamId,fromMemberId:e.memberId,toMemberId:a.fromMemberId,senderTokenHash:w(e.token),message:n,createdAt:r};return u(be(e,t),o),A(i),this.seenFiles.delete(ye(t)),o}async waitForReply(e,t,n,r,i){let a=be(e,n.id),o=this.options.now()+(i??this.options.askTimeoutMs);for(;this.options.now()<=o;){if(r?.aborted)throw Error(`Native team request cancelled.`);let i=Ae(k(a));if(i&&i.teamId===e.teamId&&i.requestId===n.id&&i.fromMemberId===t.memberId&&i.toMemberId===e.memberId&&tt(e,i.fromMemberId,i.senderTokenHash))return A(a),i;let o=j(e,t.memberId);if(!o||!M(e,o,this.options.now()))throw new f(`communication_unavailable`,`Intercom member '${t.memberId}' became unreachable before replying.`,!0,`Call intercom({"action":"members"}) and decide whether to retry with an active member.`);await ot(this.options.replyPollIntervalMs,r)}throw new f(`reply_timeout`,`Timed out waiting for intercom member '${t.memberId}' to reply.`,!0,`Check member status before deciding whether to ask again.`)}buildTool(){return{name:N,label:`Intercom`,description:`Communicate with active agents in this root session. Use members, send, ask, pending, or reply. The stable root identity is main.`,promptGuidelines:[`Send only new progress, blockers, or decisions. Do not repeat the task brief, sender task, or delegation instructions because the recipient already has them.`],parameters:Lt,execute:async(e,t,n,r)=>{let i=this.context;if(!i)throw new f(`communication_unavailable`,`Intercom is not active for this session.`,!0,`Wait for session startup or reload Doom Team.`);let a=je(t),o=this.options.now();if(Qe(i,o),a.action===`members`){let e=Re(i,o);return{content:[{type:`text`,text:e.length?e.map(it).join(`
1
+ import{__esmMin as e}from"../../../_virtual/_rolldown/runtime.mjs";import{SUBAGENT_TEAM_ID_ENV as t,SUBAGENT_TEAM_MAIN_MEMBER_ENV as n,SUBAGENT_TEAM_MEMBER_ID_ENV as r,SUBAGENT_TEAM_MEMBER_TOKEN_ENV as i,SUBAGENT_TEAM_ROOT_SESSION_ENV as a,init_environment as o}from"../../types/environment.mjs";import{LruCache as s,init_lruCache as c}from"../../services/support/lruCache.mjs";import{init_atomicJson as l,writePrivateAtomicJson as u}from"../atomicJson.mjs";import{init_paths as d,requireCurrentSessionScope as ee,scopeTeamDir as te,tryCurrentSessionScope as ne}from"../filesystem/paths.mjs";import{BoundedKeySet as re,init_boundedKeySet as ie}from"../../services/support/boundedKeySet.mjs";import{DoomTeamExpectedError as f,init_errors as ae,invalidRequest as p}from"../../services/support/errors.mjs";import{init_versioned as oe,parseVersioned as m}from"../../services/support/versioned.mjs";import*as h from"node:fs";import*as g from"node:path";import{createHash as se,randomBytes as ce}from"node:crypto";function _(e){return typeof e==`string`&&At.test(e)}function v(e){return typeof e==`number`&&Number.isInteger(e)}function y(e){return typeof e==`number`&&Number.isFinite(e)}function b(e){return typeof e==`string`&&e.trim().length>0}function x(e){return e===void 0||typeof e==`string`}function le(e){return e===void 0||v(e)}function ue(e){return e===`main`||e===`subagent`}function de(e){return e===`send`||e===`ask`}function S(e,t){return Buffer.byteLength(e,`utf-8`)<=t}function fe(e){return e instanceof Error?e.message:String(e)}function C(e){return process.env[e]?.trim()||void 0}function w(e){return se(Q).update(e).digest(`hex`)}function pe(){return ce(Nt).toString(`base64url`)}function me(e){return`${It}${w(e).slice(0,Mt)}`}function T(e){return e.trim().toLowerCase().replace(jt,ht).replace(Z,``).slice(0,H).replace(Z,``)||V}function he(e,t){let n=`${ht}${t+gt}`,r=H-n.length;return`${e.slice(0,Math.max(r,0)).replace(Z,``)||V}${n}`}function ge(e,t){if(e!==B)return e;if(t)throw Error(`Native team member name '${B}' is reserved for the root session.`);return mt}function E(e){if(!_(e))throw Error(`Invalid native team id.`);return g.join(te(ee()),e)}function _e(e,t){if(!_(t))throw Error(`Invalid native team member id.`);return g.join(E(e.teamId),I,`${t}${z}`)}function ve(e,t){if(!_(t))throw Error(`Invalid native team member id.`);return g.join(E(e.teamId),dt,`${t}${z}`)}function D(e,t){if(!_(t))throw Error(`Invalid native team member id.`);return g.join(E(e.teamId),ft,t)}function ye(e){return`${e}${z}`}function O(e,t,n){if(!_(n))throw Error(`Invalid native team message id.`);return g.join(D(e,t),ye(n))}function be(e,t){if(!_(t))throw Error(`Invalid native team request id.`);return g.join(E(e.teamId),pt,`${t}${z}`)}function xe(e,t,n){if(!_(t)||!_(n))throw Error(`Invalid intercom receipt identity.`);return g.join(E(e.teamId),L,t,`${n}${z}`)}function Se(e,t){return se(Q).update(`${e}:${t}`).digest(`hex`)}function Ce(e){let t=E(e.teamId);for(let e of[I,dt,ft,pt,L])h.mkdirSync(g.join(t,e),{recursive:!0,mode:U})}function k(e){try{let t=JSON.parse(h.readFileSync(e,`utf-8`));return t&&typeof t==`object`&&!Array.isArray(t)?t:void 0}catch{return}}function A(e){try{return h.rmSync(e,{force:!0}),!0}catch(e){return e.code===`ENOENT`}}function we(e){try{return h.rmSync(e,{recursive:!0,force:!0}),!0}catch{return!1}}function Te(e){if(!(!m(e,[q]).ok||!e)&&!(!_(e.teamId)||!b(e.rootSessionId)||e.mainMemberId!==B||!y(e.createdAt)||!y(e.updatedAt)))return{version:q,teamId:e.teamId,rootSessionId:e.rootSessionId,mainMemberId:B,createdAt:e.createdAt,updatedAt:e.updatedAt}}function Ee(e){if(!e||typeof e!=`object`||Array.isArray(e))return;let t=e;if(!(!b(t.id)||!b(t.subject))&&!(!S(t.id,G)||!S(t.subject,K)))return{id:t.id,subject:t.subject}}function De(e){if(!m(e,[J]).ok||!e||!_(e.teamId)||!b(e.rootSessionId)||!b(e.mainMemberId)||!_(e.memberId)||!ue(e.role)||!b(e.tokenHash)||!v(e.pid)||typeof e.active!=`boolean`||!y(e.joinedAt)||!x(e.agent)||!x(e.runId)||!le(e.childIndex)||!x(e.parentMemberId))return;let t=e.task===void 0?void 0:Ee(e.task);if(!(e.task!==void 0&&!t))return{version:J,teamId:e.teamId,rootSessionId:e.rootSessionId,mainMemberId:e.mainMemberId,memberId:e.memberId,role:e.role,tokenHash:e.tokenHash,pid:e.pid,active:e.active,joinedAt:e.joinedAt,...y(e.leftAt)?{leftAt:e.leftAt}:{},...e.agent===void 0?{}:{agent:e.agent},...e.runId===void 0?{}:{runId:e.runId},...e.childIndex===void 0?{}:{childIndex:e.childIndex},...e.parentMemberId===void 0?{}:{parentMemberId:e.parentMemberId},...t?{task:t}:{}}}function Oe(e){if(!(!m(e,[Y]).ok||!e)&&!(!_(e.memberId)||!b(e.tokenHash)||!v(e.pid)||!y(e.heartbeatAt)))return{version:Y,memberId:e.memberId,tokenHash:e.tokenHash,pid:e.pid,heartbeatAt:e.heartbeatAt}}function ke(e){if(!(!m(e,[X]).ok||!e)&&!(e.type!==P||!_(e.id)||!_(e.teamId)||!de(e.kind)||!_(e.fromMemberId)||!_(e.toMemberId)||!b(e.senderTokenHash)||!v(e.seq)||typeof e.message!=`string`||!S(e.message,W)||!y(e.createdAt)||!y(e.expiresAt)))return{type:P,version:X,id:e.id,teamId:e.teamId,kind:e.kind,fromMemberId:e.fromMemberId,toMemberId:e.toMemberId,senderTokenHash:e.senderTokenHash,seq:e.seq,message:e.message,createdAt:e.createdAt,expiresAt:e.expiresAt}}function Ae(e){if(!(!m(e,[X]).ok||!e)&&!(e.type!==F||!_(e.requestId)||!_(e.teamId)||!_(e.fromMemberId)||!_(e.toMemberId)||!b(e.senderTokenHash)||typeof e.message!=`string`||!S(e.message,W)||!y(e.createdAt)))return{type:F,version:X,requestId:e.requestId,teamId:e.teamId,fromMemberId:e.fromMemberId,toMemberId:e.toMemberId,senderTokenHash:e.senderTokenHash,message:e.message,createdAt:e.createdAt}}function je(e){if(!e||typeof e!=`object`||Array.isArray(e))throw p(`Intercom params must be an object.`,`Use one documented intercom action shape.`);let t=e,n=kt.find(e=>e===t.action);if(!n)throw new f(`unsupported_operation`,`Unsupported intercom action: ${String(t.action)}.`,!1,`Use members, send, ask, pending, or reply.`);if(!x(t.to)||!x(t.message)||!x(t.requestId))throw p(`Intercom to, message and requestId values must be strings.`,`Correct the action fields and retry.`);if(t.timeoutMs!==void 0&&(!v(t.timeoutMs)||t.timeoutMs<1))throw p(`Intercom timeoutMs must be a positive integer.`,`Correct timeoutMs and retry.`);let r=new Set(n===`members`||n===`pending`?[`action`]:n===`reply`?[`action`,`requestId`,`message`]:n===`ask`?[`action`,`to`,`message`,`timeoutMs`]:[`action`,`to`,`message`]),i=Object.keys(t).filter(e=>!r.has(e));if(i.length)throw p(`Intercom action '${n}' does not accept: ${i.join(`, `)}.`,`Remove unknown fields and retry.`);return{action:n,...t.to===void 0?{}:{to:t.to},...t.message===void 0?{}:{message:t.message},...t.requestId===void 0?{}:{requestId:t.requestId},...t.timeoutMs===void 0?{}:{timeoutMs:t.timeoutMs}}}function j(e,t){return De(k(_e(e,t)))}function Me(e,t){let n=Oe(k(ve(e,t.memberId)));if(!(!n||n.memberId!==t.memberId||n.tokenHash!==t.tokenHash))return n}function Ne(e){if(e===process.pid)return!0;try{return process.kill(e,0),!0}catch(e){return e.code===`EPERM`}}function Pe(e,t){return Me(e,t)?.heartbeatAt??t.leftAt??t.joinedAt}function M(e,t,n){return t.active&&Ne(t.pid)&&n-Pe(e,t)<=3e4}function Fe(e){h.mkdirSync(D(e,e.memberId),{recursive:!0,mode:U}),u(_e(e,e.memberId),e)}function Ie(e,t,n){let r={version:Y,memberId:t.memberId,tokenHash:t.tokenHash,pid:t.pid,heartbeatAt:n};u(ve(e,t.memberId),r)}function Le(e){let t=g.join(E(e.teamId),I),n;try{n=h.readdirSync(t,{withFileTypes:!0})}catch{return[]}return n.filter(e=>e.isFile()&&e.name.endsWith(z)).map(e=>De(k(g.join(t,e.name)))).filter(e=>!!e).filter(t=>t.teamId===e.teamId&&t.rootSessionId===e.rootSessionId)}function Re(e,t){return Le(e).filter(n=>M(e,n,t)).sort((e,t)=>e.joinedAt-t.joinedAt||e.memberId.localeCompare(t.memberId))}function ze(e=Date.now()){let t=qe();if(t)return{members:Re(t,e).map(at)}}function Be(e,t,n){let r=0;for(let i of Le(e))i.memberId!==t&&(M(e,i,n)||n-Pe(e,i)<=33e4||(we(D(e,i.memberId)),A(ve(e,i.memberId)),A(_e(e,i.memberId)),r+=1));return r}function Ve(e){let t=e.trim();if(!t)throw Error(`A root session id is required for native team communication.`);let n={version:q,teamId:me(t),rootSessionId:t,mainMemberId:B};Ce(n);let r=g.join(E(n.teamId),R),i=Te(k(r));if(i&&i.rootSessionId!==t)throw Error(`Native team identity collision detected.`);let a=Date.now(),o={...n,createdAt:i?.createdAt??a,updatedAt:a};return u(r,o),n}function He(e){return{[t]:e.teamId,[a]:e.rootSessionId,[n]:e.mainMemberId}}function Ue(e){return{...He(e),[r]:e.memberId,[i]:e.token}}function We(){return{[r]:void 0,[i]:void 0}}function Ge(e){Object.assign(process.env,He(e))}function Ke(e){e&&process.env.PI_SUBAGENT_TEAM_ID!==e.teamId||(delete process.env[t],delete process.env[a],delete process.env[n])}function qe(){let e=C(t),r=C(a),i=C(n);if(!e||!_(e)||!r||i!==B||e!==me(r))return;let o=Te(k(g.join(E(e),R)));if(!(!o||o.rootSessionId!==r||o.teamId!==e))return{version:q,teamId:e,rootSessionId:r,mainMemberId:i}}function Je(e){if(!e)return;let t=e.id.trim(),n=e.subject.trim();if(!t||!S(t,G))throw Error(`Native team task id must be between 1 and ${G} bytes.`);if(!n||!S(n,K))throw Error(`Native team task subject must be between 1 and ${K} bytes.`);return{id:t,subject:n}}function Ye(e){if(e.role===`main`)return e.root.mainMemberId;let t=e.name!==void 0;if(!t&&!e.agent)throw Error(`An intercom member needs a name or an agent to derive one from.`);let n=ge(T(e.name??e.agent??V),t);if(e.runId){let t=T(e.runId).slice(0,8),r=H-t.length-1;return`${n.slice(0,r).replace(Z,``)||V}-${t}`}return e.fanoutIndex===void 0?n:he(n,e.fanoutIndex)}function Xe(e){let t=Ye(e);if(!_(t))throw Error(`A safe native team member id is required.`);let n=pe(),r=w(n),i=Date.now(),a=Je(e.task),o={...e.root,memberId:t,token:n,role:e.role,...e.agent?{agent:e.agent}:{},...e.runId?{runId:e.runId}:{},...e.childIndex===void 0?{}:{childIndex:e.childIndex},...e.parentMemberId?{parentMemberId:e.parentMemberId}:{},...a?{task:a}:{}},s=j(e.root,t);s&&s.tokenHash!==r&&we(D(e.root,t));let{token:c,version:l,...u}=o,d={...u,version:J,tokenHash:r,pid:e.pid??process.pid,active:!0,joinedAt:i};Fe(d),Ie(e.root,d,i);let ee=!1;return{context:o,dispose:()=>{if(ee)return;ee=!0;let n=j(e.root,t);if(!n||n.tokenHash!==r)return;let i=Date.now();Fe({...n,active:!1,leftAt:i}),Ie(e.root,n,i)}}}function Ze(){let e=qe(),t=C(r),n=C(i);if(!e||!t||!_(t)||!n)return;let a=j(e,t);if(!(!a||a.teamId!==e.teamId||a.rootSessionId!==e.rootSessionId)&&!(a.tokenHash!==w(n)||!a.active))return{...e,memberId:t,token:n,role:a.role,...a.agent?{agent:a.agent}:{},...a.runId?{runId:a.runId}:{},...a.childIndex===void 0?{}:{childIndex:a.childIndex},...a.parentMemberId?{parentMemberId:a.parentMemberId}:{},...a.task?{task:a.task}:{}}}function Qe(e,t){let n=j(e,e.memberId);if(!n||n.tokenHash!==w(e.token)||!M(e,n,t))throw Error(`This native team member is no longer active.`);return n}function $e(e,t,n){let r=t?.trim();if(!r)throw p(`to is required for intercom send and ask.`,`Provide an explicit recipient.`);let i=Re(e,n).filter(t=>t.memberId!==e.memberId),a=T(r),o=i.find(e=>e.memberId===r||e.memberId===a);if(o)return o;let s=r.toLowerCase(),c=i.filter(e=>e.agent?.toLowerCase()===s||e.runId?.toLowerCase()===s||s===B&&e.role===`main`);if(c.length===1)return c[0];throw c.length>1?new f(`recipient_ambiguous`,`Multiple active intercom members match '${r}': ${c.map(e=>e.memberId).join(`, `)}.`,!1,`Retry with one exact member id.`):new f(`recipient_not_found`,`Active intercom member '${r}' was not found.`,!0,`Call intercom({"action":"members"}) and retry with an active member id.`)}function et(e){let t=e?.trim();if(!t)throw p(`message is required for intercom communication.`,`Provide a nonblank message.`);if(!S(t,W))throw p(`Intercom message exceeds 64 KiB.`,`Shorten the message and retry.`);return t}function tt(e,t,n){let r=j(e,t);return!!(r&&r.tokenHash===n)}function nt(e,t,n){let r=D(e,e.memberId),i;try{i=h.readdirSync(r,{withFileTypes:!0})}catch{return{messages:[],foreignFiles:[]}}let a=[],o=[];for(let s of i){if(!s.isFile()||!s.name.endsWith(z)||n?.(s.name))continue;let i=g.join(r,s.name),c=ke(k(i));if(!c){A(i);continue}if(c.teamId!==e.teamId||c.toMemberId!==e.memberId){o.push(s.name);continue}if(c.expiresAt<t||!tt(e,c.fromMemberId,c.senderTokenHash)){A(i);continue}a.push(c)}return{messages:rt(a),foreignFiles:o}}function rt(e){let t=new Map;for(let n of e){let e=t.get(n.fromMemberId);e?e.push(n):t.set(n.fromMemberId,[n])}let n=[];for(let e of t.values())e.sort((e,t)=>e.seq-t.seq),n.push(e);let r=[];for(;;){let e,t;for(let r of n){let n=r[0];n&&(!t||n.createdAt<t.createdAt||n.createdAt===t.createdAt&&n.fromMemberId<t.fromMemberId)&&(e=r,t=n)}if(!e||!t)break;e.shift(),r.push(t)}return r}function it(e){let t=e.role===`main`?B:e.agent??e.memberId,n=e.runId?` [${e.runId}]`:``,r=e.task?`, task ${e.task.id}: ${e.task.subject}`:``;return`- ${e.memberId}: ${t}${n}${r}`}function at(e){return{name:e.memberId,role:e.role,...e.agent?{agent:e.agent}:{},...e.runId?{runId:e.runId}:{},...e.task?{task:e.task}:{}}}function ot(e,t){return new Promise((n,r)=>{if(t?.aborted){r(Error(`Native team request cancelled.`));return}let i,a=()=>{i&&clearTimeout(i),t?.removeEventListener(`abort`,o)},o=()=>{a(),r(Error(`Native team request cancelled.`))};i=setTimeout(()=>{a(),n()},e),t?.addEventListener(`abort`,o,{once:!0})})}function st(e,t){let n=j(e,t.fromMemberId),r=`${t.fromMemberId}${n?.agent?` (${n.agent})`:``}`,i=n?.task?`, task ${n.task.id}`:``,a=[`${t.kind===`ask`?`Question`:`Message`} from ${r}${i}.`];return a.push(``,t.message),t.kind===`ask`&&a.push(``,`Reply with ${N}({ action: "reply", requestId: "${t.id}", message: "..." }).`),a.join(`
2
+ `)}function ct(e,t){try{return e.getAllTools().some(e=>e.name===t)}catch{return!1}}var N,P,F,lt,ut,I,dt,ft,pt,L,R,z,B,mt,V,H,ht,gt,U,W,G,K,_t,vt,yt,bt,xt,St,Ct,wt,Tt,Et,Dt,Ot,q,J,Y,X,kt,At,jt,Z,Mt,Nt,Q,Pt,$,Ft,It,Lt,Rt,zt,Bt=e((()=>{o(),l(),ie(),ae(),c(),d(),oe(),N=`intercom`,P=`subagent.team.message`,F=`subagent.team.reply`,lt=`intercom_message`,ut=`intercom_undeliverable`,I=`members`,dt=`heartbeats`,ft=`inboxes`,pt=`replies`,L=`receipts`,R=`team.json`,z=`.json`,B=`main`,mt=`main-agent`,V=`agent`,H=48,ht=`-`,gt=1,U=448,W=65536,G=256,K=4096,_t=864e5,vt=6e5,yt=5e3,bt=3e4,xt=250,St=250,Ct=5,wt=1,Tt=1024,Et=256,Dt=32,Ot=6e4,q=1,J=1,Y=1,X=2,kt=[`members`,`send`,`ask`,`reply`,`pending`],At=/^[A-Za-z0-9._-]{1,256}$/,jt=/[^a-z0-9._-]+/g,Z=/^[-.]+|[-.]+$/g,Mt=32,Nt=32,Q=`sha256`,Pt=1,$=`delivered`,Ft=`failed`,It=`session-`,Lt={oneOf:[...[`members`,`pending`].map(e=>({type:`object`,properties:{action:{const:e}},required:[`action`],additionalProperties:!1})),{type:`object`,properties:{action:{const:`send`},to:{type:`string`},message:{type:`string`}},required:[`action`,`to`,`message`],additionalProperties:!1},{type:`object`,properties:{action:{const:`ask`},to:{type:`string`},message:{type:`string`},timeoutMs:{type:`integer`,minimum:1}},required:[`action`,`to`,`message`],additionalProperties:!1},{type:`object`,properties:{action:{const:`reply`},requestId:{type:`string`},message:{type:`string`}},required:[`action`,`requestId`,`message`],additionalProperties:!1}]},Rt=class{pi;options;context;ownedMembershipDispose;poller;lastHeartbeatAt=0;lastGcAt=0;seenFiles=new re(Tt);deliveryAttempts=new s(Et);undeliverableMessages=[];outboundSeq=0;constructor(e,t){if(this.pi=e,this.options=t,ct(e,`intercom`))throw Error(`[tool_conflict] A foreign '${N}' tool is already registered. Recovery: disable the competing extension and reload Doom Team.`);e.registerTool(this.buildTool())}current(){return this.context}undeliverable(){return this.undeliverableMessages}bindMainSession(e){let t=Ve(e);Ge(t);let n=Xe({root:t,role:`main`});return this.startBinding(n.context,n.dispose)}bindChildFromEnvironment(){let e=Ze();if(e)return this.context?.memberId===e.memberId&&this.context.token===e.token?this.context:this.startBinding(e)}dispose(){let e=this.context;this.stopBinding(),e?.role===`main`&&Ke(e)}startBinding(e,t){return this.stopBinding(),this.context=e,this.ownedMembershipDispose=t,this.poll(),this.poller=setInterval(()=>{this.poll()},this.options.pollIntervalMs),this.poller.unref?.(),e}stopBinding(){this.poller&&clearInterval(this.poller),this.poller=void 0,this.ownedMembershipDispose?.(),this.ownedMembershipDispose=void 0,this.seenFiles.clear(),this.deliveryAttempts.clear(),this.lastHeartbeatAt=0,this.lastGcAt=0,this.outboundSeq=0,this.context=void 0}poll(){let e=this.context;if(!e)return;let t=this.options.now();this.heartbeat(e,t),this.collectGarbageIfDue(e,t);let n=nt(e,t,e=>this.seenFiles.has(e));for(let e of n.foreignFiles)this.seenFiles.add(e);for(let t of n.messages)this.deliverOnce(e,t)}deliverOnce(e,t){let n=ye(t.id);try{this.deliver(e,t)}catch(r){let i=(this.deliveryAttempts.get(n)??0)+wt;if(i<this.options.maxDeliveryAttempts){this.deliveryAttempts.set(n,i);return}this.deliveryAttempts.delete(n),this.seenFiles.add(n),this.reportUndeliverable(e,t,i,r);return}this.seenFiles.add(n),this.deliveryAttempts.delete(n),u(xe(e,t.fromMemberId,t.id),{version:Pt,messageId:t.id,state:$,deliveredAt:this.options.now()}),t.kind===`send`&&A(O(e,e.memberId,t.id))}deliver(e,t){let n=st(e,t);if(e.role===`subagent`){this.pi.sendUserMessage(n,{deliverAs:`steer`});return}this.pi.sendMessage({customType:lt,content:n,display:!0,details:{id:t.id,kind:t.kind,from:t.fromMemberId,to:t.toMemberId,seq:t.seq}},{triggerTurn:!0,deliverAs:`steer`})}reportUndeliverable(e,t,n,r){let i={messageId:t.id,fromMemberId:t.fromMemberId,kind:t.kind,attempts:n,reason:fe(r),at:this.options.now()};for(this.undeliverableMessages.push(i),u(xe(e,t.fromMemberId,t.id),{version:Pt,messageId:t.id,state:Ft,reason:i.reason,failedAt:i.at});this.undeliverableMessages.length>Dt;)this.undeliverableMessages.shift();try{return this.pi.sendMessage({customType:ut,content:`Native team message ${t.id} from ${t.fromMemberId} could not be delivered after ${n} attempts: ${i.reason}`,display:!0,details:{...i}},{triggerTurn:!0,deliverAs:`steer`}),!0}catch{return!1}}heartbeat(e,t){if(t-this.lastHeartbeatAt<this.options.heartbeatIntervalMs)return;let n=j(e,e.memberId);!n||n.tokenHash!==w(e.token)||!n.active||(this.lastHeartbeatAt=t,Ie(e,n,t))}collectGarbageIfDue(e,t){if(!(t-this.lastGcAt<this.options.gcIntervalMs)){this.lastGcAt=t;try{Be(e,e.memberId,t)}catch(n){for(this.undeliverableMessages.push({messageId:``,fromMemberId:e.memberId,kind:`send`,attempts:0,reason:`Native team directory sweep failed: ${fe(n)}`,at:t});this.undeliverableMessages.length>Dt;)this.undeliverableMessages.shift()}}}nextSeq(){return this.outboundSeq+=1,this.outboundSeq}queueMessage(e,t,n,r,i,a){if(Qe(e,i),!M(e,t,i))throw Error(`Native team member '${t.memberId}' is no longer active.`);let o={type:P,version:X,id:a,teamId:e.teamId,kind:n,fromMemberId:e.memberId,toMemberId:t.memberId,senderTokenHash:w(e.token),seq:this.nextSeq(),message:r,createdAt:i,expiresAt:i+_t};return h.mkdirSync(D(e,t.memberId),{recursive:!0,mode:U}),u(O(e,t.memberId,o.id),o),o}replyToRequest(e,t,n,r){if(!t||!_(t))throw Error(`requestId must be a valid intercom request id.`);Qe(e,r);let i=O(e,e.memberId,t),a=ke(k(i));if(!a||a.kind!==`ask`||a.teamId!==e.teamId||a.toMemberId!==e.memberId||!tt(e,a.fromMemberId,a.senderTokenHash))throw new f(`recipient_not_found`,`No pending intercom ask matches requestId '${t}'.`,!1,`Call intercom({"action":"pending"}) and retry with an exact requestId.`);let o={type:F,version:X,requestId:t,teamId:e.teamId,fromMemberId:e.memberId,toMemberId:a.fromMemberId,senderTokenHash:w(e.token),message:n,createdAt:r};return u(be(e,t),o),A(i),this.seenFiles.delete(ye(t)),o}async waitForReply(e,t,n,r,i){let a=be(e,n.id),o=this.options.now()+(i??this.options.askTimeoutMs);for(;this.options.now()<=o;){if(r?.aborted)throw Error(`Native team request cancelled.`);let i=Ae(k(a));if(i&&i.teamId===e.teamId&&i.requestId===n.id&&i.fromMemberId===t.memberId&&i.toMemberId===e.memberId&&tt(e,i.fromMemberId,i.senderTokenHash))return A(a),i;let o=j(e,t.memberId);if(!o||!M(e,o,this.options.now()))throw new f(`communication_unavailable`,`Intercom member '${t.memberId}' became unreachable before replying.`,!0,`Call intercom({"action":"members"}) and decide whether to retry with an active member.`);await ot(this.options.replyPollIntervalMs,r)}throw new f(`reply_timeout`,`Timed out waiting for intercom member '${t.memberId}' to reply.`,!0,`Check member status before deciding whether to ask again.`)}buildTool(){return{name:N,label:`Intercom`,description:`Communicate with active agents in this root session. Use members, send, ask, pending, or reply. The stable root identity is main.`,promptGuidelines:[`Send only new progress, blockers, or decisions. Do not repeat the task brief, sender task, or delegation instructions because the recipient already has them.`],parameters:Lt,execute:async(e,t,n,r)=>{let i=this.context;if(!i)throw new f(`communication_unavailable`,`Intercom is not active for this session.`,!0,`Wait for session startup or reload Doom Team.`);let a=je(t),o=this.options.now();if(Qe(i,o),a.action===`members`){let e=Re(i,o);return{content:[{type:`text`,text:e.length?e.map(it).join(`
3
3
  `):`No active members.`}],details:{members:e.map(at)}}}if(a.action===`pending`){let e=nt(i,o).messages.filter(e=>e.kind===`ask`),t=e.map(e=>`- ${e.id}: from ${e.fromMemberId}. Reply with ${N}({ action: "reply", requestId: "${e.id}", message: "..." }).`);return{content:[{type:`text`,text:t.length?t.join(`
4
4
  `):`No pending native team asks.`}],details:{pending:e.map(e=>({id:e.id,from:e.fromMemberId,message:e.message}))}}}let s=et(a.message);if(a.action===`reply`){let e=this.replyToRequest(i,a.requestId,s,o);return{content:[{type:`text`,text:`Replied to native team request ${e.requestId}.`}],details:{requestId:e.requestId,to:e.toMemberId}}}let c=$e(i,a.to,o);a.action===`ask`&&r?.({content:[{type:`text`,text:`Waiting for ${c.memberId} to reply...`}],details:{action:`ask`,to:c.memberId,partial:!0}});let l=Se(i.memberId,e),u=k(xe(i,i.memberId,l));if(u?.state===Ft){let e=typeof u.reason==`string`?u.reason:`unknown error`;throw new f(`delivery_unconfirmed`,`Intercom message ${l} failed: ${e}`,!1,`Call intercom({"action":"members"}) and do not resend automatically.`)}if(a.action===`send`&&u?.state===$)return{content:[{type:`text`,text:`Message ${l} delivered to ${c.memberId}.`}],details:{state:$,delivered:!0,messageId:l,to:c.memberId}};let d=this.queueMessage(i,c,a.action,s,o,l);if(a.action===`send`)return{content:[{type:`text`,text:`Message ${d.id} queued for ${c.memberId}; delivery is not yet confirmed. Do not resend.`}],details:{state:`queued`,delivered:!1,messageId:d.id,to:c.memberId,seq:d.seq}};try{let e=await this.waitForReply(i,c,d,n,a.timeoutMs);return{content:[{type:`text`,text:`Reply from ${c.memberId}:\n${e.message}`}],details:{requestId:d.id,from:c.memberId,reply:e.message}}}finally{A(O(i,c.memberId,d.id))}}}}},zt=class{runtimes=new WeakMap;pollIntervalMs=xt;replyPollIntervalMs=St;heartbeatIntervalMs=yt;gcIntervalMs=Ot;askTimeoutMs=vt;maxDeliveryAttempts=Ct;now(){return Date.now()}createRuntime(e){let t=this.runtimes.get(e);if(t)return t;let n=new Rt(e,{pollIntervalMs:this.pollIntervalMs,replyPollIntervalMs:this.replyPollIntervalMs,heartbeatIntervalMs:this.heartbeatIntervalMs,gcIntervalMs:this.gcIntervalMs,askTimeoutMs:this.askTimeoutMs,maxDeliveryAttempts:this.maxDeliveryAttempts,now:()=>this.now()});return this.runtimes.set(e,n),e.on(`session_shutdown`,()=>{this.runtimes.get(e)?.dispose()}),n}registerClient(e){ne()&&Ze()&&this.createRuntime(e).bindChildFromEnvironment()}}}));Bt();export{bt as HEARTBEAT_STALE_MS,N as NATIVE_TEAM_TOOL_NAME,zt as NativeTeamChannelService,Ge as applyNativeTeamRootEnvironment,We as clearNativeTeamMemberEnvironment,Ke as clearNativeTeamRootEnvironment,Ve as ensureNativeTeamRoot,Bt as init_nativeTeamChannel,Le as listMemberRecords,Ue as nativeTeamMemberEnvironment,He as nativeTeamRootEnvironment,T as normalizeTeamMemberName,Ne as processAlive,ze as readActiveNativeTeamSnapshot,Me as readHeartbeat,j as readMember,Ze as readNativeTeamMemberFromEnvironment,qe as readNativeTeamRootFromEnvironment,Xe as registerNativeTeamMember,E as teamDir};
5
5
  //# sourceMappingURL=nativeTeamChannel.mjs.map
@@ -1,4 +1,4 @@
1
1
  const e=require("../../../../services/models/modelResolution.cjs"),t=require("../../../runs/shared/modelFallback.cjs"),n=require("../../extensions/spawnPlan.cjs"),r=require("../../../asyncJobTracker.cjs"),i=require("./chainExpression.cjs"),a=require("./doctor.cjs"),o=require("./spawnRequestMapping.cjs"),s=require("./subagentLaunch.cjs"),c=`subagent-slash-result`;function l(e,t,n){e.sendMessage({customType:c,content:t,display:!0,...n?{details:n}:{}})}function u(e,t){e.hasUI&&e.ui.setStatus(`subagent-slash`,t)}function d(e,t){e.ui.notify(t,`error`)}function f(e,t){e.ui.notify(t,`info`)}function p(e){return e?e.attentionReason?`${e.status??`running`} - needs attention: ${e.attentionReason}`:e.activityState?`${e.status??`running`} - ${e.activityState}`:e.status??`running`:`starting…`}function m(e,t,n,i,a,o){s.watchTrackedRunUntilTerminal(n.scheduler,i,a,n=>{if(u(t,`${o} (${a}): ${p(n)}`),n?.status===void 0||!r.TERMINAL_ASYNC_JOB_STATES.has(n.status))return;u(t,void 0);let i=n.status===`complete`||n.status===`completed`?`completed`:n.status;l(e,n.error?`## Subagent ${i}\n\n${o} (${a})\n\n${n.error}`:`## Subagent ${i}\n\n${o} (${a})`,[{agent:o,runId:a,status:i,...n.error?{error:n.error}:{}}])})}function h(e,t,n,r,i){let a=i.outcomes.filter(e=>e.runId),o=i.outcomes.filter(e=>!e.runId);if(a.length>0){l(e,`## Subagent started\n\n${a.map(e=>`${e.agent} (${e.runId})${e.warning?`\n Warning: ${e.warning}`:``}`).join(`, `)}`,a.map(e=>({agent:e.agent,runId:e.runId??``,status:`started`,...e.warning?{warning:e.warning}:{}}))),u(t,`${a.length} run${a.length===1?``:`s`} started…`);for(let i of a)i.runId&&m(e,t,n,r,i.runId,i.agent)}o.length>0&&d(t,`Some subagents failed to start:\n${o.map(e=>`${e.agent}: ${e.error??`spawn failed`}`).join(`
2
- `)}`)}function g(e,t){if(e.baseCwd)return e.baseCwd;d(t,`Subagent session cwd is not initialized yet`)}function _(e,t,n,r){return e.discovery.discover(t,`both`).agents.find(e=>e.name===n)?!0:(d(r,`Unknown agent: ${n}`),!1)}async function v(r,a,c,l,u){let d=c.baseCwd;if(!d)return{ok:!1,message:`Subagent session cwd is not initialized yet`};if(!l.discovery.discover(d,`both`).agents.find(e=>e.name===u.agent))return{ok:!1,message:`Unknown agent: ${u.agent}`};let f=l.tracker.forSession(a.sessionManager.getSessionId());try{let i=n.captureSessionForkSource(a.sessionManager,`settled`),c=t.normalizeParentModel(a.model),p=o.taskInputFromParsedStep({name:u.agent,config:u.config??{},task:u.task},d,u.fork?`fork`:void 0),m=await s.launchSingleSubagent(l.spawnPlanner,f,{agent:p.agent,task:p.task??``,cwd:p.cwd??d,agentScope:`both`,parentSessionId:a.sessionManager.getSessionId(),...p.model?{model:p.model}:{},...p.context?{context:p.context}:{},...i?{parentSessionFile:i.sessionFile,parentLeafId:i.leafId}:{},availableModels:e.authenticatedModelInfos(a.modelRegistry),...c?{parentModel:c}:{}},l.loadConfig());return h(r,a,l,f,m),{ok:!0,result:m}}catch(e){if(e instanceof o.UnsupportedInlineConfigError||e instanceof i.SlashParseError)return{ok:!1,message:e.message};throw e}}function y(e,t,n,r,i){v(e,t,n,r,i).then(e=>{e.ok||d(t,e.message)},e=>{d(t,`Subagent launch failed: ${e instanceof Error?e.message:String(e)}`)})}function b(e,t){if(t instanceof o.UnsupportedInlineConfigError||t instanceof i.SlashParseError){d(e,t.message);return}throw t}function x(e){let t=e.trim();if(t.includes(` -> `)){let e=t.split(` -> `).map(e=>e.trim()).filter(Boolean).map(e=>i.parseSingleTaskToken(e));return e.length===0?void 0:{steps:e,task:e.find(e=>e.task)?.task??``,perStep:!0}}let n=t.indexOf(` -- `);if(n===-1)return;let r=t.slice(0,n).trim(),a=t.slice(n+4).trim();if(!r||!a)return;let o=r.split(/\s+/).filter(Boolean).map(e=>i.parseSingleTaskToken(e));if(o.length!==0)return{steps:o,task:a,perStep:!1}}function S(c,u,p){c.registerCommand(`run`,{description:`Run a subagent in the background: /run agent[model=x] [task] [--fork]`,handler:async(e,t)=>{let{args:n,fork:r}=i.extractForkFlag(e),a=n.trim();if(!a){d(t,`Usage: /run <agent> [task] [--fork]`);return}let o=a.indexOf(` `),{name:s,config:l}=i.parseAgentToken(o===-1?a:a.slice(0,o)),f=await v(c,t,u,p,{agent:s,task:o===-1?``:a.slice(o+1).trim(),config:l,fork:r});f.ok||d(t,f.message)}}),c.registerCommand(`parallel`,{description:`Run agents in parallel: /parallel scout "task1" -> reviewer "task2" [--fork]`,handler:async(r,a)=>{let l=p.tracker.forSession(a.sessionManager.getSessionId()),{args:f,fork:m}=i.extractForkFlag(r),v=g(u,a);if(!v)return;let y=x(f);if(!y){d(a,`Usage: /parallel agent1 "task1" -> agent2 "task2"`);return}for(let e of y.steps)if(!_(p,v,e.name,a))return;if(!y.steps.some(e=>e.task)&&!y.task){d(a,`At least one step must have a task`);return}try{let r=n.captureSessionForkSource(a.sessionManager,`settled`),i=t.normalizeParentModel(a.model),u=y.steps.map(e=>o.taskInputFromParsedStep({name:e.name,config:e.config,task:e.task??y.task},v,m?`fork`:void 0));h(c,a,p,l,await s.launchParallelSubagents(p.spawnPlanner,l,{tasks:u,cwd:v,agentScope:`both`,parentSessionId:a.sessionManager.getSessionId(),...r?{parentSessionFile:r.sessionFile,parentLeafId:r.leafId}:{},availableModels:e.authenticatedModelInfos(a.modelRegistry),...i?{parentModel:i}:{}},p.loadConfig()))}catch(e){b(a,e)}}}),c.registerCommand(`subagents-doctor`,{description:`Show subagent diagnostics`,handler:async(e,t)=>{l(c,a.buildDoctorReport({cwd:t.cwd,agentScope:`both`},{discovery:p.discovery,skills:p.skills}))}}),c.registerCommand(`subagents-stop`,{description:`Stop a running subagent: /subagents-stop [run-id]`,handler:async(e,t)=>{let n=p.tracker.forSession(t.sessionManager.getSessionId()),i=e.trim();if(!i){l(c,C(n.list()));return}try{p.management.stop(r.resolveTrackedRunId(n,i)),f(t,`Stop requested for ${i}. The run reports its own final state once it acknowledges.`)}catch(e){d(t,e instanceof Error?e.message:`Could not stop '${i}'.`)}}})}function C(e){let t=e.filter(e=>e.status===`running`||e.status===`pending`);return t.length===0?`No running subagents to stop.`:[`Running subagents:`,...t.map(e=>`- ${e.runId}${e.status?` (${e.status})`:``}`),``,"Stop one with `/subagents-stop <run-id>`, or open `/subagents-fleet` to inspect and control them interactively."].join(`
2
+ `)}`)}function g(e,t){if(e.baseCwd)return e.baseCwd;d(t,`Subagent session cwd is not initialized yet`)}function _(e,t,n,r){return e.discovery.discover(t,`both`).agents.find(e=>e.name===n)?!0:(d(r,`Unknown agent: ${n}`),!1)}async function v(r,a,c,l,u){let d=c.baseCwd;if(!d)return{ok:!1,message:`Subagent session cwd is not initialized yet`};if(!l.discovery.discover(d,`both`).agents.find(e=>e.name===u.agent))return{ok:!1,message:`Unknown agent: ${u.agent}`};let f=l.tracker.forSession(a.sessionManager.getSessionId());try{let i=n.captureSessionForkSource(a.sessionManager,`settled`),c=t.normalizeParentModel(a.model),p=o.taskInputFromParsedStep({name:u.agent,config:u.config??{},task:u.task},d,u.fork?`fork`:void 0),m=await s.launchSingleSubagent(l.spawnPlanner,f,{agent:p.agent,task:p.task??``,cwd:p.cwd??d,agentScope:`both`,parentSessionId:a.sessionManager.getSessionId(),...p.model?{model:p.model}:{},...p.context?{context:p.context}:{},...i?{parentSessionFile:i.sessionFile,parentLeafId:i.leafId}:{},availableModels:e.authenticatedModelInfos(a.modelRegistry),...c?{parentModel:c}:{}},l.loadConfig());return h(r,a,l,f,m),{ok:!0,result:m}}catch(e){if(e instanceof o.UnsupportedInlineConfigError||e instanceof i.SlashParseError)return{ok:!1,message:e.message};throw e}}function y(e,t,n,r,i){v(e,t,n,r,i).then(e=>{e.ok||d(t,e.message)},e=>{d(t,`Subagent launch failed: ${e instanceof Error?e.message:String(e)}`)})}function b(e,t){if(t instanceof o.UnsupportedInlineConfigError||t instanceof i.SlashParseError){d(e,t.message);return}throw t}function x(e){let t=e.trim();if(t.includes(` -> `)){let e=t.split(` -> `).map(e=>e.trim()).filter(Boolean).map(e=>i.parseSingleTaskToken(e));return e.length===0?void 0:{steps:e,task:e.find(e=>e.task)?.task??``,perStep:!0}}let n=t.indexOf(` -- `);if(n===-1)return;let r=t.slice(0,n).trim(),a=t.slice(n+4).trim();if(!r||!a)return;let o=r.split(/\s+/).filter(Boolean).map(e=>i.parseSingleTaskToken(e));if(o.length!==0)return{steps:o,task:a,perStep:!1}}function S(c,u,p){c.registerCommand(`run`,{description:`Run a subagent in the background: /run agent[model=x] [task] [--fork]`,handler:async(e,t)=>{let{args:n,fork:r}=i.extractForkFlag(e),a=n.trim();if(!a){d(t,`Usage: /run <agent> [task] [--fork]`);return}let o=a.indexOf(` `),{name:s,config:l}=i.parseAgentToken(o===-1?a:a.slice(0,o)),f=await v(c,t,u,p,{agent:s,task:o===-1?``:a.slice(o+1).trim(),config:l,fork:r});f.ok||d(t,f.message)}}),c.registerCommand(`parallel`,{description:`Run agents in parallel: /parallel scout "task1" -> reviewer "task2" [--fork]`,handler:async(r,a)=>{let l=p.tracker.forSession(a.sessionManager.getSessionId()),{args:f,fork:m}=i.extractForkFlag(r),v=g(u,a);if(!v)return;let y=x(f);if(!y){d(a,`Usage: /parallel agent1 "task1" -> agent2 "task2"`);return}for(let e of y.steps)if(!_(p,v,e.name,a))return;if(!y.steps.some(e=>e.task)&&!y.task){d(a,`At least one step must have a task`);return}try{let r=n.captureSessionForkSource(a.sessionManager,`settled`),i=t.normalizeParentModel(a.model),u=y.steps.map(e=>o.taskInputFromParsedStep({name:e.name,config:e.config,task:e.task??y.task},v,m?`fork`:void 0));h(c,a,p,l,await s.launchParallelSubagents(p.spawnPlanner,l,{tasks:u,cwd:v,agentScope:`both`,parentSessionId:a.sessionManager.getSessionId(),...r?{parentSessionFile:r.sessionFile,parentLeafId:r.leafId}:{},availableModels:e.authenticatedModelInfos(a.modelRegistry),...i?{parentModel:i}:{}},p.loadConfig()))}catch(e){b(a,e)}}}),c.registerCommand(`subagents-doctor`,{description:`Show subagent diagnostics`,handler:async(e,t)=>{l(c,a.buildDoctorReport({cwd:t.cwd,agentScope:`both`},{discovery:p.discovery,skills:p.skills}))}}),c.registerCommand(`subagents-steer`,{description:`Send guidance to a running subagent: /subagents-steer <run-id> <message>`,handler:async(e,t)=>{let n=e.trim(),r=n.search(/\s/);if(r===-1||!n.slice(r+1).trim()){d(t,`Usage: /subagents-steer <run-id> <message>`);return}let i=n.slice(0,r),a=n.slice(r+1).trim();try{let e=await p.management.steer(i,a),n=`Steering ${e.state} for ${i}: ${e.message}`;e.state===`failed`?d(t,n):f(t,n)}catch(e){d(t,e instanceof Error?e.message:`Could not steer '${i}'.`)}}}),c.registerCommand(`subagents-stop`,{description:`Stop a running subagent: /subagents-stop [run-id]`,handler:async(e,t)=>{let n=p.tracker.forSession(t.sessionManager.getSessionId()),i=e.trim();if(!i){l(c,C(n.list()));return}try{p.management.stop(r.resolveTrackedRunId(n,i)),f(t,`Stop requested for ${i}. The run reports its own final state once it acknowledges.`)}catch(e){d(t,e instanceof Error?e.message:`Could not stop '${i}'.`)}}})}function C(e){let t=e.filter(e=>e.status===`running`||e.status===`pending`);return t.length===0?`No running subagents to stop.`:[`Running subagents:`,...t.map(e=>`- ${e.runId}${e.status?` (${e.status})`:``}`),``,"Stop one with `/subagents-stop <run-id>`, or open `/subagents-fleet` to inspect and control them interactively."].join(`
3
3
  `)}exports.SLASH_RESULT_CUSTOM_TYPE=c,exports.launchSingleAgentRun=v,exports.registerSlashCommands=S,exports.startSingleAgentRun=y;
4
4
  //# sourceMappingURL=slashCommands.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"slashCommands.cjs","names":["TERMINAL_ASYNC_JOB_STATES","captureSessionForkSource","normalizeParentModel","taskInputFromParsedStep","launchSingleSubagent","authenticatedModelInfos","UnsupportedInlineConfigError","SlashParseError","parseSingleTaskToken","extractForkFlag","parseAgentToken","launchParallelSubagents","buildDoctorReport","resolveTrackedRunId"],"sources":["../../../../../../src/adapters/pi/commands/slash/slashCommands.ts"],"sourcesContent":["/**\n * The core `/run`, `/chain`, `/parallel` slash commands. Replaces the\n * always-blocking predecessor with the async-only shape this port settled\n * on: a command launches a spawn, sends an initial status message, and\n * hands off to `watchTrackedRunUntilTerminal` (render-key gated, backed by\n * `PollScheduler`) to update the status bar and finalize the message once\n * the run reaches a terminal state - never by awaiting completion. See\n * `subagentLaunch.ts`'s module doc for the full reasoning.\n *\n * WHAT IS NOT HERE, AND WHY:\n * - `/run-chain`, `/prompt-workflow` and `/chain-prompts`: the whole SAVED\n * work surface - saved agent pipelines (`ChainConfig`, never ported) and\n * saved `.md` prompt templates (ported, then deleted). REMOVED BY\n * DECISION, not deferred: overly complicated for the use they were\n * getting. Do not re-add them because a reader notices the predecessor had\n * them. Ad-hoc chaining (`/chain scout \"x\" -> planner`) is a different\n * feature, lives in `chainExpression.ts`, and stays\n * - `/subagent-cost`: REMOVED BY DECISION. It reads usage/cost data\n * (`totalTokens`/`totalCost`) that nothing in this package's\n * runs/extensions surface tracks - a genuinely absent data source, and\n * building it would mean threading usage out of every child process\n * - `/subagents-check-profile`: removed at the source. Calls\n * `checkSubagentProfile`/`listSubagentProfiles`, which are referenced but\n * defined nowhere in the entire predecessor package - a live\n * `ReferenceError` that only shipped because that package sets\n * `noCheck: true`. Typecheck is on here; porting it faithfully would not\n * compile, and it was asked to be removed independently of that\n * - The `SUBAGENT_FLEET_COMMAND` registration and its `Ctrl+Alt+F` shortcut:\n * fleet view is its own piece, registered by whoever builds it\n * - Inline parallel groups within `/chain` (`(a | b)` syntax): the field\n * mapping for a group's own config exists (`spawnRequestMapping.ts`),\n * but wiring a group INTO a chain request is left for the same pass that\n * revisits per-task field support, so `/chain` reports a clear\n * not-yet-supported message rather than silently flattening a group\n * - `/subagents` (admin) command registration: a separate file, not yet\n * ported\n *\n * `/subagents-doctor` IS here, in `doctor.ts` - read (not ported) the\n * predecessor's foreground-executor `doctor` action before deciding, and it\n * turned out to be a small, mostly-mechanical port. See that module's own\n * doc for what it deliberately leaves out (chain counts, spawn-budget\n * reporting).\n *\n * AVOID:\n * - Awaiting a SINGLE/PARALLEL spawn for a result that will not exist yet.\n * See `subagentLaunch.ts`\n * - A private polling loop for a message's live status. Use\n * `watchTrackedRunUntilTerminal`\n */\n\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport type { ExtensionConfig } from '../../extensions/config';\nimport type { ManagementActionsContract } from '../../extensions/managementActions';\nimport { captureSessionForkSource, type SpawnPlannerContract, type SpawnPlanResult } from '../../extensions/spawnPlan';\nimport type { SkillDiscoveryContract } from '../../../agents/skills';\nimport type { AgentScope, AgentDiscoveryContract } from '../../../agents/types';\nimport type { AsyncJobTrackerContract, TrackedAsyncJobsContract, TrackedAsyncJob } from '../../../asyncJobTracker';\nimport { resolveTrackedRunId, TERMINAL_ASYNC_JOB_STATES } from '../../../asyncJobTracker';\nimport { normalizeParentModel } from '../../../runs/shared/modelFallback';\nimport { authenticatedModelInfos } from '../../../../services/models/modelResolution';\nimport type { PollSchedulerContract } from '../../../pollScheduler';\nimport {\n extractForkFlag,\n type InlineConfig,\n type ParsedStep,\n parseAgentToken,\n parseSingleTaskToken,\n SlashParseError,\n} from './chainExpression';\nimport { buildDoctorReport } from './doctor';\nimport { taskInputFromParsedStep, UnsupportedInlineConfigError } from './spawnRequestMapping';\nimport { launchParallelSubagents, launchSingleSubagent, watchTrackedRunUntilTerminal } from './subagentLaunch';\n\nexport interface SlashCommandDeps {\n spawnPlanner: SpawnPlannerContract;\n skills: SkillDiscoveryContract;\n tracker: AsyncJobTrackerContract;\n scheduler: PollSchedulerContract;\n discovery: AgentDiscoveryContract;\n /**\n * Used by `/subagents-stop`. Preferred over calling `requestSlashRunStop`\n * directly because it resolves an id PREFIX through `RunIdResolver` and\n * raises a real error for an unknown or ambiguous one, instead of writing a\n * stop request into a directory for a run that does not exist.\n */\n management: ManagementActionsContract;\n loadConfig: () => ExtensionConfig;\n}\n\nexport interface SlashCommandState {\n baseCwd: string | undefined;\n}\n\nconst SLASH_STATUS_KEY = 'subagent-slash';\nconst STARTED_STATUS = 'started';\n\n/**\n * The custom-message type a slash launch renders under. Cross-process\n * significant the same way `SUBAGENT_NOTIFY_MESSAGE_TYPE` is: the child-side\n * prompt runtime strips this type out of a child's inherited history\n * (`PARENT_ONLY_CUSTOM_MESSAGE_TYPES`), so both sides must agree on the literal.\n */\nexport const SLASH_RESULT_CUSTOM_TYPE = 'subagent-slash-result';\n\n/**\n * One run's line in a slash-result message. `status` is the tracker's own\n * status string (plus `started`), not a closed set this module can narrow.\n */\nexport interface SlashRunDetail {\n agent: string;\n runId: string;\n status: string;\n error?: string;\n warning?: string;\n}\n\nfunction sendSlashText(pi: ExtensionAPI, text: string, details?: SlashRunDetail[]): void {\n pi.sendMessage({\n customType: SLASH_RESULT_CUSTOM_TYPE,\n content: text,\n display: true,\n ...(details ? { details } : {}),\n });\n}\n\nfunction setSlashStatus(ctx: ExtensionContext, text: string | undefined): void {\n if (ctx.hasUI) ctx.ui.setStatus(SLASH_STATUS_KEY, text);\n}\n\nfunction notifyError(ctx: ExtensionContext, message: string): void {\n ctx.ui.notify(message, 'error');\n}\n\nfunction notifyInfo(ctx: ExtensionContext, message: string): void {\n ctx.ui.notify(message, 'info');\n}\n\nfunction statusTextFor(job: TrackedAsyncJob | undefined): string {\n if (!job) return 'starting…';\n if (job.attentionReason) return `${job.status ?? 'running'} - needs attention: ${job.attentionReason}`;\n if (job.activityState) return `${job.status ?? 'running'} - ${job.activityState}`;\n return job.status ?? 'running';\n}\n\n/**\n * Watches one launched run to a terminal state and finalizes its message.\n * Each launched run gets its own subscriber, so a PARALLEL launch's\n * siblings finalize independently rather than all waiting on the slowest.\n */\nfunction watchAndFinalize(\n pi: ExtensionAPI,\n ctx: ExtensionContext,\n deps: SlashCommandDeps,\n jobs: TrackedAsyncJobsContract,\n runId: string,\n agent: string,\n): void {\n watchTrackedRunUntilTerminal(deps.scheduler, jobs, runId, (job) => {\n setSlashStatus(ctx, `${agent} (${runId}): ${statusTextFor(job)}`);\n if (job?.status === undefined || !TERMINAL_ASYNC_JOB_STATES.has(job.status)) return;\n setSlashStatus(ctx, undefined);\n const outcome = job.status === 'complete' || job.status === 'completed' ? 'completed' : job.status;\n sendSlashText(\n pi,\n job.error\n ? `## Subagent ${outcome}\\n\\n${agent} (${runId})\\n\\n${job.error}`\n : `## Subagent ${outcome}\\n\\n${agent} (${runId})`,\n [{ agent, runId, status: outcome, ...(job.error ? { error: job.error } : {}) }],\n );\n });\n}\n\nfunction reportSpawnResult(\n pi: ExtensionAPI,\n ctx: ExtensionContext,\n deps: SlashCommandDeps,\n jobs: TrackedAsyncJobsContract,\n result: SpawnPlanResult,\n): void {\n const started = result.outcomes.filter((outcome) => outcome.runId);\n const failed = result.outcomes.filter((outcome) => !outcome.runId);\n if (started.length > 0) {\n const label = started\n .map(\n (outcome) => `${outcome.agent} (${outcome.runId})${outcome.warning ? `\\n Warning: ${outcome.warning}` : ''}`,\n )\n .join(', ');\n sendSlashText(\n pi,\n `## Subagent started\\n\\n${label}`,\n started.map((outcome) => ({\n agent: outcome.agent,\n runId: outcome.runId ?? '',\n status: STARTED_STATUS,\n ...(outcome.warning ? { warning: outcome.warning } : {}),\n })),\n );\n setSlashStatus(ctx, `${started.length} run${started.length === 1 ? '' : 's'} started…`);\n for (const outcome of started) {\n if (outcome.runId) watchAndFinalize(pi, ctx, deps, jobs, outcome.runId, outcome.agent);\n }\n }\n if (failed.length > 0) {\n const label = failed.map((outcome) => `${outcome.agent}: ${outcome.error ?? 'spawn failed'}`).join('\\n');\n notifyError(ctx, `Some subagents failed to start:\\n${label}`);\n }\n}\n\nfunction requireBaseCwd(state: SlashCommandState, ctx: ExtensionContext): string | undefined {\n if (state.baseCwd) return state.baseCwd;\n notifyError(ctx, 'Subagent session cwd is not initialized yet');\n return undefined;\n}\n\nfunction findAgentOrNotify(deps: SlashCommandDeps, baseCwd: string, name: string, ctx: ExtensionContext): boolean {\n const agents = deps.discovery.discover(baseCwd, 'both' satisfies AgentScope).agents;\n if (agents.find((agent) => agent.name === name)) return true;\n notifyError(ctx, `Unknown agent: ${name}`);\n return false;\n}\n\nexport interface SingleAgentRunRequest {\n agent: string;\n task: string;\n /** Inline `agent[model=x]` config from a slash token; surfaces without that syntax send none. */\n config?: InlineConfig;\n fork?: boolean;\n}\n\nexport type SingleAgentRunOutcome = { ok: true; result: SpawnPlanResult } | { ok: false; message: string };\n\n/**\n * One agent, one task: the shared body of `/run` and the agent catalog's\n * launch key (`SPC a l`, `r`/`R`).\n *\n * Returns `ok: false` with a user-facing message for the validation failures\n * both surfaces share rather than notifying itself, because the two report\n * in different idioms - a slash command notifies, and a fullscreen overlay\n * writes a notice into its own body, where a notification would be covered.\n * Started runs are still reported here through `reportSpawnResult`, which is\n * what tracks them and finalizes their message; that is identical for both.\n */\nexport async function launchSingleAgentRun(\n pi: ExtensionAPI,\n ctx: ExtensionContext,\n state: SlashCommandState,\n deps: SlashCommandDeps,\n request: SingleAgentRunRequest,\n): Promise<SingleAgentRunOutcome> {\n const baseCwd = state.baseCwd;\n if (!baseCwd) return { ok: false, message: 'Subagent session cwd is not initialized yet' };\n const agents = deps.discovery.discover(baseCwd, 'both' satisfies AgentScope).agents;\n if (!agents.find((agent) => agent.name === request.agent)) {\n return { ok: false, message: `Unknown agent: ${request.agent}` };\n }\n const jobs = deps.tracker.forSession(ctx.sessionManager.getSessionId());\n try {\n const parentForkSource = captureSessionForkSource(ctx.sessionManager, 'settled');\n const parentModel = normalizeParentModel(ctx.model);\n const taskInput = taskInputFromParsedStep(\n { name: request.agent, config: request.config ?? {}, task: request.task },\n baseCwd,\n request.fork ? 'fork' : undefined,\n );\n const result = await launchSingleSubagent(\n deps.spawnPlanner,\n jobs,\n {\n agent: taskInput.agent,\n task: taskInput.task ?? '',\n cwd: taskInput.cwd ?? baseCwd,\n agentScope: 'both',\n parentSessionId: ctx.sessionManager.getSessionId(),\n ...(taskInput.model ? { model: taskInput.model } : {}),\n ...(taskInput.context ? { context: taskInput.context } : {}),\n ...(parentForkSource\n ? { parentSessionFile: parentForkSource.sessionFile, parentLeafId: parentForkSource.leafId }\n : {}),\n availableModels: authenticatedModelInfos(ctx.modelRegistry),\n ...(parentModel ? { parentModel } : {}),\n },\n deps.loadConfig(),\n );\n reportSpawnResult(pi, ctx, deps, jobs, result);\n return { ok: true, result };\n } catch (error) {\n if (error instanceof UnsupportedInlineConfigError || error instanceof SlashParseError) {\n return { ok: false, message: error.message };\n }\n throw error;\n }\n}\n\n/**\n * `launchSingleAgentRun` for a surface that cannot await it - the agent\n * catalog closes on launch, so nothing is left to receive the outcome. The\n * failure paths report themselves here, once the overlay is gone and a\n * notification is visible again.\n */\nexport function startSingleAgentRun(\n pi: ExtensionAPI,\n ctx: ExtensionContext,\n state: SlashCommandState,\n deps: SlashCommandDeps,\n request: SingleAgentRunRequest,\n): void {\n void launchSingleAgentRun(pi, ctx, state, deps, request).then(\n (outcome) => {\n if (!outcome.ok) notifyError(ctx, outcome.message);\n },\n (error: unknown) => {\n notifyError(ctx, `Subagent launch failed: ${error instanceof Error ? error.message : String(error)}`);\n },\n );\n}\n\nfunction reportKnownErrorOrRethrow(ctx: ExtensionContext, error: unknown): void {\n if (error instanceof UnsupportedInlineConfigError || error instanceof SlashParseError) {\n notifyError(ctx, error.message);\n return;\n }\n throw error;\n}\n\n/**\n * Shared arg parsing for /chain (no inline group) and /parallel:\n * \"agent1 task1 -> agent2 task2\" or \"agent1 agent2 -- shared task\".\n */\nfunction parseAgentArgsFallback(input: string): { steps: ParsedStep[]; task: string; perStep: boolean } | undefined {\n const trimmed = input.trim();\n if (trimmed.includes(' -> ')) {\n const steps = trimmed\n .split(' -> ')\n .map((segment) => segment.trim())\n .filter(Boolean)\n .map((segment) => parseSingleTaskToken(segment));\n if (steps.length === 0) return undefined;\n return { steps, task: steps.find((step) => step.task)?.task ?? '', perStep: true };\n }\n const delimiterIndex = trimmed.indexOf(' -- ');\n if (delimiterIndex === -1) return undefined;\n const agentsPart = trimmed.slice(0, delimiterIndex).trim();\n const sharedTask = trimmed.slice(delimiterIndex + 4).trim();\n if (!agentsPart || !sharedTask) return undefined;\n const steps = agentsPart\n .split(/\\s+/)\n .filter(Boolean)\n .map((token) => parseSingleTaskToken(token));\n if (steps.length === 0) return undefined;\n return { steps, task: sharedTask, perStep: false };\n}\n\nexport function registerSlashCommands(pi: ExtensionAPI, state: SlashCommandState, deps: SlashCommandDeps): void {\n pi.registerCommand('run', {\n description: 'Run a subagent in the background: /run agent[model=x] [task] [--fork]',\n handler: async (args, ctx) => {\n const { args: cleanedArgs, fork } = extractForkFlag(args);\n const input = cleanedArgs.trim();\n if (!input) {\n notifyError(ctx, 'Usage: /run <agent> [task] [--fork]');\n return;\n }\n const firstSpace = input.indexOf(' ');\n const { name: agentName, config } = parseAgentToken(firstSpace === -1 ? input : input.slice(0, firstSpace));\n const task = firstSpace === -1 ? '' : input.slice(firstSpace + 1).trim();\n const outcome = await launchSingleAgentRun(pi, ctx, state, deps, { agent: agentName, task, config, fork });\n if (!outcome.ok) notifyError(ctx, outcome.message);\n },\n });\n\n pi.registerCommand('parallel', {\n description: 'Run agents in parallel: /parallel scout \"task1\" -> reviewer \"task2\" [--fork]',\n handler: async (args, ctx) => {\n const jobs = deps.tracker.forSession(ctx.sessionManager.getSessionId());\n const { args: cleanedArgs, fork } = extractForkFlag(args);\n const baseCwd = requireBaseCwd(state, ctx);\n if (!baseCwd) return;\n\n const parsed = parseAgentArgsFallback(cleanedArgs);\n if (!parsed) {\n notifyError(ctx, 'Usage: /parallel agent1 \"task1\" -> agent2 \"task2\"');\n return;\n }\n for (const step of parsed.steps) {\n if (!findAgentOrNotify(deps, baseCwd, step.name, ctx)) return;\n }\n if (!parsed.steps.some((step) => step.task) && !parsed.task) {\n notifyError(ctx, 'At least one step must have a task');\n return;\n }\n\n try {\n const parentForkSource = captureSessionForkSource(ctx.sessionManager, 'settled');\n const parentModel = normalizeParentModel(ctx.model);\n const tasks = parsed.steps.map((step) =>\n taskInputFromParsedStep(\n { name: step.name, config: step.config, task: step.task ?? parsed.task },\n baseCwd,\n fork ? 'fork' : undefined,\n ),\n );\n const result = await launchParallelSubagents(\n deps.spawnPlanner,\n jobs,\n {\n tasks,\n cwd: baseCwd,\n agentScope: 'both',\n parentSessionId: ctx.sessionManager.getSessionId(),\n ...(parentForkSource\n ? { parentSessionFile: parentForkSource.sessionFile, parentLeafId: parentForkSource.leafId }\n : {}),\n availableModels: authenticatedModelInfos(ctx.modelRegistry),\n ...(parentModel ? { parentModel } : {}),\n },\n deps.loadConfig(),\n );\n reportSpawnResult(pi, ctx, deps, jobs, result);\n } catch (error) {\n reportKnownErrorOrRethrow(ctx, error);\n }\n },\n });\n\n pi.registerCommand('subagents-doctor', {\n description: 'Show subagent diagnostics',\n handler: async (_args, ctx) => {\n sendSlashText(\n pi,\n buildDoctorReport({ cwd: ctx.cwd, agentScope: 'both' }, { discovery: deps.discovery, skills: deps.skills }),\n );\n },\n });\n\n pi.registerCommand('subagents-stop', {\n description: 'Stop a running subagent: /subagents-stop [run-id]',\n handler: async (args, ctx) => {\n const jobs = deps.tracker.forSession(ctx.sessionManager.getSessionId());\n const id = args.trim();\n if (!id) {\n sendSlashText(pi, stoppableRunsReport(jobs.list()));\n return;\n }\n try {\n deps.management.stop(resolveTrackedRunId(jobs, id));\n // Deliberately reports the REQUEST, not the outcome. Stop is\n // asynchronous in this package: the request is a file the child\n // claims on its next control-channel tick, so claiming \"stopped\"\n // here would assert something this process has not observed. The\n // run's own status is what confirms it, via /subagents-fleet or a\n // completion notification.\n notifyInfo(ctx, `Stop requested for ${id}. The run reports its own final state once it acknowledges.`);\n } catch (error) {\n // `ManagementActions.stop` throws only for an id that resolves to no\n // run or to more than one. Both are bad user input, not internal\n // faults, so they are notified rather than rethrown at the host - the\n // same treatment `reportKnownErrorOrRethrow` gives a parse error.\n notifyError(ctx, error instanceof Error ? error.message : `Could not stop '${id}'.`);\n }\n },\n });\n}\n\n/**\n * The no-argument `/subagents-stop` listing.\n *\n * The predecessor opened a TUI selector overlay here. This reports the same\n * information as text instead, for one reason worth stating rather than\n * hiding: a selector is a second, independent renderer of run state, and this\n * package already has one in `/subagents-fleet` that shows more (live status,\n * transcripts, and the full set of runtime controls including stop). Building\n * a second, weaker one would mean two things to keep in step. Passing an\n * explicit id stays the direct path, and the fleet overlay is the interactive\n * one.\n */\nfunction stoppableRunsReport(runs: readonly TrackedAsyncJob[]): string {\n const stoppable = runs.filter((run) => run.status === 'running' || run.status === 'pending');\n if (stoppable.length === 0) return 'No running subagents to stop.';\n const lines = stoppable.map((run) => `- ${run.runId}${run.status ? ` (${run.status})` : ''}`);\n return [\n 'Running subagents:',\n ...lines,\n '',\n 'Stop one with `/subagents-stop <run-id>`, or open `/subagents-fleet` to inspect and control them interactively.',\n ].join('\\n');\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"slashCommands.cjs","names":["TERMINAL_ASYNC_JOB_STATES","captureSessionForkSource","normalizeParentModel","taskInputFromParsedStep","launchSingleSubagent","authenticatedModelInfos","UnsupportedInlineConfigError","SlashParseError","parseSingleTaskToken","extractForkFlag","parseAgentToken","launchParallelSubagents","buildDoctorReport","resolveTrackedRunId"],"sources":["../../../../../../src/adapters/pi/commands/slash/slashCommands.ts"],"sourcesContent":["/**\n * The core `/run`, `/chain`, `/parallel` slash commands. Replaces the\n * always-blocking predecessor with the async-only shape this port settled\n * on: a command launches a spawn, sends an initial status message, and\n * hands off to `watchTrackedRunUntilTerminal` (render-key gated, backed by\n * `PollScheduler`) to update the status bar and finalize the message once\n * the run reaches a terminal state - never by awaiting completion. See\n * `subagentLaunch.ts`'s module doc for the full reasoning.\n *\n * WHAT IS NOT HERE, AND WHY:\n * - `/run-chain`, `/prompt-workflow` and `/chain-prompts`: the whole SAVED\n * work surface - saved agent pipelines (`ChainConfig`, never ported) and\n * saved `.md` prompt templates (ported, then deleted). REMOVED BY\n * DECISION, not deferred: overly complicated for the use they were\n * getting. Do not re-add them because a reader notices the predecessor had\n * them. Ad-hoc chaining (`/chain scout \"x\" -> planner`) is a different\n * feature, lives in `chainExpression.ts`, and stays\n * - `/subagent-cost`: REMOVED BY DECISION. It reads usage/cost data\n * (`totalTokens`/`totalCost`) that nothing in this package's\n * runs/extensions surface tracks - a genuinely absent data source, and\n * building it would mean threading usage out of every child process\n * - `/subagents-check-profile`: removed at the source. Calls\n * `checkSubagentProfile`/`listSubagentProfiles`, which are referenced but\n * defined nowhere in the entire predecessor package - a live\n * `ReferenceError` that only shipped because that package sets\n * `noCheck: true`. Typecheck is on here; porting it faithfully would not\n * compile, and it was asked to be removed independently of that\n * - The `SUBAGENT_FLEET_COMMAND` registration and its `Ctrl+Alt+F` shortcut:\n * fleet view is its own piece, registered by whoever builds it\n * - Inline parallel groups within `/chain` (`(a | b)` syntax): the field\n * mapping for a group's own config exists (`spawnRequestMapping.ts`),\n * but wiring a group INTO a chain request is left for the same pass that\n * revisits per-task field support, so `/chain` reports a clear\n * not-yet-supported message rather than silently flattening a group\n * - `/subagents` (admin) command registration: a separate file, not yet\n * ported\n *\n * `/subagents-doctor` IS here, in `doctor.ts` - read (not ported) the\n * predecessor's foreground-executor `doctor` action before deciding, and it\n * turned out to be a small, mostly-mechanical port. See that module's own\n * doc for what it deliberately leaves out (chain counts, spawn-budget\n * reporting).\n *\n * AVOID:\n * - Awaiting a SINGLE/PARALLEL spawn for a result that will not exist yet.\n * See `subagentLaunch.ts`\n * - A private polling loop for a message's live status. Use\n * `watchTrackedRunUntilTerminal`\n */\n\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport type { ExtensionConfig } from '../../extensions/config';\nimport type { ManagementActionsContract } from '../../extensions/managementActions';\nimport { captureSessionForkSource, type SpawnPlannerContract, type SpawnPlanResult } from '../../extensions/spawnPlan';\nimport type { SkillDiscoveryContract } from '../../../agents/skills';\nimport type { AgentScope, AgentDiscoveryContract } from '../../../agents/types';\nimport type { AsyncJobTrackerContract, TrackedAsyncJobsContract, TrackedAsyncJob } from '../../../asyncJobTracker';\nimport { resolveTrackedRunId, TERMINAL_ASYNC_JOB_STATES } from '../../../asyncJobTracker';\nimport { normalizeParentModel } from '../../../runs/shared/modelFallback';\nimport { authenticatedModelInfos } from '../../../../services/models/modelResolution';\nimport type { PollSchedulerContract } from '../../../pollScheduler';\nimport {\n extractForkFlag,\n type InlineConfig,\n type ParsedStep,\n parseAgentToken,\n parseSingleTaskToken,\n SlashParseError,\n} from './chainExpression';\nimport { buildDoctorReport } from './doctor';\nimport { taskInputFromParsedStep, UnsupportedInlineConfigError } from './spawnRequestMapping';\nimport { launchParallelSubagents, launchSingleSubagent, watchTrackedRunUntilTerminal } from './subagentLaunch';\n\nexport interface SlashCommandDeps {\n spawnPlanner: SpawnPlannerContract;\n skills: SkillDiscoveryContract;\n tracker: AsyncJobTrackerContract;\n scheduler: PollSchedulerContract;\n discovery: AgentDiscoveryContract;\n /**\n * Used by `/subagents-stop`. Preferred over calling `requestSlashRunStop`\n * directly because it resolves an id PREFIX through `RunIdResolver` and\n * raises a real error for an unknown or ambiguous one, instead of writing a\n * stop request into a directory for a run that does not exist.\n */\n management: ManagementActionsContract;\n loadConfig: () => ExtensionConfig;\n}\n\nexport interface SlashCommandState {\n baseCwd: string | undefined;\n}\n\nconst SLASH_STATUS_KEY = 'subagent-slash';\nconst STARTED_STATUS = 'started';\n\n/**\n * The custom-message type a slash launch renders under. Cross-process\n * significant the same way `SUBAGENT_NOTIFY_MESSAGE_TYPE` is: the child-side\n * prompt runtime strips this type out of a child's inherited history\n * (`PARENT_ONLY_CUSTOM_MESSAGE_TYPES`), so both sides must agree on the literal.\n */\nexport const SLASH_RESULT_CUSTOM_TYPE = 'subagent-slash-result';\n\n/**\n * One run's line in a slash-result message. `status` is the tracker's own\n * status string (plus `started`), not a closed set this module can narrow.\n */\nexport interface SlashRunDetail {\n agent: string;\n runId: string;\n status: string;\n error?: string;\n warning?: string;\n}\n\nfunction sendSlashText(pi: ExtensionAPI, text: string, details?: SlashRunDetail[]): void {\n pi.sendMessage({\n customType: SLASH_RESULT_CUSTOM_TYPE,\n content: text,\n display: true,\n ...(details ? { details } : {}),\n });\n}\n\nfunction setSlashStatus(ctx: ExtensionContext, text: string | undefined): void {\n if (ctx.hasUI) ctx.ui.setStatus(SLASH_STATUS_KEY, text);\n}\n\nfunction notifyError(ctx: ExtensionContext, message: string): void {\n ctx.ui.notify(message, 'error');\n}\n\nfunction notifyInfo(ctx: ExtensionContext, message: string): void {\n ctx.ui.notify(message, 'info');\n}\n\nfunction statusTextFor(job: TrackedAsyncJob | undefined): string {\n if (!job) return 'starting…';\n if (job.attentionReason) return `${job.status ?? 'running'} - needs attention: ${job.attentionReason}`;\n if (job.activityState) return `${job.status ?? 'running'} - ${job.activityState}`;\n return job.status ?? 'running';\n}\n\n/**\n * Watches one launched run to a terminal state and finalizes its message.\n * Each launched run gets its own subscriber, so a PARALLEL launch's\n * siblings finalize independently rather than all waiting on the slowest.\n */\nfunction watchAndFinalize(\n pi: ExtensionAPI,\n ctx: ExtensionContext,\n deps: SlashCommandDeps,\n jobs: TrackedAsyncJobsContract,\n runId: string,\n agent: string,\n): void {\n watchTrackedRunUntilTerminal(deps.scheduler, jobs, runId, (job) => {\n setSlashStatus(ctx, `${agent} (${runId}): ${statusTextFor(job)}`);\n if (job?.status === undefined || !TERMINAL_ASYNC_JOB_STATES.has(job.status)) return;\n setSlashStatus(ctx, undefined);\n const outcome = job.status === 'complete' || job.status === 'completed' ? 'completed' : job.status;\n sendSlashText(\n pi,\n job.error\n ? `## Subagent ${outcome}\\n\\n${agent} (${runId})\\n\\n${job.error}`\n : `## Subagent ${outcome}\\n\\n${agent} (${runId})`,\n [{ agent, runId, status: outcome, ...(job.error ? { error: job.error } : {}) }],\n );\n });\n}\n\nfunction reportSpawnResult(\n pi: ExtensionAPI,\n ctx: ExtensionContext,\n deps: SlashCommandDeps,\n jobs: TrackedAsyncJobsContract,\n result: SpawnPlanResult,\n): void {\n const started = result.outcomes.filter((outcome) => outcome.runId);\n const failed = result.outcomes.filter((outcome) => !outcome.runId);\n if (started.length > 0) {\n const label = started\n .map(\n (outcome) => `${outcome.agent} (${outcome.runId})${outcome.warning ? `\\n Warning: ${outcome.warning}` : ''}`,\n )\n .join(', ');\n sendSlashText(\n pi,\n `## Subagent started\\n\\n${label}`,\n started.map((outcome) => ({\n agent: outcome.agent,\n runId: outcome.runId ?? '',\n status: STARTED_STATUS,\n ...(outcome.warning ? { warning: outcome.warning } : {}),\n })),\n );\n setSlashStatus(ctx, `${started.length} run${started.length === 1 ? '' : 's'} started…`);\n for (const outcome of started) {\n if (outcome.runId) watchAndFinalize(pi, ctx, deps, jobs, outcome.runId, outcome.agent);\n }\n }\n if (failed.length > 0) {\n const label = failed.map((outcome) => `${outcome.agent}: ${outcome.error ?? 'spawn failed'}`).join('\\n');\n notifyError(ctx, `Some subagents failed to start:\\n${label}`);\n }\n}\n\nfunction requireBaseCwd(state: SlashCommandState, ctx: ExtensionContext): string | undefined {\n if (state.baseCwd) return state.baseCwd;\n notifyError(ctx, 'Subagent session cwd is not initialized yet');\n return undefined;\n}\n\nfunction findAgentOrNotify(deps: SlashCommandDeps, baseCwd: string, name: string, ctx: ExtensionContext): boolean {\n const agents = deps.discovery.discover(baseCwd, 'both' satisfies AgentScope).agents;\n if (agents.find((agent) => agent.name === name)) return true;\n notifyError(ctx, `Unknown agent: ${name}`);\n return false;\n}\n\nexport interface SingleAgentRunRequest {\n agent: string;\n task: string;\n /** Inline `agent[model=x]` config from a slash token; surfaces without that syntax send none. */\n config?: InlineConfig;\n fork?: boolean;\n}\n\nexport type SingleAgentRunOutcome = { ok: true; result: SpawnPlanResult } | { ok: false; message: string };\n\n/**\n * One agent, one task: the shared body of `/run` and the agent catalog's\n * launch key (`SPC a l`, `r`/`R`).\n *\n * Returns `ok: false` with a user-facing message for the validation failures\n * both surfaces share rather than notifying itself, because the two report\n * in different idioms - a slash command notifies, and a fullscreen overlay\n * writes a notice into its own body, where a notification would be covered.\n * Started runs are still reported here through `reportSpawnResult`, which is\n * what tracks them and finalizes their message; that is identical for both.\n */\nexport async function launchSingleAgentRun(\n pi: ExtensionAPI,\n ctx: ExtensionContext,\n state: SlashCommandState,\n deps: SlashCommandDeps,\n request: SingleAgentRunRequest,\n): Promise<SingleAgentRunOutcome> {\n const baseCwd = state.baseCwd;\n if (!baseCwd) return { ok: false, message: 'Subagent session cwd is not initialized yet' };\n const agents = deps.discovery.discover(baseCwd, 'both' satisfies AgentScope).agents;\n if (!agents.find((agent) => agent.name === request.agent)) {\n return { ok: false, message: `Unknown agent: ${request.agent}` };\n }\n const jobs = deps.tracker.forSession(ctx.sessionManager.getSessionId());\n try {\n const parentForkSource = captureSessionForkSource(ctx.sessionManager, 'settled');\n const parentModel = normalizeParentModel(ctx.model);\n const taskInput = taskInputFromParsedStep(\n { name: request.agent, config: request.config ?? {}, task: request.task },\n baseCwd,\n request.fork ? 'fork' : undefined,\n );\n const result = await launchSingleSubagent(\n deps.spawnPlanner,\n jobs,\n {\n agent: taskInput.agent,\n task: taskInput.task ?? '',\n cwd: taskInput.cwd ?? baseCwd,\n agentScope: 'both',\n parentSessionId: ctx.sessionManager.getSessionId(),\n ...(taskInput.model ? { model: taskInput.model } : {}),\n ...(taskInput.context ? { context: taskInput.context } : {}),\n ...(parentForkSource\n ? { parentSessionFile: parentForkSource.sessionFile, parentLeafId: parentForkSource.leafId }\n : {}),\n availableModels: authenticatedModelInfos(ctx.modelRegistry),\n ...(parentModel ? { parentModel } : {}),\n },\n deps.loadConfig(),\n );\n reportSpawnResult(pi, ctx, deps, jobs, result);\n return { ok: true, result };\n } catch (error) {\n if (error instanceof UnsupportedInlineConfigError || error instanceof SlashParseError) {\n return { ok: false, message: error.message };\n }\n throw error;\n }\n}\n\n/**\n * `launchSingleAgentRun` for a surface that cannot await it - the agent\n * catalog closes on launch, so nothing is left to receive the outcome. The\n * failure paths report themselves here, once the overlay is gone and a\n * notification is visible again.\n */\nexport function startSingleAgentRun(\n pi: ExtensionAPI,\n ctx: ExtensionContext,\n state: SlashCommandState,\n deps: SlashCommandDeps,\n request: SingleAgentRunRequest,\n): void {\n void launchSingleAgentRun(pi, ctx, state, deps, request).then(\n (outcome) => {\n if (!outcome.ok) notifyError(ctx, outcome.message);\n },\n (error: unknown) => {\n notifyError(ctx, `Subagent launch failed: ${error instanceof Error ? error.message : String(error)}`);\n },\n );\n}\n\nfunction reportKnownErrorOrRethrow(ctx: ExtensionContext, error: unknown): void {\n if (error instanceof UnsupportedInlineConfigError || error instanceof SlashParseError) {\n notifyError(ctx, error.message);\n return;\n }\n throw error;\n}\n\n/**\n * Shared arg parsing for /chain (no inline group) and /parallel:\n * \"agent1 task1 -> agent2 task2\" or \"agent1 agent2 -- shared task\".\n */\nfunction parseAgentArgsFallback(input: string): { steps: ParsedStep[]; task: string; perStep: boolean } | undefined {\n const trimmed = input.trim();\n if (trimmed.includes(' -> ')) {\n const steps = trimmed\n .split(' -> ')\n .map((segment) => segment.trim())\n .filter(Boolean)\n .map((segment) => parseSingleTaskToken(segment));\n if (steps.length === 0) return undefined;\n return { steps, task: steps.find((step) => step.task)?.task ?? '', perStep: true };\n }\n const delimiterIndex = trimmed.indexOf(' -- ');\n if (delimiterIndex === -1) return undefined;\n const agentsPart = trimmed.slice(0, delimiterIndex).trim();\n const sharedTask = trimmed.slice(delimiterIndex + 4).trim();\n if (!agentsPart || !sharedTask) return undefined;\n const steps = agentsPart\n .split(/\\s+/)\n .filter(Boolean)\n .map((token) => parseSingleTaskToken(token));\n if (steps.length === 0) return undefined;\n return { steps, task: sharedTask, perStep: false };\n}\n\nexport function registerSlashCommands(pi: ExtensionAPI, state: SlashCommandState, deps: SlashCommandDeps): void {\n pi.registerCommand('run', {\n description: 'Run a subagent in the background: /run agent[model=x] [task] [--fork]',\n handler: async (args, ctx) => {\n const { args: cleanedArgs, fork } = extractForkFlag(args);\n const input = cleanedArgs.trim();\n if (!input) {\n notifyError(ctx, 'Usage: /run <agent> [task] [--fork]');\n return;\n }\n const firstSpace = input.indexOf(' ');\n const { name: agentName, config } = parseAgentToken(firstSpace === -1 ? input : input.slice(0, firstSpace));\n const task = firstSpace === -1 ? '' : input.slice(firstSpace + 1).trim();\n const outcome = await launchSingleAgentRun(pi, ctx, state, deps, { agent: agentName, task, config, fork });\n if (!outcome.ok) notifyError(ctx, outcome.message);\n },\n });\n\n pi.registerCommand('parallel', {\n description: 'Run agents in parallel: /parallel scout \"task1\" -> reviewer \"task2\" [--fork]',\n handler: async (args, ctx) => {\n const jobs = deps.tracker.forSession(ctx.sessionManager.getSessionId());\n const { args: cleanedArgs, fork } = extractForkFlag(args);\n const baseCwd = requireBaseCwd(state, ctx);\n if (!baseCwd) return;\n\n const parsed = parseAgentArgsFallback(cleanedArgs);\n if (!parsed) {\n notifyError(ctx, 'Usage: /parallel agent1 \"task1\" -> agent2 \"task2\"');\n return;\n }\n for (const step of parsed.steps) {\n if (!findAgentOrNotify(deps, baseCwd, step.name, ctx)) return;\n }\n if (!parsed.steps.some((step) => step.task) && !parsed.task) {\n notifyError(ctx, 'At least one step must have a task');\n return;\n }\n\n try {\n const parentForkSource = captureSessionForkSource(ctx.sessionManager, 'settled');\n const parentModel = normalizeParentModel(ctx.model);\n const tasks = parsed.steps.map((step) =>\n taskInputFromParsedStep(\n { name: step.name, config: step.config, task: step.task ?? parsed.task },\n baseCwd,\n fork ? 'fork' : undefined,\n ),\n );\n const result = await launchParallelSubagents(\n deps.spawnPlanner,\n jobs,\n {\n tasks,\n cwd: baseCwd,\n agentScope: 'both',\n parentSessionId: ctx.sessionManager.getSessionId(),\n ...(parentForkSource\n ? { parentSessionFile: parentForkSource.sessionFile, parentLeafId: parentForkSource.leafId }\n : {}),\n availableModels: authenticatedModelInfos(ctx.modelRegistry),\n ...(parentModel ? { parentModel } : {}),\n },\n deps.loadConfig(),\n );\n reportSpawnResult(pi, ctx, deps, jobs, result);\n } catch (error) {\n reportKnownErrorOrRethrow(ctx, error);\n }\n },\n });\n\n pi.registerCommand('subagents-doctor', {\n description: 'Show subagent diagnostics',\n handler: async (_args, ctx) => {\n sendSlashText(\n pi,\n buildDoctorReport({ cwd: ctx.cwd, agentScope: 'both' }, { discovery: deps.discovery, skills: deps.skills }),\n );\n },\n });\n\n pi.registerCommand('subagents-steer', {\n description: 'Send guidance to a running subagent: /subagents-steer <run-id> <message>',\n handler: async (args, ctx) => {\n const input = args.trim();\n const separator = input.search(/\\s/);\n if (separator === -1 || !input.slice(separator + 1).trim()) {\n notifyError(ctx, 'Usage: /subagents-steer <run-id> <message>');\n return;\n }\n const id = input.slice(0, separator);\n const message = input.slice(separator + 1).trim();\n try {\n const result = await deps.management.steer(id, message);\n const summary = `Steering ${result.state} for ${id}: ${result.message}`;\n if (result.state === 'failed') notifyError(ctx, summary);\n else notifyInfo(ctx, summary);\n } catch (error) {\n notifyError(ctx, error instanceof Error ? error.message : `Could not steer '${id}'.`);\n }\n },\n });\n\n pi.registerCommand('subagents-stop', {\n description: 'Stop a running subagent: /subagents-stop [run-id]',\n handler: async (args, ctx) => {\n const jobs = deps.tracker.forSession(ctx.sessionManager.getSessionId());\n const id = args.trim();\n if (!id) {\n sendSlashText(pi, stoppableRunsReport(jobs.list()));\n return;\n }\n try {\n deps.management.stop(resolveTrackedRunId(jobs, id));\n // Deliberately reports the REQUEST, not the outcome. Stop is\n // asynchronous in this package: the request is a file the child\n // claims on its next control-channel tick, so claiming \"stopped\"\n // here would assert something this process has not observed. The\n // run's own status is what confirms it, via /subagents-fleet or a\n // completion notification.\n notifyInfo(ctx, `Stop requested for ${id}. The run reports its own final state once it acknowledges.`);\n } catch (error) {\n // `ManagementActions.stop` throws only for an id that resolves to no\n // run or to more than one. Both are bad user input, not internal\n // faults, so they are notified rather than rethrown at the host - the\n // same treatment `reportKnownErrorOrRethrow` gives a parse error.\n notifyError(ctx, error instanceof Error ? error.message : `Could not stop '${id}'.`);\n }\n },\n });\n}\n\n/**\n * The no-argument `/subagents-stop` listing.\n *\n * The predecessor opened a TUI selector overlay here. This reports the same\n * information as text instead, for one reason worth stating rather than\n * hiding: a selector is a second, independent renderer of run state, and this\n * package already has one in `/subagents-fleet` that shows more (live status,\n * transcripts, and the full set of runtime controls including stop). Building\n * a second, weaker one would mean two things to keep in step. Passing an\n * explicit id stays the direct path, and the fleet overlay is the interactive\n * one.\n */\nfunction stoppableRunsReport(runs: readonly TrackedAsyncJob[]): string {\n const stoppable = runs.filter((run) => run.status === 'running' || run.status === 'pending');\n if (stoppable.length === 0) return 'No running subagents to stop.';\n const lines = stoppable.map((run) => `- ${run.runId}${run.status ? ` (${run.status})` : ''}`);\n return [\n 'Running subagents:',\n ...lines,\n '',\n 'Stop one with `/subagents-stop <run-id>`, or open `/subagents-fleet` to inspect and control them interactively.',\n ].join('\\n');\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  import{authenticatedModelInfos as e}from"../../../../services/models/modelResolution.mjs";import{normalizeParentModel as t}from"../../../runs/shared/modelFallback.mjs";import{captureSessionForkSource as n}from"../../extensions/spawnPlan.mjs";import{TERMINAL_ASYNC_JOB_STATES as r,init_asyncJobTracker as i,resolveTrackedRunId as a}from"../../../asyncJobTracker.mjs";import{SlashParseError as o,extractForkFlag as s,parseAgentToken as c,parseSingleTaskToken as l}from"./chainExpression.mjs";import{buildDoctorReport as u}from"./doctor.mjs";import{UnsupportedInlineConfigError as d,taskInputFromParsedStep as f}from"./spawnRequestMapping.mjs";import{launchParallelSubagents as p,launchSingleSubagent as m,watchTrackedRunUntilTerminal as h}from"./subagentLaunch.mjs";i();const g=`subagent-slash-result`;function _(e,t,n){e.sendMessage({customType:g,content:t,display:!0,...n?{details:n}:{}})}function v(e,t){e.hasUI&&e.ui.setStatus(`subagent-slash`,t)}function y(e,t){e.ui.notify(t,`error`)}function b(e,t){e.ui.notify(t,`info`)}function x(e){return e?e.attentionReason?`${e.status??`running`} - needs attention: ${e.attentionReason}`:e.activityState?`${e.status??`running`} - ${e.activityState}`:e.status??`running`:`starting…`}function S(e,t,n,i,a,o){h(n.scheduler,i,a,n=>{if(v(t,`${o} (${a}): ${x(n)}`),n?.status===void 0||!r.has(n.status))return;v(t,void 0);let i=n.status===`complete`||n.status===`completed`?`completed`:n.status;_(e,n.error?`## Subagent ${i}\n\n${o} (${a})\n\n${n.error}`:`## Subagent ${i}\n\n${o} (${a})`,[{agent:o,runId:a,status:i,...n.error?{error:n.error}:{}}])})}function C(e,t,n,r,i){let a=i.outcomes.filter(e=>e.runId),o=i.outcomes.filter(e=>!e.runId);if(a.length>0){_(e,`## Subagent started\n\n${a.map(e=>`${e.agent} (${e.runId})${e.warning?`\n Warning: ${e.warning}`:``}`).join(`, `)}`,a.map(e=>({agent:e.agent,runId:e.runId??``,status:`started`,...e.warning?{warning:e.warning}:{}}))),v(t,`${a.length} run${a.length===1?``:`s`} started…`);for(let i of a)i.runId&&S(e,t,n,r,i.runId,i.agent)}o.length>0&&y(t,`Some subagents failed to start:\n${o.map(e=>`${e.agent}: ${e.error??`spawn failed`}`).join(`
2
- `)}`)}function w(e,t){if(e.baseCwd)return e.baseCwd;y(t,`Subagent session cwd is not initialized yet`)}function T(e,t,n,r){return e.discovery.discover(t,`both`).agents.find(e=>e.name===n)?!0:(y(r,`Unknown agent: ${n}`),!1)}async function E(r,i,a,s,c){let l=a.baseCwd;if(!l)return{ok:!1,message:`Subagent session cwd is not initialized yet`};if(!s.discovery.discover(l,`both`).agents.find(e=>e.name===c.agent))return{ok:!1,message:`Unknown agent: ${c.agent}`};let u=s.tracker.forSession(i.sessionManager.getSessionId());try{let a=n(i.sessionManager,`settled`),o=t(i.model),d=f({name:c.agent,config:c.config??{},task:c.task},l,c.fork?`fork`:void 0),p=await m(s.spawnPlanner,u,{agent:d.agent,task:d.task??``,cwd:d.cwd??l,agentScope:`both`,parentSessionId:i.sessionManager.getSessionId(),...d.model?{model:d.model}:{},...d.context?{context:d.context}:{},...a?{parentSessionFile:a.sessionFile,parentLeafId:a.leafId}:{},availableModels:e(i.modelRegistry),...o?{parentModel:o}:{}},s.loadConfig());return C(r,i,s,u,p),{ok:!0,result:p}}catch(e){if(e instanceof d||e instanceof o)return{ok:!1,message:e.message};throw e}}function D(e,t,n,r,i){E(e,t,n,r,i).then(e=>{e.ok||y(t,e.message)},e=>{y(t,`Subagent launch failed: ${e instanceof Error?e.message:String(e)}`)})}function O(e,t){if(t instanceof d||t instanceof o){y(e,t.message);return}throw t}function k(e){let t=e.trim();if(t.includes(` -> `)){let e=t.split(` -> `).map(e=>e.trim()).filter(Boolean).map(e=>l(e));return e.length===0?void 0:{steps:e,task:e.find(e=>e.task)?.task??``,perStep:!0}}let n=t.indexOf(` -- `);if(n===-1)return;let r=t.slice(0,n).trim(),i=t.slice(n+4).trim();if(!r||!i)return;let a=r.split(/\s+/).filter(Boolean).map(e=>l(e));if(a.length!==0)return{steps:a,task:i,perStep:!1}}function A(r,i,o){r.registerCommand(`run`,{description:`Run a subagent in the background: /run agent[model=x] [task] [--fork]`,handler:async(e,t)=>{let{args:n,fork:a}=s(e),l=n.trim();if(!l){y(t,`Usage: /run <agent> [task] [--fork]`);return}let u=l.indexOf(` `),{name:d,config:f}=c(u===-1?l:l.slice(0,u)),p=await E(r,t,i,o,{agent:d,task:u===-1?``:l.slice(u+1).trim(),config:f,fork:a});p.ok||y(t,p.message)}}),r.registerCommand(`parallel`,{description:`Run agents in parallel: /parallel scout "task1" -> reviewer "task2" [--fork]`,handler:async(a,c)=>{let l=o.tracker.forSession(c.sessionManager.getSessionId()),{args:u,fork:d}=s(a),m=w(i,c);if(!m)return;let h=k(u);if(!h){y(c,`Usage: /parallel agent1 "task1" -> agent2 "task2"`);return}for(let e of h.steps)if(!T(o,m,e.name,c))return;if(!h.steps.some(e=>e.task)&&!h.task){y(c,`At least one step must have a task`);return}try{let i=n(c.sessionManager,`settled`),a=t(c.model),s=h.steps.map(e=>f({name:e.name,config:e.config,task:e.task??h.task},m,d?`fork`:void 0));C(r,c,o,l,await p(o.spawnPlanner,l,{tasks:s,cwd:m,agentScope:`both`,parentSessionId:c.sessionManager.getSessionId(),...i?{parentSessionFile:i.sessionFile,parentLeafId:i.leafId}:{},availableModels:e(c.modelRegistry),...a?{parentModel:a}:{}},o.loadConfig()))}catch(e){O(c,e)}}}),r.registerCommand(`subagents-doctor`,{description:`Show subagent diagnostics`,handler:async(e,t)=>{_(r,u({cwd:t.cwd,agentScope:`both`},{discovery:o.discovery,skills:o.skills}))}}),r.registerCommand(`subagents-stop`,{description:`Stop a running subagent: /subagents-stop [run-id]`,handler:async(e,t)=>{let n=o.tracker.forSession(t.sessionManager.getSessionId()),i=e.trim();if(!i){_(r,j(n.list()));return}try{o.management.stop(a(n,i)),b(t,`Stop requested for ${i}. The run reports its own final state once it acknowledges.`)}catch(e){y(t,e instanceof Error?e.message:`Could not stop '${i}'.`)}}})}function j(e){let t=e.filter(e=>e.status===`running`||e.status===`pending`);return t.length===0?`No running subagents to stop.`:[`Running subagents:`,...t.map(e=>`- ${e.runId}${e.status?` (${e.status})`:``}`),``,"Stop one with `/subagents-stop <run-id>`, or open `/subagents-fleet` to inspect and control them interactively."].join(`
2
+ `)}`)}function w(e,t){if(e.baseCwd)return e.baseCwd;y(t,`Subagent session cwd is not initialized yet`)}function T(e,t,n,r){return e.discovery.discover(t,`both`).agents.find(e=>e.name===n)?!0:(y(r,`Unknown agent: ${n}`),!1)}async function E(r,i,a,s,c){let l=a.baseCwd;if(!l)return{ok:!1,message:`Subagent session cwd is not initialized yet`};if(!s.discovery.discover(l,`both`).agents.find(e=>e.name===c.agent))return{ok:!1,message:`Unknown agent: ${c.agent}`};let u=s.tracker.forSession(i.sessionManager.getSessionId());try{let a=n(i.sessionManager,`settled`),o=t(i.model),d=f({name:c.agent,config:c.config??{},task:c.task},l,c.fork?`fork`:void 0),p=await m(s.spawnPlanner,u,{agent:d.agent,task:d.task??``,cwd:d.cwd??l,agentScope:`both`,parentSessionId:i.sessionManager.getSessionId(),...d.model?{model:d.model}:{},...d.context?{context:d.context}:{},...a?{parentSessionFile:a.sessionFile,parentLeafId:a.leafId}:{},availableModels:e(i.modelRegistry),...o?{parentModel:o}:{}},s.loadConfig());return C(r,i,s,u,p),{ok:!0,result:p}}catch(e){if(e instanceof d||e instanceof o)return{ok:!1,message:e.message};throw e}}function D(e,t,n,r,i){E(e,t,n,r,i).then(e=>{e.ok||y(t,e.message)},e=>{y(t,`Subagent launch failed: ${e instanceof Error?e.message:String(e)}`)})}function O(e,t){if(t instanceof d||t instanceof o){y(e,t.message);return}throw t}function k(e){let t=e.trim();if(t.includes(` -> `)){let e=t.split(` -> `).map(e=>e.trim()).filter(Boolean).map(e=>l(e));return e.length===0?void 0:{steps:e,task:e.find(e=>e.task)?.task??``,perStep:!0}}let n=t.indexOf(` -- `);if(n===-1)return;let r=t.slice(0,n).trim(),i=t.slice(n+4).trim();if(!r||!i)return;let a=r.split(/\s+/).filter(Boolean).map(e=>l(e));if(a.length!==0)return{steps:a,task:i,perStep:!1}}function A(r,i,o){r.registerCommand(`run`,{description:`Run a subagent in the background: /run agent[model=x] [task] [--fork]`,handler:async(e,t)=>{let{args:n,fork:a}=s(e),l=n.trim();if(!l){y(t,`Usage: /run <agent> [task] [--fork]`);return}let u=l.indexOf(` `),{name:d,config:f}=c(u===-1?l:l.slice(0,u)),p=await E(r,t,i,o,{agent:d,task:u===-1?``:l.slice(u+1).trim(),config:f,fork:a});p.ok||y(t,p.message)}}),r.registerCommand(`parallel`,{description:`Run agents in parallel: /parallel scout "task1" -> reviewer "task2" [--fork]`,handler:async(a,c)=>{let l=o.tracker.forSession(c.sessionManager.getSessionId()),{args:u,fork:d}=s(a),m=w(i,c);if(!m)return;let h=k(u);if(!h){y(c,`Usage: /parallel agent1 "task1" -> agent2 "task2"`);return}for(let e of h.steps)if(!T(o,m,e.name,c))return;if(!h.steps.some(e=>e.task)&&!h.task){y(c,`At least one step must have a task`);return}try{let i=n(c.sessionManager,`settled`),a=t(c.model),s=h.steps.map(e=>f({name:e.name,config:e.config,task:e.task??h.task},m,d?`fork`:void 0));C(r,c,o,l,await p(o.spawnPlanner,l,{tasks:s,cwd:m,agentScope:`both`,parentSessionId:c.sessionManager.getSessionId(),...i?{parentSessionFile:i.sessionFile,parentLeafId:i.leafId}:{},availableModels:e(c.modelRegistry),...a?{parentModel:a}:{}},o.loadConfig()))}catch(e){O(c,e)}}}),r.registerCommand(`subagents-doctor`,{description:`Show subagent diagnostics`,handler:async(e,t)=>{_(r,u({cwd:t.cwd,agentScope:`both`},{discovery:o.discovery,skills:o.skills}))}}),r.registerCommand(`subagents-steer`,{description:`Send guidance to a running subagent: /subagents-steer <run-id> <message>`,handler:async(e,t)=>{let n=e.trim(),r=n.search(/\s/);if(r===-1||!n.slice(r+1).trim()){y(t,`Usage: /subagents-steer <run-id> <message>`);return}let i=n.slice(0,r),a=n.slice(r+1).trim();try{let e=await o.management.steer(i,a),n=`Steering ${e.state} for ${i}: ${e.message}`;e.state===`failed`?y(t,n):b(t,n)}catch(e){y(t,e instanceof Error?e.message:`Could not steer '${i}'.`)}}}),r.registerCommand(`subagents-stop`,{description:`Stop a running subagent: /subagents-stop [run-id]`,handler:async(e,t)=>{let n=o.tracker.forSession(t.sessionManager.getSessionId()),i=e.trim();if(!i){_(r,j(n.list()));return}try{o.management.stop(a(n,i)),b(t,`Stop requested for ${i}. The run reports its own final state once it acknowledges.`)}catch(e){y(t,e instanceof Error?e.message:`Could not stop '${i}'.`)}}})}function j(e){let t=e.filter(e=>e.status===`running`||e.status===`pending`);return t.length===0?`No running subagents to stop.`:[`Running subagents:`,...t.map(e=>`- ${e.runId}${e.status?` (${e.status})`:``}`),``,"Stop one with `/subagents-stop <run-id>`, or open `/subagents-fleet` to inspect and control them interactively."].join(`
3
3
  `)}export{g as SLASH_RESULT_CUSTOM_TYPE,E as launchSingleAgentRun,A as registerSlashCommands,D as startSingleAgentRun};
4
4
  //# sourceMappingURL=slashCommands.mjs.map