shennian 0.3.9 → 0.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/publish-build-manifest.json +46 -41
  2. package/dist/src/commands/daemon-windows.d.ts +7 -0
  3. package/dist/src/commands/daemon-windows.js +11 -7
  4. package/dist/src/commands/daemon.d.ts +1 -1
  5. package/dist/src/commands/daemon.js +7 -7
  6. package/dist/src/commands/room.d.ts +9 -0
  7. package/dist/src/commands/room.js +8 -4
  8. package/dist/src/index.js +2 -2
  9. package/dist/src/integrations/room-plugin-shared.js +2 -2
  10. package/dist/src/integrations/workbuddy-plugin-lifecycle.d.ts +10 -0
  11. package/dist/src/integrations/workbuddy-plugin-lifecycle.js +2 -2
  12. package/dist/src/room/activation-service.d.ts +11 -0
  13. package/dist/src/room/activation-service.js +10 -4
  14. package/dist/src/room/agent-tool.d.ts +1 -0
  15. package/dist/src/room/agent-tool.js +1 -1
  16. package/dist/src/room/managed-room-binding.d.ts +23 -1
  17. package/dist/src/room/managed-room-binding.js +1 -1
  18. package/dist/src/room/managed-room-session-runtime.d.ts +18 -0
  19. package/dist/src/room/managed-room-session-runtime.js +1 -0
  20. package/dist/src/room/mirror-sync-service.d.ts +5 -5
  21. package/dist/src/room/mirror-sync-service.js +1 -1
  22. package/dist/src/room/operator-ipc.d.ts +2 -0
  23. package/dist/src/room/operator-ipc.js +1 -1
  24. package/dist/src/room/room-action-client.d.ts +10 -0
  25. package/dist/src/room/room-action-client.js +1 -1
  26. package/dist/src/room/room-action-ipc.d.ts +1 -0
  27. package/dist/src/room/room-action-ipc.js +1 -1
  28. package/dist/src/room/room-binding-client.d.ts +9 -0
  29. package/dist/src/room/room-binding-client.js +1 -1
  30. package/dist/src/room/room-binding-ipc.d.ts +3 -1
  31. package/dist/src/room/session-registry.d.ts +7 -1
  32. package/dist/src/room/session-registry.js +2 -2
  33. package/dist/src/room/tool-schema.d.ts +1 -1
  34. package/dist/src/room/tool-schema.js +1 -1
  35. package/dist/src/session/handlers/chat.d.ts +8 -1
  36. package/dist/src/session/handlers/chat.js +1 -1
  37. package/dist/src/session/handlers/room-managed.d.ts +1 -0
  38. package/dist/src/session/handlers/room-managed.js +1 -1
  39. package/dist/src/session/manager.d.ts +20 -0
  40. package/dist/src/session/manager.js +1 -1
  41. package/dist/src/upgrade/engine.d.ts +5 -0
  42. package/dist/src/upgrade/engine.js +2 -2
  43. package/node_modules/@shennian/wire/dist/agent-workspace.d.ts +1 -0
  44. package/node_modules/@shennian/wire/dist/agent-workspace.d.ts.map +1 -1
  45. package/node_modules/@shennian/wire/dist/methods.d.ts +1 -1
  46. package/node_modules/@shennian/wire/dist/methods.d.ts.map +1 -1
  47. package/node_modules/@shennian/wire/dist/room.d.ts +2 -0
  48. package/node_modules/@shennian/wire/dist/room.d.ts.map +1 -1
  49. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- import y from"node:crypto";import c from"node:fs";import b from"node:path";import{resolveShennianPath as S}from"../config/index.js";const p=500,P=/^[A-Za-z0-9_.:@/-]{1,512}$/,R=new Set(["codex","claude_code","workbuddy"]),_=new Set(["pending_approval","active","paused","detached"]),I=new Set(["auto_follow","mention_only","paused"]);class o extends Error{code;constructor(e,i){super(i),this.code=e,this.name="RoomSessionRegistryError"}}class C{filePath;state;mutexTails=new Map;constructor(e=S("runtime","room-session-registry.json")){this.filePath=e,this.state=this.load()}register(e){r(e.machineId,"machine_id"),f(e.runtimeAdapter),w(e.sourceSessionKey),r(e.nianSessionId,"nian_session_id"),r(e.hostProcessIdentity,"host_process_identity"),A(e.capabilities);const i=m(e),s=(e.now??new Date).toISOString(),n=this.state.records[i];if(Object.values(this.state.records).find(g=>g.registryKey!==i&&g.nianSessionId===e.nianSessionId&&g.lifecycleState!=="closed"))throw new o("nian_session_already_registered","This Shennian session is already registered to another native Agent session.");const u=!!(n&&n.hostProcessIdentity!==e.hostProcessIdentity),l={schemaVersion:1,registryKey:i,machineId:e.machineId,runtimeAdapter:e.runtimeAdapter,sourceSessionKey:e.sourceSessionKey,nianSessionId:e.nianSessionId,panelContextKey:e.nianSessionId,hostProcessIdentity:e.hostProcessIdentity,registrationEpoch:n?n.registrationEpoch+(u?1:0):1,lifecycleState:"active",capabilities:{...e.capabilities},binding:n?.binding??null,registeredAt:n?.registeredAt??s,lastSeenAt:s,updatedAt:s};return this.state.records[i]=l,this.persist(),d(l)}getBySource(e){const i=this.state.records[m(e)];return i?d(i):null}getByNianSessionId(e){r(e,"nian_session_id");const i=Object.values(this.state.records).find(s=>s.nianSessionId===e&&s.lifecycleState!=="closed");return i?d(i):null}getByRegistryKey(e){if(!/^[a-f0-9]{64}$/.test(e))throw new o("invalid_registry_key","Invalid Room session registry key.");const i=this.state.records[e];return i?d(i):null}list(){return Object.values(this.state.records).sort((e,i)=>e.registeredAt.localeCompare(i.registeredAt)).map(d)}setBinding(e){const i=this.requireRecord(e.registryKey);for(const[n,a]of Object.entries({binding_id:e.bindingId,room_id:e.roomId,agent_identity_id:e.agentIdentityId}))r(a,n);if(!_.has(e.status))throw new o("invalid_binding_status","Invalid binding status.");if(e.status==="pending_approval"&&e.agentMembershipId!==null||(e.status==="active"||e.status==="paused")&&e.agentMembershipId===null)throw new o("invalid_agent_membership_id","Pending Room bindings cannot claim an Agent membership.");e.agentMembershipId!==null&&r(e.agentMembershipId,"agent_membership_id");const s=e.activationMode??"auto_follow";if(!I.has(s))throw new o("invalid_activation_mode","Invalid activation mode.");if(i.binding&&i.binding.status!=="detached"&&(i.binding.bindingId!==e.bindingId||i.binding.roomId!==e.roomId))throw new o("session_already_bound","An Agent session can have only one active Room binding.");return i.binding={bindingId:e.bindingId,roomId:e.roomId,agentIdentityId:e.agentIdentityId,agentMembershipId:e.agentMembershipId,status:e.status,activationMode:s,lastDeliveredSequence:i.binding?.lastDeliveredSequence??"0",lastActivatedSequence:i.binding?.lastActivatedSequence??"0",activationQueue:i.binding?.activationQueue??[],activeActivation:i.binding?.activeActivation??null,loopBreaker:i.binding?.loopBreaker??{windowStartedAt:null,activationCount:0,pausedUntil:null}},this.touchAndPersist(i,e.now),d(i)}detachBinding(e,i=new Date){const s=this.requireRecord(e);return s.binding&&(s.binding.status="detached",s.binding.activationMode="paused",s.binding.activationQueue=[]),this.touchAndPersist(s,i),d(s)}advanceCursor(e){const i=this.requireBoundRecord(e.registryKey);h(e.sequence);const s=e.cursor==="delivered"?"lastDeliveredSequence":"lastActivatedSequence";if(BigInt(e.sequence)<BigInt(i.binding[s]))throw new o("cursor_regression","Room cursor cannot move backwards.");return i.binding[s]=e.sequence,this.touchAndPersist(i,e.now),d(i)}enqueueActivation(e,i,s=new Date){const n=this.requireBoundRecord(e);v(i);const a=n.binding.activationQueue;if(!a.some(u=>u.causeMessageId===i.causeMessageId)){if(a.length>=p)throw new o("activation_queue_full","Agent activation queue is full.");a.push(d(i))}return this.touchAndPersist(n,s),d(n)}dequeueActivation(e,i,s=new Date){const n=this.requireBoundRecord(e);return n.binding.activationQueue=n.binding.activationQueue.filter(a=>a.causeMessageId!==i),this.touchAndPersist(n,s),d(n)}markActivationDispatching(e,i,s=new Date){const n=this.requireBoundRecord(e),a=n.binding.activationQueue.find(u=>u.causeMessageId===i);if(!a)throw new o("activation_not_found","Agent activation is unavailable.");return n.binding.activeActivation=d(a),n.binding.activationQueue=n.binding.activationQueue.filter(u=>u.causeMessageId!==i),this.touchAndPersist(n,s),d(n)}clearActiveActivation(e,i=new Date){const s=this.requireBoundRecord(e);return s.binding.activeActivation=null,this.touchAndPersist(s,i),d(s)}retryActiveActivation(e){const i=this.requireBoundRecord(e.registryKey),s=i.binding.activeActivation;if(!s)return{queued:!1,attempts:0};const n=e.now??new Date,a={...s,attempts:s.attempts+1};return i.binding.activeActivation=null,a.attempts<e.maxAttempts?(i.binding.activationQueue.some(u=>u.causeMessageId===a.causeMessageId)||i.binding.activationQueue.unshift(a),this.touchAndPersist(i,n),{queued:!0,attempts:a.attempts}):(i.binding.loopBreaker.pausedUntil=new Date(n.getTime()+e.pauseMs).toISOString(),this.touchAndPersist(i,n),{queued:!1,attempts:a.attempts})}claimActivation(e){const i=this.requireBoundRecord(e.registryKey),s=e.now??new Date,n=i.binding.loopBreaker;return n.pausedUntil&&Date.parse(n.pausedUntil)>s.getTime()?{allowed:!1,pausedUntil:n.pausedUntil,newlyPaused:!1}:((!n.windowStartedAt||s.getTime()-Date.parse(n.windowStartedAt)>=e.windowMs)&&(n.windowStartedAt=s.toISOString(),n.activationCount=0,n.pausedUntil=null),n.activationCount>=e.maxActivations?(n.pausedUntil=new Date(s.getTime()+e.pauseMs).toISOString(),this.touchAndPersist(i,s),{allowed:!1,pausedUntil:n.pausedUntil,newlyPaused:!0}):(n.activationCount+=1,this.touchAndPersist(i,s),{allowed:!0,pausedUntil:null}))}updateLifecycle(e,i,s=new Date){const n=this.requireRecord(e);return n.lifecycleState=i,i==="closed"&&n.binding&&(n.binding.status="detached",n.binding.activationMode="paused",n.binding.activationQueue=[]),this.touchAndPersist(n,s),d(n)}async runExclusive(e,i){this.requireRecord(e);const s=this.mutexTails.get(e)??Promise.resolve();let n;const a=new Promise(l=>{n=l}),u=s.then(()=>a);this.mutexTails.set(e,u),await s;try{return await i()}finally{n(),this.mutexTails.get(e)===u&&this.mutexTails.delete(e)}}requireRecord(e){const i=this.state.records[e];if(!i)throw new o("session_registration_not_found","Agent session is not registered.");return i}requireBoundRecord(e){const i=this.requireRecord(e);if(!i.binding||i.binding.status!=="active"&&i.binding.status!=="paused")throw new o("session_not_bound","Agent session has no active Room binding.");return i}touchAndPersist(e,i=new Date){e.updatedAt=i.toISOString(),this.persist()}load(){try{const e=c.lstatSync(this.filePath);if(!e.isFile()||e.isSymbolicLink())throw new o("unsafe_session_registry","Room session registry is not a regular file.");process.platform!=="win32"&&(e.mode&63)!==0&&c.chmodSync(this.filePath,384);const i=JSON.parse(c.readFileSync(this.filePath,"utf8"));return q(i)}catch(e){if(B(e))return{schemaVersion:1,records:{}};throw e instanceof o?e:new o("corrupt_session_registry","Room Agent session registry is corrupt.")}}persist(){const e=b.dirname(this.filePath);c.mkdirSync(e,{recursive:!0,mode:448}),process.platform!=="win32"&&c.chmodSync(e,448);const i=`${this.filePath}.tmp-${process.pid}-${y.randomBytes(6).toString("hex")}`;try{if(c.writeFileSync(i,`${JSON.stringify(this.state,null,2)}
2
- `,{encoding:"utf8",mode:384,flag:"wx"}),process.platform!=="win32"&&c.chmodSync(i,384),process.platform==="win32"&&c.existsSync(this.filePath)){const s=c.lstatSync(this.filePath);if(!s.isFile()||s.isSymbolicLink())throw new o("unsafe_session_registry","Refusing to replace an unsafe Room session registry.");c.unlinkSync(this.filePath)}c.renameSync(i,this.filePath),process.platform!=="win32"&&c.chmodSync(this.filePath,384)}finally{try{c.unlinkSync(i)}catch{}}}}function m(t){return r(t.machineId,"machine_id"),f(t.runtimeAdapter),w(t.sourceSessionKey),y.createHash("sha256").update(`${t.machineId}\0${t.runtimeAdapter}\0${t.sourceSessionKey}`,"utf8").digest("hex")}function q(t){if(!t||typeof t!="object"||t.schemaVersion!==1)throw new o("corrupt_session_registry","Unsupported Room session registry.");const e=t.records;if(!e||typeof e!="object"||Array.isArray(e))throw new o("corrupt_session_registry","Room session records are invalid.");const i={};for(const[s,n]of Object.entries(e)){if(x(n),s!==n.registryKey||s!==m(n))throw new o("corrupt_session_registry","Room session registry key mismatch.");i[s]={...n,binding:n.binding?{...n.binding,activeActivation:n.binding.activeActivation??null}:null}}return{schemaVersion:1,records:i}}function x(t){if(!t||t.schemaVersion!==1)throw new o("corrupt_session_registry","Invalid registration.");if(r(t.machineId,"machine_id"),f(t.runtimeAdapter),w(t.sourceSessionKey),r(t.nianSessionId,"nian_session_id"),r(t.hostProcessIdentity,"host_process_identity"),t.panelContextKey!==t.nianSessionId)throw new o("corrupt_session_registry","Invalid panel context.");if(!Number.isInteger(t.registrationEpoch)||t.registrationEpoch<1)throw new o("corrupt_session_registry","Invalid registration epoch.");A(t.capabilities),t.binding&&M(t.binding)}function M(t){if(r(t.bindingId,"binding_id"),r(t.roomId,"room_id"),r(t.agentIdentityId,"agent_identity_id"),!_.has(t.status))throw new o("corrupt_session_registry","Invalid binding status.");if(t.status==="pending_approval"&&t.agentMembershipId!==null||(t.status==="active"||t.status==="paused")&&t.agentMembershipId===null)throw new o("corrupt_session_registry","Invalid Agent membership.");if(t.agentMembershipId!==null&&r(t.agentMembershipId,"agent_membership_id"),!I.has(t.activationMode))throw new o("corrupt_session_registry","Invalid activation mode.");if(h(t.lastDeliveredSequence),h(t.lastActivatedSequence),!Array.isArray(t.activationQueue)||t.activationQueue.length>p)throw new o("corrupt_session_registry","Invalid activation queue.");t.activationQueue.forEach(v),t.activeActivation!=null&&v(t.activeActivation)}function v(t){if(r(t.causeMessageId,"cause_message_id"),r(t.rootCauseMessageId,"root_cause_message_id"),h(t.sequence),!Number.isInteger(t.hopCount)||t.hopCount<0||t.hopCount>32)throw new o("invalid_hop_count","Invalid Agent activation hop count.");if(!Number.isInteger(t.attempts)||t.attempts<0||t.attempts>100)throw new o("invalid_activation_attempts","Invalid Agent activation attempts.");if(!Number.isFinite(new Date(t.enqueuedAt).getTime()))throw new o("invalid_activation_time","Invalid Agent activation time.");if(t.deliveryText!==void 0&&(typeof t.deliveryText!="string"||!t.deliveryText.trim()||t.deliveryText.length>24e3))throw new o("invalid_activation_text","Invalid Agent activation text.");if(t.systemPrompt!==void 0&&(typeof t.systemPrompt!="string"||!t.systemPrompt.trim()||t.systemPrompt.length>24e3))throw new o("invalid_activation_prompt","Invalid Agent activation prompt.")}function A(t){if(!t||["canIdentifySession","canBindAutomatically","canOpenEmbeddedRoomPage","canResumeIdleSession","canActivateWhileHostOpen"].some(i=>typeof t[i]!="boolean"))throw new o("invalid_session_capabilities","Invalid Agent session capabilities.")}function f(t){if(!R.has(t))throw new o("invalid_runtime_adapter","Unsupported Room runtime adapter.")}function w(t){if(!t||t.length>1024||/[\0\r\n]/.test(t))throw new o("invalid_source_session_key","Invalid native Agent session key.")}function r(t,e){if(!P.test(t))throw new o(`invalid_${e}`,`Invalid ${e}.`)}function h(t){if(!/^(0|[1-9]\d{0,19})$/.test(t))throw new o("invalid_room_sequence","Invalid Room sequence.")}function d(t){return structuredClone(t)}function B(t){return typeof t=="object"&&t!==null&&"code"in t&&t.code==="ENOENT"}export{C as RoomSessionRegistry,o as RoomSessionRegistryError,m as buildRoomSessionRegistryKey};
1
+ import w from"node:crypto";import u from"node:fs";import x from"node:path";import{resolveShennianPath as P}from"../config/index.js";const _=500,p=20,q=/^[A-Za-z0-9_.:@/-]{1,512}$/,R=new Set(["codex","claude_code","workbuddy"]),I=new Set(["pending_approval","active","paused","detached"]),A=new Set(["auto_follow","mention_only","paused"]);class o extends Error{code;constructor(e,i){super(i),this.code=e,this.name="RoomSessionRegistryError"}}class N{filePath;state;mutexTails=new Map;constructor(e=P("runtime","room-session-registry.json")){this.filePath=e,this.state=this.load()}register(e){c(e.machineId,"machine_id"),f(e.runtimeAdapter),y(e.sourceSessionKey),c(e.nianSessionId,"nian_session_id"),c(e.hostProcessIdentity,"host_process_identity"),S(e.capabilities);const i=m(e),s=(e.now??new Date).toISOString(),n=this.state.records[i];if(Object.values(this.state.records).find(g=>g.registryKey!==i&&g.nianSessionId===e.nianSessionId&&g.lifecycleState!=="closed"))throw new o("nian_session_already_registered","This Shennian session is already registered to another native Agent session.");const r=!!(n&&n.hostProcessIdentity!==e.hostProcessIdentity),l={schemaVersion:1,registryKey:i,machineId:e.machineId,runtimeAdapter:e.runtimeAdapter,sourceSessionKey:e.sourceSessionKey,nianSessionId:e.nianSessionId,panelContextKey:e.nianSessionId,hostProcessIdentity:e.hostProcessIdentity,registrationEpoch:n?n.registrationEpoch+(r?1:0):1,lifecycleState:"active",capabilities:{...e.capabilities},binding:n?.binding??null,registeredAt:n?.registeredAt??s,lastSeenAt:s,updatedAt:s};return this.state.records[i]=l,this.persist(),d(l)}getBySource(e){const i=this.state.records[m(e)];return i?d(i):null}getByNianSessionId(e){c(e,"nian_session_id");const i=Object.values(this.state.records).find(s=>s.nianSessionId===e&&s.lifecycleState!=="closed");return i?d(i):null}getByRegistryKey(e){if(!/^[a-f0-9]{64}$/.test(e))throw new o("invalid_registry_key","Invalid Room session registry key.");const i=this.state.records[e];return i?d(i):null}list(){return Object.values(this.state.records).sort((e,i)=>e.registeredAt.localeCompare(i.registeredAt)).map(d)}setBinding(e){const i=this.requireRecord(e.registryKey);for(const[a,r]of Object.entries({binding_id:e.bindingId,room_id:e.roomId,agent_identity_id:e.agentIdentityId}))c(r,a);if(!I.has(e.status))throw new o("invalid_binding_status","Invalid binding status.");if(e.status==="pending_approval"&&e.agentMembershipId!==null||(e.status==="active"||e.status==="paused")&&e.agentMembershipId===null)throw new o("invalid_agent_membership_id","Pending Room bindings cannot claim an Agent membership.");e.agentMembershipId!==null&&c(e.agentMembershipId,"agent_membership_id");const s=e.activationMode??"auto_follow";if(!A.has(s))throw new o("invalid_activation_mode","Invalid activation mode.");if(i.binding&&i.binding.status!=="detached"&&(i.binding.bindingId!==e.bindingId||i.binding.roomId!==e.roomId))throw new o("session_already_bound","An Agent session can have only one active Room binding.");const n=i.binding?.activationMode;return i.binding={bindingId:e.bindingId,roomId:e.roomId,agentIdentityId:e.agentIdentityId,agentMembershipId:e.agentMembershipId,status:e.status,activationMode:s,lastDeliveredSequence:i.binding?.lastDeliveredSequence??"0",lastActivatedSequence:i.binding?.lastActivatedSequence??"0",activationQueue:i.binding?.activationQueue??[],activeActivation:i.binding?.activeActivation??null,mentionContext:n==="mention_only"&&s==="mention_only"?i.binding?.mentionContext??[]:[],loopBreaker:i.binding?.loopBreaker??{windowStartedAt:null,activationCount:0,pausedUntil:null}},this.touchAndPersist(i,e.now),d(i)}detachBinding(e,i=new Date){const s=this.requireRecord(e);return s.binding&&(s.binding.status="detached",s.binding.activationMode="paused",s.binding.activationQueue=[],s.binding.mentionContext=[]),this.touchAndPersist(s,i),d(s)}advanceCursor(e){const i=this.requireBoundRecord(e.registryKey);h(e.sequence);const s=e.cursor==="delivered"?"lastDeliveredSequence":"lastActivatedSequence";if(BigInt(e.sequence)<BigInt(i.binding[s]))throw new o("cursor_regression","Room cursor cannot move backwards.");return i.binding[s]=e.sequence,this.touchAndPersist(i,e.now),d(i)}enqueueActivation(e,i,s=new Date,n=!1){const a=this.requireBoundRecord(e);v(i);const r=a.binding.activationQueue;if(!r.some(l=>l.causeMessageId===i.causeMessageId)){if(r.length>=_)throw new o("activation_queue_full","Agent activation queue is full.");r.push(d(i))}return n&&(a.binding.mentionContext=[]),this.touchAndPersist(a,s),d(a)}appendMentionContext(e,i,s=new Date){const n=this.requireBoundRecord(e);b(i);const a=n.binding.mentionContext??[];return a.some(r=>r.sequence===i.sequence)||(a.push(d(i)),n.binding.mentionContext=a.slice(-p)),this.touchAndPersist(n,s),d(n)}dequeueActivation(e,i,s=new Date){const n=this.requireBoundRecord(e);return n.binding.activationQueue=n.binding.activationQueue.filter(a=>a.causeMessageId!==i),this.touchAndPersist(n,s),d(n)}markActivationDispatching(e,i,s=new Date){const n=this.requireBoundRecord(e),a=n.binding.activationQueue.find(r=>r.causeMessageId===i);if(!a)throw new o("activation_not_found","Agent activation is unavailable.");return n.binding.activeActivation=d(a),n.binding.activationQueue=n.binding.activationQueue.filter(r=>r.causeMessageId!==i),this.touchAndPersist(n,s),d(n)}clearActiveActivation(e,i=new Date){const s=this.requireBoundRecord(e);return s.binding.activeActivation=null,this.touchAndPersist(s,i),d(s)}retryActiveActivation(e){const i=this.requireBoundRecord(e.registryKey),s=i.binding.activeActivation;if(!s)return{queued:!1,attempts:0};const n=e.now??new Date,a={...s,attempts:s.attempts+1};return i.binding.activeActivation=null,a.attempts<e.maxAttempts?(i.binding.activationQueue.some(r=>r.causeMessageId===a.causeMessageId)||i.binding.activationQueue.unshift(a),this.touchAndPersist(i,n),{queued:!0,attempts:a.attempts}):(i.binding.loopBreaker.pausedUntil=new Date(n.getTime()+e.pauseMs).toISOString(),this.touchAndPersist(i,n),{queued:!1,attempts:a.attempts})}claimActivation(e){const i=this.requireBoundRecord(e.registryKey),s=e.now??new Date,n=i.binding.loopBreaker;return n.pausedUntil&&Date.parse(n.pausedUntil)>s.getTime()?{allowed:!1,pausedUntil:n.pausedUntil,newlyPaused:!1}:((!n.windowStartedAt||s.getTime()-Date.parse(n.windowStartedAt)>=e.windowMs)&&(n.windowStartedAt=s.toISOString(),n.activationCount=0,n.pausedUntil=null),n.activationCount>=e.maxActivations?(n.pausedUntil=new Date(s.getTime()+e.pauseMs).toISOString(),this.touchAndPersist(i,s),{allowed:!1,pausedUntil:n.pausedUntil,newlyPaused:!0}):(n.activationCount+=1,this.touchAndPersist(i,s),{allowed:!0,pausedUntil:null}))}updateLifecycle(e,i,s=new Date){const n=this.requireRecord(e);return n.lifecycleState=i,i==="closed"&&n.binding&&(n.binding.status="detached",n.binding.activationMode="paused",n.binding.activationQueue=[],n.binding.mentionContext=[]),this.touchAndPersist(n,s),d(n)}async runExclusive(e,i){this.requireRecord(e);const s=this.mutexTails.get(e)??Promise.resolve();let n;const a=new Promise(l=>{n=l}),r=s.then(()=>a);this.mutexTails.set(e,r),await s;try{return await i()}finally{n(),this.mutexTails.get(e)===r&&this.mutexTails.delete(e)}}requireRecord(e){const i=this.state.records[e];if(!i)throw new o("session_registration_not_found","Agent session is not registered.");return i}requireBoundRecord(e){const i=this.requireRecord(e);if(!i.binding||i.binding.status!=="active"&&i.binding.status!=="paused")throw new o("session_not_bound","Agent session has no active Room binding.");return i}touchAndPersist(e,i=new Date){e.updatedAt=i.toISOString(),this.persist()}load(){try{const e=u.lstatSync(this.filePath);if(!e.isFile()||e.isSymbolicLink())throw new o("unsafe_session_registry","Room session registry is not a regular file.");process.platform!=="win32"&&(e.mode&63)!==0&&u.chmodSync(this.filePath,384);const i=JSON.parse(u.readFileSync(this.filePath,"utf8"));return C(i)}catch(e){if(B(e))return{schemaVersion:1,records:{}};throw e instanceof o?e:new o("corrupt_session_registry","Room Agent session registry is corrupt.")}}persist(){const e=x.dirname(this.filePath);u.mkdirSync(e,{recursive:!0,mode:448}),process.platform!=="win32"&&u.chmodSync(e,448);const i=`${this.filePath}.tmp-${process.pid}-${w.randomBytes(6).toString("hex")}`;try{if(u.writeFileSync(i,`${JSON.stringify(this.state,null,2)}
2
+ `,{encoding:"utf8",mode:384,flag:"wx"}),process.platform!=="win32"&&u.chmodSync(i,384),process.platform==="win32"&&u.existsSync(this.filePath)){const s=u.lstatSync(this.filePath);if(!s.isFile()||s.isSymbolicLink())throw new o("unsafe_session_registry","Refusing to replace an unsafe Room session registry.");u.unlinkSync(this.filePath)}u.renameSync(i,this.filePath),process.platform!=="win32"&&u.chmodSync(this.filePath,384)}finally{try{u.unlinkSync(i)}catch{}}}}function m(t){return c(t.machineId,"machine_id"),f(t.runtimeAdapter),y(t.sourceSessionKey),w.createHash("sha256").update(`${t.machineId}\0${t.runtimeAdapter}\0${t.sourceSessionKey}`,"utf8").digest("hex")}function C(t){if(!t||typeof t!="object"||t.schemaVersion!==1)throw new o("corrupt_session_registry","Unsupported Room session registry.");const e=t.records;if(!e||typeof e!="object"||Array.isArray(e))throw new o("corrupt_session_registry","Room session records are invalid.");const i={};for(const[s,n]of Object.entries(e)){if(M(n),s!==n.registryKey||s!==m(n))throw new o("corrupt_session_registry","Room session registry key mismatch.");i[s]={...n,binding:n.binding?{...n.binding,activeActivation:n.binding.activeActivation??null,mentionContext:n.binding.mentionContext??[]}:null}}return{schemaVersion:1,records:i}}function M(t){if(!t||t.schemaVersion!==1)throw new o("corrupt_session_registry","Invalid registration.");if(c(t.machineId,"machine_id"),f(t.runtimeAdapter),y(t.sourceSessionKey),c(t.nianSessionId,"nian_session_id"),c(t.hostProcessIdentity,"host_process_identity"),t.panelContextKey!==t.nianSessionId)throw new o("corrupt_session_registry","Invalid panel context.");if(!Number.isInteger(t.registrationEpoch)||t.registrationEpoch<1)throw new o("corrupt_session_registry","Invalid registration epoch.");S(t.capabilities),t.binding&&T(t.binding)}function T(t){if(c(t.bindingId,"binding_id"),c(t.roomId,"room_id"),c(t.agentIdentityId,"agent_identity_id"),!I.has(t.status))throw new o("corrupt_session_registry","Invalid binding status.");if(t.status==="pending_approval"&&t.agentMembershipId!==null||(t.status==="active"||t.status==="paused")&&t.agentMembershipId===null)throw new o("corrupt_session_registry","Invalid Agent membership.");if(t.agentMembershipId!==null&&c(t.agentMembershipId,"agent_membership_id"),!A.has(t.activationMode))throw new o("corrupt_session_registry","Invalid activation mode.");if(h(t.lastDeliveredSequence),h(t.lastActivatedSequence),!Array.isArray(t.activationQueue)||t.activationQueue.length>_)throw new o("corrupt_session_registry","Invalid activation queue.");if(t.activationQueue.forEach(v),t.activeActivation!=null&&v(t.activeActivation),t.mentionContext!==void 0&&(!Array.isArray(t.mentionContext)||t.mentionContext.length>p))throw new o("corrupt_session_registry","Invalid mention context.");t.mentionContext?.forEach(b)}function b(t){if(h(t.sequence),typeof t.deliveryText!="string"||!t.deliveryText.trim()||t.deliveryText.length>24e3)throw new o("invalid_mention_context","Invalid mention context.")}function v(t){if(c(t.causeMessageId,"cause_message_id"),c(t.rootCauseMessageId,"root_cause_message_id"),h(t.sequence),!Number.isInteger(t.hopCount)||t.hopCount<0||t.hopCount>32)throw new o("invalid_hop_count","Invalid Agent activation hop count.");if(!Number.isInteger(t.attempts)||t.attempts<0||t.attempts>100)throw new o("invalid_activation_attempts","Invalid Agent activation attempts.");if(!Number.isFinite(new Date(t.enqueuedAt).getTime()))throw new o("invalid_activation_time","Invalid Agent activation time.");if(t.deliveryText!==void 0&&(typeof t.deliveryText!="string"||!t.deliveryText.trim()||t.deliveryText.length>24e3))throw new o("invalid_activation_text","Invalid Agent activation text.");if(t.systemPrompt!==void 0&&(typeof t.systemPrompt!="string"||!t.systemPrompt.trim()||t.systemPrompt.length>24e3))throw new o("invalid_activation_prompt","Invalid Agent activation prompt.")}function S(t){if(!t||["canIdentifySession","canBindAutomatically","canOpenEmbeddedRoomPage","canResumeIdleSession","canActivateWhileHostOpen"].some(i=>typeof t[i]!="boolean"))throw new o("invalid_session_capabilities","Invalid Agent session capabilities.")}function f(t){if(!R.has(t))throw new o("invalid_runtime_adapter","Unsupported Room runtime adapter.")}function y(t){if(!t||t.length>1024||/[\0\r\n]/.test(t))throw new o("invalid_source_session_key","Invalid native Agent session key.")}function c(t,e){if(!q.test(t))throw new o(`invalid_${e}`,`Invalid ${e}.`)}function h(t){if(!/^(0|[1-9]\d{0,19})$/.test(t))throw new o("invalid_room_sequence","Invalid Room sequence.")}function d(t){return structuredClone(t)}function B(t){return typeof t=="object"&&t!==null&&"code"in t&&t.code==="ENOENT"}export{N as RoomSessionRegistry,o as RoomSessionRegistryError,m as buildRoomSessionRegistryKey};
@@ -4,7 +4,7 @@ export declare const SHENNIAN_ROOM_TOOL_NAME = "shennian_room";
4
4
  export declare const SHENNIAN_ROOM_TOOL: {
5
5
  readonly name: "shennian_room";
6
6
  readonly title: "Shennian Room";
7
- readonly description: "Create, join, read, search, send to, configure, or inspect the single Shennian Room bound to this Agent session.";
7
+ readonly description: "Create, join, read, search, send to, configure, or inspect the single Shennian Room bound to this Agent session. Status includes member and Agent descriptions plus the canonical local JSONL mirror path.";
8
8
  readonly inputSchema: {
9
9
  readonly type: "object";
10
10
  readonly additionalProperties: false;
@@ -1 +1 @@
1
- import{normalizeRoomActionParameters as c}from"./room-action-schema.js";const d="shennian_room",l={name:d,title:"Shennian Room",description:"Create, join, read, search, send to, configure, or inspect the single Shennian Room bound to this Agent session.",inputSchema:{type:"object",additionalProperties:!1,required:["action"],properties:{action:{type:"string",enum:["create","join","read","send","mode","status"],description:"The Room action to perform."},name:{type:"string",minLength:1,maxLength:80},agentAlias:{type:"string",minLength:1,maxLength:80},agentDescription:{type:"string",maxLength:1e3},inviteUrl:{type:"string",format:"uri",maxLength:2048},message:{type:"string",maxLength:500},activationMode:{type:"string",enum:["auto","auto_follow","mention","mention_only","paused"]},afterSequence:{type:"string",pattern:"^(0|[1-9]\\d{0,19})$"},limit:{type:"integer",minimum:1,maximum:100},query:{type:"string",minLength:1,maxLength:200},attachmentIds:{type:"array",maxItems:10,uniqueItems:!0,items:{type:"string",minLength:1,maxLength:191}},clientMessageId:{type:"string",minLength:1,maxLength:191},text:{type:"string",minLength:1,maxLength:2e4},files:{type:"array",description:"Up to 10 files inside the current Agent workspace to upload privately with this message.",minItems:1,maxItems:10,items:{type:"string",minLength:1,maxLength:4096}},mentionMembershipIds:{type:"array",maxItems:20,uniqueItems:!0,items:{type:"string",minLength:1,maxLength:191}},replyToMessageId:{type:"string",minLength:1,maxLength:191}}}},u=new Map([["create","room.create"],["join","room.join"],["read","room.read"],["send","room.send"],["mode","room.mode"],["status","room.status"]]);function f(i){(!i||typeof i!="object"||Array.isArray(i))&&g();const t=i,n=typeof t.action=="string"?u.get(t.action):void 0;n||g();const o=t._shennianRegistryKey,r=t._shennianInvocationToken,s=t._shennianAuthorizedActionId,a=Object.keys(t).filter(e=>e.startsWith("_shennian"));if(typeof s=="string"&&/^[A-Za-z0-9_-]{8,128}$/.test(s)&&a.length===1){const e=Object.fromEntries(Object.entries(t).filter(([m])=>m!=="action"&&m!=="_shennianAuthorizedActionId"));return{action:n,actionParameters:c(n,e),authorizedActionId:s}}if(typeof o!="string"||!/^[a-f0-9]{64}$/.test(o)||typeof r!="string"||!/^sni_v1_[A-Za-z0-9_-]{40,80}$/.test(r)||a.some(e=>e!=="_shennianRegistryKey"&&e!=="_shennianInvocationToken"))throw new p("session_context_required","The current Agent session is not connected to Shennian Room yet.");const h=Object.fromEntries(Object.entries(t).filter(([e])=>e!=="action"&&e!=="_shennianRegistryKey"&&e!=="_shennianInvocationToken"));return{action:n,actionParameters:c(n,h),registryKey:o,invocationToken:r}}class p extends Error{code;constructor(t,n){super(n),this.code=t,this.name="RoomToolInputError"}}function g(){throw new p("invalid_tool_input","Invalid Shennian Room tool input.")}export{p as RoomToolInputError,l as SHENNIAN_ROOM_TOOL,d as SHENNIAN_ROOM_TOOL_NAME,f as normalizeRoomToolInput};
1
+ import{normalizeRoomActionParameters as c}from"./room-action-schema.js";const d="shennian_room",l={name:d,title:"Shennian Room",description:"Create, join, read, search, send to, configure, or inspect the single Shennian Room bound to this Agent session. Status includes member and Agent descriptions plus the canonical local JSONL mirror path.",inputSchema:{type:"object",additionalProperties:!1,required:["action"],properties:{action:{type:"string",enum:["create","join","read","send","mode","status"],description:"The Room action to perform."},name:{type:"string",minLength:1,maxLength:80},agentAlias:{type:"string",minLength:1,maxLength:80},agentDescription:{type:"string",maxLength:1e3},inviteUrl:{type:"string",format:"uri",maxLength:2048},message:{type:"string",maxLength:500},activationMode:{type:"string",enum:["auto","auto_follow","mention","mention_only","paused"]},afterSequence:{type:"string",pattern:"^(0|[1-9]\\d{0,19})$"},limit:{type:"integer",minimum:1,maximum:100},query:{type:"string",minLength:1,maxLength:200},attachmentIds:{type:"array",maxItems:10,uniqueItems:!0,items:{type:"string",minLength:1,maxLength:191}},clientMessageId:{type:"string",minLength:1,maxLength:191},text:{type:"string",minLength:1,maxLength:2e4},files:{type:"array",description:"Up to 10 files inside the current Agent workspace to upload privately with this message.",minItems:1,maxItems:10,items:{type:"string",minLength:1,maxLength:4096}},mentionMembershipIds:{type:"array",maxItems:20,uniqueItems:!0,items:{type:"string",minLength:1,maxLength:191}},replyToMessageId:{type:"string",minLength:1,maxLength:191}}}},u=new Map([["create","room.create"],["join","room.join"],["read","room.read"],["send","room.send"],["mode","room.mode"],["status","room.status"]]);function f(i){(!i||typeof i!="object"||Array.isArray(i))&&g();const t=i,n=typeof t.action=="string"?u.get(t.action):void 0;n||g();const o=t._shennianRegistryKey,r=t._shennianInvocationToken,s=t._shennianAuthorizedActionId,a=Object.keys(t).filter(e=>e.startsWith("_shennian"));if(typeof s=="string"&&/^[A-Za-z0-9_-]{8,128}$/.test(s)&&a.length===1){const e=Object.fromEntries(Object.entries(t).filter(([m])=>m!=="action"&&m!=="_shennianAuthorizedActionId"));return{action:n,actionParameters:c(n,e),authorizedActionId:s}}if(typeof o!="string"||!/^[a-f0-9]{64}$/.test(o)||typeof r!="string"||!/^sni_v1_[A-Za-z0-9_-]{40,80}$/.test(r)||a.some(e=>e!=="_shennianRegistryKey"&&e!=="_shennianInvocationToken"))throw new p("session_context_required","The current Agent session is not connected to Shennian Room yet.");const h=Object.fromEntries(Object.entries(t).filter(([e])=>e!=="action"&&e!=="_shennianRegistryKey"&&e!=="_shennianInvocationToken"));return{action:n,actionParameters:c(n,h),registryKey:o,invocationToken:r}}class p extends Error{code;constructor(t,n){super(n),this.code=t,this.name="RoomToolInputError"}}function g(){throw new p("invalid_tool_input","Invalid Shennian Room tool input.")}export{p as RoomToolInputError,l as SHENNIAN_ROOM_TOOL,d as SHENNIAN_ROOM_TOOL_NAME,f as normalizeRoomToolInput};
@@ -1,4 +1,11 @@
1
- import { type ReqFrame } from '@shennian/wire';
1
+ import { type ReqFrame, type AgentType } from '@shennian/wire';
2
2
  import type { SessionManagerRuntime } from '../types.js';
3
+ export declare function sendSessionUpdateEvent(runtime: SessionManagerRuntime, input: {
4
+ sessionId: string;
5
+ agentType: AgentType;
6
+ workDir: string;
7
+ agentSessionId?: string | null;
8
+ modelId?: string;
9
+ }): void;
3
10
  export declare function handleChatSend(runtime: SessionManagerRuntime, req: ReqFrame): Promise<void>;
4
11
  export declare function handleChatAbort(runtime: SessionManagerRuntime, req: ReqFrame): Promise<void>;
@@ -1,2 +1,2 @@
1
1
  import z from"node:os";import{createAgent as J}from"../../agents/adapter.js";import{buildApprovalPendingPayload as K,buildUserMessagePayload as Q}from"@shennian/wire";import{reportLog as S}from"../../log-reporter.js";import{lookupClaudeTranscriptCwd as Y}from"../../native-fusion/parsers.js";import{appendMessage as E,recordSession as B}from"../store.js";import{mergeProjectedSessions as V}from"../projection.js";import{buildManagedAgentEnv as X}from"../../agents/config-status.js";import{materializeRemoteChatAttachments as Z}from"../remote-attachments.js";function ee(t){if(!Array.isArray(t))return;const e=t.map(a=>{if(!a||typeof a!="object")return null;const s=a,l=typeof s.path=="string"?s.path:"",u=typeof s.name=="string"?s.name:"",d=typeof s.mimeType=="string"?s.mimeType:"";if(!l||!u||!d)return null;const c=typeof s.previewData=="string"&&s.previewData.trim()?s.previewData.trim():void 0;return{path:l,name:u,mimeType:d,kind:d.startsWith("image/")?"image":"file",...c?{previewData:c}:{}}}).filter(a=>a!=null);return e.length?e:void 0}function te(t){const e=t.indexOf(`
2
- `),a=e>0?Math.min(e,80):Math.min(t.length,80);return t.slice(0,a)}function ne(t,e,a={}){if(t.state==="tool-call"||t.state==="tool-result"){const s={runId:t.runId,sourceSeq:t.seq};return{state:t.state,runId:t.runId,seq:t.seq,sessionId:e,detailRef:s,...t.name?{name:t.name}:{},...t.source?{source:t.source}:{},...t.agentSessionId?{agentSessionId:t.agentSessionId}:{},...a}}return{...t,sessionId:e,...a}}const ae=3e4;function re(t){return t.state==="heartbeat"?t.runPhase??null:t.state==="tool-call"||t.state==="tool-result"?"tool_running":t.state==="approval-pending"?"waiting_approval":t.state==="delta"?t.thinking?"thinking":"streaming_text":t.state==="init"||t.state==="start"?"thinking":null}function se(t,e){return`Agent send failed: ${e instanceof Error?e.message:String(e)}`}function L(t,e){return t!=="manager"?t:e==="claude"?"claude":"codex"}function O(t,e,a){t.client.sendEvent({type:"event",event:"session.message",payload:{sessionId:e.sessionId,message:e,session:{id:e.sessionId,agentType:a.agentType,agentSessionId:a.agentSessionId??null,modelId:a.modelId??null,workDir:a.workDir,status:"active",externalChannel:null}}})}function oe(t,e){B({sessionId:e.sessionId,agentType:e.agentType,workDir:e.workDir,agentSessionId:e.agentSessionId??null,modelId:e.modelId??null}),t.client.sendEvent({type:"event",event:"session.update",payload:{session:{id:e.sessionId,agentType:e.agentType,agentSessionId:e.agentSessionId??null,modelId:e.modelId??null,workDir:e.workDir,status:"active",externalChannel:null}}})}function Ae(t){if(!t||typeof t!="object")return null;const e=t;return{configured:e.configured===void 0?void 0:!!e.configured,connected:!!e.connected,type:typeof e.type=="string"?e.type:null,channelId:typeof e.channelId=="string"?e.channelId:null,name:typeof e.name=="string"?e.name:null,canReply:e.canReply===void 0||e.canReply===null?null:!!e.canReply,systemPrompt:typeof e.systemPrompt=="string"?e.systemPrompt:null,wechatRpaSource:typeof e.wechatRpaSource=="string"?e.wechatRpaSource:null,wechatRpaGroups:Array.isArray(e.wechatRpaGroups)?e.wechatRpaGroups.map(a=>({name:String(a?.name||"").trim()})).filter(a=>a.name):null,pollIntervalMs:Number.isFinite(e.pollIntervalMs)?Number(e.pollIntervalMs):null,recentLimit:Number.isFinite(e.recentLimit)?Number(e.recentLimit):null,idleSeconds:Number.isFinite(e.idleSeconds)?Number(e.idleSeconds):null,forceForeground:e.forceForeground===void 0||e.forceForeground===null?null:!!e.forceForeground,noRestore:e.noRestore===void 0||e.noRestore===null?null:!!e.noRestore,downloadAttachments:e.downloadAttachments===void 0||e.downloadAttachments===null?null:!!e.downloadAttachments,downloadAttachmentsDir:typeof e.downloadAttachmentsDir=="string"?e.downloadAttachmentsDir:null}}function Re(t){return!!(t?.configured??t?.connected)}function W(t){return X(t)}function H(t,e,a){return{}}function j(t,e,a,s,l,u){t.configure?.({sessionId:e,externalChannel:s??null,env:{...W(a),...H(e,s,l),...u?{SHENNIAN_ROOM_REGISTRY_KEY:u}:{}}})}function Te(t,e,a){return null}function le(t,e,a){if(t!=="claude"||!a)return e;const s=e.trim();return!!s&&s.startsWith("-")&&!s.includes("/")?Y(a)??e:e}function de(t,e,a,s){let l=null;function u(n,r={}){t.client.sendAgentEvent({type:"event",event:"agent",payload:ne(n,e,r),seq:n.seq,id:`agent-evt-${n.runId}-${n.seq}`})}function d(n){n?.heartbeatTimer&&(clearInterval(n.heartbeatTimer),n.heartbeatTimer=null)}function c(n){if(!n.currentRunId||!n.currentRunPhase)return;const r=n.heartbeatSeq++;t.client.sendAgentEvent({type:"event",event:"agent",payload:{state:"heartbeat",sessionId:e,runId:n.currentRunId,seq:r,runPhase:n.currentRunPhase},seq:r,id:`agent-heartbeat-${n.currentRunId}-${r}-${Date.now()}`})}function m(n){!n||n.heartbeatTimer||(n.heartbeatTimer=setInterval(()=>{c(n)},ae),n.heartbeatTimer.unref?.())}function I(n){const r=n?.pendingTextEvent;!n||!r||!r.text||(u({state:"delta",runId:r.runId,seq:r.seq,text:r.text,thinking:r.thinking||void 0}),n.pendingTextEvent=null)}s.on("agentEvent",n=>{const r=t.sessions.get(e),A=re(n),R=n.state==="final"||n.state==="error"||n.state==="aborted";r&&(r.nextEventSeq=n.seq+1,R||(r.currentRunId=n.runId),!R&&A&&(r.currentRunPhase=A,m(r)),n.agentSessionId&&(r.agentSessionId=n.agentSessionId)),t.managerRuntime?.noteAgentEvent(e,n),n.state!=="delta"&&S({level:"info",sessionId:e,wsEvent:`agent.${n.state}`,wsDirection:"out",metadata:{runId:n.runId,seq:n.seq,agentType:a}}),n.state==="delta"&&n.text&&!n.thinking?E(e,{id:`agent-${n.runId}-${n.seq}`,sessionId:e,role:"agent",ts:Date.now(),payload:n.text}):n.state==="tool-call"||n.state==="tool-result"?E(e,{id:`agent-${n.runId}-${n.seq}`,sessionId:e,role:"agent",ts:Date.now(),payload:JSON.stringify({v:1,type:n.state==="tool-call"?"tool_use":"tool_result",name:n.name,status:n.state==="tool-call"?"running":"completed",detailRef:{runId:n.runId,sourceSeq:n.seq},args:n.args,result:n.result})}):n.state==="approval-pending"?E(e,{id:`agent-${n.runId||"run"}-${n.seq}`,sessionId:e,role:"agent",ts:Date.now(),payload:K(n.approval)}):(n.state==="error"||n.state==="aborted")&&n.message&&E(e,{id:`agent-${n.runId||"run"}-${n.seq}`,sessionId:e,role:"agent",ts:Date.now(),payload:n.message});const y=`${e}:${n.runId}`;if(n.state==="delta"&&!n.thinking&&n.text&&t.runTextAcc.set(y,(t.runTextAcc.get(y)??"")+n.text),n.agentSessionId&&n.agentSessionId!==l&&(l=n.agentSessionId,t.nativeFusion?.noteManagedSourceSession(e,L(a,n.source),n.agentSessionId),r&&B({sessionId:e,agentType:a,workDir:r.workDir,agentSessionId:n.agentSessionId}),t.client.sendEvent({type:"event",event:"session.update",payload:{session:{id:e,agentType:a,agentSessionId:n.agentSessionId}}})),n.state==="delta"){const h=n.text??"";if(!h)return;const b=!!n.thinking;r?.pendingTextEvent&&(r.pendingTextEvent.runId!==n.runId||r.pendingTextEvent.thinking!==b)&&I(r),r&&!r.pendingTextEvent&&(r.pendingTextEvent={runId:n.runId,seq:n.seq,text:"",thinking:b}),r?.pendingTextEvent&&(r.pendingTextEvent.text+=h,r.pendingTextEvent.seq=n.seq);return}let x={};if(n.state==="final"){I(r);const h=t.runTextAcc.get(y)??"";h&&(x={messageSummary:te(h)}),t.runTextAcc.delete(y)}else n.state==="error"||n.state==="aborted"?(I(r),t.runTextAcc.delete(y)):(n.state==="tool-call"||n.state==="tool-result"||n.state==="approval-pending")&&I(r);R&&r?.currentRunId===n.runId&&(r.currentRunId=null,r.currentRunPhase=null,r.nextEventSeq=0,d(r),t.chatQueue?.noteTerminal(e)),u(n,x)}),s.on("error",n=>{console.error(`[chat.send] adapter error sessionId=${e} agentType=${a}: ${n.message}`),t.sessions.delete(e),t.chatQueue?.noteTerminal(e),t.client.sendEvent({type:"event",event:"agent",payload:{state:"error",sessionId:e,message:n.message,runId:"",seq:0}})})}function ie(t,e){if(t.processedReqIds.add(e),t.processedReqIds.size>1e3){const a=t.processedReqIds.values().next().value;t.processedReqIds.delete(a)}}async function M(t){t.heartbeatTimer&&(clearInterval(t.heartbeatTimer),t.heartbeatTimer=null),t.adapter.removeAllListeners(),await t.adapter.stop().catch(()=>{})}function G(t,e,a,s,l,u){return u?.trim()?t.send(e,a,s,l,u):l?.length?t.send(e,a,s,l):s?t.send(e,a,s):t.send(e,a)}async function ce(t,e,a,s,l,u,d){t.evictIdleSessions();const c=J(a);if(!c)throw new Error(`Unsupported agent: ${a}`);j(c,e,a,u,d),await c.start(e,s,l);const m={adapter:c,workDir:s,agentType:a,agentSessionId:l??null,lastActiveAt:Date.now(),currentRunId:null,currentRunPhase:null,nextEventSeq:0,heartbeatSeq:0,heartbeatTimer:null,pendingTextEvent:null,externalChannel:u??null,externalReplyTarget:d??null,externalChannelEnv:{...W(a),...H(e,u,d)}};return t.sessions.set(e,m),de(t,e,a,c),m}function ue(t,e){const a=t.sessions.get(e),s=a?.currentRunId;if(!a||!s)return;const l=a.nextEventSeq;t.runTextAcc.delete(`${e}:${s}`),a.pendingTextEvent=null,a.currentRunId=null,a.currentRunPhase=null,a.nextEventSeq=0,a.heartbeatTimer&&(clearInterval(a.heartbeatTimer),a.heartbeatTimer=null),t.client.sendAgentEvent({type:"event",event:"agent",payload:{state:"aborted",sessionId:e,runId:s,seq:l},seq:l,id:`agent-evt-${s}-${l}`}),t.chatQueue?.noteTerminal(e)}async function xe(t,e){if(t.processedReqIds.has(e.id)){t.client.sendRes({type:"res",id:e.id,ok:!0});return}ie(t,e.id);const{sessionId:a,text:s,agentType:l,workDir:u,agentSessionId:d,modelId:c,systemPrompt:m,managerDefaultWorkerAgentType:I,managerDefaultWorkerModelId:n,reasoningEffort:r,clientMessageId:A,sessionListProjection:R,waitForDispatch:y,responseId:x,roomContextRegistryKey:h,suppressExternalOwnerEcho:b}=e.params,T=x||e.id;V(R);const $=null,_="";if(!a||!s){t.processedReqIds.delete(e.id),t.client.sendRes({type:"res",id:T,ok:!1,error:"sessionId and text are required"});return}const g=l;g==="manager"&&t.managerRuntime?.setManagerWorkerDefaults(a,I??null,n??null);const q=(g==="claude"||g==="codex"||g==="workbuddy")&&typeof r=="string"&&r.trim()?r.trim():void 0,w=t.resolvePath(le(g,u||z.homedir(),d)||z.homedir()),D=w,P=ee(e.params.attachments),f=P?.length?await Z({text:s,attachments:P,workDir:w}):{text:s,attachments:P,localized:!1};let o=t.sessions.get(a);if(o){if(o.lastActiveAt=Date.now(),o.agentType!==g||o.workDir!==w||JSON.stringify(o.externalChannel??null)!==JSON.stringify($??null)){t.sessions.delete(a);try{await M(o)}catch{t.processedReqIds.delete(e.id)}o=void 0}else if(d&&o.agentSessionId!==d)try{await o.adapter.resume(d),o.agentSessionId=d}catch{t.sessions.delete(a);try{await M(o)}catch{t.processedReqIds.delete(e.id)}o=void 0}}if(!o)try{o=await ce(t,a,g,w,d,$,_)}catch(i){const p=i instanceof Error&&i.message.startsWith("Unsupported agent:")?i.message:`Failed to start ${l}: ${i instanceof Error?i.message:String(i)}`;console.error(`[chat.send] start failed reqId=${e.id} sessionId=${a} agentType=${l} workDir=${w} agentSessionId=${d??""}: ${p}`),t.client.sendEvent({type:"event",event:"agent",payload:{state:"error",sessionId:a,message:p,runId:"",seq:0}}),t.processedReqIds.delete(e.id),t.client.sendRes({type:"res",id:T,ok:!1,error:p});return}h&&/^[a-f0-9]{64}$/.test(h)&&j(o.adapter,a,g,$,_,h);const C={id:A??`user-${e.id}`,sessionId:a,role:"user",ts:Date.now(),payload:Q(f.text,f.attachments)};S({level:"info",sessionId:a,wsEvent:"chat.send.start",metadata:{reqId:e.id,agentType:g,modelId:c,reasoningEffort:q}});const F=i=>{oe(t,{sessionId:a,agentType:g,workDir:D,agentSessionId:o.agentSessionId??d??null,modelId:c}),o.currentRunId||(o.nextEventSeq=0),t.nativeFusion?.registerManagedSend({sessionId:a,agentType:g,sourceAgentType:L(g,c),canonicalMessageId:A??null,sourceSessionKey:o.agentSessionId??d??null,text:f.text,managedEchoPolicy:i?.deliveryMode==="external_owner_queue"&&!b?"import_following":"suppress_following"}),E(a,C),O(t,C,{agentType:g,workDir:D,agentSessionId:o.agentSessionId??d??null,modelId:c})},N=async(i,p)=>{const k=se(g,i);console.error(`[chat.send] send failed reqId=${e.id} sessionId=${a} agentType=${l} workDir=${w} agentSessionId=${o.agentSessionId??d??""}: ${k}`),t.sessions.delete(a);try{await M(o)}catch{}if(t.client.sendEvent({type:"event",event:"agent",payload:{state:"error",sessionId:a,message:k,runId:"",seq:0}}),!p){const v={id:`agent-error-${e.id}-${Date.now()}`,sessionId:a,role:"agent",ts:Date.now(),payload:k};E(a,v),O(t,v,{agentType:g,workDir:D,agentSessionId:o.agentSessionId??d??null,modelId:c})}p&&(t.processedReqIds.delete(e.id),t.client.sendRes({type:"res",id:T,ok:!1,error:k}))};if(y){let i;try{const p=f.attachments;i=await G(o.adapter,f.text,c,q,p,m),S({level:"info",sessionId:a,wsEvent:"chat.send.done",metadata:{reqId:e.id}})}catch(p){await N(p,!0);return}F(i??void 0),t.client.sendRes({type:"res",id:T,ok:!0,...f.localized||i?.deliveryMode==="external_owner_queue"?{payload:{...f.localized?{localizedAttachments:!0}:{},...i?.deliveryMode==="external_owner_queue"?{queued:!0,deliveryMode:i.deliveryMode,queuedSubmissionId:i.queuedSubmissionId}:{}}}:{}}),S({level:"info",sessionId:a,wsEvent:"chat.send.res",metadata:{reqId:e.id,ok:!0}});return}F(),t.client.sendRes({type:"res",id:T,ok:!0,...f.localized?{payload:{localizedAttachments:!0}}:{}}),S({level:"info",sessionId:a,wsEvent:"chat.send.res",metadata:{reqId:e.id,ok:!0}});const U=f.attachments;G(o.adapter,f.text,c,q,U,m).then(()=>{S({level:"info",sessionId:a,wsEvent:"chat.send.done",metadata:{reqId:e.id}})}).catch(i=>{N(i,!1)})}async function be(t,e){const{sessionId:a}=e.params,s=t.sessions.get(a);if(s){try{await s.adapter.stop()}catch{}ue(t,a),t.activityPublisher?.publish(a,null)}t.client.sendRes({type:"res",id:e.id,ok:!0})}export{be as handleChatAbort,xe as handleChatSend};
2
+ `),a=e>0?Math.min(e,80):Math.min(t.length,80);return t.slice(0,a)}function ne(t,e,a={}){if(t.state==="tool-call"||t.state==="tool-result"){const s={runId:t.runId,sourceSeq:t.seq};return{state:t.state,runId:t.runId,seq:t.seq,sessionId:e,detailRef:s,...t.name?{name:t.name}:{},...t.source?{source:t.source}:{},...t.agentSessionId?{agentSessionId:t.agentSessionId}:{},...a}}return{...t,sessionId:e,...a}}const ae=3e4;function re(t){return t.state==="heartbeat"?t.runPhase??null:t.state==="tool-call"||t.state==="tool-result"?"tool_running":t.state==="approval-pending"?"waiting_approval":t.state==="delta"?t.thinking?"thinking":"streaming_text":t.state==="init"||t.state==="start"?"thinking":null}function se(t,e){return`Agent send failed: ${e instanceof Error?e.message:String(e)}`}function L(t,e){return t!=="manager"?t:e==="claude"?"claude":"codex"}function O(t,e,a){t.client.sendEvent({type:"event",event:"session.message",payload:{sessionId:e.sessionId,message:e,session:{id:e.sessionId,agentType:a.agentType,agentSessionId:a.agentSessionId??null,modelId:a.modelId??null,workDir:a.workDir,status:"active",externalChannel:null}}})}function oe(t,e){B({sessionId:e.sessionId,agentType:e.agentType,workDir:e.workDir,agentSessionId:e.agentSessionId??null,modelId:e.modelId??null}),t.client.sendEvent({type:"event",event:"session.update",payload:{session:{id:e.sessionId,agentType:e.agentType,agentSessionId:e.agentSessionId??null,modelId:e.modelId??null,workDir:e.workDir,status:"active",externalChannel:null}}})}function Ae(t){if(!t||typeof t!="object")return null;const e=t;return{configured:e.configured===void 0?void 0:!!e.configured,connected:!!e.connected,type:typeof e.type=="string"?e.type:null,channelId:typeof e.channelId=="string"?e.channelId:null,name:typeof e.name=="string"?e.name:null,canReply:e.canReply===void 0||e.canReply===null?null:!!e.canReply,systemPrompt:typeof e.systemPrompt=="string"?e.systemPrompt:null,wechatRpaSource:typeof e.wechatRpaSource=="string"?e.wechatRpaSource:null,wechatRpaGroups:Array.isArray(e.wechatRpaGroups)?e.wechatRpaGroups.map(a=>({name:String(a?.name||"").trim()})).filter(a=>a.name):null,pollIntervalMs:Number.isFinite(e.pollIntervalMs)?Number(e.pollIntervalMs):null,recentLimit:Number.isFinite(e.recentLimit)?Number(e.recentLimit):null,idleSeconds:Number.isFinite(e.idleSeconds)?Number(e.idleSeconds):null,forceForeground:e.forceForeground===void 0||e.forceForeground===null?null:!!e.forceForeground,noRestore:e.noRestore===void 0||e.noRestore===null?null:!!e.noRestore,downloadAttachments:e.downloadAttachments===void 0||e.downloadAttachments===null?null:!!e.downloadAttachments,downloadAttachmentsDir:typeof e.downloadAttachmentsDir=="string"?e.downloadAttachmentsDir:null}}function Re(t){return!!(t?.configured??t?.connected)}function W(t){return X(t)}function H(t,e,a){return{}}function j(t,e,a,s,l,u){t.configure?.({sessionId:e,externalChannel:s??null,env:{...W(a),...H(e,s,l),...u?{SHENNIAN_ROOM_REGISTRY_KEY:u}:{}}})}function Te(t,e,a){return null}function le(t,e,a){if(t!=="claude"||!a)return e;const s=e.trim();return!!s&&s.startsWith("-")&&!s.includes("/")?Y(a)??e:e}function de(t,e,a,s){let l=null;function u(n,r={}){t.client.sendAgentEvent({type:"event",event:"agent",payload:ne(n,e,r),seq:n.seq,id:`agent-evt-${n.runId}-${n.seq}`})}function d(n){n?.heartbeatTimer&&(clearInterval(n.heartbeatTimer),n.heartbeatTimer=null)}function c(n){if(!n.currentRunId||!n.currentRunPhase)return;const r=n.heartbeatSeq++;t.client.sendAgentEvent({type:"event",event:"agent",payload:{state:"heartbeat",sessionId:e,runId:n.currentRunId,seq:r,runPhase:n.currentRunPhase},seq:r,id:`agent-heartbeat-${n.currentRunId}-${r}-${Date.now()}`})}function m(n){!n||n.heartbeatTimer||(n.heartbeatTimer=setInterval(()=>{c(n)},ae),n.heartbeatTimer.unref?.())}function I(n){const r=n?.pendingTextEvent;!n||!r||!r.text||(u({state:"delta",runId:r.runId,seq:r.seq,text:r.text,thinking:r.thinking||void 0}),n.pendingTextEvent=null)}s.on("agentEvent",n=>{const r=t.sessions.get(e),A=re(n),R=n.state==="final"||n.state==="error"||n.state==="aborted";r&&(r.nextEventSeq=n.seq+1,R||(r.currentRunId=n.runId),!R&&A&&(r.currentRunPhase=A,m(r)),n.agentSessionId&&(r.agentSessionId=n.agentSessionId)),t.managerRuntime?.noteAgentEvent(e,n),n.state!=="delta"&&S({level:"info",sessionId:e,wsEvent:`agent.${n.state}`,wsDirection:"out",metadata:{runId:n.runId,seq:n.seq,agentType:a}}),n.state==="delta"&&n.text&&!n.thinking?E(e,{id:`agent-${n.runId}-${n.seq}`,sessionId:e,role:"agent",ts:Date.now(),payload:n.text}):n.state==="tool-call"||n.state==="tool-result"?E(e,{id:`agent-${n.runId}-${n.seq}`,sessionId:e,role:"agent",ts:Date.now(),payload:JSON.stringify({v:1,type:n.state==="tool-call"?"tool_use":"tool_result",name:n.name,status:n.state==="tool-call"?"running":"completed",detailRef:{runId:n.runId,sourceSeq:n.seq},args:n.args,result:n.result})}):n.state==="approval-pending"?E(e,{id:`agent-${n.runId||"run"}-${n.seq}`,sessionId:e,role:"agent",ts:Date.now(),payload:K(n.approval)}):(n.state==="error"||n.state==="aborted")&&n.message&&E(e,{id:`agent-${n.runId||"run"}-${n.seq}`,sessionId:e,role:"agent",ts:Date.now(),payload:n.message});const y=`${e}:${n.runId}`;if(n.state==="delta"&&!n.thinking&&n.text&&t.runTextAcc.set(y,(t.runTextAcc.get(y)??"")+n.text),n.agentSessionId&&n.agentSessionId!==l&&(l=n.agentSessionId,t.nativeFusion?.noteManagedSourceSession(e,L(a,n.source),n.agentSessionId),r&&B({sessionId:e,agentType:a,workDir:r.workDir,agentSessionId:n.agentSessionId}),t.client.sendEvent({type:"event",event:"session.update",payload:{session:{id:e,agentType:a,agentSessionId:n.agentSessionId}}})),n.state==="delta"){const h=n.text??"";if(!h)return;const b=!!n.thinking;r?.pendingTextEvent&&(r.pendingTextEvent.runId!==n.runId||r.pendingTextEvent.thinking!==b)&&I(r),r&&!r.pendingTextEvent&&(r.pendingTextEvent={runId:n.runId,seq:n.seq,text:"",thinking:b}),r?.pendingTextEvent&&(r.pendingTextEvent.text+=h,r.pendingTextEvent.seq=n.seq);return}let x={};if(n.state==="final"){I(r);const h=t.runTextAcc.get(y)??"";h&&(x={messageSummary:te(h)}),t.runTextAcc.delete(y)}else n.state==="error"||n.state==="aborted"?(I(r),t.runTextAcc.delete(y)):(n.state==="tool-call"||n.state==="tool-result"||n.state==="approval-pending")&&I(r);R&&r?.currentRunId===n.runId&&(r.currentRunId=null,r.currentRunPhase=null,r.nextEventSeq=0,d(r),t.chatQueue?.noteTerminal(e)),u(n,x)}),s.on("error",n=>{console.error(`[chat.send] adapter error sessionId=${e} agentType=${a}: ${n.message}`),t.sessions.delete(e),t.chatQueue?.noteTerminal(e),t.client.sendEvent({type:"event",event:"agent",payload:{state:"error",sessionId:e,message:n.message,runId:"",seq:0}})})}function ie(t,e){if(t.processedReqIds.add(e),t.processedReqIds.size>1e3){const a=t.processedReqIds.values().next().value;t.processedReqIds.delete(a)}}async function M(t){t.heartbeatTimer&&(clearInterval(t.heartbeatTimer),t.heartbeatTimer=null),t.adapter.removeAllListeners(),await t.adapter.stop().catch(()=>{})}function G(t,e,a,s,l,u){return u?.trim()?t.send(e,a,s,l,u):l?.length?t.send(e,a,s,l):s?t.send(e,a,s):t.send(e,a)}async function ce(t,e,a,s,l,u,d){t.evictIdleSessions();const c=J(a);if(!c)throw new Error(`Unsupported agent: ${a}`);j(c,e,a,u,d),await c.start(e,s,l);const m={adapter:c,workDir:s,agentType:a,agentSessionId:l??null,lastActiveAt:Date.now(),currentRunId:null,currentRunPhase:null,nextEventSeq:0,heartbeatSeq:0,heartbeatTimer:null,pendingTextEvent:null,externalChannel:u??null,externalReplyTarget:d??null,externalChannelEnv:{...W(a),...H(e,u,d)}};return t.sessions.set(e,m),de(t,e,a,c),m}function ue(t,e){const a=t.sessions.get(e),s=a?.currentRunId;if(!a||!s)return;const l=a.nextEventSeq;t.runTextAcc.delete(`${e}:${s}`),a.pendingTextEvent=null,a.currentRunId=null,a.currentRunPhase=null,a.nextEventSeq=0,a.heartbeatTimer&&(clearInterval(a.heartbeatTimer),a.heartbeatTimer=null),t.client.sendAgentEvent({type:"event",event:"agent",payload:{state:"aborted",sessionId:e,runId:s,seq:l},seq:l,id:`agent-evt-${s}-${l}`}),t.chatQueue?.noteTerminal(e)}async function xe(t,e){if(t.processedReqIds.has(e.id)){t.client.sendRes({type:"res",id:e.id,ok:!0});return}ie(t,e.id);const{sessionId:a,text:s,agentType:l,workDir:u,agentSessionId:d,modelId:c,systemPrompt:m,managerDefaultWorkerAgentType:I,managerDefaultWorkerModelId:n,reasoningEffort:r,clientMessageId:A,sessionListProjection:R,waitForDispatch:y,responseId:x,roomContextRegistryKey:h,suppressExternalOwnerEcho:b}=e.params,T=x||e.id;V(R);const $=null,_="";if(!a||!s){t.processedReqIds.delete(e.id),t.client.sendRes({type:"res",id:T,ok:!1,error:"sessionId and text are required"});return}const g=l;g==="manager"&&t.managerRuntime?.setManagerWorkerDefaults(a,I??null,n??null);const q=(g==="claude"||g==="codex"||g==="workbuddy")&&typeof r=="string"&&r.trim()?r.trim():void 0,w=t.resolvePath(le(g,u||z.homedir(),d)||z.homedir()),D=w,P=ee(e.params.attachments),f=P?.length?await Z({text:s,attachments:P,workDir:w}):{text:s,attachments:P,localized:!1};let o=t.sessions.get(a);if(o){if(o.lastActiveAt=Date.now(),o.agentType!==g||o.workDir!==w||JSON.stringify(o.externalChannel??null)!==JSON.stringify($??null)){t.sessions.delete(a);try{await M(o)}catch{t.processedReqIds.delete(e.id)}o=void 0}else if(d&&o.agentSessionId!==d)try{await o.adapter.resume(d),o.agentSessionId=d}catch{t.sessions.delete(a);try{await M(o)}catch{t.processedReqIds.delete(e.id)}o=void 0}}if(!o)try{o=await ce(t,a,g,w,d,$,_)}catch(i){const p=i instanceof Error&&i.message.startsWith("Unsupported agent:")?i.message:`Failed to start ${l}: ${i instanceof Error?i.message:String(i)}`;console.error(`[chat.send] start failed reqId=${e.id} sessionId=${a} agentType=${l} workDir=${w} agentSessionId=${d??""}: ${p}`),t.client.sendEvent({type:"event",event:"agent",payload:{state:"error",sessionId:a,message:p,runId:"",seq:0}}),t.processedReqIds.delete(e.id),t.client.sendRes({type:"res",id:T,ok:!1,error:p});return}h&&/^[a-f0-9]{64}$/.test(h)&&j(o.adapter,a,g,$,_,h);const C={id:A??`user-${e.id}`,sessionId:a,role:"user",ts:Date.now(),payload:Q(f.text,f.attachments)};S({level:"info",sessionId:a,wsEvent:"chat.send.start",metadata:{reqId:e.id,agentType:g,modelId:c,reasoningEffort:q}});const F=i=>{oe(t,{sessionId:a,agentType:g,workDir:D,agentSessionId:o.agentSessionId??d??null,modelId:c}),o.currentRunId||(o.nextEventSeq=0),t.nativeFusion?.registerManagedSend({sessionId:a,agentType:g,sourceAgentType:L(g,c),canonicalMessageId:A??null,sourceSessionKey:o.agentSessionId??d??null,text:f.text,managedEchoPolicy:i?.deliveryMode==="external_owner_queue"&&!b?"import_following":"suppress_following"}),E(a,C),O(t,C,{agentType:g,workDir:D,agentSessionId:o.agentSessionId??d??null,modelId:c})},N=async(i,p)=>{const k=se(g,i);console.error(`[chat.send] send failed reqId=${e.id} sessionId=${a} agentType=${l} workDir=${w} agentSessionId=${o.agentSessionId??d??""}: ${k}`),t.sessions.delete(a);try{await M(o)}catch{}if(t.client.sendEvent({type:"event",event:"agent",payload:{state:"error",sessionId:a,message:k,runId:"",seq:0}}),!p){const v={id:`agent-error-${e.id}-${Date.now()}`,sessionId:a,role:"agent",ts:Date.now(),payload:k};E(a,v),O(t,v,{agentType:g,workDir:D,agentSessionId:o.agentSessionId??d??null,modelId:c})}p&&(t.processedReqIds.delete(e.id),t.client.sendRes({type:"res",id:T,ok:!1,error:k}))};if(y){let i;try{const p=f.attachments;i=await G(o.adapter,f.text,c,q,p,m),S({level:"info",sessionId:a,wsEvent:"chat.send.done",metadata:{reqId:e.id}})}catch(p){await N(p,!0);return}F(i??void 0),t.client.sendRes({type:"res",id:T,ok:!0,...f.localized||i?.deliveryMode==="external_owner_queue"?{payload:{...f.localized?{localizedAttachments:!0}:{},...i?.deliveryMode==="external_owner_queue"?{queued:!0,deliveryMode:i.deliveryMode,queuedSubmissionId:i.queuedSubmissionId}:{}}}:{}}),S({level:"info",sessionId:a,wsEvent:"chat.send.res",metadata:{reqId:e.id,ok:!0}});return}F(),t.client.sendRes({type:"res",id:T,ok:!0,...f.localized?{payload:{localizedAttachments:!0}}:{}}),S({level:"info",sessionId:a,wsEvent:"chat.send.res",metadata:{reqId:e.id,ok:!0}});const U=f.attachments;G(o.adapter,f.text,c,q,U,m).then(()=>{S({level:"info",sessionId:a,wsEvent:"chat.send.done",metadata:{reqId:e.id}})}).catch(i=>{N(i,!1)})}async function be(t,e){const{sessionId:a}=e.params,s=t.sessions.get(a);if(s){try{await s.adapter.stop()}catch{}ue(t,a),t.activityPublisher?.publish(a,null)}t.client.sendRes({type:"res",id:e.id,ok:!0})}export{be as handleChatAbort,xe as handleChatSend,oe as sendSessionUpdateEvent};
@@ -2,3 +2,4 @@ import type { ReqFrame } from '@shennian/wire';
2
2
  import type { ManagedRoomBinder } from '../../room/managed-room-binding.js';
3
3
  import type { SessionManagerRuntime } from '../types.js';
4
4
  export declare function handleManagedRoomBind(runtime: SessionManagerRuntime, binder: ManagedRoomBinder | null, req: ReqFrame): Promise<void>;
5
+ export declare function handleManagedRoomRestart(runtime: SessionManagerRuntime, binder: ManagedRoomBinder | null, req: ReqFrame): Promise<void>;
@@ -1 +1 @@
1
- const m=/^[A-Za-z0-9_.:@/-]{1,191}$/,c=new Set(["roomId","agentIdentityId","nianSessionId","assignmentIntentId"]);async function p(n,e,t){if(!e)throw new Error("Managed Room binding is unavailable.");if(Object.keys(t.params).some(g=>!c.has(g)))throw new Error("Managed Room binding contains unsupported parameters.");const i=o(t.params.roomId,"roomId"),d=o(t.params.agentIdentityId,"agentIdentityId"),a=o(t.params.nianSessionId,"nianSessionId"),r=o(t.params.assignmentIntentId,"assignmentIntentId"),s=n.sessions.get(a);if(!s?.agentSessionId)throw new Error("The exact native Agent session is not ready for Room binding.");const I=await e.bind({roomId:i,agentIdentityId:d,nianSessionId:a,assignmentIntentId:r,agentSessionId:s.agentSessionId,workDir:s.workDir,agentType:s.agentType});n.client.sendRes({type:"res",id:t.id,ok:!0,payload:I})}function o(n,e){if(typeof n!="string"||!m.test(n))throw new Error(`Invalid ${e}.`);return n}export{p as handleManagedRoomBind};
1
+ const c=/^[A-Za-z0-9_.:@/-]{1,191}$/,S=new Set(["roomId","agentIdentityId","nianSessionId","assignmentIntentId"]),y=new Set(["roomId","bindingId","agentIdentityId","previousNianSessionId","nianSessionId","assignmentIntentId"]);async function w(e,t,n){if(!t)throw new Error("Managed Room binding is unavailable.");if(Object.keys(n.params).some(a=>!S.has(a)))throw new Error("Managed Room binding contains unsupported parameters.");const d=s(n.params.roomId,"roomId"),r=s(n.params.agentIdentityId,"agentIdentityId"),i=s(n.params.nianSessionId,"nianSessionId"),I=s(n.params.assignmentIntentId,"assignmentIntentId"),o=e.sessions.get(i);if(!o?.agentSessionId)throw new Error("The exact native Agent session is not ready for Room binding.");const g=await t.bind({roomId:d,agentIdentityId:r,nianSessionId:i,assignmentIntentId:I,agentSessionId:o.agentSessionId,workDir:o.workDir,agentType:o.agentType});e.client.sendRes({type:"res",id:n.id,ok:!0,payload:g})}async function u(e,t,n){if(!t)throw new Error("Managed Room binding is unavailable.");if(Object.keys(n.params).some(p=>!y.has(p)))throw new Error("Managed Room restart contains unsupported parameters.");const d=s(n.params.roomId,"roomId"),r=s(n.params.bindingId,"bindingId"),i=s(n.params.agentIdentityId,"agentIdentityId"),I=s(n.params.previousNianSessionId,"previousNianSessionId"),o=s(n.params.nianSessionId,"nianSessionId"),g=s(n.params.assignmentIntentId,"assignmentIntentId"),a=e.sessions.get(o);if(!a?.agentSessionId)throw new Error("The replacement native Agent session is not ready for Room binding.");const m=await t.restart({roomId:d,bindingId:r,agentIdentityId:i,previousNianSessionId:I,nianSessionId:o,assignmentIntentId:g,agentSessionId:a.agentSessionId,workDir:a.workDir,agentType:a.agentType});e.client.sendRes({type:"res",id:n.id,ok:!0,payload:m})}function s(e,t){if(typeof e!="string"||!c.test(e))throw new Error(`Invalid ${t}.`);return e}export{w as handleManagedRoomBind,u as handleManagedRoomRestart};
@@ -32,6 +32,26 @@ export declare class SessionManager {
32
32
  constructor(client: CliRelayClient, nativeFusion?: NativeSessionFusionService | null, cliVersion?: string | undefined, upgradePolicyController?: UpgradePolicyController | null, managedRoomBinder?: ManagedRoomBinder | null);
33
33
  private getRuntime;
34
34
  getUpgradeIdleState(): UpgradeIdleState;
35
+ createManagedRoomSession(input: {
36
+ creationKey: string;
37
+ agentType: 'codex' | 'claude' | 'workbuddy';
38
+ workDir: string;
39
+ modelId: string | null;
40
+ initialMessage: string;
41
+ }): Promise<{
42
+ nianSessionId: string;
43
+ }>;
44
+ waitForManagedNativeSession(input: {
45
+ nianSessionId: string;
46
+ agentType: 'codex' | 'claude' | 'workbuddy';
47
+ timeoutMs: number;
48
+ }): Promise<{
49
+ sourceSessionKey: string;
50
+ }>;
51
+ publishManagedRoomSession(input: {
52
+ nianSessionId: string;
53
+ agentType: 'codex' | 'claude' | 'workbuddy';
54
+ }): void;
35
55
  activateRoomSession(input: {
36
56
  sessionId: string;
37
57
  agentType: AgentType;
@@ -1 +1 @@
1
- import{getRegisteredAgents as l,unregisterAgent as h}from"../agents/adapter.js";import{loadConfig as u}from"../config/index.js";import{handleUpgradeStart as d,handleUpgradeStatus as m}from"../commands/upgrade.js";import{handleAgentsRefresh as p,handleModelsRefresh as f}from"./handlers/agents.js";import{handleAgentCapabilitiesList as g}from"./handlers/agent-capabilities.js";import{handleAgentConfigClear as b,handleAgentConfigGet as w,handleAgentConfigTest as v,handleAgentConfigUpsert as k}from"./handlers/agent-config.js";import{handleChatAbort as R,handleChatSend as r}from"./handlers/chat.js";import{handleSessionRefresh as y}from"./handlers/session-refresh.js";import{handleSessionToolDetail as S}from"./handlers/tool-detail.js";import{handleSessionTitleSet as A}from"./handlers/title.js";import{cleanupPendingTransfers as T,handleFsLs as P,handleFsRead as I,handleFsRename as C,handleFsWrite as F,handleFsTransfer as M,handleFsTransferAbort as x,handleFsTransferChunk as E,handleFsTransferFinish as Q,handleFsTransferStart as z,handleFsExportMarkdownPdf as D,handleFsExportMarkdownPdfSetup as O,handleFsArchiveZip as U}from"./handlers/fs.js";import{handleRegionProbe as V,handleRegionSwitch as _,handleUpgradeSetPolicy as B}from"./handlers/control.js";import{ManagerRuntimeService as W,setManagerRuntimeService as o}from"../manager/runtime.js";import{ChatQueueManager as j}from"./queue.js";import{createAuthorizedFsRoot as L,resolveAuthorizedPath as $,resolveSessionWorkDir as G}from"../fs/boundary.js";import"../agents/claude.js";import"../agents/codex.js";import"../agents/workbuddy.js";import"../agents/gemini.js";import"../agents/cursor.js";import"../agents/opencode.js";import"../agents/manager.js";import{registerCustomAgent as N}from"../agents/custom.js";import{handleManagedRoomBind as X}from"./handlers/room-managed.js";const Z=50;import{resolveSessionWorkDir as Se}from"../fs/boundary.js";class ke{client;nativeFusion;cliVersion;upgradePolicyController;managedRoomBinder;sessions=new Map;processedReqIds=new Set;runTextAcc=new Map;pendingTransfers=new Map;managerRuntime;chatQueue;activityProbeTimer=null;activeRequests=0;constructor(e,t=null,s,i=null,n=null){this.client=e,this.nativeFusion=t,this.cliVersion=s,this.upgradePolicyController=i,this.managedRoomBinder=n,this.managerRuntime=new W({getRuntime:()=>this.getRuntime(),dispatchReq:a=>this.handleReq(a)}),this.chatQueue=new j({getRuntime:()=>this.getRuntime(),dispatchReq:a=>this.handleReq(a)}),o(this.managerRuntime),this.managerRuntime.start(),this.reloadCustomAgents(),this.activityProbeTimer=setInterval(()=>{this.publishManagedActivitySnapshots().catch(a=>{console.error("[session.activity] managed probe failed",a)})},15e3),this.activityProbeTimer.unref?.()}getRuntime(){return{client:this.client,pendingTransfers:this.pendingTransfers,processedReqIds:this.processedReqIds,reloadCustomAgents:()=>this.reloadCustomAgents(),resolvePath:e=>this.resolvePath(e),resolveAuthorizedPath:(e,t)=>this.resolveAuthorizedPath(e,t),runTextAcc:this.runTextAcc,sessions:this.sessions,evictIdleSessions:()=>this.evictIdleSessions(),nativeFusion:this.nativeFusion,managerRuntime:this.managerRuntime,chatQueue:this.chatQueue,activityPublisher:{publish:(e,t)=>this.publishSessionActivity(e,t)},upgradePolicyController:this.upgradePolicyController}}getUpgradeIdleState(){const e=[];return[...this.sessions.values()].some(t=>t.currentRunId!==null)&&e.push("active-agent-turn"),this.pendingTransfers.size>0&&e.push("file-transfer"),this.activeRequests>0&&e.push("active-daemon-request"),{idle:e.length===0,reasons:e}}async activateRoomSession(e){const t={value:null},s=new Proxy(this.client,{get:(i,n)=>{if(n==="sendRes")return c=>{t.value=c};const a=Reflect.get(i,n,i);return typeof a=="function"?a.bind(i):a}});return await r({...this.getRuntime(),client:s},{type:"req",id:e.clientMessageId,method:"chat.send",params:{...e,waitForDispatch:!0,suppressExternalOwnerEcho:!0}}),{externalOwnerQueued:t.value?.ok===!0&&t.value.payload?.deliveryMode==="external_owner_queue"}}publishSessionActivity(e,t){this.client.sendEvent({type:"event",event:"session.activity",payload:{sessionId:e,activity:t}})}async publishManagedActivitySnapshots(){for(const[e,t]of this.sessions.entries()){if(!t.currentRunId||!t.adapter.getStatus)continue;const s=await t.adapter.getStatus().catch(()=>null);if(!s?.active||!s.runPhase)continue;const i=new Date().toISOString();this.publishSessionActivity(e,{sessionId:e,runId:s.runId||t.currentRunId,runPhase:s.runPhase,startedAt:new Date(t.lastActiveAt).toISOString(),updatedAt:i,canStop:s.canStop??!0});const n=t.heartbeatSeq++;this.client.sendAgentEvent({type:"event",event:"agent",payload:{state:"heartbeat",sessionId:e,runId:s.runId||t.currentRunId,seq:n,runPhase:s.runPhase,canStop:s.canStop??!0},seq:n,id:`agent-status-${s.runId||t.currentRunId}-${Date.now()}`})}}reloadCustomAgents(){for(const t of l())t.startsWith("custom:")&&h(t);const e=u();for(const[t,s]of Object.entries(e.customAgents??{}))N(t,s)}async handleReq(e){const t=this.getRuntime();this.activeRequests++;try{switch(e.method){case"chat.send":await r(t,e);break;case"chat.enqueue":await this.chatQueue.handleEnqueue(e);break;case"chat.queue.get":await this.chatQueue.handleGet(e);break;case"chat.queue.edit":await this.chatQueue.handleEdit(e);break;case"chat.queue.delete":await this.chatQueue.handleDelete(e);break;case"chat.abort":await R(t,e);break;case"session.refresh":await y(t,e);break;case"session.tool.detail":await S(t,e);break;case"session.title.set":await A(t,e);break;case"room.agent.bind-managed":await X(t,this.managedRoomBinder,e);break;case"fs.ls":await P(t,e);break;case"fs.read":await I(t,e);break;case"fs.write":await F(t,e);break;case"fs.export.markdown-pdf":await D(t,e);break;case"fs.export.markdown-pdf.setup":await O(t,e);break;case"fs.archive.zip":await U(t,e);break;case"fs.rename":await C(t,e);break;case"fs.transfer":await M(t,e);break;case"fs.transfer.start":await z(t,e);break;case"fs.transfer.chunk":await E(t,e);break;case"fs.transfer.finish":await Q(t,e);break;case"fs.transfer.abort":await x(t,e);break;case"region.probe":await V(t,e);break;case"region.switch":await _(t,e);break;case"upgrade.start":await d(this.client,e.id,e.params.version,{currentVersion:this.cliVersion,confirmedMajor:e.params.confirmedMajor===!0});break;case"upgrade.status":await m(this.client,e.id,{currentVersion:this.cliVersion});break;case"upgrade.set-policy":await B(t,e);break;case"agents.refresh":await p(t,e);break;case"models.refresh":await f(t,e);break;case"agent.config.get":await w(t,e);break;case"agent.config.upsert":await k(t,e);break;case"agent.config.clear":await b(t,e);break;case"agent.config.test":await v(t,e);break;case"agent.capabilities.list":await g(t,e);break;case"skill.list":case"skill.install":case"skill.doctor":case"skill.setup":case"skill.use":this.client.sendRes({type:"res",id:e.id,ok:!1,error:"feature_retired"});break;case"session.wechat-rpa.channel.get":case"session.wechat-rpa.channel.upsert":case"session.wechat-rpa.channel.sync":case"manager.wechat-rpa.channel.get":case"manager.wechat-rpa.channel.upsert":case"manager.wechat-rpa.channel.sync":this.client.sendRes({type:"res",id:e.id,ok:!1,error:"feature_retired"});break;default:this.client.sendRes({type:"res",id:e.id,ok:!1,error:`Unknown method: ${e.method}`})}}catch(s){this.client.sendRes({type:"res",id:e.id,ok:!1,error:s instanceof Error?s.message:String(s)})}finally{this.activeRequests--}}evictIdleSessions(){if(this.sessions.size<Z)return;let e=null;for(const[t,s]of this.sessions)(!e||s.lastActiveAt<e.session.lastActiveAt)&&(e={key:t,session:s});e&&(e.session.heartbeatTimer&&(clearInterval(e.session.heartbeatTimer),e.session.heartbeatTimer=null),e.session.adapter.removeAllListeners(),e.session.adapter.stop().catch(()=>{}),this.sessions.delete(e.key))}resolvePath(e){return G(e)}resolveAuthorizedPath(e,t){return $(e,L(t))}async cleanup(){this.activityProbeTimer&&(clearInterval(this.activityProbeTimer),this.activityProbeTimer=null);for(const[,e]of this.sessions)e.heartbeatTimer&&(clearInterval(e.heartbeatTimer),e.heartbeatTimer=null),await e.adapter.stop().catch(()=>{});this.sessions.clear(),this.runTextAcc.clear(),T(this.getRuntime()),await this.managerRuntime.stop(),o(null)}}export{ke as SessionManager,Se as resolveSessionWorkDir};
1
+ import g from"node:crypto";import{getRegisteredAgents as m,unregisterAgent as f}from"../agents/adapter.js";import{loadConfig as p}from"../config/index.js";import{handleUpgradeStart as w,handleUpgradeStatus as b}from"../commands/upgrade.js";import{handleAgentsRefresh as v,handleModelsRefresh as R}from"./handlers/agents.js";import{handleAgentCapabilitiesList as k}from"./handlers/agent-capabilities.js";import{handleAgentConfigClear as y,handleAgentConfigGet as S,handleAgentConfigTest as I,handleAgentConfigUpsert as A}from"./handlers/agent-config.js";import{handleChatAbort as T,handleChatSend as c,sendSessionUpdateEvent as P}from"./handlers/chat.js";import{handleSessionRefresh as M}from"./handlers/session-refresh.js";import{handleSessionToolDetail as _}from"./handlers/tool-detail.js";import{handleSessionTitleSet as C}from"./handlers/title.js";import{cleanupPendingTransfers as F,handleFsLs as x,handleFsRead as D,handleFsRename as E,handleFsWrite as O,handleFsTransfer as Q,handleFsTransferAbort as j,handleFsTransferChunk as z,handleFsTransferFinish as U,handleFsTransferStart as V,handleFsExportMarkdownPdf as $,handleFsExportMarkdownPdfSetup as B,handleFsArchiveZip as W}from"./handlers/fs.js";import{handleRegionProbe as L,handleRegionSwitch as G,handleUpgradeSetPolicy as K}from"./handlers/control.js";import{ManagerRuntimeService as N,setManagerRuntimeService as h}from"../manager/runtime.js";import{ChatQueueManager as H}from"./queue.js";import{createAuthorizedFsRoot as X,resolveAuthorizedPath as Z,resolveSessionWorkDir as J}from"../fs/boundary.js";import"../agents/claude.js";import"../agents/codex.js";import"../agents/workbuddy.js";import"../agents/gemini.js";import"../agents/cursor.js";import"../agents/opencode.js";import"../agents/manager.js";import{registerCustomAgent as Y}from"../agents/custom.js";import{handleManagedRoomBind as q,handleManagedRoomRestart as ee}from"./handlers/room-managed.js";import{listSessionRecords as d}from"./store.js";const te=50;import{resolveSessionWorkDir as xe}from"../fs/boundary.js";class _e{client;nativeFusion;cliVersion;upgradePolicyController;managedRoomBinder;sessions=new Map;processedReqIds=new Set;runTextAcc=new Map;pendingTransfers=new Map;managerRuntime;chatQueue;activityProbeTimer=null;activeRequests=0;constructor(e,t=null,s,n=null,i=null){this.client=e,this.nativeFusion=t,this.cliVersion=s,this.upgradePolicyController=n,this.managedRoomBinder=i,this.managerRuntime=new N({getRuntime:()=>this.getRuntime(),dispatchReq:a=>this.handleReq(a)}),this.chatQueue=new H({getRuntime:()=>this.getRuntime(),dispatchReq:a=>this.handleReq(a)}),h(this.managerRuntime),this.managerRuntime.start(),this.reloadCustomAgents(),this.activityProbeTimer=setInterval(()=>{this.publishManagedActivitySnapshots().catch(a=>{console.error("[session.activity] managed probe failed",a)})},15e3),this.activityProbeTimer.unref?.()}getRuntime(){return{client:this.client,pendingTransfers:this.pendingTransfers,processedReqIds:this.processedReqIds,reloadCustomAgents:()=>this.reloadCustomAgents(),resolvePath:e=>this.resolvePath(e),resolveAuthorizedPath:(e,t)=>this.resolveAuthorizedPath(e,t),runTextAcc:this.runTextAcc,sessions:this.sessions,evictIdleSessions:()=>this.evictIdleSessions(),nativeFusion:this.nativeFusion,managerRuntime:this.managerRuntime,chatQueue:this.chatQueue,activityPublisher:{publish:(e,t)=>this.publishSessionActivity(e,t)},upgradePolicyController:this.upgradePolicyController}}getUpgradeIdleState(){const e=[];return[...this.sessions.values()].some(t=>t.currentRunId!==null)&&e.push("active-agent-turn"),this.pendingTransfers.size>0&&e.push("file-transfer"),this.activeRequests>0&&e.push("active-daemon-request"),{idle:e.length===0,reasons:e}}async createManagedRoomSession(e){const t=g.createHash("sha256").update(e.creationKey,"utf8").digest("hex"),s=`room-managed-${t.slice(0,48)}`,n=d().find(r=>r.sessionId===s);if(n&&(n.agentType!==e.agentType||n.workDir!==e.workDir))throw Object.assign(new Error("Managed Room Session identity conflicts with local state."),{code:"managed_room_session_conflict"});if(n?.agentSessionId)return{nianSessionId:s};const i={value:null},a=new Proxy(this.client,{get:(r,l)=>{if(l==="sendRes")return u=>{i.value=u};const o=Reflect.get(r,l,r);return typeof o=="function"?o.bind(r):o}});if(await c({...this.getRuntime(),client:a},{type:"req",id:`managed-create-${t.slice(0,32)}`,method:"chat.send",params:{sessionId:s,text:e.initialMessage,agentType:e.agentType,workDir:e.workDir,modelId:e.modelId??void 0,clientMessageId:`managed-bootstrap-${t.slice(0,32)}`,waitForDispatch:!0}}),i.value?.ok!==!0)throw Object.assign(new Error(i.value?.error||"Managed Agent failed to start."),{code:"managed_agent_start_failed"});return{nianSessionId:s}}async waitForManagedNativeSession(e){const t=Date.now();for(;Date.now()-t<e.timeoutMs;){const s=this.sessions.get(e.nianSessionId);if(s&&s.agentType!==e.agentType)throw Object.assign(new Error("Managed Agent runtime does not match the created session."),{code:"managed_room_session_conflict"});const n=d().find(a=>a.sessionId===e.nianSessionId),i=s?.agentSessionId??n?.agentSessionId;if(i)return{sourceSessionKey:i};await new Promise(a=>setTimeout(a,100))}throw Object.assign(new Error("Timed out waiting for the exact native Agent Session."),{code:"native_session_timeout"})}publishManagedRoomSession(e){const t=d().find(s=>s.sessionId===e.nianSessionId);if(!t?.agentSessionId||t.agentType!==e.agentType)throw Object.assign(new Error("Managed Agent Session is unavailable for publication."),{code:"managed_room_session_unavailable"});if(this.client.getState()!=="connected")throw Object.assign(new Error("Shennian Relay is disconnected."),{code:"managed_room_relay_disconnected"});P(this.getRuntime(),{sessionId:t.sessionId,agentType:t.agentType,workDir:t.workDir,agentSessionId:t.agentSessionId,modelId:t.modelId??void 0})}async activateRoomSession(e){const t={value:null},s=new Proxy(this.client,{get:(n,i)=>{if(i==="sendRes")return r=>{t.value=r};const a=Reflect.get(n,i,n);return typeof a=="function"?a.bind(n):a}});return await c({...this.getRuntime(),client:s},{type:"req",id:e.clientMessageId,method:"chat.send",params:{...e,waitForDispatch:!0,suppressExternalOwnerEcho:!0}}),{externalOwnerQueued:t.value?.ok===!0&&t.value.payload?.deliveryMode==="external_owner_queue"}}publishSessionActivity(e,t){this.client.sendEvent({type:"event",event:"session.activity",payload:{sessionId:e,activity:t}})}async publishManagedActivitySnapshots(){for(const[e,t]of this.sessions.entries()){if(!t.currentRunId||!t.adapter.getStatus)continue;const s=await t.adapter.getStatus().catch(()=>null);if(!s?.active||!s.runPhase)continue;const n=new Date().toISOString();this.publishSessionActivity(e,{sessionId:e,runId:s.runId||t.currentRunId,runPhase:s.runPhase,startedAt:new Date(t.lastActiveAt).toISOString(),updatedAt:n,canStop:s.canStop??!0});const i=t.heartbeatSeq++;this.client.sendAgentEvent({type:"event",event:"agent",payload:{state:"heartbeat",sessionId:e,runId:s.runId||t.currentRunId,seq:i,runPhase:s.runPhase,canStop:s.canStop??!0},seq:i,id:`agent-status-${s.runId||t.currentRunId}-${Date.now()}`})}}reloadCustomAgents(){for(const t of m())t.startsWith("custom:")&&f(t);const e=p();for(const[t,s]of Object.entries(e.customAgents??{}))Y(t,s)}async handleReq(e){const t=this.getRuntime();this.activeRequests++;try{switch(e.method){case"chat.send":await c(t,e);break;case"chat.enqueue":await this.chatQueue.handleEnqueue(e);break;case"chat.queue.get":await this.chatQueue.handleGet(e);break;case"chat.queue.edit":await this.chatQueue.handleEdit(e);break;case"chat.queue.delete":await this.chatQueue.handleDelete(e);break;case"chat.abort":await T(t,e);break;case"session.refresh":await M(t,e);break;case"session.tool.detail":await _(t,e);break;case"session.title.set":await C(t,e);break;case"room.agent.bind-managed":await q(t,this.managedRoomBinder,e);break;case"room.agent.restart-managed":await ee(t,this.managedRoomBinder,e);break;case"fs.ls":await x(t,e);break;case"fs.read":await D(t,e);break;case"fs.write":await O(t,e);break;case"fs.export.markdown-pdf":await $(t,e);break;case"fs.export.markdown-pdf.setup":await B(t,e);break;case"fs.archive.zip":await W(t,e);break;case"fs.rename":await E(t,e);break;case"fs.transfer":await Q(t,e);break;case"fs.transfer.start":await V(t,e);break;case"fs.transfer.chunk":await z(t,e);break;case"fs.transfer.finish":await U(t,e);break;case"fs.transfer.abort":await j(t,e);break;case"region.probe":await L(t,e);break;case"region.switch":await G(t,e);break;case"upgrade.start":await w(this.client,e.id,e.params.version,{currentVersion:this.cliVersion,confirmedMajor:e.params.confirmedMajor===!0});break;case"upgrade.status":await b(this.client,e.id,{currentVersion:this.cliVersion});break;case"upgrade.set-policy":await K(t,e);break;case"agents.refresh":await v(t,e);break;case"models.refresh":await R(t,e);break;case"agent.config.get":await S(t,e);break;case"agent.config.upsert":await A(t,e);break;case"agent.config.clear":await y(t,e);break;case"agent.config.test":await I(t,e);break;case"agent.capabilities.list":await k(t,e);break;case"skill.list":case"skill.install":case"skill.doctor":case"skill.setup":case"skill.use":this.client.sendRes({type:"res",id:e.id,ok:!1,error:"feature_retired"});break;case"session.wechat-rpa.channel.get":case"session.wechat-rpa.channel.upsert":case"session.wechat-rpa.channel.sync":case"manager.wechat-rpa.channel.get":case"manager.wechat-rpa.channel.upsert":case"manager.wechat-rpa.channel.sync":this.client.sendRes({type:"res",id:e.id,ok:!1,error:"feature_retired"});break;default:this.client.sendRes({type:"res",id:e.id,ok:!1,error:`Unknown method: ${e.method}`})}}catch(s){this.client.sendRes({type:"res",id:e.id,ok:!1,error:s instanceof Error?s.message:String(s)})}finally{this.activeRequests--}}evictIdleSessions(){if(this.sessions.size<te)return;let e=null;for(const[t,s]of this.sessions)(!e||s.lastActiveAt<e.session.lastActiveAt)&&(e={key:t,session:s});e&&(e.session.heartbeatTimer&&(clearInterval(e.session.heartbeatTimer),e.session.heartbeatTimer=null),e.session.adapter.removeAllListeners(),e.session.adapter.stop().catch(()=>{}),this.sessions.delete(e.key))}resolvePath(e){return J(e)}resolveAuthorizedPath(e,t){return Z(e,X(t))}async cleanup(){this.activityProbeTimer&&(clearInterval(this.activityProbeTimer),this.activityProbeTimer=null);for(const[,e]of this.sessions)e.heartbeatTimer&&(clearInterval(e.heartbeatTimer),e.heartbeatTimer=null),await e.adapter.stop().catch(()=>{});this.sessions.clear(),this.runTextAcc.clear(),F(this.getRuntime()),await this.managerRuntime.stop(),h(null)}}export{_e as SessionManager,xe as resolveSessionWorkDir};
@@ -79,6 +79,11 @@ export declare function handleStartupCrashCheck(): Promise<boolean>;
79
79
  export declare function performUpgrade(targetVersion: string, onProgress: (p: UpgradeProgress) => void, opts?: {
80
80
  currentVersion?: string;
81
81
  }): Promise<UpgradeResult>;
82
+ export declare function npmExecOptionsForPlatform(platform: NodeJS.Platform, timeout: number): {
83
+ timeout: number;
84
+ windowsHide: boolean;
85
+ shell: boolean;
86
+ };
82
87
  export declare function installShennianVersion(targetVersion: string): Promise<void>;
83
88
  export declare function verifyInstalledVersion(targetVersion: string): Promise<void>;
84
89
  export declare function rollbackToExactVersion(version: string, deps?: {
@@ -1,3 +1,3 @@
1
- import i from"node:fs";import p from"node:path";import{execSync as F,execFile as D}from"node:child_process";import{promisify as O}from"node:util";import{fileURLToPath as L}from"node:url";import{getShennianDir as $,resolveShennianPath as d}from"../config/index.js";const f=O(D),m=d("upgrade-attempt.json"),J=3,I="https://registry.npmjs.org",H=10*6e4,U=[5*6e4,30*6e4,120*6e4,360*6e4];function y(){try{const r=B();if(r)return JSON.parse(i.readFileSync(r,"utf-8")).version}catch{}return"0.0.0"}function B(r=L(import.meta.url)){let e=p.dirname(r);for(let n=0;n<6;n++){const t=p.join(e,"package.json");if(i.existsSync(t)&&JSON.parse(i.readFileSync(t,"utf-8")).name==="shennian")return t;e=p.dirname(e)}return null}async function G(){const r=await fetch("https://registry.npmjs.org/shennian/latest",{headers:{Accept:"application/json"},signal:AbortSignal.timeout(1e4)});if(!r.ok)throw new Error(`npm registry returned ${r.status}`);return(await r.json()).version}function P(r,e){const n=u=>u.replace(/^v/,"").split(".").map(Number),[t,s,o]=n(r),[a,l,c]=n(e);return a>t?"major":a===t&&l>s?"minor":a===t&&l===s&&c>o?"patch":"none"}function Y(){return F("npm root -g",{encoding:"utf-8",stdio:"pipe",windowsHide:!0}).trim()}function z(){const r=Y();return p.join(r,"shennian","dist","bin","shennian.js")}function K(){try{return JSON.parse(i.readFileSync(m,"utf-8"))}catch{return null}}function g(r){i.mkdirSync($(),{recursive:!0}),i.writeFileSync(m,JSON.stringify(r,null,2))}function h(){try{i.unlinkSync(m)}catch{}}function _(){return d("upgrade-failures.json")}function X(){return d("upgrade.lock")}function N(r=X(),e={}){const n=e.now??Date.now(),t=e.pid??process.pid,s=e.isProcessAlive??(c=>{try{return process.kill(c,0),!0}catch{return!1}});i.mkdirSync(p.dirname(r),{recursive:!0});const o=()=>i.openSync(r,"wx",384);let a;try{a=o()}catch(c){if(c.code!=="EEXIST")throw c;let u=!1;try{const v=JSON.parse(i.readFileSync(r,"utf-8")),E=Number(v.pid),b=Number(v.createdAt);u=!Number.isInteger(E)||!Number.isFinite(b)||n-b>H||!s(E)}catch{u=!0}if(!u)throw new Error("Another Shennian upgrade is already running");i.rmSync(r,{force:!0}),a=o()}i.writeFileSync(a,JSON.stringify({pid:t,createdAt:n})),i.closeSync(a);let l=!1;return{release(){if(!l){l=!0;try{i.unlinkSync(r)}catch{}}}}}function k(r=_()){try{const e=JSON.parse(i.readFileSync(r,"utf-8"));return!e||typeof e!="object"||!e.versions?{versions:{}}:{versions:e.versions}}catch{return{versions:{}}}}function R(r){i.mkdirSync($(),{recursive:!0}),i.writeFileSync(_(),JSON.stringify(r,null,2))}function Z(r){return U[Math.min(Math.max(r-1,0),U.length-1)]}function nr(r,e=Date.now(),n=k()){const t=n.versions[r];return!!(t&&t.nextRetryAt>e)}function or(r,e,n=Date.now()){const t=k(),s=t.versions[r],o=(s?.failureCount??0)+1,a={version:r,failureCount:o,firstFailedAt:s?.firstFailedAt??n,lastFailedAt:n,nextRetryAt:n+Z(o),error:e};return t.versions[r]=a,R(t),a}function w(r){const e=k();e.versions[r]&&(delete e.versions[r],R(e))}async function ar(){const r=K();if(!r)return!1;if(Date.now()-r.attemptAt>600*1e3)return h(),!1;if(r.attemptCount++,r.attemptCount>=J){console.error(`[upgrade] New version crashed ${r.attemptCount} times, rolling back to ${r.from}...`);let n;try{n=N()}catch(t){return console.error(`[upgrade] Rollback deferred: ${t instanceof Error?t.message:String(t)}`),!1}try{return await M(r.from),h(),console.error(`[upgrade] Rolled back to ${r.from}. Restarting...`),!0}catch(t){return console.error(`[upgrade] Rollback failed: ${t instanceof Error?t.message:String(t)}`),h(),!1}finally{n.release()}}return g(r),!1}async function ir(r,e,n={}){let t;try{t=N()}catch(s){return{ok:!1,error:s instanceof Error?s.message:String(s)}}try{return await q(r,e,n)}finally{t.release()}}async function q(r,e,n={}){const t=n.currentVersion??y(),s=y();if(t===r)return w(r),{ok:!1,error:`Already on version ${r}`};e({step:"checking"});try{F("npm --version",{stdio:"pipe",windowsHide:!0})}catch{return{ok:!1,error:"npm is not available in PATH"}}if(s===r){e({step:"verifying",version:r});try{await A(r)}catch(o){return{ok:!1,error:`Smoke test failed: ${o instanceof Error?o.message:String(o)}`}}return g({from:t,to:r,attemptCount:0,attemptAt:Date.now()}),w(r),e({step:"restarting",from:t,to:r}),{ok:!0,from:t,to:r}}e({step:"backing-up"}),e({step:"installing",version:r});try{await j(r)}catch(o){const a=await T(t);return{ok:!1,error:`npm install failed: ${o instanceof Error?o.message:String(o)}${a.ok?"":`; rollback failed: ${a.error}`}`,rolledBack:a.ok}}e({step:"verifying",version:r});try{await A(r)}catch(o){const a=await T(t);return{ok:!1,error:`Smoke test failed: ${o instanceof Error?o.message:String(o)}${a.ok?"":`; rollback failed: ${a.error}`}`,rolledBack:a.ok}}return g({from:t,to:r,attemptCount:0,attemptAt:Date.now()}),w(r),e({step:"restarting",from:t,to:r}),{ok:!0,from:t,to:r}}function C(r){if(!/^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(r))throw new Error(`Invalid npm version: ${r}`)}function S(){return process.platform==="win32"?"npm.cmd":"npm"}function x(r){return{timeout:r,windowsHide:!0,shell:process.platform==="win32"}}async function j(r){C(r);try{await f(S(),["install","-g",`shennian@${r}`],x(12e4))}catch(e){const n=e instanceof Error?e.message:String(e);try{await f(S(),["install","-g",`shennian@${r}`,"--registry",I],{...x(12e4)})}catch(t){const s=t instanceof Error?t.message:String(t);throw new Error(`${n}
1
+ import i from"node:fs";import p from"node:path";import{execSync as F,execFile as T}from"node:child_process";import{promisify as D}from"node:util";import{fileURLToPath as L}from"node:url";import{getShennianDir as $,resolveShennianPath as d}from"../config/index.js";const f=D(T),m=d("upgrade-attempt.json"),J=3,I="https://registry.npmjs.org",H=10*6e4,U=[5*6e4,30*6e4,120*6e4,360*6e4];function y(){try{const r=P();if(r)return JSON.parse(i.readFileSync(r,"utf-8")).version}catch{}return"0.0.0"}function P(r=L(import.meta.url)){let e=p.dirname(r);for(let n=0;n<6;n++){const t=p.join(e,"package.json");if(i.existsSync(t)&&JSON.parse(i.readFileSync(t,"utf-8")).name==="shennian")return t;e=p.dirname(e)}return null}async function B(){const r=await fetch("https://registry.npmjs.org/shennian/latest",{headers:{Accept:"application/json"},signal:AbortSignal.timeout(1e4)});if(!r.ok)throw new Error(`npm registry returned ${r.status}`);return(await r.json()).version}function G(r,e){const n=u=>u.replace(/^v/,"").split(".").map(Number),[t,s,o]=n(r),[a,l,c]=n(e);return a>t?"major":a===t&&l>s?"minor":a===t&&l===s&&c>o?"patch":"none"}function Y(){return F("npm root -g",{encoding:"utf-8",stdio:"pipe",windowsHide:!0}).trim()}function z(){const r=Y();return p.join(r,"shennian","dist","bin","shennian.js")}function K(){try{return JSON.parse(i.readFileSync(m,"utf-8"))}catch{return null}}function g(r){i.mkdirSync($(),{recursive:!0}),i.writeFileSync(m,JSON.stringify(r,null,2))}function h(){try{i.unlinkSync(m)}catch{}}function _(){return d("upgrade-failures.json")}function X(){return d("upgrade.lock")}function N(r=X(),e={}){const n=e.now??Date.now(),t=e.pid??process.pid,s=e.isProcessAlive??(c=>{try{return process.kill(c,0),!0}catch{return!1}});i.mkdirSync(p.dirname(r),{recursive:!0});const o=()=>i.openSync(r,"wx",384);let a;try{a=o()}catch(c){if(c.code!=="EEXIST")throw c;let u=!1;try{const v=JSON.parse(i.readFileSync(r,"utf-8")),E=Number(v.pid),b=Number(v.createdAt);u=!Number.isInteger(E)||!Number.isFinite(b)||n-b>H||!s(E)}catch{u=!0}if(!u)throw new Error("Another Shennian upgrade is already running");i.rmSync(r,{force:!0}),a=o()}i.writeFileSync(a,JSON.stringify({pid:t,createdAt:n})),i.closeSync(a);let l=!1;return{release(){if(!l){l=!0;try{i.unlinkSync(r)}catch{}}}}}function k(r=_()){try{const e=JSON.parse(i.readFileSync(r,"utf-8"));return!e||typeof e!="object"||!e.versions?{versions:{}}:{versions:e.versions}}catch{return{versions:{}}}}function R(r){i.mkdirSync($(),{recursive:!0}),i.writeFileSync(_(),JSON.stringify(r,null,2))}function Z(r){return U[Math.min(Math.max(r-1,0),U.length-1)]}function or(r,e=Date.now(),n=k()){const t=n.versions[r];return!!(t&&t.nextRetryAt>e)}function ar(r,e,n=Date.now()){const t=k(),s=t.versions[r],o=(s?.failureCount??0)+1,a={version:r,failureCount:o,firstFailedAt:s?.firstFailedAt??n,lastFailedAt:n,nextRetryAt:n+Z(o),error:e};return t.versions[r]=a,R(t),a}function w(r){const e=k();e.versions[r]&&(delete e.versions[r],R(e))}async function ir(){const r=K();if(!r)return!1;if(Date.now()-r.attemptAt>600*1e3)return h(),!1;if(r.attemptCount++,r.attemptCount>=J){console.error(`[upgrade] New version crashed ${r.attemptCount} times, rolling back to ${r.from}...`);let n;try{n=N()}catch(t){return console.error(`[upgrade] Rollback deferred: ${t instanceof Error?t.message:String(t)}`),!1}try{return await M(r.from),h(),console.error(`[upgrade] Rolled back to ${r.from}. Restarting...`),!0}catch(t){return console.error(`[upgrade] Rollback failed: ${t instanceof Error?t.message:String(t)}`),h(),!1}finally{n.release()}}return g(r),!1}async function sr(r,e,n={}){let t;try{t=N()}catch(s){return{ok:!1,error:s instanceof Error?s.message:String(s)}}try{return await q(r,e,n)}finally{t.release()}}async function q(r,e,n={}){const t=n.currentVersion??y(),s=y();if(t===r)return w(r),{ok:!1,error:`Already on version ${r}`};e({step:"checking"});try{F("npm --version",{stdio:"pipe",windowsHide:!0})}catch{return{ok:!1,error:"npm is not available in PATH"}}if(s===r){e({step:"verifying",version:r});try{await A(r)}catch(o){return{ok:!1,error:`Smoke test failed: ${o instanceof Error?o.message:String(o)}`}}return g({from:t,to:r,attemptCount:0,attemptAt:Date.now()}),w(r),e({step:"restarting",from:t,to:r}),{ok:!0,from:t,to:r}}e({step:"backing-up"}),e({step:"installing",version:r});try{await j(r)}catch(o){const a=await O(t);return{ok:!1,error:`npm install failed: ${o instanceof Error?o.message:String(o)}${a.ok?"":`; rollback failed: ${a.error}`}`,rolledBack:a.ok}}e({step:"verifying",version:r});try{await A(r)}catch(o){const a=await O(t);return{ok:!1,error:`Smoke test failed: ${o instanceof Error?o.message:String(o)}${a.ok?"":`; rollback failed: ${a.error}`}`,rolledBack:a.ok}}return g({from:t,to:r,attemptCount:0,attemptAt:Date.now()}),w(r),e({step:"restarting",from:t,to:r}),{ok:!0,from:t,to:r}}function C(r){if(!/^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(r))throw new Error(`Invalid npm version: ${r}`)}function S(){return process.platform==="win32"?"npm.cmd":"npm"}function Q(r,e){return{timeout:e,windowsHide:!0,shell:r==="win32"}}function x(r){return Q(process.platform,r)}async function j(r){C(r);try{await f(S(),["install","-g",`shennian@${r}`],x(12e4))}catch(e){const n=e instanceof Error?e.message:String(e);try{await f(S(),["install","-g",`shennian@${r}`,"--registry",I],{...x(12e4)})}catch(t){const s=t instanceof Error?t.message:String(t);throw new Error(`${n}
2
2
  --- npmjs fallback ---
3
- ${s}`)}}}async function A(r){C(r);const e=z(),{stdout:n}=await f(process.execPath,[e,"--version"],{timeout:1e4,windowsHide:!0});if(n.trim()!==r)throw new Error(`Version verification failed: expected ${r}, got ${n.trim()||"empty output"}`);await f(S(),["ls","-g",`shennian@${r}`,"--omit=dev","--depth=0"],{...x(3e4)})}async function M(r,e={}){await(e.install??j)(r),await(e.verify??A)(r)}async function T(r){try{return await M(r),{ok:!0}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}async function sr(r){const e=r??y(),n=await G(),t=P(e,n);return t==="none"?{hasUpdate:!1}:{hasUpdate:!0,current:e,latest:n,changeType:t}}export{N as acquireUpgradeLock,sr as checkForUpdate,h as clearUpgradeAttempt,w as clearUpgradeFailure,P as compareVersions,G as fetchLatestVersion,B as findPackageJson,y as getCurrentVersion,Z as getUpgradeRetryDelayMs,ar as handleStartupCrashCheck,j as installShennianVersion,nr as isUpgradeVersionInCooldown,ir as performUpgrade,K as readUpgradeAttempt,k as readUpgradeFailures,or as recordUpgradeFailure,M as rollbackToExactVersion,A as verifyInstalledVersion,g as writeUpgradeAttempt};
3
+ ${s}`)}}}async function A(r){C(r);const e=z(),{stdout:n}=await f(process.execPath,[e,"--version"],{timeout:1e4,windowsHide:!0});if(n.trim()!==r)throw new Error(`Version verification failed: expected ${r}, got ${n.trim()||"empty output"}`);await f(S(),["ls","-g",`shennian@${r}`,"--omit=dev","--depth=0"],{...x(3e4)})}async function M(r,e={}){await(e.install??j)(r),await(e.verify??A)(r)}async function O(r){try{return await M(r),{ok:!0}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}async function cr(r){const e=r??y(),n=await B(),t=G(e,n);return t==="none"?{hasUpdate:!1}:{hasUpdate:!0,current:e,latest:n,changeType:t}}export{N as acquireUpgradeLock,cr as checkForUpdate,h as clearUpgradeAttempt,w as clearUpgradeFailure,G as compareVersions,B as fetchLatestVersion,P as findPackageJson,y as getCurrentVersion,Z as getUpgradeRetryDelayMs,ir as handleStartupCrashCheck,j as installShennianVersion,or as isUpgradeVersionInCooldown,Q as npmExecOptionsForPlatform,sr as performUpgrade,K as readUpgradeAttempt,k as readUpgradeFailures,ar as recordUpgradeFailure,M as rollbackToExactVersion,A as verifyInstalledVersion,g as writeUpgradeAttempt};
@@ -31,6 +31,7 @@ export type AgentWorkspace = {
31
31
  updatedAt: string;
32
32
  } | null;
33
33
  status: string;
34
+ pinnedAt?: string | null;
34
35
  machineId: string | null;
35
36
  machineName: string | null;
36
37
  runtimeAdapter: AgentType | null;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-workspace.d.ts","sourceRoot":"","sources":["../src/agent-workspace.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAEnD,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,kBAAkB,CAAA;CACnC,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,SAAS,CAAA;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;IACtB,IAAI,EAAE,sBAAsB,GAAG,IAAI,CAAA;CACpC,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;QAChB,SAAS,EAAE,MAAM,CAAA;QACjB,SAAS,EAAE,MAAM,CAAA;KAClB,GAAG,IAAI,CAAA;IACR,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,cAAc,EAAE,SAAS,GAAG,IAAI,CAAA;IAChC,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,qBAAqB,EAAE,CAAA;CAClC,CAAA"}
1
+ {"version":3,"file":"agent-workspace.d.ts","sourceRoot":"","sources":["../src/agent-workspace.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAEnD,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,kBAAkB,CAAA;CACnC,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,SAAS,CAAA;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;IACtB,IAAI,EAAE,sBAAsB,GAAG,IAAI,CAAA;CACpC,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;QAChB,SAAS,EAAE,MAAM,CAAA;QACjB,SAAS,EAAE,MAAM,CAAA;KAClB,GAAG,IAAI,CAAA;IACR,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,cAAc,EAAE,SAAS,GAAG,IAAI,CAAA;IAChC,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,qBAAqB,EAAE,CAAA;CAClC,CAAA"}
@@ -1,2 +1,2 @@
1
- export type ReqMethod = 'chat.send' | 'chat.enqueue' | 'chat.queue.get' | 'chat.queue.edit' | 'chat.queue.delete' | 'chat.abort' | 'session.resume' | 'session.history' | 'session.refresh' | 'session.tool.detail' | 'session.title.set' | 'fs.ls' | 'fs.read' | 'fs.write' | 'fs.export.markdown-pdf' | 'fs.export.markdown-pdf.setup' | 'fs.archive.zip' | 'fs.transfer' | 'fs.transfer.start' | 'fs.transfer.chunk' | 'fs.transfer.finish' | 'fs.transfer.abort' | 'fs.rename' | 'skill.list' | 'skill.install' | 'skill.doctor' | 'skill.setup' | 'skill.use' | 'region.probe' | 'region.switch' | 'upgrade.start' | 'upgrade.status' | 'upgrade.set-policy' | 'agents.refresh' | 'models.refresh' | 'agent.config.get' | 'agent.config.upsert' | 'agent.config.clear' | 'agent.config.test' | 'agent.capabilities.list' | 'manager.channel.get' | 'manager.channel.upsert' | 'session.wechat-rpa.channel.get' | 'session.wechat-rpa.channel.upsert' | 'session.wechat-rpa.channel.sync' | 'session.wechat-rpa.outbound.cancel' | 'manager.wechat-rpa.channel.get' | 'manager.wechat-rpa.channel.upsert' | 'manager.wechat-rpa.channel.sync' | 'manager.wechat-rpa.outbound.cancel' | 'wechat-rpa.helper.runtime' | 'wecom.send' | 'external.send' | 'room.sync' | 'room.send' | 'room.bind' | 'room.agent.bind-managed' | 'room.unbind';
1
+ export type ReqMethod = 'chat.send' | 'chat.enqueue' | 'chat.queue.get' | 'chat.queue.edit' | 'chat.queue.delete' | 'chat.abort' | 'session.resume' | 'session.history' | 'session.refresh' | 'session.tool.detail' | 'session.title.set' | 'fs.ls' | 'fs.read' | 'fs.write' | 'fs.export.markdown-pdf' | 'fs.export.markdown-pdf.setup' | 'fs.archive.zip' | 'fs.transfer' | 'fs.transfer.start' | 'fs.transfer.chunk' | 'fs.transfer.finish' | 'fs.transfer.abort' | 'fs.rename' | 'skill.list' | 'skill.install' | 'skill.doctor' | 'skill.setup' | 'skill.use' | 'region.probe' | 'region.switch' | 'upgrade.start' | 'upgrade.status' | 'upgrade.set-policy' | 'agents.refresh' | 'models.refresh' | 'agent.config.get' | 'agent.config.upsert' | 'agent.config.clear' | 'agent.config.test' | 'agent.capabilities.list' | 'manager.channel.get' | 'manager.channel.upsert' | 'session.wechat-rpa.channel.get' | 'session.wechat-rpa.channel.upsert' | 'session.wechat-rpa.channel.sync' | 'session.wechat-rpa.outbound.cancel' | 'manager.wechat-rpa.channel.get' | 'manager.wechat-rpa.channel.upsert' | 'manager.wechat-rpa.channel.sync' | 'manager.wechat-rpa.outbound.cancel' | 'wechat-rpa.helper.runtime' | 'wecom.send' | 'external.send' | 'room.sync' | 'room.send' | 'room.bind' | 'room.agent.bind-managed' | 'room.agent.restart-managed' | 'room.unbind';
2
2
  //# sourceMappingURL=methods.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"methods.d.ts","sourceRoot":"","sources":["../src/methods.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,WAAW,GACX,cAAc,GACd,gBAAgB,GAChB,iBAAiB,GACjB,mBAAmB,GACnB,YAAY,GACZ,gBAAgB,GAChB,iBAAiB,GACjB,iBAAiB,GACjB,qBAAqB,GACrB,mBAAmB,GACnB,OAAO,GACP,SAAS,GACT,UAAU,GACV,wBAAwB,GACxB,8BAA8B,GAC9B,gBAAgB,GAChB,aAAa,GACb,mBAAmB,GACnB,mBAAmB,GACnB,oBAAoB,GACpB,mBAAmB,GACnB,WAAW,GAGX,YAAY,GACZ,eAAe,GACf,cAAc,GACd,aAAa,GACb,WAAW,GACX,cAAc,GACd,eAAe,GACf,eAAe,GACf,gBAAgB,GAChB,oBAAoB,GACpB,gBAAgB,GAChB,gBAAgB,GAChB,kBAAkB,GAClB,qBAAqB,GACrB,oBAAoB,GACpB,mBAAmB,GACnB,yBAAyB,GACzB,qBAAqB,GACrB,wBAAwB,GACxB,gCAAgC,GAChC,mCAAmC,GACnC,iCAAiC,GACjC,oCAAoC,GACpC,gCAAgC,GAChC,mCAAmC,GACnC,iCAAiC,GACjC,oCAAoC,GACpC,2BAA2B,GAC3B,YAAY,GACZ,eAAe,GACf,WAAW,GACX,WAAW,GACX,WAAW,GACX,yBAAyB,GACzB,aAAa,CAAA"}
1
+ {"version":3,"file":"methods.d.ts","sourceRoot":"","sources":["../src/methods.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,WAAW,GACX,cAAc,GACd,gBAAgB,GAChB,iBAAiB,GACjB,mBAAmB,GACnB,YAAY,GACZ,gBAAgB,GAChB,iBAAiB,GACjB,iBAAiB,GACjB,qBAAqB,GACrB,mBAAmB,GACnB,OAAO,GACP,SAAS,GACT,UAAU,GACV,wBAAwB,GACxB,8BAA8B,GAC9B,gBAAgB,GAChB,aAAa,GACb,mBAAmB,GACnB,mBAAmB,GACnB,oBAAoB,GACpB,mBAAmB,GACnB,WAAW,GAGX,YAAY,GACZ,eAAe,GACf,cAAc,GACd,aAAa,GACb,WAAW,GACX,cAAc,GACd,eAAe,GACf,eAAe,GACf,gBAAgB,GAChB,oBAAoB,GACpB,gBAAgB,GAChB,gBAAgB,GAChB,kBAAkB,GAClB,qBAAqB,GACrB,oBAAoB,GACpB,mBAAmB,GACnB,yBAAyB,GACzB,qBAAqB,GACrB,wBAAwB,GACxB,gCAAgC,GAChC,mCAAmC,GACnC,iCAAiC,GACjC,oCAAoC,GACpC,gCAAgC,GAChC,mCAAmC,GACnC,iCAAiC,GACjC,oCAAoC,GACpC,2BAA2B,GAC3B,YAAY,GACZ,eAAe,GACf,WAAW,GACX,WAAW,GACX,WAAW,GACX,yBAAyB,GACzB,4BAA4B,GAC5B,aAAa,CAAA"}
@@ -25,6 +25,8 @@ export type RoomSummary = {
25
25
  lastSequence: RoomSequence;
26
26
  lastReadSequence?: RoomSequence;
27
27
  unreadCount?: number;
28
+ membershipRole?: RoomMembershipRole;
29
+ pinnedAt?: string | null;
28
30
  updatedAt: string;
29
31
  };
30
32
  export type RoomAuthorSnapshot = {
@@ -1 +1 @@
1
- {"version":3,"file":"room.d.ts","sourceRoot":"","sources":["../src/room.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"room.d.ts","sourceRoot":"","sources":["../src/room.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,aAAa,CAAA;AACtD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAA;AAC3D,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAA;AAC1D,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,OAAO,CAAA;AACjD,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAA;AAC7D,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAA;AAChE,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,CAAA;AACxE,MAAM,MAAM,kBAAkB,GAAG,aAAa,GAAG,cAAc,GAAG,QAAQ,CAAA;AAC1E,MAAM,MAAM,wBAAwB,GAAG,SAAS,GAAG,aAAa,GAAG,aAAa,CAAA;AAChF,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,aAAa,CAAA;AACvD,MAAM,MAAM,iBAAiB,GAAG,kBAAkB,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAA;AACrF,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,aAAa,GAAG,WAAW,CAAA;AACtE,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAA;AACrE,MAAM,MAAM,oBAAoB,GAC5B,SAAS,GACT,UAAU,GACV,UAAU,GACV,OAAO,GACP,UAAU,GACV,SAAS,GACT,SAAS,CAAA;AAEb,gEAAgE;AAChE,MAAM,MAAM,YAAY,GAAG,MAAM,CAAA;AAEjC,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,UAAU,CAAA;IAClB,UAAU,EAAE,cAAc,CAAA;IAC1B,UAAU,EAAE,cAAc,CAAA;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,YAAY,CAAA;IAC1B,gBAAgB,CAAC,EAAE,YAAY,CAAA;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,kBAAkB,CAAA;IACnC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,iBAAiB,CAAA;IAChC,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CACxC,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,iBAAiB,CAAA;IAChC,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,kBAAkB,CAAA;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,YAAY,CAAA;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,MAAM,EAAE,oBAAoB,CAAA;IAC5B,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,YAAY,CAAA;IACtB,IAAI,EAAE,eAAe,CAAA;IACrB,MAAM,EAAE,kBAAkB,CAAA;IAC1B,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAA;IAChC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,WAAW,EAAE,kBAAkB,EAAE,CAAA;IACjC,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,eAAe,CAAC,EAAE;QAChB,cAAc,EAAE,MAAM,CAAA;QACtB,kBAAkB,EAAE,MAAM,CAAA;QAC1B,QAAQ,EAAE,MAAM,CAAA;KACjB,GAAG,IAAI,CAAA;CACT,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,sBAAsB,CAAA;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,YAAY,CAAA;IACtB,OAAO,EAAE,eAAe,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EACD,cAAc,GACd,cAAc,GACd,yBAAyB,GACzB,2BAA2B,GAC3B,2BAA2B,GAC3B,sBAAsB,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,uBAAuB,GAAG,gBAAgB,CAAA;AAElE,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,aAAa,EAAE,YAAY,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,EAAE,MAAM,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC/B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,EAAE,MAAM,CAAA;IACvB,eAAe,EAAE,MAAM,CAAA;IACvB,oBAAoB,CAAC,EAAE,wBAAwB,CAAA;IAC/C,cAAc,CAAC,EAAE,kBAAkB,CAAA;CACpC,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shennian",
3
- "version": "0.3.9",
3
+ "version": "0.3.11",
4
4
  "description": "Shennian — AI Agent Control Plane CLI",
5
5
  "type": "module",
6
6
  "bin": {