@agimon-ai/doompi-team 0.0.1-alpha.65 → 0.0.1-alpha.67

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.
@@ -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/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(`
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/versioned.cjs"),o=require("../../services/support/errors.cjs"),s=require("../../services/support/boundedKeySet.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(a.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(!a.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(a.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(a.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(a.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 s.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
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
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{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(`
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{init_versioned as re,parseVersioned as f}from"../../services/support/versioned.mjs";import{DoomTeamExpectedError as p,init_errors as ie,invalidRequest as m}from"../../services/support/errors.mjs";import{BoundedKeySet as ae,init_boundedKeySet as oe}from"../../services/support/boundedKeySet.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(f(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(!f(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(f(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(f(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(f(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 m(`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 p(`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 m(`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 m(`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 m(`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 m(`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 p(`recipient_ambiguous`,`Multiple active intercom members match '${r}': ${c.map(e=>e.memberId).join(`, `)}.`,!1,`Retry with one exact member id.`):new p(`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 m(`message is required for intercom communication.`,`Provide a nonblank message.`);if(!S(t,W))throw m(`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(),oe(),ie(),c(),d(),re(),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 ae(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 p(`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 p(`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 p(`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 p(`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
- `):`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};
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 p(`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,2 +1,2 @@
1
- const e=require("../agents/discovery.cjs"),t=require("../../services/webSubagentCatalog.cjs"),n=require("../sessionCatalogSnapshot.cjs"),r=require("../filesystem/paths.cjs"),i=require("../api/teamSnapshot.cjs"),a=require("../../services/models/modelResolution.cjs"),o=require("../runs/shared/modelFallback.cjs"),ee=require("../scopeOwner.cjs"),te=require("./extensions/spawnPlan.cjs"),s=require("../asyncJobTracker.cjs"),c=require("./commands/slash/slashCommands.cjs"),l=require("./extensions/config.cjs"),u=require("./extensions/delegationBridge.cjs"),d=require("./extensions/fablePlanBridge.cjs"),f=require("./extensions/orchestratorPrompt.cjs"),ne=require("../suspendedRuns.cjs"),p=require("../runs/registry/sessionLifecycle.cjs"),m=require("./tui/completionNotice.cjs"),re=require("./tui/slashRunNotice.cjs"),h=require("./tui/register.cjs"),ie=require("./collaboration.cjs"),ae=require("./teamRuntime.cjs");let g=require("@agimon-ai/doompi-extension-contracts/child-process"),_=require("@agimon-ai/doompi-extension-contracts/cordis-host"),v=require("@agimon-ai/doompi-extension-contracts/context-contributions"),y=require("@agimon-ai/doompi-extension-contracts/mcp-tool-resolver"),oe=require("@agimon-ai/doompi-extension-contracts/readiness"),b=require("@agimon-ai/doompi-extension-contracts/ui-hub"),se=require("@agimon-ai/doompi-telemetry");const x=`unknown`,S=`@agimon-ai/doompi-team`;function ce(e,t){let n=Reflect.get(e,t,e);return typeof n==`function`?n.bind(e):n}function le(e){let t=e.diagnostics.join(`; `),n=(e.error?.message??t)||`Initialization did not complete.`;return`${e.packageId} initialization ${e.state}: ${n}`}function ue(e,t,n,r,i,a){return{spawnPlanner:n,tracker:r,scheduler:i,discovery:e,skills:t,management:a,loadConfig:()=>l.loadConfig().config}}function de(e,t){if(t.kind===`requested`){let{event:n}=t;e.recordEvent(`doom_team.delegation_requested`,{"agent.name":n.agent,"task.id":n.taskId,mode:n.runMode??`foreground`})}else if(t.kind===`started`){let{event:n}=t;e.recordEvent(`doom_team.child_started`,{"run.id":n.runId,outcome:`started`})}else if(t.kind===`updated`){let{event:n}=t;e.recordEvent(`doom_team.delegation_updated`,{"run.id":n.runId,"team.tool_count":n.toolCount??0,"team.duration_ms":n.durationMs??0,"team.token_count":n.tokens??0,outcome:n.status??`updated`})}else if(t.kind===`finished`){let{event:n}=t;e.recordEvent(`doom_team.delegation_finished`,{"run.id":n.runId,"team.tool_count":n.toolCount??0,"team.duration_ms":n.durationMs??0,outcome:n.status})}else e.recordEvent(`doom_team.delegation_cancelled`,{outcome:`cancelled`})}function C(C,w){let T,fe=e=>(T??=(0,se.createDoomTelemetry)({serviceName:`doom-team`,packageName:`@agimon-ai/doompi-team`,cwd:e.cwd,env:process.env,enableLogs:!0,enableTraces:!0}),T),pe=(e,t)=>{T?.recordEvent(e,t)};C.effect(()=>async()=>{await T?.shutdown(),T=void 0},`@agimon-ai/doompi-team/telemetry`);let E=ae.createTeamExtensionRuntime(pe),{subagentTool:me,teamChannel:D,pollScheduler:O,asyncJobTracker:k,subagentWaiter:A,asyncSubagentSpawner:he,discovery:j,skills:M,spawnPlanner:N,completionNotifier:P,resultWatcher:F,staleRunReconciler:I,management:L,capabilityPolicies:R,mcpToolResolver:ge}=E,z=!0,B=0,V,H,U,W,G,K;C.inject([_.DOOM_CORDIS_SESSION_SERVICE],e=>{let t={cordis:e,service:e.get(_.DOOM_CORDIS_SESSION_SERVICE)};K=t,e.inject([y.DOOM_MCP_TOOL_RESOLVER_SERVICE],e=>ge.bind((0,y.requireDoomMcpToolResolver)(e))),e.inject([v.DOOM_CONTEXT_CONTRIBUTIONS_SERVICE],e=>{let t=(0,v.requireDoomContextContributions)(e).register({source:S,id:`runtime`,label:`Team`,order:200,snapshot:()=>i.formatTeamContextSnapshot(i.readActiveTeamSnapshot())});return()=>t.dispose()}),e.effect(()=>()=>{K===t&&(K=void 0)},`${S}/cordis-session`)});let _e=e=>{let t=K,n=e.sessionManager.getSessionId();return(t?.service.context.sessionManager===e.sessionManager&&t.service.sessionId===n?(0,oe.readDoomReadinessCoordinator)(t.cordis):void 0)||(W??=(0,oe.createDoomReadinessCoordinator)({notify:e=>{let t=le(e);G?.hasUI?G.ui.notify(t,`warning`):process.emitWarning(t)}}),W)},q=async(e,t)=>{t?.throwIfAborted();let n=H;if(!n)throw Error(`Doom Team session initialization has not started.`);if(U!==e.sessionManager)throw Error(`Doom Team readiness belongs to a stale Pi session.`);let r=await n;if(t?.throwIfAborted(),await r.wait(t?{signal:t}:void 0),!z||n!==H||U!==e.sessionManager)throw Error(`Doom Team readiness belongs to a stale extension generation.`)},J=new Proxy(w,{get(e,t){return t===`registerTool`?t=>{e.registerTool({...t,execute:async(e,n,r,i,a)=>(await q(a,r),t.execute(e,n,r,i,a))})}:t===`registerCommand`?(t,n)=>{e.registerCommand(t,{...n,handler:async(e,t)=>(await q(t),n.handler(e,t))})}:t===`registerShortcut`?(t,n)=>{e.registerShortcut(t,{...n,handler:async e=>(await q(e),n.handler(e))})}:ce(e,t)}});me.registerTool(J),C.inject([b.DOOM_UI_HUB_SERVICE],e=>h.registerSubagentLeaderContribution((0,b.requireDoomUiHub)(e)));let Y=D.createRuntime(J);C.effect(()=>()=>Y.dispose(),`@agimon-ai/doompi-team/channel`),D.registerClient(J),P.attachHost(w),C.effect(()=>()=>P.dispose(),`@agimon-ai/doompi-team/completions`),O.start(),C.effect(()=>()=>O.stop(),`@agimon-ai/doompi-team/polling`),k.start(),C.effect(()=>()=>k.stop(),`@agimon-ai/doompi-team/jobs`);let X,Z,Q,ve=u.createDelegationBridge({planner:N,management:L,waiter:A,scheduler:O,tracker:k,loadConfig:()=>l.loadConfig().config}),ye=d.createFablePlanBridge({spawner:he,waiter:A,management:L,policies:R,report:(e,t)=>{T?.recordEvent(e,t)}});C.effect(()=>async()=>{await X?.dispose(),X=void 0},`@agimon-ai/doompi-team/collaboration`),C.effect(()=>()=>{F.stop(),Q=void 0},`@agimon-ai/doompi-team/result-watcher`);let be=O.register({id:`stale-run-reconciler`,intervalMs:2e3,run:async()=>{let e=!1,t=!1;for(let n of Z?.list()??[]){if(n.status&&s.TERMINAL_ASYNC_JOB_STATES.has(n.status))continue;t=!0;let{reconcile:r,sweep:i}=I.reconcileAndSweepAsync?await I.reconcileAndSweepAsync(n.runId):I.reconcileAndSweep(n.runId);r.repaired&&(Z?.track(n.runId),e=!0),i.recovered.length>0&&(e=!0)}return e||t}});C.effect(()=>be,`@agimon-ai/doompi-team/stale-runs`),w.on(`before_agent_start`,e=>{if(z&&f.shouldInjectOrchestratorPrompt(l.loadConfig().config))return{systemPrompt:f.appendOrchestratorPrompt(e.systemPrompt)}});let $={baseCwd:void 0},xe=(r,i)=>{if((0,g.resolveRootSessionId)(i)===i)try{n.writeSessionCatalogSnapshot(i,{cwd:r,agents:t.presentCatalog(j.discover(r,`both`).agents),models:e.resolveActiveTeamModelSpecs()??[]})}catch{}};w.on(`before_agent_start`,(e,t)=>{z&&xe(t.cwd,t.sessionManager.getSessionId())});let Se=ue(j,M,N,k,O,L);c.registerSlashCommands(J,$,Se),h.registerAgentListCommand(J,{discovery:j,skills:M,policies:R,launchAgent:(e,t)=>c.startSingleAgentRun(J,e,$,Se,{agent:t.agent,task:t.task,fork:t.context===`fork`})}),h.registerFleetCommand(J,{scheduler:O,tracker:k,management:L}),C.inject([b.DOOM_UI_HUB_SERVICE],e=>h.registerAgentStatus(w,(0,b.requireDoomUiHub)(e),{scheduler:O,tracker:k})),m.registerCompletionRenderer(w),re.registerSlashRunRenderer(w);let Ce=async()=>{let e=[],t=X;X=void 0;try{await t?.dispose()}catch(t){e.push(t)}for(let t of[()=>R.clear(),()=>ve.abandonAll(),()=>ye.abandonAll(),()=>Y.dispose()])try{t()}catch(t){e.push(t)}if(Z=void 0,e.length!==0)return e.length===1&&e[0]instanceof Error?e[0]:AggregateError(e,`Team session cleanup failed.`)};w.on(`session_start`,(e,t)=>{if(!z)return;let n=++B,i=H;V?.abort(Error(`Doom Team session initialization was superseded.`));let s=new AbortController;V=s,U=t.sessionManager,G=t;let c=fe(t);c.recordEvent(`doom_team.session_started`,{"team.root_session":(0,g.resolveRootSessionId)(t.sessionManager.getSessionId())===t.sessionManager.getSessionId()});let l=t.sessionManager.getSessionId(),u=r.createSessionScope((0,g.resolveRootSessionId)(l));r.setCurrentSessionScope(u),$.baseCwd=t.cwd,xe(t.cwd,l),Q!==void 0&&Q!==u.scopeKey&&(F.stop(),Q=void 0);let d=Ce(),f=_e(t),m=()=>z&&n===B&&U===t.sessionManager&&!s.signal.aborted;H=(async()=>{if(i&&await Promise.allSettled([i.then(e=>e.wait())]),!m())throw Error(`Doom Team session initialization was superseded.`);return f.start(S,`${l}:${n}`,async e=>{e.throwIfAborted();let n=await d;if(n)throw n;if(!m()||(await ee.writeScopeOwnerAsync(u),e.throwIfAborted(),!m()))return{value:void 0};let r=await p.openScopeAsync(u,{readStatusAsync:async e=>L.statusAsync?(await L.statusAsync(e)).status:L.status(e).status});if(e.throwIfAborted(),!m())return{value:void 0};if(r.suspended.length>0&&t.hasUI){let n=await ne.formatSuspendedRunsAsync(r.suspended);if(e.throwIfAborted(),!m())return{value:void 0};t.ui.notify(n,`info`)}c.recordEvent(`doom_team.runs_restored`,{"team.suspended_count":r.suspended.length,"team.pruned_count":r.pruned.length,"team.reaped_count":r.reaped,outcome:`reported`}),Z=k.forSession(l),Q!==u.scopeKey&&(Q=u.scopeKey,F.start(async e=>{if(!Z?.get(e.runId))return!1;let t=await P.deliver(e);return t&&k.acknowledgeHandoff(l,e.runId),t}));let i=o.normalizeParentModel(t.model),s=K,f=(s?.service.context.sessionManager===t.sessionManager?s.cordis:C).plugin(ie.teamCollaborationPlugin,{session:{sessionId:l,cwd:t.cwd,availableModels:a.authenticatedModelInfos(t.modelRegistry),...i?{parentModel:i}:{},captureForkSource:()=>te.captureSessionForkSource(t.sessionManager,`tool`)},directRunTracker:k,delegation:ve,fablePlan:ye,policies:R,observeDelegation:e=>de(c,e)});return X=f,await f.await(),m()?(Y.bindMainSession(l),{value:void 0}):(await f.dispose(),X===f&&(X=void 0),{value:void 0})})})(),Promise.allSettled([H.then(e=>e.wait())])}),C.effect(()=>async()=>{z=!1,B+=1;let e=H;H=void 0,U=void 0,V?.abort(Error(`Doom Team runtime was disposed.`)),V=void 0;let t=W;W=void 0,t?await t.dispose():e&&await Promise.allSettled([e.then(e=>e.wait())]),G=void 0},`@agimon-ai/doompi-team/session-fence`);let we,Te=async e=>{z=!1,B+=1;let t=H;H=void 0,U=void 0,V?.abort(Error(`Doom Team session ended.`)),V=void 0;let n=W;W=void 0,await Promise.allSettled([...t?[t.then(e=>e.wait())]:[],...n?[n.dispose()]:[]]);let i=r.tryCurrentSessionScope(),a=i?p.suspendScopeRuns({scope:i,reason:e.reason??x,readStatus:e=>L.status(e).status}):Promise.resolve(void 0),o;try{o=await a,await T?.recordEvent(`doom_team.session_finished`,{reason:e.reason??x,"team.suspended_count":o?.suspended.length??0,"team.unstoppable_count":o?.unstoppable.length??0,outcome:o?.unstoppable.length?`degraded`:`suspended`})}catch(t){await T?.recordError(`doom_team.session_shutdown_failed`,t,{reason:e.reason??x})}finally{await T?.shutdown(),T=void 0}};return w.on(`session_shutdown`,e=>(we??=Te(e),we)),E}exports.installTeamRuntime=C;
1
+ const e=require("../agents/discovery.cjs"),t=require("../../services/webSubagentCatalog.cjs"),n=require("../sessionCatalogSnapshot.cjs"),r=require("../filesystem/paths.cjs"),i=require("../../services/models/modelResolution.cjs"),a=require("../runs/shared/modelFallback.cjs"),o=require("../scopeOwner.cjs"),ee=require("./extensions/spawnPlan.cjs"),s=require("../asyncJobTracker.cjs"),c=require("./commands/slash/slashCommands.cjs"),l=require("./extensions/config.cjs"),u=require("./extensions/delegationBridge.cjs"),d=require("./extensions/fablePlanBridge.cjs"),f=require("./extensions/orchestratorPrompt.cjs"),p=require("../api/teamSnapshot.cjs"),te=require("../suspendedRuns.cjs"),ne=require("../runs/registry/sessionLifecycle.cjs"),m=require("./tui/completionNotice.cjs"),re=require("./tui/slashRunNotice.cjs"),h=require("./tui/register.cjs"),ie=require("./collaboration.cjs"),ae=require("./teamRuntime.cjs");let g=require("@agimon-ai/doompi-extension-contracts/child-process"),_=require("@agimon-ai/doompi-extension-contracts/cordis-host"),v=require("@agimon-ai/doompi-extension-contracts/context-contributions"),y=require("@agimon-ai/doompi-extension-contracts/mcp-tool-resolver"),oe=require("@agimon-ai/doompi-extension-contracts/readiness"),b=require("@agimon-ai/doompi-extension-contracts/ui-hub"),se=require("@agimon-ai/doompi-telemetry");const x=`unknown`,S=`@agimon-ai/doompi-team`;function ce(e,t){let n=Reflect.get(e,t,e);return typeof n==`function`?n.bind(e):n}function le(e){let t=e.diagnostics.join(`; `),n=(e.error?.message??t)||`Initialization did not complete.`;return`${e.packageId} initialization ${e.state}: ${n}`}function ue(e,t,n,r,i,a){return{spawnPlanner:n,tracker:r,scheduler:i,discovery:e,skills:t,management:a,loadConfig:()=>l.loadConfig().config}}function de(e,t){if(t.kind===`requested`){let{event:n}=t;e.recordEvent(`doom_team.delegation_requested`,{"agent.name":n.agent,"task.id":n.taskId,mode:n.runMode??`foreground`})}else if(t.kind===`started`){let{event:n}=t;e.recordEvent(`doom_team.child_started`,{"run.id":n.runId,outcome:`started`})}else if(t.kind===`updated`){let{event:n}=t;e.recordEvent(`doom_team.delegation_updated`,{"run.id":n.runId,"team.tool_count":n.toolCount??0,"team.duration_ms":n.durationMs??0,"team.token_count":n.tokens??0,outcome:n.status??`updated`})}else if(t.kind===`finished`){let{event:n}=t;e.recordEvent(`doom_team.delegation_finished`,{"run.id":n.runId,"team.tool_count":n.toolCount??0,"team.duration_ms":n.durationMs??0,outcome:n.status})}else e.recordEvent(`doom_team.delegation_cancelled`,{outcome:`cancelled`})}function C(C,w){let T,fe=e=>(T??=(0,se.createDoomTelemetry)({serviceName:`doom-team`,packageName:`@agimon-ai/doompi-team`,cwd:e.cwd,env:process.env,enableLogs:!0,enableTraces:!0}),T),pe=(e,t)=>{T?.recordEvent(e,t)};C.effect(()=>async()=>{await T?.shutdown(),T=void 0},`@agimon-ai/doompi-team/telemetry`);let E=ae.createTeamExtensionRuntime(pe),{subagentTool:me,teamChannel:D,pollScheduler:O,asyncJobTracker:k,subagentWaiter:he,asyncSubagentSpawner:ge,discovery:A,skills:j,spawnPlanner:M,completionNotifier:N,resultWatcher:P,staleRunReconciler:F,management:I,capabilityPolicies:L,mcpToolResolver:_e}=E,R=!0,z=0,B,V,H,U,W,G;C.inject([_.DOOM_CORDIS_SESSION_SERVICE],e=>{let t={cordis:e,service:e.get(_.DOOM_CORDIS_SESSION_SERVICE)};G=t,e.inject([y.DOOM_MCP_TOOL_RESOLVER_SERVICE],e=>_e.bind((0,y.requireDoomMcpToolResolver)(e))),e.inject([v.DOOM_CONTEXT_CONTRIBUTIONS_SERVICE],e=>{let t=(0,v.requireDoomContextContributions)(e).register({source:S,id:`runtime`,label:`Team`,order:200,snapshot:()=>p.formatTeamContextSnapshot(p.readActiveTeamSnapshot())});return()=>t.dispose()}),e.effect(()=>()=>{G===t&&(G=void 0)},`${S}/cordis-session`)});let ve=e=>{let t=G,n=e.sessionManager.getSessionId();return(t?.service.context.sessionManager===e.sessionManager&&t.service.sessionId===n?(0,oe.readDoomReadinessCoordinator)(t.cordis):void 0)||(U??=(0,oe.createDoomReadinessCoordinator)({notify:e=>{let t=le(e);W?.hasUI?W.ui.notify(t,`warning`):process.emitWarning(t)}}),U)},K=async(e,t)=>{t?.throwIfAborted();let n=V;if(!n)throw Error(`Doom Team session initialization has not started.`);if(H!==e.sessionManager)throw Error(`Doom Team readiness belongs to a stale Pi session.`);let r=await n;if(t?.throwIfAborted(),await r.wait(t?{signal:t}:void 0),!R||n!==V||H!==e.sessionManager)throw Error(`Doom Team readiness belongs to a stale extension generation.`)},q=new Proxy(w,{get(e,t){return t===`registerTool`?t=>{e.registerTool({...t,execute:async(e,n,r,i,a)=>(await K(a,r),t.execute(e,n,r,i,a))})}:t===`registerCommand`?(t,n)=>{e.registerCommand(t,{...n,handler:async(e,t)=>(await K(t),n.handler(e,t))})}:t===`registerShortcut`?(t,n)=>{e.registerShortcut(t,{...n,handler:async e=>(await K(e),n.handler(e))})}:ce(e,t)}});me.registerTool(q),C.inject([b.DOOM_UI_HUB_SERVICE],e=>h.registerSubagentLeaderContribution((0,b.requireDoomUiHub)(e)));let J=D.createRuntime(q);C.effect(()=>()=>J.dispose(),`@agimon-ai/doompi-team/channel`),D.registerClient(q),N.attachHost(w),C.effect(()=>()=>N.dispose(),`@agimon-ai/doompi-team/completions`),O.start(),C.effect(()=>()=>O.stop(),`@agimon-ai/doompi-team/polling`),k.start(),C.effect(()=>()=>k.stop(),`@agimon-ai/doompi-team/jobs`);let Y,X,Z,Q=u.createDelegationBridge({planner:M,management:I,waiter:he,scheduler:O,tracker:k,loadConfig:()=>l.loadConfig().config}),ye=d.createFablePlanBridge({spawner:ge,waiter:he,management:I,policies:L,report:(e,t)=>{T?.recordEvent(e,t)}});C.effect(()=>async()=>{await Y?.dispose(),Y=void 0},`@agimon-ai/doompi-team/collaboration`),C.effect(()=>()=>{P.stop(),Z=void 0},`@agimon-ai/doompi-team/result-watcher`);let be=O.register({id:`stale-run-reconciler`,intervalMs:2e3,run:async()=>{let e=!1,t=!1;for(let n of X?.list()??[]){if(n.status&&s.TERMINAL_ASYNC_JOB_STATES.has(n.status))continue;t=!0;let{reconcile:r,sweep:i}=F.reconcileAndSweepAsync?await F.reconcileAndSweepAsync(n.runId):F.reconcileAndSweep(n.runId);r.repaired&&(X?.track(n.runId),e=!0),i.recovered.length>0&&(e=!0)}return e||t}});C.effect(()=>be,`@agimon-ai/doompi-team/stale-runs`),w.on(`before_agent_start`,e=>{if(R&&f.shouldInjectOrchestratorPrompt(l.loadConfig().config))return{systemPrompt:f.appendOrchestratorPrompt(e.systemPrompt)}});let $={baseCwd:void 0},xe=(r,i)=>{if((0,g.resolveRootSessionId)(i)===i)try{n.writeSessionCatalogSnapshot(i,{cwd:r,agents:t.presentCatalog(A.discover(r,`both`).agents),models:e.resolveActiveTeamModelSpecs()??[]})}catch{}};w.on(`before_agent_start`,(e,t)=>{R&&xe(t.cwd,t.sessionManager.getSessionId())});let Se=ue(A,j,M,k,O,I);c.registerSlashCommands(q,$,Se),h.registerAgentListCommand(q,{discovery:A,skills:j,policies:L,launchAgent:(e,t)=>c.startSingleAgentRun(q,e,$,Se,{agent:t.agent,task:t.task,fork:t.context===`fork`})}),h.registerFleetCommand(q,{scheduler:O,tracker:k,management:I}),C.inject([b.DOOM_UI_HUB_SERVICE],e=>h.registerAgentStatus(w,(0,b.requireDoomUiHub)(e),{scheduler:O,tracker:k})),m.registerCompletionRenderer(w),re.registerSlashRunRenderer(w);let Ce=async()=>{let e=[],t=Y;Y=void 0;try{await t?.dispose()}catch(t){e.push(t)}for(let t of[()=>L.clear(),()=>Q.abandonAll(),()=>ye.abandonAll(),()=>J.dispose()])try{t()}catch(t){e.push(t)}if(X=void 0,e.length!==0)return e.length===1&&e[0]instanceof Error?e[0]:AggregateError(e,`Team session cleanup failed.`)};w.on(`session_start`,(e,t)=>{if(!R)return;let n=++z,s=V;B?.abort(Error(`Doom Team session initialization was superseded.`));let c=new AbortController;B=c,H=t.sessionManager,W=t;let l=fe(t);l.recordEvent(`doom_team.session_started`,{"team.root_session":(0,g.resolveRootSessionId)(t.sessionManager.getSessionId())===t.sessionManager.getSessionId()});let u=t.sessionManager.getSessionId(),d=r.createSessionScope((0,g.resolveRootSessionId)(u));r.setCurrentSessionScope(d),$.baseCwd=t.cwd,xe(t.cwd,u),Z!==void 0&&Z!==d.scopeKey&&(P.stop(),Z=void 0);let f=Ce(),p=ve(t),m=()=>R&&n===z&&H===t.sessionManager&&!c.signal.aborted;V=(async()=>{if(s&&await Promise.allSettled([s.then(e=>e.wait())]),!m())throw Error(`Doom Team session initialization was superseded.`);return p.start(S,`${u}:${n}`,async e=>{e.throwIfAborted();let n=await f;if(n)throw n;if(!m()||(await o.writeScopeOwnerAsync(d),e.throwIfAborted(),!m()))return{value:void 0};let r=await ne.openScopeAsync(d,{readStatusAsync:async e=>I.statusAsync?(await I.statusAsync(e)).status:I.status(e).status});if(e.throwIfAborted(),!m())return{value:void 0};if(r.suspended.length>0&&t.hasUI){let n=await te.formatSuspendedRunsAsync(r.suspended);if(e.throwIfAborted(),!m())return{value:void 0};t.ui.notify(n,`info`)}l.recordEvent(`doom_team.runs_restored`,{"team.suspended_count":r.suspended.length,"team.pruned_count":r.pruned.length,"team.reaped_count":r.reaped,outcome:`reported`}),X=k.forSession(u),Z!==d.scopeKey&&(Z=d.scopeKey,P.start(async e=>{if(!X?.get(e.runId))return!1;let t=await N.deliver(e);return t&&k.acknowledgeHandoff(u,e.runId),t}));let s=a.normalizeParentModel(t.model),c=G,p=(c?.service.context.sessionManager===t.sessionManager?c.cordis:C).plugin(ie.teamCollaborationPlugin,{session:{sessionId:u,cwd:t.cwd,availableModels:i.authenticatedModelInfos(t.modelRegistry),...s?{parentModel:s}:{},captureForkSource:()=>ee.captureSessionForkSource(t.sessionManager,`tool`)},directRunTracker:k,delegation:Q,fablePlan:ye,policies:L,observeDelegation:e=>de(l,e)});return Y=p,await p.await(),m()?(J.bindMainSession(u),{value:void 0}):(await p.dispose(),Y===p&&(Y=void 0),{value:void 0})})})(),Promise.allSettled([V.then(e=>e.wait())])}),C.effect(()=>async()=>{R=!1,z+=1;let e=V;V=void 0,H=void 0,B?.abort(Error(`Doom Team runtime was disposed.`)),B=void 0;let t=U;U=void 0,t?await t.dispose():e&&await Promise.allSettled([e.then(e=>e.wait())]),W=void 0},`@agimon-ai/doompi-team/session-fence`);let we,Te=async e=>{R=!1,z+=1;let t=V;V=void 0,H=void 0,B?.abort(Error(`Doom Team session ended.`)),B=void 0;let n=U;U=void 0,await Promise.allSettled([...t?[t.then(e=>e.wait())]:[],...n?[n.dispose()]:[]]);let i=r.tryCurrentSessionScope(),a=i?ne.suspendScopeRuns({scope:i,reason:e.reason??x,readStatus:e=>I.status(e).status}):Promise.resolve(void 0),o;try{o=await a,await T?.recordEvent(`doom_team.session_finished`,{reason:e.reason??x,"team.suspended_count":o?.suspended.length??0,"team.unstoppable_count":o?.unstoppable.length??0,outcome:o?.unstoppable.length?`degraded`:`suspended`})}catch(t){await T?.recordError(`doom_team.session_shutdown_failed`,t,{reason:e.reason??x})}finally{await T?.shutdown(),T=void 0}};return w.on(`session_shutdown`,e=>(we??=Te(e),we)),E}exports.installTeamRuntime=C;
2
2
  //# sourceMappingURL=extension.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"extension.cjs","names":["loadConfig","createDoomTelemetry","createTeamExtensionRuntime","DOOM_CORDIS_SESSION_SERVICE","DOOM_MCP_TOOL_RESOLVER_SERVICE","requireDoomMcpToolResolver","DOOM_CONTEXT_CONTRIBUTIONS_SERVICE","requireDoomContextContributions","formatTeamContextSnapshot","readActiveTeamSnapshot","readDoomReadinessCoordinator","createDoomReadinessCoordinator","DOOM_UI_HUB_SERVICE","registerSubagentLeaderContribution","requireDoomUiHub","createDelegationBridge","createFablePlanBridge","TERMINAL_ASYNC_JOB_STATES","shouldInjectOrchestratorPrompt","appendOrchestratorPrompt","resolveRootSessionId","presentCatalog","resolveActiveTeamModelSpecs","startSingleAgentRun","registerAgentStatus","createSessionScope","writeScopeOwnerAsync","openScopeAsync","formatSuspendedRunsAsync","jobs","normalizeParentModel","teamCollaborationPlugin","authenticatedModelInfos","captureSessionForkSource","tryCurrentSessionScope","suspendScopeRuns"],"sources":["../../../../src/adapters/pi/extension.ts"],"sourcesContent":["/**\n * Install the Team feature into one package-local Cordis root.\n *\n * The standard Pi factory owns that root and disposes it when Pi emits\n * `session_shutdown`. Each factory invocation therefore creates fresh session\n * state; no process-global container or replacement-root handshake participates\n * in reload. Long-lived services are registered as Cordis effects, and stale\n * asynchronous session-start continuations are fenced by a generation token.\n */\n\nimport { resolveRootSessionId } from '@agimon-ai/doompi-extension-contracts/child-process';\nimport {\n DOOM_CONTEXT_CONTRIBUTIONS_SERVICE,\n requireDoomContextContributions,\n} from '@agimon-ai/doompi-extension-contracts/context-contributions';\nimport {\n DOOM_CORDIS_SESSION_SERVICE,\n type DoomCordisSessionService,\n} from '@agimon-ai/doompi-extension-contracts/cordis-host';\nimport {\n DOOM_MCP_TOOL_RESOLVER_SERVICE,\n requireDoomMcpToolResolver,\n} from '@agimon-ai/doompi-extension-contracts/mcp-tool-resolver';\nimport {\n createDoomReadinessCoordinator,\n type DoomReadinessCoordinator,\n type DoomReadinessHandle,\n type DoomReadinessNotification,\n readDoomReadinessCoordinator,\n} from '@agimon-ai/doompi-extension-contracts/readiness';\nimport { DOOM_UI_HUB_SERVICE, requireDoomUiHub } from '@agimon-ai/doompi-extension-contracts/ui-hub';\nimport { createDoomTelemetry, type DoomTelemetry } from '@agimon-ai/doompi-telemetry';\nimport type { Context, Fiber } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport {\n registerSlashCommands,\n startSingleAgentRun,\n type SlashCommandDeps,\n type SlashCommandState,\n} from './commands/slash/slashCommands';\nimport { loadConfig } from './extensions/config';\nimport { createDelegationBridge } from './extensions/delegationBridge';\nimport { createFablePlanBridge } from './extensions/fablePlanBridge';\nimport type { ManagementActionsContract } from './extensions/managementActions';\nimport { appendOrchestratorPrompt, shouldInjectOrchestratorPrompt } from './extensions/orchestratorPrompt';\nimport { captureSessionForkSource, type SpawnPlannerContract } from './extensions/spawnPlan';\nimport type { SkillDiscoveryContract } from '../agents/skills';\nimport type { AgentDiscoveryContract } from '../agents/types';\nimport { formatTeamContextSnapshot, readActiveTeamSnapshot } from '../api/teamSnapshot';\nimport {\n type AsyncJobTrackerContract,\n type TrackedAsyncJobsContract,\n TERMINAL_ASYNC_JOB_STATES,\n} from '../asyncJobTracker';\nimport { openScopeAsync, suspendScopeRuns } from '../runs/registry/sessionLifecycle';\nimport { formatSuspendedRunsAsync } from '../suspendedRuns';\nimport { normalizeParentModel } from '../runs/shared/modelFallback';\nimport { authenticatedModelInfos } from '../../services/models/modelResolution';\nimport { createSessionScope, setCurrentSessionScope, tryCurrentSessionScope } from '../filesystem/paths';\nimport type { PollSchedulerContract } from '../pollScheduler';\nimport { writeScopeOwnerAsync } from '../scopeOwner';\nimport { resolveActiveTeamModelSpecs } from '../agents/discovery';\nimport { writeSessionCatalogSnapshot } from '../sessionCatalogSnapshot';\nimport { presentCatalog } from '../../services/webSubagentCatalog';\nimport { registerCompletionRenderer } from './tui/completionNotice';\nimport { registerSlashRunRenderer } from './tui/slashRunNotice';\nimport {\n registerAgentListCommand,\n registerAgentStatus,\n registerFleetCommand,\n registerSubagentLeaderContribution,\n} from './tui/register';\nimport { teamCollaborationPlugin, type TeamDelegationObservation } from './collaboration';\nimport { createTeamExtensionRuntime, type TeamExtensionRuntime } from './teamRuntime';\n\n/** See the subscriber's own comment for why crash detection does not need the 250ms floor. */\nconst STALE_RUN_RECONCILE_INTERVAL_MS = 2_000;\nconst SESSION_SHUTDOWN_REASON_FALLBACK = 'unknown';\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-team';\n\ntype RegisteredTool = Parameters<ExtensionAPI['registerTool']>[0];\ntype CommandOptions = Parameters<ExtensionAPI['registerCommand']>[1];\ntype ShortcutOptions = Parameters<ExtensionAPI['registerShortcut']>[1];\n\nfunction boundPiValue(target: ExtensionAPI, property: PropertyKey): unknown {\n const value = Reflect.get(target, property, target);\n return typeof value === 'function' ? value.bind(target) : value;\n}\n\nfunction readinessNotificationMessage(notification: DoomReadinessNotification): string {\n const diagnostics = notification.diagnostics.join('; ');\n const detail = (notification.error?.message ?? diagnostics) || 'Initialization did not complete.';\n return `${notification.packageId} initialization ${notification.state}: ${detail}`;\n}\n\nfunction buildSlashCommandDeps(\n discovery: AgentDiscoveryContract,\n skills: SkillDiscoveryContract,\n planner: SpawnPlannerContract,\n tracker: AsyncJobTrackerContract,\n scheduler: PollSchedulerContract,\n management: ManagementActionsContract,\n): SlashCommandDeps {\n return {\n spawnPlanner: planner,\n tracker,\n scheduler,\n discovery,\n skills,\n management,\n loadConfig: () => loadConfig().config,\n };\n}\n\nfunction recordDelegationObservation(telemetry: DoomTelemetry, observation: TeamDelegationObservation): void {\n if (observation.kind === 'requested') {\n const { event } = observation;\n void telemetry.recordEvent('doom_team.delegation_requested', {\n 'agent.name': event.agent,\n 'task.id': event.taskId,\n mode: event.runMode ?? 'foreground',\n });\n } else if (observation.kind === 'started') {\n const { event } = observation;\n void telemetry.recordEvent('doom_team.child_started', { 'run.id': event.runId, outcome: 'started' });\n } else if (observation.kind === 'updated') {\n const { event } = observation;\n void telemetry.recordEvent('doom_team.delegation_updated', {\n 'run.id': event.runId,\n 'team.tool_count': event.toolCount ?? 0,\n 'team.duration_ms': event.durationMs ?? 0,\n 'team.token_count': event.tokens ?? 0,\n outcome: event.status ?? 'updated',\n });\n } else if (observation.kind === 'finished') {\n const { event } = observation;\n void telemetry.recordEvent('doom_team.delegation_finished', {\n 'run.id': event.runId,\n 'team.tool_count': event.toolCount ?? 0,\n 'team.duration_ms': event.durationMs ?? 0,\n outcome: event.status,\n });\n } else {\n void telemetry.recordEvent('doom_team.delegation_cancelled', { outcome: 'cancelled' });\n }\n}\n\n/**\n * The extension factory pi's loader calls, exported as the module default\n * (see the override this file carries in `vibe-lint.config.yaml`). This is an\n * ESM `.ts` module, so it CANNOT use the `export =` form that\n * `subagentPromptRuntimeEntry.cts` is required to use - that file is `.cts`\n * and is resolved by raw path, this one is resolved as a package subpath and\n * matches the `export default` convention every sibling extension in this repo\n * already uses (`doom-task`, `doom-file-edit`, `doom-pi-ui`).\n */\nexport function installTeamRuntime(cordis: Context, pi: ExtensionAPI): TeamExtensionRuntime {\n let telemetry: DoomTelemetry | undefined;\n const getTelemetry = (ctx: ExtensionContext): DoomTelemetry => {\n telemetry ??= createDoomTelemetry({\n serviceName: 'doom-team',\n packageName: '@agimon-ai/doompi-team',\n cwd: ctx.cwd,\n env: process.env,\n enableLogs: true,\n enableTraces: true,\n });\n return telemetry;\n };\n const reportConcurrencyEvent = (event: string, attributes: Record<string, unknown>): void => {\n void telemetry?.recordEvent(event, attributes);\n };\n cordis.effect(\n () => async () => {\n await telemetry?.shutdown();\n telemetry = undefined;\n },\n '@agimon-ai/doompi-team/telemetry',\n );\n const runtime = createTeamExtensionRuntime(reportConcurrencyEvent);\n const {\n subagentTool,\n teamChannel,\n pollScheduler,\n asyncJobTracker,\n subagentWaiter,\n asyncSubagentSpawner,\n discovery,\n skills,\n spawnPlanner,\n completionNotifier,\n resultWatcher,\n staleRunReconciler,\n management,\n capabilityPolicies,\n mcpToolResolver,\n } = runtime;\n\n let active = true;\n let sessionGeneration = 0;\n let readinessAbort: AbortController | undefined;\n let readinessHandle: Promise<DoomReadinessHandle<void>> | undefined;\n let readinessSessionManager: object | undefined;\n let standaloneReadiness: DoomReadinessCoordinator | undefined;\n let readinessNotificationContext: ExtensionContext | undefined;\n let activeCordisSession:\n | {\n readonly cordis: Context;\n readonly service: DoomCordisSessionService;\n }\n | undefined;\n cordis.inject([DOOM_CORDIS_SESSION_SERVICE], (sessionContext) => {\n const service = sessionContext.get(DOOM_CORDIS_SESSION_SERVICE) as DoomCordisSessionService;\n const binding = { cordis: sessionContext, service };\n activeCordisSession = binding;\n sessionContext.inject([DOOM_MCP_TOOL_RESOLVER_SERVICE], (resolverContext) =>\n mcpToolResolver.bind(requireDoomMcpToolResolver(resolverContext)),\n );\n sessionContext.inject([DOOM_CONTEXT_CONTRIBUTIONS_SERVICE], (contributionContext) => {\n const registration = requireDoomContextContributions(contributionContext).register({\n source: PACKAGE_SOURCE,\n id: 'runtime',\n label: 'Team',\n order: 200,\n snapshot: () => formatTeamContextSnapshot(readActiveTeamSnapshot()),\n });\n return () => registration.dispose();\n });\n sessionContext.effect(\n () => () => {\n if (activeCordisSession === binding) activeCordisSession = undefined;\n },\n `${PACKAGE_SOURCE}/cordis-session`,\n );\n });\n const coordinatorFor = (ctx: ExtensionContext): DoomReadinessCoordinator => {\n const cordisSession = activeCordisSession;\n const sessionId = ctx.sessionManager.getSessionId();\n const activeSessionMatches =\n cordisSession?.service.context.sessionManager === ctx.sessionManager &&\n cordisSession.service.sessionId === sessionId;\n const shared = activeSessionMatches ? readDoomReadinessCoordinator(cordisSession.cordis) : undefined;\n if (shared) return shared;\n standaloneReadiness ??= createDoomReadinessCoordinator({\n notify: (notification) => {\n const message = readinessNotificationMessage(notification);\n if (readinessNotificationContext?.hasUI) readinessNotificationContext.ui.notify(message, 'warning');\n else process.emitWarning(message);\n },\n });\n return standaloneReadiness;\n };\n const waitForSessionReadiness = async (ctx: ExtensionContext, signal?: AbortSignal): Promise<void> => {\n signal?.throwIfAborted();\n const pending = readinessHandle;\n if (!pending) throw new Error('Doom Team session initialization has not started.');\n if (readinessSessionManager !== ctx.sessionManager) {\n throw new Error('Doom Team readiness belongs to a stale Pi session.');\n }\n const handle = await pending;\n signal?.throwIfAborted();\n await handle.wait(signal ? { signal } : undefined);\n if (!active || pending !== readinessHandle || readinessSessionManager !== ctx.sessionManager) {\n throw new Error('Doom Team readiness belongs to a stale extension generation.');\n }\n };\n const readinessPi = new Proxy(pi, {\n get(target, property) {\n if (property === 'registerTool') {\n return (tool: RegisteredTool): void => {\n target.registerTool({\n ...tool,\n execute: async (toolCallId, params, signal, onUpdate, ctx) => {\n await waitForSessionReadiness(ctx, signal);\n return tool.execute(toolCallId, params, signal, onUpdate, ctx);\n },\n });\n };\n }\n if (property === 'registerCommand') {\n return (name: string, options: CommandOptions): void => {\n target.registerCommand(name, {\n ...options,\n handler: async (args, ctx) => {\n await waitForSessionReadiness(ctx);\n return options.handler(args, ctx);\n },\n });\n };\n }\n if (property === 'registerShortcut') {\n return (shortcut: Parameters<ExtensionAPI['registerShortcut']>[0], options: ShortcutOptions): void => {\n target.registerShortcut(shortcut, {\n ...options,\n handler: async (ctx) => {\n await waitForSessionReadiness(ctx);\n return options.handler(ctx);\n },\n });\n };\n }\n return boundPiValue(target, property);\n },\n });\n\n subagentTool.registerTool(readinessPi);\n\n cordis.inject([DOOM_UI_HUB_SERVICE], (uiContext) => registerSubagentLeaderContribution(requireDoomUiHub(uiContext)));\n\n const teamRuntime = teamChannel.createRuntime(readinessPi);\n cordis.effect(() => () => teamRuntime.dispose(), '@agimon-ai/doompi-team/channel');\n teamChannel.registerClient(readinessPi);\n\n // Attach before `ResultWatcher.start()`, which `session_start` drives.\n completionNotifier.attachHost(pi);\n cordis.effect(() => () => completionNotifier.dispose(), '@agimon-ai/doompi-team/completions');\n\n pollScheduler.start();\n cordis.effect(() => () => pollScheduler.stop(), '@agimon-ai/doompi-team/polling');\n\n asyncJobTracker.start();\n cordis.effect(() => () => asyncJobTracker.stop(), '@agimon-ai/doompi-team/jobs');\n\n let collaborationFiber: Fiber | undefined;\n let currentSessionJobs: TrackedAsyncJobsContract | undefined;\n // The scope `ResultWatcher` is currently watching. See its start site in\n // the `session_start` handler for why the watcher is latched on this\n // rather than started once.\n let watchedScopeKey: string | undefined;\n const delegationBridge = createDelegationBridge({\n planner: spawnPlanner,\n management,\n waiter: subagentWaiter,\n scheduler: pollScheduler,\n tracker: asyncJobTracker,\n loadConfig: () => loadConfig().config,\n });\n const fablePlanBridge = createFablePlanBridge({\n spawner: asyncSubagentSpawner,\n waiter: subagentWaiter,\n management,\n policies: capabilityPolicies,\n report: (event, attributes) => {\n void telemetry?.recordEvent(event, attributes);\n },\n });\n cordis.effect(\n () => async () => {\n await collaborationFiber?.dispose();\n collaborationFiber = undefined;\n },\n '@agimon-ai/doompi-team/collaboration',\n );\n cordis.effect(\n () => () => {\n resultWatcher.stop();\n watchedScopeKey = undefined;\n },\n '@agimon-ai/doompi-team/result-watcher',\n );\n\n const unregisterStaleRunReconciler = pollScheduler.register({\n id: 'stale-run-reconciler',\n // Crash detection, not status freshness - `AsyncJobTracker` owns that and\n // polls on its own 250ms. This subscriber only ever acts on a run whose\n // process is provably dead, so noticing that 2s later is invisible, while\n // running it 4x/second per active run was not: each pass is a status read,\n // a run-id resolve and a pid probe that a healthy child always discards.\n intervalMs: STALE_RUN_RECONCILE_INTERVAL_MS,\n run: async () => {\n let repaired = false;\n let hasActiveRun = false;\n for (const job of currentSessionJobs?.list() ?? []) {\n if (job.status && TERMINAL_ASYNC_JOB_STATES.has(job.status)) continue;\n hasActiveRun = true;\n // One pass, one `inspect()`. Calling `reconcile` and\n // `sweepOrphanedClaims` separately probed the same pid twice for the\n // same answer - see `StaleRunReconcilerContract.reconcileAndSweep`.\n const { reconcile: outcome, sweep } = staleRunReconciler.reconcileAndSweepAsync\n ? await staleRunReconciler.reconcileAndSweepAsync(job.runId)\n : staleRunReconciler.reconcileAndSweep(job.runId);\n if (outcome.repaired) {\n currentSessionJobs?.track(job.runId);\n repaired = true;\n }\n if (sweep.recovered.length > 0) repaired = true;\n }\n // An active runner is useful work for scheduling purposes: keeping\n // the shared scheduler at its floor prevents crash detection from\n // inheriting the idle five-second backoff ceiling.\n return repaired || hasActiveRun;\n },\n });\n cordis.effect(() => unregisterStaleRunReconciler, '@agimon-ai/doompi-team/stale-runs');\n // The orchestration addendum. Registered here rather than inside the\n // `subagent` tool's description because it is behavioural guidance, and it\n // has to land before the model decides whether to reach for the tool at\n // all - see `orchestratorPrompt.ts`. Read config per turn so toggling it\n // does not need a session restart; `loadConfig` is memoized on the file's\n // own mtime, so this is a stat, not a read.\n pi.on('before_agent_start', (event: { systemPrompt?: string }) => {\n if (!active || !shouldInjectOrchestratorPrompt(loadConfig().config)) return undefined;\n return { systemPrompt: appendOrchestratorPrompt(event.systemPrompt) };\n });\n\n const state: SlashCommandState = { baseCwd: undefined };\n\n /**\n * Publish what this session can launch, for the cockpit hub to read.\n *\n * The hub and the session API run in `doompi-server`, which never receives\n * the domain projection's agent directories or the harness state behind the\n * Team model policy, so discovery run there misses every domain-provided\n * agent. This process has both. Republished on each turn so an agent file\n * added mid-session shows up without a restart.\n */\n const publishCatalogSnapshot = (cwd: string, sessionId: string): void => {\n // A spawned child shares its parent's scope directory; only the root\n // session may write the catalog the user is looking at.\n if (resolveRootSessionId(sessionId) !== sessionId) return;\n try {\n writeSessionCatalogSnapshot(sessionId, {\n cwd,\n agents: presentCatalog(discovery.discover(cwd, 'both').agents),\n models: resolveActiveTeamModelSpecs() ?? [],\n });\n } catch {\n // Best effort: the hub falls back to its own discovery, and every launch\n // path reports discovery failures on its own.\n }\n };\n\n pi.on('before_agent_start', (_event: { systemPrompt?: string }, ctx: ExtensionContext) => {\n if (!active) return undefined;\n publishCatalogSnapshot(ctx.cwd, ctx.sessionManager.getSessionId());\n return undefined;\n });\n const slashCommandDeps = buildSlashCommandDeps(\n discovery,\n skills,\n spawnPlanner,\n asyncJobTracker,\n pollScheduler,\n management,\n );\n registerSlashCommands(readinessPi, state, slashCommandDeps);\n registerAgentListCommand(readinessPi, {\n discovery,\n skills,\n policies: capabilityPolicies,\n // The catalog's r/R keys spawn through the same path as `/run`, so a run\n // started from the overlay is tracked and reported like any other.\n launchAgent: (ctx, request) =>\n startSingleAgentRun(readinessPi, ctx, state, slashCommandDeps, {\n agent: request.agent,\n task: request.task,\n fork: request.context === 'fork',\n }),\n });\n registerFleetCommand(readinessPi, {\n scheduler: pollScheduler,\n tracker: asyncJobTracker,\n management,\n });\n cordis.inject([DOOM_UI_HUB_SERVICE], (uiContext) => {\n return registerAgentStatus(pi, requireDoomUiHub(uiContext), {\n scheduler: pollScheduler,\n tracker: asyncJobTracker,\n });\n });\n registerCompletionRenderer(pi);\n registerSlashRunRenderer(pi);\n\n const retireSessionBindings = async (): Promise<Error | undefined> => {\n const errors: unknown[] = [];\n const previousCollaboration = collaborationFiber;\n collaborationFiber = undefined;\n try {\n await previousCollaboration?.dispose();\n } catch (error) {\n errors.push(error);\n }\n for (const cleanup of [\n () => capabilityPolicies.clear(),\n () => delegationBridge.abandonAll(),\n () => fablePlanBridge.abandonAll(),\n () => teamRuntime.dispose(),\n ]) {\n try {\n cleanup();\n } catch (error) {\n errors.push(error);\n }\n }\n currentSessionJobs = undefined;\n if (errors.length === 0) return undefined;\n if (errors.length === 1 && errors[0] instanceof Error) return errors[0];\n return new AggregateError(errors, 'Team session cleanup failed.');\n };\n\n // Bind the root session directly into the one intercom transport. Child\n // processes bind from the team environment written during spawn.\n pi.on('session_start', (_event, ctx: ExtensionContext) => {\n if (!active) return undefined;\n const ownGeneration = ++sessionGeneration;\n const previousReadiness = readinessHandle;\n readinessAbort?.abort(new Error('Doom Team session initialization was superseded.'));\n const ownReadinessAbort = new AbortController();\n readinessAbort = ownReadinessAbort;\n readinessSessionManager = ctx.sessionManager;\n readinessNotificationContext = ctx;\n const activeTelemetry = getTelemetry(ctx);\n void activeTelemetry.recordEvent('doom_team.session_started', {\n 'team.root_session':\n resolveRootSessionId(ctx.sessionManager.getSessionId()) === ctx.sessionManager.getSessionId(),\n });\n // Before anything else: every scoped path helper reads this. A child\n // keeps the root inherited from its spawn environment, while a top-level\n // session falls back to its own Pi session id.\n const sessionId = ctx.sessionManager.getSessionId();\n const scope = createSessionScope(resolveRootSessionId(sessionId));\n setCurrentSessionScope(scope);\n state.baseCwd = ctx.cwd;\n publishCatalogSnapshot(ctx.cwd, sessionId);\n if (watchedScopeKey !== undefined && watchedScopeKey !== scope.scopeKey) {\n resultWatcher.stop();\n watchedScopeKey = undefined;\n }\n const retirement = retireSessionBindings();\n const coordinator = coordinatorFor(ctx);\n const ownsSession = (): boolean =>\n active &&\n ownGeneration === sessionGeneration &&\n readinessSessionManager === ctx.sessionManager &&\n !ownReadinessAbort.signal.aborted;\n\n readinessHandle = (async (): Promise<DoomReadinessHandle<void>> => {\n if (previousReadiness) {\n await Promise.allSettled([previousReadiness.then((handle) => handle.wait())]);\n }\n if (!ownsSession()) throw new Error('Doom Team session initialization was superseded.');\n return coordinator.start(PACKAGE_SOURCE, `${sessionId}:${ownGeneration}`, async (signal) => {\n signal.throwIfAborted();\n const retirementError = await retirement;\n if (retirementError) throw retirementError;\n if (!ownsSession()) return { value: undefined };\n // Claim the scope for this process, so a later sweep can tell an\n // abandoned tree from a live one. Rewritten on every session_start\n // because /resume legitimately re-adopts a scope under a new process.\n await writeScopeOwnerAsync(scope);\n signal.throwIfAborted();\n if (!ownsSession()) return { value: undefined };\n // Prune records whose process is gone, reap sibling scopes holding\n // nothing alive, and REPORT what is suspended. Nothing is restarted:\n // reopening a session must not silently spend tokens on stale work.\n const opened = await openScopeAsync(scope, {\n readStatusAsync: async (runId) =>\n management.statusAsync ? (await management.statusAsync(runId)).status : management.status(runId).status,\n });\n signal.throwIfAborted();\n if (!ownsSession()) return { value: undefined };\n if (opened.suspended.length > 0 && ctx.hasUI) {\n const message = await formatSuspendedRunsAsync(opened.suspended);\n signal.throwIfAborted();\n if (!ownsSession()) return { value: undefined };\n ctx.ui.notify(message, 'info');\n }\n void activeTelemetry.recordEvent('doom_team.runs_restored', {\n 'team.suspended_count': opened.suspended.length,\n 'team.pruned_count': opened.pruned.length,\n 'team.reaped_count': opened.reaped,\n outcome: 'reported',\n });\n currentSessionJobs = asyncJobTracker.forSession(sessionId);\n // ResultWatcher needs the session scope, but a repeated start for the\n // same scope must not reset its in-flight claims.\n if (watchedScopeKey !== scope.scopeKey) {\n watchedScopeKey = scope.scopeKey;\n resultWatcher.start(async (result) => {\n const jobs = currentSessionJobs;\n if (!jobs?.get(result.runId)) return false;\n const accepted = await completionNotifier.deliver(result);\n if (accepted) asyncJobTracker.acknowledgeHandoff(sessionId, result.runId);\n return accepted;\n });\n }\n const parentModel = normalizeParentModel(ctx.model);\n const activeSession = activeCordisSession;\n const collaborationParent =\n activeSession?.service.context.sessionManager === ctx.sessionManager ? activeSession.cordis : cordis;\n const nextCollaboration = collaborationParent.plugin(teamCollaborationPlugin, {\n session: {\n sessionId,\n cwd: ctx.cwd,\n availableModels: authenticatedModelInfos(ctx.modelRegistry),\n ...(parentModel ? { parentModel } : {}),\n captureForkSource: () => captureSessionForkSource(ctx.sessionManager, 'tool'),\n },\n directRunTracker: asyncJobTracker,\n delegation: delegationBridge,\n fablePlan: fablePlanBridge,\n policies: capabilityPolicies,\n observeDelegation: (observation) => recordDelegationObservation(activeTelemetry, observation),\n });\n collaborationFiber = nextCollaboration;\n await nextCollaboration.await();\n if (!ownsSession()) {\n await nextCollaboration.dispose();\n if (collaborationFiber === nextCollaboration) collaborationFiber = undefined;\n return { value: undefined };\n }\n teamRuntime.bindMainSession(sessionId);\n return { value: undefined };\n });\n })();\n // Config's coordinator owns the single user-facing failure notification.\n void Promise.allSettled([readinessHandle.then((handle) => handle.wait())]);\n return undefined;\n });\n\n cordis.effect(\n () => async () => {\n active = false;\n sessionGeneration += 1;\n const pendingReadiness = readinessHandle;\n readinessHandle = undefined;\n readinessSessionManager = undefined;\n readinessAbort?.abort(new Error('Doom Team runtime was disposed.'));\n readinessAbort = undefined;\n const ownedReadiness = standaloneReadiness;\n standaloneReadiness = undefined;\n if (ownedReadiness) await ownedReadiness.dispose();\n else if (pendingReadiness) await Promise.allSettled([pendingReadiness.then((handle) => handle.wait())]);\n readinessNotificationContext = undefined;\n },\n '@agimon-ai/doompi-team/session-fence',\n );\n\n /**\n * Every reason suspends, with no exception for `reload`.\n *\n * Pi emits this for `quit`, `reload`, `new`, `resume` and `fork`. Treating\n * `reload` differently - keeping children alive because `/domains`, `/major-mode`\n * and `/profile` only reload the extension - would be the one case someone\n * has to remember, and the one that silently misbehaves if Pi adds a sixth\n * reason. Suspending uniformly costs a respawn on reload; restore continues\n * the child's own transcript rather than restarting its task.\n */\n let shutdownPromise: Promise<void> | undefined;\n const shutdownSession = async (event: { reason?: string }): Promise<void> => {\n active = false;\n sessionGeneration += 1;\n const pendingReadiness = readinessHandle;\n readinessHandle = undefined;\n readinessSessionManager = undefined;\n readinessAbort?.abort(new Error('Doom Team session ended.'));\n readinessAbort = undefined;\n const ownedReadiness = standaloneReadiness;\n standaloneReadiness = undefined;\n await Promise.allSettled([\n ...(pendingReadiness ? [pendingReadiness.then((handle) => handle.wait())] : []),\n ...(ownedReadiness ? [ownedReadiness.dispose()] : []),\n ]);\n const scope = tryCurrentSessionScope();\n const suspensionPromise = scope\n ? suspendScopeRuns({\n scope,\n reason: event.reason ?? SESSION_SHUTDOWN_REASON_FALLBACK,\n readStatus: (runId) => management.status(runId).status,\n })\n : Promise.resolve(undefined);\n let suspension: Awaited<ReturnType<typeof suspendScopeRuns>> | undefined;\n try {\n suspension = await suspensionPromise;\n await telemetry?.recordEvent('doom_team.session_finished', {\n reason: event.reason ?? SESSION_SHUTDOWN_REASON_FALLBACK,\n 'team.suspended_count': suspension?.suspended.length ?? 0,\n 'team.unstoppable_count': suspension?.unstoppable.length ?? 0,\n outcome: suspension?.unstoppable.length ? 'degraded' : 'suspended',\n });\n } catch (error) {\n await telemetry?.recordError('doom_team.session_shutdown_failed', error, {\n reason: event.reason ?? SESSION_SHUTDOWN_REASON_FALLBACK,\n });\n } finally {\n await telemetry?.shutdown();\n telemetry = undefined;\n }\n };\n pi.on('session_shutdown', (event: { reason?: string }) => {\n shutdownPromise ??= shutdownSession(event);\n return shutdownPromise;\n });\n\n return runtime;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"extension.cjs","names":["loadConfig","createDoomTelemetry","createTeamExtensionRuntime","DOOM_CORDIS_SESSION_SERVICE","DOOM_MCP_TOOL_RESOLVER_SERVICE","requireDoomMcpToolResolver","DOOM_CONTEXT_CONTRIBUTIONS_SERVICE","requireDoomContextContributions","formatTeamContextSnapshot","readActiveTeamSnapshot","readDoomReadinessCoordinator","createDoomReadinessCoordinator","DOOM_UI_HUB_SERVICE","registerSubagentLeaderContribution","requireDoomUiHub","createDelegationBridge","createFablePlanBridge","TERMINAL_ASYNC_JOB_STATES","shouldInjectOrchestratorPrompt","appendOrchestratorPrompt","resolveRootSessionId","presentCatalog","resolveActiveTeamModelSpecs","startSingleAgentRun","registerAgentStatus","createSessionScope","writeScopeOwnerAsync","openScopeAsync","formatSuspendedRunsAsync","jobs","normalizeParentModel","teamCollaborationPlugin","authenticatedModelInfos","captureSessionForkSource","tryCurrentSessionScope","suspendScopeRuns"],"sources":["../../../../src/adapters/pi/extension.ts"],"sourcesContent":["/**\n * Install the Team feature into one package-local Cordis root.\n *\n * The standard Pi factory owns that root and disposes it when Pi emits\n * `session_shutdown`. Each factory invocation therefore creates fresh session\n * state; no process-global container or replacement-root handshake participates\n * in reload. Long-lived services are registered as Cordis effects, and stale\n * asynchronous session-start continuations are fenced by a generation token.\n */\n\nimport { resolveRootSessionId } from '@agimon-ai/doompi-extension-contracts/child-process';\nimport {\n DOOM_CONTEXT_CONTRIBUTIONS_SERVICE,\n requireDoomContextContributions,\n} from '@agimon-ai/doompi-extension-contracts/context-contributions';\nimport {\n DOOM_CORDIS_SESSION_SERVICE,\n type DoomCordisSessionService,\n} from '@agimon-ai/doompi-extension-contracts/cordis-host';\nimport {\n DOOM_MCP_TOOL_RESOLVER_SERVICE,\n requireDoomMcpToolResolver,\n} from '@agimon-ai/doompi-extension-contracts/mcp-tool-resolver';\nimport {\n createDoomReadinessCoordinator,\n type DoomReadinessCoordinator,\n type DoomReadinessHandle,\n type DoomReadinessNotification,\n readDoomReadinessCoordinator,\n} from '@agimon-ai/doompi-extension-contracts/readiness';\nimport { DOOM_UI_HUB_SERVICE, requireDoomUiHub } from '@agimon-ai/doompi-extension-contracts/ui-hub';\nimport { createDoomTelemetry, type DoomTelemetry } from '@agimon-ai/doompi-telemetry';\nimport type { Context, Fiber } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport {\n registerSlashCommands,\n startSingleAgentRun,\n type SlashCommandDeps,\n type SlashCommandState,\n} from './commands/slash/slashCommands';\nimport { loadConfig } from './extensions/config';\nimport { createDelegationBridge } from './extensions/delegationBridge';\nimport { createFablePlanBridge } from './extensions/fablePlanBridge';\nimport type { ManagementActionsContract } from './extensions/managementActions';\nimport { appendOrchestratorPrompt, shouldInjectOrchestratorPrompt } from './extensions/orchestratorPrompt';\nimport { captureSessionForkSource, type SpawnPlannerContract } from './extensions/spawnPlan';\nimport type { SkillDiscoveryContract } from '../agents/skills';\nimport type { AgentDiscoveryContract } from '../agents/types';\nimport { formatTeamContextSnapshot, readActiveTeamSnapshot } from '../api/teamSnapshot';\nimport {\n type AsyncJobTrackerContract,\n type TrackedAsyncJobsContract,\n TERMINAL_ASYNC_JOB_STATES,\n} from '../asyncJobTracker';\nimport { openScopeAsync, suspendScopeRuns } from '../runs/registry/sessionLifecycle';\nimport { formatSuspendedRunsAsync } from '../suspendedRuns';\nimport { normalizeParentModel } from '../runs/shared/modelFallback';\nimport { authenticatedModelInfos } from '../../services/models/modelResolution';\nimport { createSessionScope, setCurrentSessionScope, tryCurrentSessionScope } from '../filesystem/paths';\nimport type { PollSchedulerContract } from '../pollScheduler';\nimport { writeScopeOwnerAsync } from '../scopeOwner';\nimport { resolveActiveTeamModelSpecs } from '../agents/discovery';\nimport { writeSessionCatalogSnapshot } from '../sessionCatalogSnapshot';\nimport { presentCatalog } from '../../services/webSubagentCatalog';\nimport { registerCompletionRenderer } from './tui/completionNotice';\nimport { registerSlashRunRenderer } from './tui/slashRunNotice';\nimport {\n registerAgentListCommand,\n registerAgentStatus,\n registerFleetCommand,\n registerSubagentLeaderContribution,\n} from './tui/register';\nimport { teamCollaborationPlugin, type TeamDelegationObservation } from './collaboration';\nimport { createTeamExtensionRuntime, type TeamExtensionRuntime } from './teamRuntime';\n\n/** See the subscriber's own comment for why crash detection does not need the 250ms floor. */\nconst STALE_RUN_RECONCILE_INTERVAL_MS = 2_000;\nconst SESSION_SHUTDOWN_REASON_FALLBACK = 'unknown';\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-team';\n\ntype RegisteredTool = Parameters<ExtensionAPI['registerTool']>[0];\ntype CommandOptions = Parameters<ExtensionAPI['registerCommand']>[1];\ntype ShortcutOptions = Parameters<ExtensionAPI['registerShortcut']>[1];\n\nfunction boundPiValue(target: ExtensionAPI, property: PropertyKey): unknown {\n const value = Reflect.get(target, property, target);\n return typeof value === 'function' ? value.bind(target) : value;\n}\n\nfunction readinessNotificationMessage(notification: DoomReadinessNotification): string {\n const diagnostics = notification.diagnostics.join('; ');\n const detail = (notification.error?.message ?? diagnostics) || 'Initialization did not complete.';\n return `${notification.packageId} initialization ${notification.state}: ${detail}`;\n}\n\nfunction buildSlashCommandDeps(\n discovery: AgentDiscoveryContract,\n skills: SkillDiscoveryContract,\n planner: SpawnPlannerContract,\n tracker: AsyncJobTrackerContract,\n scheduler: PollSchedulerContract,\n management: ManagementActionsContract,\n): SlashCommandDeps {\n return {\n spawnPlanner: planner,\n tracker,\n scheduler,\n discovery,\n skills,\n management,\n loadConfig: () => loadConfig().config,\n };\n}\n\nfunction recordDelegationObservation(telemetry: DoomTelemetry, observation: TeamDelegationObservation): void {\n if (observation.kind === 'requested') {\n const { event } = observation;\n void telemetry.recordEvent('doom_team.delegation_requested', {\n 'agent.name': event.agent,\n 'task.id': event.taskId,\n mode: event.runMode ?? 'foreground',\n });\n } else if (observation.kind === 'started') {\n const { event } = observation;\n void telemetry.recordEvent('doom_team.child_started', { 'run.id': event.runId, outcome: 'started' });\n } else if (observation.kind === 'updated') {\n const { event } = observation;\n void telemetry.recordEvent('doom_team.delegation_updated', {\n 'run.id': event.runId,\n 'team.tool_count': event.toolCount ?? 0,\n 'team.duration_ms': event.durationMs ?? 0,\n 'team.token_count': event.tokens ?? 0,\n outcome: event.status ?? 'updated',\n });\n } else if (observation.kind === 'finished') {\n const { event } = observation;\n void telemetry.recordEvent('doom_team.delegation_finished', {\n 'run.id': event.runId,\n 'team.tool_count': event.toolCount ?? 0,\n 'team.duration_ms': event.durationMs ?? 0,\n outcome: event.status,\n });\n } else {\n void telemetry.recordEvent('doom_team.delegation_cancelled', { outcome: 'cancelled' });\n }\n}\n\n/**\n * The extension factory pi's loader calls, exported as the module default\n * (see the override this file carries in `vibe-lint.config.yaml`). This is an\n * ESM `.ts` module, so it CANNOT use the `export =` form that\n * `subagentPromptRuntimeEntry.cts` is required to use - that file is `.cts`\n * and is resolved by raw path, this one is resolved as a package subpath and\n * matches the `export default` convention every sibling extension in this repo\n * already uses (`doom-task`, `doom-file-edit`, `doom-pi-ui`).\n */\nexport function installTeamRuntime(cordis: Context, pi: ExtensionAPI): TeamExtensionRuntime {\n let telemetry: DoomTelemetry | undefined;\n const getTelemetry = (ctx: ExtensionContext): DoomTelemetry => {\n telemetry ??= createDoomTelemetry({\n serviceName: 'doom-team',\n packageName: '@agimon-ai/doompi-team',\n cwd: ctx.cwd,\n env: process.env,\n enableLogs: true,\n enableTraces: true,\n });\n return telemetry;\n };\n const reportConcurrencyEvent = (event: string, attributes: Record<string, unknown>): void => {\n void telemetry?.recordEvent(event, attributes);\n };\n cordis.effect(\n () => async () => {\n await telemetry?.shutdown();\n telemetry = undefined;\n },\n '@agimon-ai/doompi-team/telemetry',\n );\n const runtime = createTeamExtensionRuntime(reportConcurrencyEvent);\n const {\n subagentTool,\n teamChannel,\n pollScheduler,\n asyncJobTracker,\n subagentWaiter,\n asyncSubagentSpawner,\n discovery,\n skills,\n spawnPlanner,\n completionNotifier,\n resultWatcher,\n staleRunReconciler,\n management,\n capabilityPolicies,\n mcpToolResolver,\n } = runtime;\n\n let active = true;\n let sessionGeneration = 0;\n let readinessAbort: AbortController | undefined;\n let readinessHandle: Promise<DoomReadinessHandle<void>> | undefined;\n let readinessSessionManager: object | undefined;\n let standaloneReadiness: DoomReadinessCoordinator | undefined;\n let readinessNotificationContext: ExtensionContext | undefined;\n let activeCordisSession:\n | {\n readonly cordis: Context;\n readonly service: DoomCordisSessionService;\n }\n | undefined;\n cordis.inject([DOOM_CORDIS_SESSION_SERVICE], (sessionContext) => {\n const service = sessionContext.get(DOOM_CORDIS_SESSION_SERVICE) as DoomCordisSessionService;\n const binding = { cordis: sessionContext, service };\n activeCordisSession = binding;\n sessionContext.inject([DOOM_MCP_TOOL_RESOLVER_SERVICE], (resolverContext) =>\n mcpToolResolver.bind(requireDoomMcpToolResolver(resolverContext)),\n );\n sessionContext.inject([DOOM_CONTEXT_CONTRIBUTIONS_SERVICE], (contributionContext) => {\n const registration = requireDoomContextContributions(contributionContext).register({\n source: PACKAGE_SOURCE,\n id: 'runtime',\n label: 'Team',\n order: 200,\n snapshot: () => formatTeamContextSnapshot(readActiveTeamSnapshot()),\n });\n return () => registration.dispose();\n });\n sessionContext.effect(\n () => () => {\n if (activeCordisSession === binding) activeCordisSession = undefined;\n },\n `${PACKAGE_SOURCE}/cordis-session`,\n );\n });\n const coordinatorFor = (ctx: ExtensionContext): DoomReadinessCoordinator => {\n const cordisSession = activeCordisSession;\n const sessionId = ctx.sessionManager.getSessionId();\n const activeSessionMatches =\n cordisSession?.service.context.sessionManager === ctx.sessionManager &&\n cordisSession.service.sessionId === sessionId;\n const shared = activeSessionMatches ? readDoomReadinessCoordinator(cordisSession.cordis) : undefined;\n if (shared) return shared;\n standaloneReadiness ??= createDoomReadinessCoordinator({\n notify: (notification) => {\n const message = readinessNotificationMessage(notification);\n if (readinessNotificationContext?.hasUI) readinessNotificationContext.ui.notify(message, 'warning');\n else process.emitWarning(message);\n },\n });\n return standaloneReadiness;\n };\n const waitForSessionReadiness = async (ctx: ExtensionContext, signal?: AbortSignal): Promise<void> => {\n signal?.throwIfAborted();\n const pending = readinessHandle;\n if (!pending) throw new Error('Doom Team session initialization has not started.');\n if (readinessSessionManager !== ctx.sessionManager) {\n throw new Error('Doom Team readiness belongs to a stale Pi session.');\n }\n const handle = await pending;\n signal?.throwIfAborted();\n await handle.wait(signal ? { signal } : undefined);\n if (!active || pending !== readinessHandle || readinessSessionManager !== ctx.sessionManager) {\n throw new Error('Doom Team readiness belongs to a stale extension generation.');\n }\n };\n const readinessPi = new Proxy(pi, {\n get(target, property) {\n if (property === 'registerTool') {\n return (tool: RegisteredTool): void => {\n target.registerTool({\n ...tool,\n execute: async (toolCallId, params, signal, onUpdate, ctx) => {\n await waitForSessionReadiness(ctx, signal);\n return tool.execute(toolCallId, params, signal, onUpdate, ctx);\n },\n });\n };\n }\n if (property === 'registerCommand') {\n return (name: string, options: CommandOptions): void => {\n target.registerCommand(name, {\n ...options,\n handler: async (args, ctx) => {\n await waitForSessionReadiness(ctx);\n return options.handler(args, ctx);\n },\n });\n };\n }\n if (property === 'registerShortcut') {\n return (shortcut: Parameters<ExtensionAPI['registerShortcut']>[0], options: ShortcutOptions): void => {\n target.registerShortcut(shortcut, {\n ...options,\n handler: async (ctx) => {\n await waitForSessionReadiness(ctx);\n return options.handler(ctx);\n },\n });\n };\n }\n return boundPiValue(target, property);\n },\n });\n\n subagentTool.registerTool(readinessPi);\n\n cordis.inject([DOOM_UI_HUB_SERVICE], (uiContext) => registerSubagentLeaderContribution(requireDoomUiHub(uiContext)));\n\n const teamRuntime = teamChannel.createRuntime(readinessPi);\n cordis.effect(() => () => teamRuntime.dispose(), '@agimon-ai/doompi-team/channel');\n teamChannel.registerClient(readinessPi);\n\n // Attach before `ResultWatcher.start()`, which `session_start` drives.\n completionNotifier.attachHost(pi);\n cordis.effect(() => () => completionNotifier.dispose(), '@agimon-ai/doompi-team/completions');\n\n pollScheduler.start();\n cordis.effect(() => () => pollScheduler.stop(), '@agimon-ai/doompi-team/polling');\n\n asyncJobTracker.start();\n cordis.effect(() => () => asyncJobTracker.stop(), '@agimon-ai/doompi-team/jobs');\n\n let collaborationFiber: Fiber | undefined;\n let currentSessionJobs: TrackedAsyncJobsContract | undefined;\n // The scope `ResultWatcher` is currently watching. See its start site in\n // the `session_start` handler for why the watcher is latched on this\n // rather than started once.\n let watchedScopeKey: string | undefined;\n const delegationBridge = createDelegationBridge({\n planner: spawnPlanner,\n management,\n waiter: subagentWaiter,\n scheduler: pollScheduler,\n tracker: asyncJobTracker,\n loadConfig: () => loadConfig().config,\n });\n const fablePlanBridge = createFablePlanBridge({\n spawner: asyncSubagentSpawner,\n waiter: subagentWaiter,\n management,\n policies: capabilityPolicies,\n report: (event, attributes) => {\n void telemetry?.recordEvent(event, attributes);\n },\n });\n cordis.effect(\n () => async () => {\n await collaborationFiber?.dispose();\n collaborationFiber = undefined;\n },\n '@agimon-ai/doompi-team/collaboration',\n );\n cordis.effect(\n () => () => {\n resultWatcher.stop();\n watchedScopeKey = undefined;\n },\n '@agimon-ai/doompi-team/result-watcher',\n );\n\n const unregisterStaleRunReconciler = pollScheduler.register({\n id: 'stale-run-reconciler',\n // Crash detection, not status freshness - `AsyncJobTracker` owns that and\n // polls on its own 250ms. This subscriber only ever acts on a run whose\n // process is provably dead, so noticing that 2s later is invisible, while\n // running it 4x/second per active run was not: each pass is a status read,\n // a run-id resolve and a pid probe that a healthy child always discards.\n intervalMs: STALE_RUN_RECONCILE_INTERVAL_MS,\n run: async () => {\n let repaired = false;\n let hasActiveRun = false;\n for (const job of currentSessionJobs?.list() ?? []) {\n if (job.status && TERMINAL_ASYNC_JOB_STATES.has(job.status)) continue;\n hasActiveRun = true;\n // One pass, one `inspect()`. Calling `reconcile` and\n // `sweepOrphanedClaims` separately probed the same pid twice for the\n // same answer - see `StaleRunReconcilerContract.reconcileAndSweep`.\n const { reconcile: outcome, sweep } = staleRunReconciler.reconcileAndSweepAsync\n ? await staleRunReconciler.reconcileAndSweepAsync(job.runId)\n : staleRunReconciler.reconcileAndSweep(job.runId);\n if (outcome.repaired) {\n currentSessionJobs?.track(job.runId);\n repaired = true;\n }\n if (sweep.recovered.length > 0) repaired = true;\n }\n // An active runner is useful work for scheduling purposes: keeping\n // the shared scheduler at its floor prevents crash detection from\n // inheriting the idle five-second backoff ceiling.\n return repaired || hasActiveRun;\n },\n });\n cordis.effect(() => unregisterStaleRunReconciler, '@agimon-ai/doompi-team/stale-runs');\n // The orchestration addendum. Registered here rather than inside the\n // `subagent` tool's description because it is behavioural guidance, and it\n // has to land before the model decides whether to reach for the tool at\n // all - see `orchestratorPrompt.ts`. Read config per turn so toggling it\n // does not need a session restart; `loadConfig` is memoized on the file's\n // own mtime, so this is a stat, not a read.\n pi.on('before_agent_start', (event: { systemPrompt?: string }) => {\n if (!active || !shouldInjectOrchestratorPrompt(loadConfig().config)) return undefined;\n return { systemPrompt: appendOrchestratorPrompt(event.systemPrompt) };\n });\n\n const state: SlashCommandState = { baseCwd: undefined };\n\n /**\n * Publish what this session can launch, for the cockpit hub to read.\n *\n * The hub and the session API run in `doompi-server`, which never receives\n * the domain projection's agent directories or the harness state behind the\n * Team model policy, so discovery run there misses every domain-provided\n * agent. This process has both. Republished on each turn so an agent file\n * added mid-session shows up without a restart.\n */\n const publishCatalogSnapshot = (cwd: string, sessionId: string): void => {\n // A spawned child shares its parent's scope directory; only the root\n // session may write the catalog the user is looking at.\n if (resolveRootSessionId(sessionId) !== sessionId) return;\n try {\n writeSessionCatalogSnapshot(sessionId, {\n cwd,\n agents: presentCatalog(discovery.discover(cwd, 'both').agents),\n models: resolveActiveTeamModelSpecs() ?? [],\n });\n } catch {\n // Best effort: the hub falls back to its own discovery, and every launch\n // path reports discovery failures on its own.\n }\n };\n\n pi.on('before_agent_start', (_event: { systemPrompt?: string }, ctx: ExtensionContext) => {\n if (!active) return undefined;\n publishCatalogSnapshot(ctx.cwd, ctx.sessionManager.getSessionId());\n return undefined;\n });\n const slashCommandDeps = buildSlashCommandDeps(\n discovery,\n skills,\n spawnPlanner,\n asyncJobTracker,\n pollScheduler,\n management,\n );\n registerSlashCommands(readinessPi, state, slashCommandDeps);\n registerAgentListCommand(readinessPi, {\n discovery,\n skills,\n policies: capabilityPolicies,\n // The catalog's r/R keys spawn through the same path as `/run`, so a run\n // started from the overlay is tracked and reported like any other.\n launchAgent: (ctx, request) =>\n startSingleAgentRun(readinessPi, ctx, state, slashCommandDeps, {\n agent: request.agent,\n task: request.task,\n fork: request.context === 'fork',\n }),\n });\n registerFleetCommand(readinessPi, {\n scheduler: pollScheduler,\n tracker: asyncJobTracker,\n management,\n });\n cordis.inject([DOOM_UI_HUB_SERVICE], (uiContext) => {\n return registerAgentStatus(pi, requireDoomUiHub(uiContext), {\n scheduler: pollScheduler,\n tracker: asyncJobTracker,\n });\n });\n registerCompletionRenderer(pi);\n registerSlashRunRenderer(pi);\n\n const retireSessionBindings = async (): Promise<Error | undefined> => {\n const errors: unknown[] = [];\n const previousCollaboration = collaborationFiber;\n collaborationFiber = undefined;\n try {\n await previousCollaboration?.dispose();\n } catch (error) {\n errors.push(error);\n }\n for (const cleanup of [\n () => capabilityPolicies.clear(),\n () => delegationBridge.abandonAll(),\n () => fablePlanBridge.abandonAll(),\n () => teamRuntime.dispose(),\n ]) {\n try {\n cleanup();\n } catch (error) {\n errors.push(error);\n }\n }\n currentSessionJobs = undefined;\n if (errors.length === 0) return undefined;\n if (errors.length === 1 && errors[0] instanceof Error) return errors[0];\n return new AggregateError(errors, 'Team session cleanup failed.');\n };\n\n // Bind the root session directly into the one intercom transport. Child\n // processes bind from the team environment written during spawn.\n pi.on('session_start', (_event, ctx: ExtensionContext) => {\n if (!active) return undefined;\n const ownGeneration = ++sessionGeneration;\n const previousReadiness = readinessHandle;\n readinessAbort?.abort(new Error('Doom Team session initialization was superseded.'));\n const ownReadinessAbort = new AbortController();\n readinessAbort = ownReadinessAbort;\n readinessSessionManager = ctx.sessionManager;\n readinessNotificationContext = ctx;\n const activeTelemetry = getTelemetry(ctx);\n void activeTelemetry.recordEvent('doom_team.session_started', {\n 'team.root_session':\n resolveRootSessionId(ctx.sessionManager.getSessionId()) === ctx.sessionManager.getSessionId(),\n });\n // Before anything else: every scoped path helper reads this. A child\n // keeps the root inherited from its spawn environment, while a top-level\n // session falls back to its own Pi session id.\n const sessionId = ctx.sessionManager.getSessionId();\n const scope = createSessionScope(resolveRootSessionId(sessionId));\n setCurrentSessionScope(scope);\n state.baseCwd = ctx.cwd;\n publishCatalogSnapshot(ctx.cwd, sessionId);\n if (watchedScopeKey !== undefined && watchedScopeKey !== scope.scopeKey) {\n resultWatcher.stop();\n watchedScopeKey = undefined;\n }\n const retirement = retireSessionBindings();\n const coordinator = coordinatorFor(ctx);\n const ownsSession = (): boolean =>\n active &&\n ownGeneration === sessionGeneration &&\n readinessSessionManager === ctx.sessionManager &&\n !ownReadinessAbort.signal.aborted;\n\n readinessHandle = (async (): Promise<DoomReadinessHandle<void>> => {\n if (previousReadiness) {\n await Promise.allSettled([previousReadiness.then((handle) => handle.wait())]);\n }\n if (!ownsSession()) throw new Error('Doom Team session initialization was superseded.');\n return coordinator.start(PACKAGE_SOURCE, `${sessionId}:${ownGeneration}`, async (signal) => {\n signal.throwIfAborted();\n const retirementError = await retirement;\n if (retirementError) throw retirementError;\n if (!ownsSession()) return { value: undefined };\n // Claim the scope for this process, so a later sweep can tell an\n // abandoned tree from a live one. Rewritten on every session_start\n // because /resume legitimately re-adopts a scope under a new process.\n await writeScopeOwnerAsync(scope);\n signal.throwIfAborted();\n if (!ownsSession()) return { value: undefined };\n // Prune records whose process is gone, reap sibling scopes holding\n // nothing alive, and REPORT what is suspended. Nothing is restarted:\n // reopening a session must not silently spend tokens on stale work.\n const opened = await openScopeAsync(scope, {\n readStatusAsync: async (runId) =>\n management.statusAsync ? (await management.statusAsync(runId)).status : management.status(runId).status,\n });\n signal.throwIfAborted();\n if (!ownsSession()) return { value: undefined };\n if (opened.suspended.length > 0 && ctx.hasUI) {\n const message = await formatSuspendedRunsAsync(opened.suspended);\n signal.throwIfAborted();\n if (!ownsSession()) return { value: undefined };\n ctx.ui.notify(message, 'info');\n }\n void activeTelemetry.recordEvent('doom_team.runs_restored', {\n 'team.suspended_count': opened.suspended.length,\n 'team.pruned_count': opened.pruned.length,\n 'team.reaped_count': opened.reaped,\n outcome: 'reported',\n });\n currentSessionJobs = asyncJobTracker.forSession(sessionId);\n // ResultWatcher needs the session scope, but a repeated start for the\n // same scope must not reset its in-flight claims.\n if (watchedScopeKey !== scope.scopeKey) {\n watchedScopeKey = scope.scopeKey;\n resultWatcher.start(async (result) => {\n const jobs = currentSessionJobs;\n if (!jobs?.get(result.runId)) return false;\n const accepted = await completionNotifier.deliver(result);\n if (accepted) asyncJobTracker.acknowledgeHandoff(sessionId, result.runId);\n return accepted;\n });\n }\n const parentModel = normalizeParentModel(ctx.model);\n const activeSession = activeCordisSession;\n const collaborationParent =\n activeSession?.service.context.sessionManager === ctx.sessionManager ? activeSession.cordis : cordis;\n const nextCollaboration = collaborationParent.plugin(teamCollaborationPlugin, {\n session: {\n sessionId,\n cwd: ctx.cwd,\n availableModels: authenticatedModelInfos(ctx.modelRegistry),\n ...(parentModel ? { parentModel } : {}),\n captureForkSource: () => captureSessionForkSource(ctx.sessionManager, 'tool'),\n },\n directRunTracker: asyncJobTracker,\n delegation: delegationBridge,\n fablePlan: fablePlanBridge,\n policies: capabilityPolicies,\n observeDelegation: (observation) => recordDelegationObservation(activeTelemetry, observation),\n });\n collaborationFiber = nextCollaboration;\n await nextCollaboration.await();\n if (!ownsSession()) {\n await nextCollaboration.dispose();\n if (collaborationFiber === nextCollaboration) collaborationFiber = undefined;\n return { value: undefined };\n }\n teamRuntime.bindMainSession(sessionId);\n return { value: undefined };\n });\n })();\n // Config's coordinator owns the single user-facing failure notification.\n void Promise.allSettled([readinessHandle.then((handle) => handle.wait())]);\n return undefined;\n });\n\n cordis.effect(\n () => async () => {\n active = false;\n sessionGeneration += 1;\n const pendingReadiness = readinessHandle;\n readinessHandle = undefined;\n readinessSessionManager = undefined;\n readinessAbort?.abort(new Error('Doom Team runtime was disposed.'));\n readinessAbort = undefined;\n const ownedReadiness = standaloneReadiness;\n standaloneReadiness = undefined;\n if (ownedReadiness) await ownedReadiness.dispose();\n else if (pendingReadiness) await Promise.allSettled([pendingReadiness.then((handle) => handle.wait())]);\n readinessNotificationContext = undefined;\n },\n '@agimon-ai/doompi-team/session-fence',\n );\n\n /**\n * Every reason suspends, with no exception for `reload`.\n *\n * Pi emits this for `quit`, `reload`, `new`, `resume` and `fork`. Treating\n * `reload` differently - keeping children alive because `/domains`, `/major-mode`\n * and `/profile` only reload the extension - would be the one case someone\n * has to remember, and the one that silently misbehaves if Pi adds a sixth\n * reason. Suspending uniformly costs a respawn on reload; restore continues\n * the child's own transcript rather than restarting its task.\n */\n let shutdownPromise: Promise<void> | undefined;\n const shutdownSession = async (event: { reason?: string }): Promise<void> => {\n active = false;\n sessionGeneration += 1;\n const pendingReadiness = readinessHandle;\n readinessHandle = undefined;\n readinessSessionManager = undefined;\n readinessAbort?.abort(new Error('Doom Team session ended.'));\n readinessAbort = undefined;\n const ownedReadiness = standaloneReadiness;\n standaloneReadiness = undefined;\n await Promise.allSettled([\n ...(pendingReadiness ? [pendingReadiness.then((handle) => handle.wait())] : []),\n ...(ownedReadiness ? [ownedReadiness.dispose()] : []),\n ]);\n const scope = tryCurrentSessionScope();\n const suspensionPromise = scope\n ? suspendScopeRuns({\n scope,\n reason: event.reason ?? SESSION_SHUTDOWN_REASON_FALLBACK,\n readStatus: (runId) => management.status(runId).status,\n })\n : Promise.resolve(undefined);\n let suspension: Awaited<ReturnType<typeof suspendScopeRuns>> | undefined;\n try {\n suspension = await suspensionPromise;\n await telemetry?.recordEvent('doom_team.session_finished', {\n reason: event.reason ?? SESSION_SHUTDOWN_REASON_FALLBACK,\n 'team.suspended_count': suspension?.suspended.length ?? 0,\n 'team.unstoppable_count': suspension?.unstoppable.length ?? 0,\n outcome: suspension?.unstoppable.length ? 'degraded' : 'suspended',\n });\n } catch (error) {\n await telemetry?.recordError('doom_team.session_shutdown_failed', error, {\n reason: event.reason ?? SESSION_SHUTDOWN_REASON_FALLBACK,\n });\n } finally {\n await telemetry?.shutdown();\n telemetry = undefined;\n }\n };\n pi.on('session_shutdown', (event: { reason?: string }) => {\n shutdownPromise ??= shutdownSession(event);\n return shutdownPromise;\n });\n\n return runtime;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{resolveActiveTeamModelSpecs as e}from"../agents/discovery.mjs";import{presentCatalog as t}from"../../services/webSubagentCatalog.mjs";import{writeSessionCatalogSnapshot as n}from"../sessionCatalogSnapshot.mjs";import{createSessionScope as r,init_paths as i,setCurrentSessionScope as a,tryCurrentSessionScope as o}from"../filesystem/paths.mjs";import{formatTeamContextSnapshot as s,readActiveTeamSnapshot as c}from"../api/teamSnapshot.mjs";import{authenticatedModelInfos as ee}from"../../services/models/modelResolution.mjs";import{normalizeParentModel as te}from"../runs/shared/modelFallback.mjs";import{init_scopeOwner as l,writeScopeOwnerAsync as ne}from"../scopeOwner.mjs";import{captureSessionForkSource as re}from"./extensions/spawnPlan.mjs";import{TERMINAL_ASYNC_JOB_STATES as u,init_asyncJobTracker as d}from"../asyncJobTracker.mjs";import{registerSlashCommands as f,startSingleAgentRun as p}from"./commands/slash/slashCommands.mjs";import{loadConfig as m}from"./extensions/config.mjs";import{createDelegationBridge as ie}from"./extensions/delegationBridge.mjs";import{createFablePlanBridge as ae}from"./extensions/fablePlanBridge.mjs";import{appendOrchestratorPrompt as oe,shouldInjectOrchestratorPrompt as se}from"./extensions/orchestratorPrompt.mjs";import{formatSuspendedRunsAsync as ce}from"../suspendedRuns.mjs";import{openScopeAsync as le,suspendScopeRuns as ue}from"../runs/registry/sessionLifecycle.mjs";import{registerCompletionRenderer as de}from"./tui/completionNotice.mjs";import{registerSlashRunRenderer as fe}from"./tui/slashRunNotice.mjs";import{registerAgentListCommand as pe,registerAgentStatus as me,registerFleetCommand as he,registerSubagentLeaderContribution as ge}from"./tui/register.mjs";import{teamCollaborationPlugin as _e}from"./collaboration.mjs";import{createTeamExtensionRuntime as ve}from"./teamRuntime.mjs";import{resolveRootSessionId as h}from"@agimon-ai/doompi-extension-contracts/child-process";import{DOOM_CORDIS_SESSION_SERVICE as g}from"@agimon-ai/doompi-extension-contracts/cordis-host";import{DOOM_CONTEXT_CONTRIBUTIONS_SERVICE as ye,requireDoomContextContributions as be}from"@agimon-ai/doompi-extension-contracts/context-contributions";import{DOOM_MCP_TOOL_RESOLVER_SERVICE as xe,requireDoomMcpToolResolver as Se}from"@agimon-ai/doompi-extension-contracts/mcp-tool-resolver";import{createDoomReadinessCoordinator as Ce,readDoomReadinessCoordinator as we}from"@agimon-ai/doompi-extension-contracts/readiness";import{DOOM_UI_HUB_SERVICE as _,requireDoomUiHub as v}from"@agimon-ai/doompi-extension-contracts/ui-hub";import{createDoomTelemetry as Te}from"@agimon-ai/doompi-telemetry";d(),i(),l();const y=`unknown`,b=`@agimon-ai/doompi-team`;function Ee(e,t){let n=Reflect.get(e,t,e);return typeof n==`function`?n.bind(e):n}function De(e){let t=e.diagnostics.join(`; `),n=(e.error?.message??t)||`Initialization did not complete.`;return`${e.packageId} initialization ${e.state}: ${n}`}function Oe(e,t,n,r,i,a){return{spawnPlanner:n,tracker:r,scheduler:i,discovery:e,skills:t,management:a,loadConfig:()=>m().config}}function ke(e,t){if(t.kind===`requested`){let{event:n}=t;e.recordEvent(`doom_team.delegation_requested`,{"agent.name":n.agent,"task.id":n.taskId,mode:n.runMode??`foreground`})}else if(t.kind===`started`){let{event:n}=t;e.recordEvent(`doom_team.child_started`,{"run.id":n.runId,outcome:`started`})}else if(t.kind===`updated`){let{event:n}=t;e.recordEvent(`doom_team.delegation_updated`,{"run.id":n.runId,"team.tool_count":n.toolCount??0,"team.duration_ms":n.durationMs??0,"team.token_count":n.tokens??0,outcome:n.status??`updated`})}else if(t.kind===`finished`){let{event:n}=t;e.recordEvent(`doom_team.delegation_finished`,{"run.id":n.runId,"team.tool_count":n.toolCount??0,"team.duration_ms":n.durationMs??0,outcome:n.status})}else e.recordEvent(`doom_team.delegation_cancelled`,{outcome:`cancelled`})}function x(i,l){let d,x=e=>(d??=Te({serviceName:`doom-team`,packageName:`@agimon-ai/doompi-team`,cwd:e.cwd,env:process.env,enableLogs:!0,enableTraces:!0}),d),Ae=(e,t)=>{d?.recordEvent(e,t)};i.effect(()=>async()=>{await d?.shutdown(),d=void 0},`@agimon-ai/doompi-team/telemetry`);let S=ve(Ae),{subagentTool:je,teamChannel:C,pollScheduler:w,asyncJobTracker:T,subagentWaiter:E,asyncSubagentSpawner:Me,discovery:D,skills:O,spawnPlanner:k,completionNotifier:A,resultWatcher:j,staleRunReconciler:M,management:N,capabilityPolicies:P,mcpToolResolver:Ne}=S,F=!0,I=0,L,R,z,B,V,H;i.inject([g],e=>{let t={cordis:e,service:e.get(g)};H=t,e.inject([xe],e=>Ne.bind(Se(e))),e.inject([ye],e=>{let t=be(e).register({source:b,id:`runtime`,label:`Team`,order:200,snapshot:()=>s(c())});return()=>t.dispose()}),e.effect(()=>()=>{H===t&&(H=void 0)},`${b}/cordis-session`)});let Pe=e=>{let t=H,n=e.sessionManager.getSessionId();return(t?.service.context.sessionManager===e.sessionManager&&t.service.sessionId===n?we(t.cordis):void 0)||(B??=Ce({notify:e=>{let t=De(e);V?.hasUI?V.ui.notify(t,`warning`):process.emitWarning(t)}}),B)},U=async(e,t)=>{t?.throwIfAborted();let n=R;if(!n)throw Error(`Doom Team session initialization has not started.`);if(z!==e.sessionManager)throw Error(`Doom Team readiness belongs to a stale Pi session.`);let r=await n;if(t?.throwIfAborted(),await r.wait(t?{signal:t}:void 0),!F||n!==R||z!==e.sessionManager)throw Error(`Doom Team readiness belongs to a stale extension generation.`)},W=new Proxy(l,{get(e,t){return t===`registerTool`?t=>{e.registerTool({...t,execute:async(e,n,r,i,a)=>(await U(a,r),t.execute(e,n,r,i,a))})}:t===`registerCommand`?(t,n)=>{e.registerCommand(t,{...n,handler:async(e,t)=>(await U(t),n.handler(e,t))})}:t===`registerShortcut`?(t,n)=>{e.registerShortcut(t,{...n,handler:async e=>(await U(e),n.handler(e))})}:Ee(e,t)}});je.registerTool(W),i.inject([_],e=>ge(v(e)));let G=C.createRuntime(W);i.effect(()=>()=>G.dispose(),`@agimon-ai/doompi-team/channel`),C.registerClient(W),A.attachHost(l),i.effect(()=>()=>A.dispose(),`@agimon-ai/doompi-team/completions`),w.start(),i.effect(()=>()=>w.stop(),`@agimon-ai/doompi-team/polling`),T.start(),i.effect(()=>()=>T.stop(),`@agimon-ai/doompi-team/jobs`);let K,q,J,Y=ie({planner:k,management:N,waiter:E,scheduler:w,tracker:T,loadConfig:()=>m().config}),X=ae({spawner:Me,waiter:E,management:N,policies:P,report:(e,t)=>{d?.recordEvent(e,t)}});i.effect(()=>async()=>{await K?.dispose(),K=void 0},`@agimon-ai/doompi-team/collaboration`),i.effect(()=>()=>{j.stop(),J=void 0},`@agimon-ai/doompi-team/result-watcher`);let Fe=w.register({id:`stale-run-reconciler`,intervalMs:2e3,run:async()=>{let e=!1,t=!1;for(let n of q?.list()??[]){if(n.status&&u.has(n.status))continue;t=!0;let{reconcile:r,sweep:i}=M.reconcileAndSweepAsync?await M.reconcileAndSweepAsync(n.runId):M.reconcileAndSweep(n.runId);r.repaired&&(q?.track(n.runId),e=!0),i.recovered.length>0&&(e=!0)}return e||t}});i.effect(()=>Fe,`@agimon-ai/doompi-team/stale-runs`),l.on(`before_agent_start`,e=>{if(F&&se(m().config))return{systemPrompt:oe(e.systemPrompt)}});let Z={baseCwd:void 0},Q=(r,i)=>{if(h(i)===i)try{n(i,{cwd:r,agents:t(D.discover(r,`both`).agents),models:e()??[]})}catch{}};l.on(`before_agent_start`,(e,t)=>{F&&Q(t.cwd,t.sessionManager.getSessionId())});let $=Oe(D,O,k,T,w,N);f(W,Z,$),pe(W,{discovery:D,skills:O,policies:P,launchAgent:(e,t)=>p(W,e,Z,$,{agent:t.agent,task:t.task,fork:t.context===`fork`})}),he(W,{scheduler:w,tracker:T,management:N}),i.inject([_],e=>me(l,v(e),{scheduler:w,tracker:T})),de(l),fe(l);let Ie=async()=>{let e=[],t=K;K=void 0;try{await t?.dispose()}catch(t){e.push(t)}for(let t of[()=>P.clear(),()=>Y.abandonAll(),()=>X.abandonAll(),()=>G.dispose()])try{t()}catch(t){e.push(t)}if(q=void 0,e.length!==0)return e.length===1&&e[0]instanceof Error?e[0]:AggregateError(e,`Team session cleanup failed.`)};l.on(`session_start`,(e,t)=>{if(!F)return;let n=++I,o=R;L?.abort(Error(`Doom Team session initialization was superseded.`));let s=new AbortController;L=s,z=t.sessionManager,V=t;let c=x(t);c.recordEvent(`doom_team.session_started`,{"team.root_session":h(t.sessionManager.getSessionId())===t.sessionManager.getSessionId()});let l=t.sessionManager.getSessionId(),u=r(h(l));a(u),Z.baseCwd=t.cwd,Q(t.cwd,l),J!==void 0&&J!==u.scopeKey&&(j.stop(),J=void 0);let d=Ie(),f=Pe(t),p=()=>F&&n===I&&z===t.sessionManager&&!s.signal.aborted;R=(async()=>{if(o&&await Promise.allSettled([o.then(e=>e.wait())]),!p())throw Error(`Doom Team session initialization was superseded.`);return f.start(b,`${l}:${n}`,async e=>{e.throwIfAborted();let n=await d;if(n)throw n;if(!p()||(await ne(u),e.throwIfAborted(),!p()))return{value:void 0};let r=await le(u,{readStatusAsync:async e=>N.statusAsync?(await N.statusAsync(e)).status:N.status(e).status});if(e.throwIfAborted(),!p())return{value:void 0};if(r.suspended.length>0&&t.hasUI){let n=await ce(r.suspended);if(e.throwIfAborted(),!p())return{value:void 0};t.ui.notify(n,`info`)}c.recordEvent(`doom_team.runs_restored`,{"team.suspended_count":r.suspended.length,"team.pruned_count":r.pruned.length,"team.reaped_count":r.reaped,outcome:`reported`}),q=T.forSession(l),J!==u.scopeKey&&(J=u.scopeKey,j.start(async e=>{if(!q?.get(e.runId))return!1;let t=await A.deliver(e);return t&&T.acknowledgeHandoff(l,e.runId),t}));let a=te(t.model),o=H,s=(o?.service.context.sessionManager===t.sessionManager?o.cordis:i).plugin(_e,{session:{sessionId:l,cwd:t.cwd,availableModels:ee(t.modelRegistry),...a?{parentModel:a}:{},captureForkSource:()=>re(t.sessionManager,`tool`)},directRunTracker:T,delegation:Y,fablePlan:X,policies:P,observeDelegation:e=>ke(c,e)});return K=s,await s.await(),p()?(G.bindMainSession(l),{value:void 0}):(await s.dispose(),K===s&&(K=void 0),{value:void 0})})})(),Promise.allSettled([R.then(e=>e.wait())])}),i.effect(()=>async()=>{F=!1,I+=1;let e=R;R=void 0,z=void 0,L?.abort(Error(`Doom Team runtime was disposed.`)),L=void 0;let t=B;B=void 0,t?await t.dispose():e&&await Promise.allSettled([e.then(e=>e.wait())]),V=void 0},`@agimon-ai/doompi-team/session-fence`);let Le,Re=async e=>{F=!1,I+=1;let t=R;R=void 0,z=void 0,L?.abort(Error(`Doom Team session ended.`)),L=void 0;let n=B;B=void 0,await Promise.allSettled([...t?[t.then(e=>e.wait())]:[],...n?[n.dispose()]:[]]);let r=o(),i=r?ue({scope:r,reason:e.reason??y,readStatus:e=>N.status(e).status}):Promise.resolve(void 0),a;try{a=await i,await d?.recordEvent(`doom_team.session_finished`,{reason:e.reason??y,"team.suspended_count":a?.suspended.length??0,"team.unstoppable_count":a?.unstoppable.length??0,outcome:a?.unstoppable.length?`degraded`:`suspended`})}catch(t){await d?.recordError(`doom_team.session_shutdown_failed`,t,{reason:e.reason??y})}finally{await d?.shutdown(),d=void 0}};return l.on(`session_shutdown`,e=>(Le??=Re(e),Le)),S}export{x as installTeamRuntime};
1
+ import{resolveActiveTeamModelSpecs as e}from"../agents/discovery.mjs";import{presentCatalog as t}from"../../services/webSubagentCatalog.mjs";import{writeSessionCatalogSnapshot as n}from"../sessionCatalogSnapshot.mjs";import{createSessionScope as r,init_paths as i,setCurrentSessionScope as a,tryCurrentSessionScope as o}from"../filesystem/paths.mjs";import{authenticatedModelInfos as ee}from"../../services/models/modelResolution.mjs";import{normalizeParentModel as te}from"../runs/shared/modelFallback.mjs";import{init_scopeOwner as s,writeScopeOwnerAsync as ne}from"../scopeOwner.mjs";import{captureSessionForkSource as re}from"./extensions/spawnPlan.mjs";import{TERMINAL_ASYNC_JOB_STATES as c,init_asyncJobTracker as l}from"../asyncJobTracker.mjs";import{registerSlashCommands as u,startSingleAgentRun as d}from"./commands/slash/slashCommands.mjs";import{loadConfig as f}from"./extensions/config.mjs";import{createDelegationBridge as p}from"./extensions/delegationBridge.mjs";import{createFablePlanBridge as ie}from"./extensions/fablePlanBridge.mjs";import{appendOrchestratorPrompt as ae,shouldInjectOrchestratorPrompt as oe}from"./extensions/orchestratorPrompt.mjs";import{formatTeamContextSnapshot as se,readActiveTeamSnapshot as ce}from"../api/teamSnapshot.mjs";import{formatSuspendedRunsAsync as le}from"../suspendedRuns.mjs";import{openScopeAsync as ue,suspendScopeRuns as de}from"../runs/registry/sessionLifecycle.mjs";import{registerCompletionRenderer as fe}from"./tui/completionNotice.mjs";import{registerSlashRunRenderer as pe}from"./tui/slashRunNotice.mjs";import{registerAgentListCommand as me,registerAgentStatus as he,registerFleetCommand as ge,registerSubagentLeaderContribution as _e}from"./tui/register.mjs";import{teamCollaborationPlugin as ve}from"./collaboration.mjs";import{createTeamExtensionRuntime as ye}from"./teamRuntime.mjs";import{resolveRootSessionId as m}from"@agimon-ai/doompi-extension-contracts/child-process";import{DOOM_CORDIS_SESSION_SERVICE as h}from"@agimon-ai/doompi-extension-contracts/cordis-host";import{DOOM_CONTEXT_CONTRIBUTIONS_SERVICE as be,requireDoomContextContributions as xe}from"@agimon-ai/doompi-extension-contracts/context-contributions";import{DOOM_MCP_TOOL_RESOLVER_SERVICE as Se,requireDoomMcpToolResolver as Ce}from"@agimon-ai/doompi-extension-contracts/mcp-tool-resolver";import{createDoomReadinessCoordinator as we,readDoomReadinessCoordinator as Te}from"@agimon-ai/doompi-extension-contracts/readiness";import{DOOM_UI_HUB_SERVICE as g,requireDoomUiHub as _}from"@agimon-ai/doompi-extension-contracts/ui-hub";import{createDoomTelemetry as Ee}from"@agimon-ai/doompi-telemetry";l(),i(),s();const v=`unknown`,y=`@agimon-ai/doompi-team`;function De(e,t){let n=Reflect.get(e,t,e);return typeof n==`function`?n.bind(e):n}function Oe(e){let t=e.diagnostics.join(`; `),n=(e.error?.message??t)||`Initialization did not complete.`;return`${e.packageId} initialization ${e.state}: ${n}`}function ke(e,t,n,r,i,a){return{spawnPlanner:n,tracker:r,scheduler:i,discovery:e,skills:t,management:a,loadConfig:()=>f().config}}function Ae(e,t){if(t.kind===`requested`){let{event:n}=t;e.recordEvent(`doom_team.delegation_requested`,{"agent.name":n.agent,"task.id":n.taskId,mode:n.runMode??`foreground`})}else if(t.kind===`started`){let{event:n}=t;e.recordEvent(`doom_team.child_started`,{"run.id":n.runId,outcome:`started`})}else if(t.kind===`updated`){let{event:n}=t;e.recordEvent(`doom_team.delegation_updated`,{"run.id":n.runId,"team.tool_count":n.toolCount??0,"team.duration_ms":n.durationMs??0,"team.token_count":n.tokens??0,outcome:n.status??`updated`})}else if(t.kind===`finished`){let{event:n}=t;e.recordEvent(`doom_team.delegation_finished`,{"run.id":n.runId,"team.tool_count":n.toolCount??0,"team.duration_ms":n.durationMs??0,outcome:n.status})}else e.recordEvent(`doom_team.delegation_cancelled`,{outcome:`cancelled`})}function b(i,s){let l,b=e=>(l??=Ee({serviceName:`doom-team`,packageName:`@agimon-ai/doompi-team`,cwd:e.cwd,env:process.env,enableLogs:!0,enableTraces:!0}),l),je=(e,t)=>{l?.recordEvent(e,t)};i.effect(()=>async()=>{await l?.shutdown(),l=void 0},`@agimon-ai/doompi-team/telemetry`);let x=ye(je),{subagentTool:Me,teamChannel:S,pollScheduler:C,asyncJobTracker:w,subagentWaiter:T,asyncSubagentSpawner:Ne,discovery:E,skills:D,spawnPlanner:O,completionNotifier:k,resultWatcher:A,staleRunReconciler:j,management:M,capabilityPolicies:N,mcpToolResolver:Pe}=x,P=!0,F=0,I,L,R,z,B,V;i.inject([h],e=>{let t={cordis:e,service:e.get(h)};V=t,e.inject([Se],e=>Pe.bind(Ce(e))),e.inject([be],e=>{let t=xe(e).register({source:y,id:`runtime`,label:`Team`,order:200,snapshot:()=>se(ce())});return()=>t.dispose()}),e.effect(()=>()=>{V===t&&(V=void 0)},`${y}/cordis-session`)});let Fe=e=>{let t=V,n=e.sessionManager.getSessionId();return(t?.service.context.sessionManager===e.sessionManager&&t.service.sessionId===n?Te(t.cordis):void 0)||(z??=we({notify:e=>{let t=Oe(e);B?.hasUI?B.ui.notify(t,`warning`):process.emitWarning(t)}}),z)},H=async(e,t)=>{t?.throwIfAborted();let n=L;if(!n)throw Error(`Doom Team session initialization has not started.`);if(R!==e.sessionManager)throw Error(`Doom Team readiness belongs to a stale Pi session.`);let r=await n;if(t?.throwIfAborted(),await r.wait(t?{signal:t}:void 0),!P||n!==L||R!==e.sessionManager)throw Error(`Doom Team readiness belongs to a stale extension generation.`)},U=new Proxy(s,{get(e,t){return t===`registerTool`?t=>{e.registerTool({...t,execute:async(e,n,r,i,a)=>(await H(a,r),t.execute(e,n,r,i,a))})}:t===`registerCommand`?(t,n)=>{e.registerCommand(t,{...n,handler:async(e,t)=>(await H(t),n.handler(e,t))})}:t===`registerShortcut`?(t,n)=>{e.registerShortcut(t,{...n,handler:async e=>(await H(e),n.handler(e))})}:De(e,t)}});Me.registerTool(U),i.inject([g],e=>_e(_(e)));let W=S.createRuntime(U);i.effect(()=>()=>W.dispose(),`@agimon-ai/doompi-team/channel`),S.registerClient(U),k.attachHost(s),i.effect(()=>()=>k.dispose(),`@agimon-ai/doompi-team/completions`),C.start(),i.effect(()=>()=>C.stop(),`@agimon-ai/doompi-team/polling`),w.start(),i.effect(()=>()=>w.stop(),`@agimon-ai/doompi-team/jobs`);let G,K,q,J=p({planner:O,management:M,waiter:T,scheduler:C,tracker:w,loadConfig:()=>f().config}),Y=ie({spawner:Ne,waiter:T,management:M,policies:N,report:(e,t)=>{l?.recordEvent(e,t)}});i.effect(()=>async()=>{await G?.dispose(),G=void 0},`@agimon-ai/doompi-team/collaboration`),i.effect(()=>()=>{A.stop(),q=void 0},`@agimon-ai/doompi-team/result-watcher`);let Ie=C.register({id:`stale-run-reconciler`,intervalMs:2e3,run:async()=>{let e=!1,t=!1;for(let n of K?.list()??[]){if(n.status&&c.has(n.status))continue;t=!0;let{reconcile:r,sweep:i}=j.reconcileAndSweepAsync?await j.reconcileAndSweepAsync(n.runId):j.reconcileAndSweep(n.runId);r.repaired&&(K?.track(n.runId),e=!0),i.recovered.length>0&&(e=!0)}return e||t}});i.effect(()=>Ie,`@agimon-ai/doompi-team/stale-runs`),s.on(`before_agent_start`,e=>{if(P&&oe(f().config))return{systemPrompt:ae(e.systemPrompt)}});let X={baseCwd:void 0},Z=(r,i)=>{if(m(i)===i)try{n(i,{cwd:r,agents:t(E.discover(r,`both`).agents),models:e()??[]})}catch{}};s.on(`before_agent_start`,(e,t)=>{P&&Z(t.cwd,t.sessionManager.getSessionId())});let Q=ke(E,D,O,w,C,M);u(U,X,Q),me(U,{discovery:E,skills:D,policies:N,launchAgent:(e,t)=>d(U,e,X,Q,{agent:t.agent,task:t.task,fork:t.context===`fork`})}),ge(U,{scheduler:C,tracker:w,management:M}),i.inject([g],e=>he(s,_(e),{scheduler:C,tracker:w})),fe(s),pe(s);let Le=async()=>{let e=[],t=G;G=void 0;try{await t?.dispose()}catch(t){e.push(t)}for(let t of[()=>N.clear(),()=>J.abandonAll(),()=>Y.abandonAll(),()=>W.dispose()])try{t()}catch(t){e.push(t)}if(K=void 0,e.length!==0)return e.length===1&&e[0]instanceof Error?e[0]:AggregateError(e,`Team session cleanup failed.`)};s.on(`session_start`,(e,t)=>{if(!P)return;let n=++F,o=L;I?.abort(Error(`Doom Team session initialization was superseded.`));let s=new AbortController;I=s,R=t.sessionManager,B=t;let c=b(t);c.recordEvent(`doom_team.session_started`,{"team.root_session":m(t.sessionManager.getSessionId())===t.sessionManager.getSessionId()});let l=t.sessionManager.getSessionId(),u=r(m(l));a(u),X.baseCwd=t.cwd,Z(t.cwd,l),q!==void 0&&q!==u.scopeKey&&(A.stop(),q=void 0);let d=Le(),f=Fe(t),p=()=>P&&n===F&&R===t.sessionManager&&!s.signal.aborted;L=(async()=>{if(o&&await Promise.allSettled([o.then(e=>e.wait())]),!p())throw Error(`Doom Team session initialization was superseded.`);return f.start(y,`${l}:${n}`,async e=>{e.throwIfAborted();let n=await d;if(n)throw n;if(!p()||(await ne(u),e.throwIfAborted(),!p()))return{value:void 0};let r=await ue(u,{readStatusAsync:async e=>M.statusAsync?(await M.statusAsync(e)).status:M.status(e).status});if(e.throwIfAborted(),!p())return{value:void 0};if(r.suspended.length>0&&t.hasUI){let n=await le(r.suspended);if(e.throwIfAborted(),!p())return{value:void 0};t.ui.notify(n,`info`)}c.recordEvent(`doom_team.runs_restored`,{"team.suspended_count":r.suspended.length,"team.pruned_count":r.pruned.length,"team.reaped_count":r.reaped,outcome:`reported`}),K=w.forSession(l),q!==u.scopeKey&&(q=u.scopeKey,A.start(async e=>{if(!K?.get(e.runId))return!1;let t=await k.deliver(e);return t&&w.acknowledgeHandoff(l,e.runId),t}));let a=te(t.model),o=V,s=(o?.service.context.sessionManager===t.sessionManager?o.cordis:i).plugin(ve,{session:{sessionId:l,cwd:t.cwd,availableModels:ee(t.modelRegistry),...a?{parentModel:a}:{},captureForkSource:()=>re(t.sessionManager,`tool`)},directRunTracker:w,delegation:J,fablePlan:Y,policies:N,observeDelegation:e=>Ae(c,e)});return G=s,await s.await(),p()?(W.bindMainSession(l),{value:void 0}):(await s.dispose(),G===s&&(G=void 0),{value:void 0})})})(),Promise.allSettled([L.then(e=>e.wait())])}),i.effect(()=>async()=>{P=!1,F+=1;let e=L;L=void 0,R=void 0,I?.abort(Error(`Doom Team runtime was disposed.`)),I=void 0;let t=z;z=void 0,t?await t.dispose():e&&await Promise.allSettled([e.then(e=>e.wait())]),B=void 0},`@agimon-ai/doompi-team/session-fence`);let $,Re=async e=>{P=!1,F+=1;let t=L;L=void 0,R=void 0,I?.abort(Error(`Doom Team session ended.`)),I=void 0;let n=z;z=void 0,await Promise.allSettled([...t?[t.then(e=>e.wait())]:[],...n?[n.dispose()]:[]]);let r=o(),i=r?de({scope:r,reason:e.reason??v,readStatus:e=>M.status(e).status}):Promise.resolve(void 0),a;try{a=await i,await l?.recordEvent(`doom_team.session_finished`,{reason:e.reason??v,"team.suspended_count":a?.suspended.length??0,"team.unstoppable_count":a?.unstoppable.length??0,outcome:a?.unstoppable.length?`degraded`:`suspended`})}catch(t){await l?.recordError(`doom_team.session_shutdown_failed`,t,{reason:e.reason??v})}finally{await l?.shutdown(),l=void 0}};return s.on(`session_shutdown`,e=>($??=Re(e),$)),x}export{b as installTeamRuntime};
2
2
  //# sourceMappingURL=extension.mjs.map