@messenger-agent/client 0.36.0 → 0.37.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,11 @@
1
1
  import type { MaintenanceScheduler } from "./maintenance.js";
2
- import { type ReleaseChannel } from "./runtime.js";
2
+ import { type ReleaseChannel, type RuntimePreparation } from "./runtime.js";
3
3
  export type AutoUpgradeState = {
4
4
  status: "up-to-date" | "pending" | "scheduled" | "failed";
5
5
  currentVersion: string;
6
6
  channel: ReleaseChannel;
7
7
  latestVersion?: string;
8
+ prepared?: RuntimePreparation;
8
9
  lastCheckedAt?: string;
9
10
  updatedAt: string;
10
11
  message?: string;
@@ -18,7 +19,9 @@ type AutoUpgradeOptions = {
18
19
  now?: () => number;
19
20
  getCurrentVersion?: () => Promise<string>;
20
21
  getLatestVersion?: (channel: ReleaseChannel) => Promise<string>;
22
+ prepareUpgrade?: (version: string) => Promise<RuntimePreparation>;
21
23
  };
24
+ export declare const AUTO_UPGRADE_CHECK_INTERVAL_MS: number;
22
25
  export declare class AutoUpgradeScheduler {
23
26
  private readonly options;
24
27
  private state;
@@ -28,6 +31,7 @@ export declare class AutoUpgradeScheduler {
28
31
  private readonly now;
29
32
  private readonly getCurrentVersion;
30
33
  private readonly getLatestVersion;
34
+ private readonly prepareUpgrade;
31
35
  private readonly getChannel;
32
36
  constructor(options: AutoUpgradeOptions);
33
37
  start(): Promise<void>;
@@ -1,2 +1,2 @@
1
- import{mkdir as o,readFile as c,rename as u,writeFile as d}from"node:fs/promises";import{dirname as l}from"node:path";import{compareSemverVersions as m,currentPackageVersion as g,isPrereleaseVersion as r,resolveChannelPackageVersion as p}from"./runtime.js";const h=new Set(["scheduled","waiting","running","restarting","stopping"]);class y{options;state;timer;checkIntervalMs;pendingRetryMs;now;getCurrentVersion;getLatestVersion;getChannel;constructor(t){this.options=t,this.checkIntervalMs=t.checkIntervalMs??7200*1e3,this.pendingRetryMs=t.pendingRetryMs??3e4,this.now=t.now??Date.now,this.getCurrentVersion=t.getCurrentVersion??g,this.getLatestVersion=t.getLatestVersion??p,this.getChannel=t.getChannel??(()=>Promise.resolve("latest"))}async start(){if(this.state=await this.readState(),this.state?.status==="pending"||this.state?.status==="scheduled"){this.arm(this.pendingRetryMs);return}const t=this.state?.lastCheckedAt?Date.parse(this.state.lastCheckedAt):void 0,e=t===void 0?this.checkIntervalMs:this.checkIntervalMs-(this.now()-t);this.arm(Math.max(0,e))}stop(){this.timer&&clearTimeout(this.timer),this.timer=void 0}getState(){return this.state?structuredClone(this.state):void 0}async checkNow(){this.timer&&clearTimeout(this.timer),this.timer=void 0,await this.tick()}arm(t){this.timer&&clearTimeout(this.timer),this.timer=setTimeout(()=>{this.tick()},t),this.timer.unref()}async tick(){this.timer=void 0;try{const t=await this.getChannel(),e=await this.getCurrentVersion();let s=this.state?.status==="pending"||this.state?.status==="scheduled"?this.state.latestVersion:void 0,i=this.state?.lastCheckedAt;if(s||(s=await this.getLatestVersion(t),i=this.isoNow()),m(s,e)<=0){await this.updateState({status:"up-to-date",currentVersion:e,channel:t,latestVersion:s,lastCheckedAt:i,message:`Runtime ${e} is up to date on the ${t} channel`}),this.arm(this.checkIntervalMs);return}if(t==="latest"&&r(e)&&!r(s)){await this.updateState({status:"up-to-date",currentVersion:e,channel:t,latestVersion:s,lastCheckedAt:i,message:`Runtime ${e} is a pre-release ahead of the latest stable ${s}`}),this.arm(this.checkIntervalMs);return}const a=this.options.maintenance.getTask();if(w(a,s)){await this.updateState({status:"scheduled",currentVersion:e,channel:t,latestVersion:s,lastCheckedAt:i,message:`Waiting to upgrade to ${s}`}),this.arm(this.pendingRetryMs);return}if(a&&h.has(a.status)){await this.updateState({status:"pending",currentVersion:e,channel:t,latestVersion:s,lastCheckedAt:i,message:`Waiting for maintenance task ${a.id}`}),this.arm(this.pendingRetryMs);return}if(a?.source==="automatic"&&(a.status==="failed"||a.status==="cancelled")){await this.updateState({status:"failed",currentVersion:e,channel:t,latestVersion:s,lastCheckedAt:i,message:a.message??(a.status==="cancelled"?`Automatic upgrade to ${s} was cancelled`:`Automatic upgrade to ${s} failed`)}),this.arm(this.checkIntervalMs);return}await this.options.maintenance.schedule({operation:{type:"upgrade",version:s},delaySeconds:1,allowWaiting:!0,source:"automatic"}),await this.updateState({status:"scheduled",currentVersion:e,channel:t,latestVersion:s,lastCheckedAt:i,message:`Waiting to upgrade to ${s}`}),this.arm(this.pendingRetryMs)}catch(t){const e=await this.getCurrentVersion().catch(()=>"unknown");await this.updateState({status:"failed",currentVersion:e,channel:this.state?.channel??"latest",latestVersion:this.state?.latestVersion,lastCheckedAt:this.isoNow(),message:t instanceof Error?t.message:String(t)}),this.arm(this.checkIntervalMs)}}async updateState(t){this.state={...t,updatedAt:this.isoNow()},await o(l(this.options.statePath),{recursive:!0,mode:448});const e=`${this.options.statePath}.tmp`;await d(e,`${JSON.stringify(this.state,null,2)}
2
- `,{mode:384}),await u(e,this.options.statePath)}async readState(){try{return JSON.parse(await c(this.options.statePath,"utf8"))}catch(t){if(t.code==="ENOENT")return;throw t}}isoNow(){return new Date(this.now()).toISOString()}}function w(n,t){return n?.source==="automatic"&&h.has(n.status)&&n.operation.type==="upgrade"&&n.operation.version===t}export{y as AutoUpgradeScheduler};
1
+ import{mkdir as u,readFile as p,rename as l,writeFile as m}from"node:fs/promises";import{dirname as g}from"node:path";import{compareSemverVersions as w,currentPackageVersion as f,isPrereleaseVersion as o,resolveChannelPackageVersion as k}from"./runtime.js";const d=new Set(["scheduled","waiting","running","restarting","stopping"]),S=3600*1e3;class V{options;state;timer;checkIntervalMs;pendingRetryMs;now;getCurrentVersion;getLatestVersion;prepareUpgrade;getChannel;constructor(t){this.options=t,this.checkIntervalMs=t.checkIntervalMs??S,this.pendingRetryMs=t.pendingRetryMs??3e4,this.now=t.now??Date.now,this.getCurrentVersion=t.getCurrentVersion??f,this.getLatestVersion=t.getLatestVersion??k,this.prepareUpgrade=t.prepareUpgrade,this.getChannel=t.getChannel??(()=>Promise.resolve("latest"))}async start(){if(this.state=await this.readState(),this.state?.status==="pending"||this.state?.status==="scheduled"){this.arm(this.pendingRetryMs);return}const t=this.state?.lastCheckedAt?Date.parse(this.state.lastCheckedAt):void 0,s=t===void 0?this.checkIntervalMs:this.checkIntervalMs-(this.now()-t);this.arm(Math.max(0,s))}stop(){this.timer&&clearTimeout(this.timer),this.timer=void 0}getState(){return this.state?structuredClone(this.state):void 0}async checkNow(){this.timer&&clearTimeout(this.timer),this.timer=void 0,await this.tick()}arm(t){this.timer&&clearTimeout(this.timer),this.timer=setTimeout(()=>{this.tick()},t),this.timer.unref()}async tick(){this.timer=void 0;try{const t=await this.getChannel(),s=await this.getCurrentVersion();let e=this.state?.status==="pending"||this.state?.status==="scheduled"?this.state.latestVersion:void 0,i=this.state?.lastCheckedAt;if(e||(e=await this.getLatestVersion(t),i=this.isoNow()),w(e,s)<=0){await this.updateState({status:"up-to-date",currentVersion:s,channel:t,latestVersion:e,lastCheckedAt:i,message:`Runtime ${s} is up to date on the ${t} channel`}),this.arm(this.checkIntervalMs);return}if(t==="latest"&&o(s)&&!o(e)){await this.updateState({status:"up-to-date",currentVersion:s,channel:t,latestVersion:e,lastCheckedAt:i,message:`Runtime ${s} is a pre-release ahead of the latest stable ${e}`}),this.arm(this.checkIntervalMs);return}const a=this.options.maintenance.getTask();if(a?.source==="automatic"&&(a.status==="failed"||a.status==="cancelled")){await this.updateState({status:"failed",currentVersion:s,channel:t,latestVersion:e,prepared:this.state?.prepared,lastCheckedAt:i,message:a.message??(a.status==="cancelled"?`Automatic upgrade to ${e} was cancelled`:`Automatic upgrade to ${e} failed`)}),this.arm(this.checkIntervalMs);return}const h=c(a,e)?a:void 0;let r=(h?.operation.type==="upgrade"?h.operation.prepared:void 0)??(this.state?.prepared?.version===e?this.state.prepared:void 0);if(!r&&this.prepareUpgrade&&(r=await this.prepareUpgrade(e)),c(a,e)){await this.updateState({status:"scheduled",currentVersion:s,channel:t,latestVersion:e,prepared:r,lastCheckedAt:i,message:`Waiting to upgrade to ${e}`}),this.arm(this.pendingRetryMs);return}if(a&&d.has(a.status)){await this.updateState({status:"pending",currentVersion:s,channel:t,latestVersion:e,prepared:r,lastCheckedAt:i,message:`Waiting for maintenance task ${a.id}`}),this.arm(this.pendingRetryMs);return}await this.options.maintenance.schedule({operation:{type:"upgrade",version:e,...r?{prepared:r}:{}},delaySeconds:1,allowWaiting:!0,source:"automatic"}),await this.updateState({status:"scheduled",currentVersion:s,channel:t,latestVersion:e,prepared:r,lastCheckedAt:i,message:`Waiting to upgrade to ${e}`}),this.arm(this.pendingRetryMs)}catch(t){const s=await this.getCurrentVersion().catch(()=>"unknown");await this.updateState({status:"failed",currentVersion:s,channel:this.state?.channel??"latest",latestVersion:this.state?.latestVersion,prepared:this.state?.prepared,lastCheckedAt:this.isoNow(),message:t instanceof Error?t.message:String(t)}),this.arm(this.checkIntervalMs)}}async updateState(t){this.state={...t,updatedAt:this.isoNow()},await u(g(this.options.statePath),{recursive:!0,mode:448});const s=`${this.options.statePath}.tmp`;await m(s,`${JSON.stringify(this.state,null,2)}
2
+ `,{mode:384}),await l(s,this.options.statePath)}async readState(){try{return JSON.parse(await p(this.options.statePath,"utf8"))}catch(t){if(t.code==="ENOENT")return;throw t}}isoNow(){return new Date(this.now()).toISOString()}}function c(n,t){return n?.source==="automatic"&&d.has(n.status)&&n.operation.type==="upgrade"&&n.operation.version===t}export{S as AUTO_UPGRADE_CHECK_INTERVAL_MS,V as AutoUpgradeScheduler};
package/dist/control.js CHANGED
@@ -1,2 +1,2 @@
1
- import{chmod as d,mkdir as m,rm as s}from"node:fs/promises";import{createConnection as w,createServer as g}from"node:net";import{dirname as y,join as p}from"node:path";import{readConfigYaml as v}from"./config-file.js";import{productName as c}from"./identity.js";import{defaultDataDir as S}from"./paths.js";async function u(e){const n=await v(e),t=typeof n.data_dir=="string"&&n.data_dir.trim()?n.data_dir:S;return p(t,"runtime","client.sock")}async function I(e,n){await m(y(e),{recursive:!0,mode:448}),await s(e,{force:!0});const t=g({allowHalfOpen:!0},r=>{let a="";r.setEncoding("utf8"),r.on("error",()=>{}),r.on("data",o=>{a+=o}),r.on("end",()=>{h(a,n).then(o=>r.end(`${JSON.stringify(o)}
2
- `))})});return await k(t,e),await d(e,384),{async close(){await E(t),await s(e,{force:!0})}}}async function A(e,n){const t=await u(e),r=await l(t,{action:"restart",agent:n}).catch(a=>{const o=a instanceof Error?a.message:String(a);throw new Error(`Unable to contact the ${c} service: ${o}`)});if(!r.ok)throw new Error(r.error??`Failed to restart ${n} agent`)}async function D(e){return i(e,{action:"activity"})}async function J(e,n){return i(e,{action:"schedule-maintenance",...n})}async function M(e){return i(e,{action:"maintenance-status"})}async function R(e){return i(e,{action:"maintenance-cancel"})}async function h(e,n){try{const t=JSON.parse(e);switch(t.action){case"restart":return t.agent!=="codex"&&t.agent!=="claude"?{ok:!1,error:"Invalid control request"}:(await n.restartAgent(t.agent),{ok:!0});case"activity":return{ok:!0,data:await n.getActivity()};case"schedule-maintenance":return!q(t.operation)||!Number.isInteger(t.delaySeconds)||typeof t.allowWaiting!="boolean"?{ok:!1,error:"Invalid maintenance request"}:{ok:!0,data:await n.maintenance.schedule({operation:t.operation,delaySeconds:t.delaySeconds,allowWaiting:t.allowWaiting})};case"maintenance-status":return{ok:!0,data:n.maintenance.getTask()};case"maintenance-cancel":return{ok:!0,data:await n.maintenance.cancel()};default:return{ok:!1,error:"Invalid control request"}}}catch(t){return{ok:!1,error:t instanceof Error?t.message:String(t)}}}function q(e){return!e||typeof e!="object"||!("type"in e)?!1:e.type==="upgrade"?"version"in e&&typeof e.version=="string"&&e.version.length>0:e.type==="restart"?!("agent"in e&&e.agent!==void 0&&e.agent!=="codex"&&e.agent!=="claude"):e.type==="stop"||e.type==="uninstall"}async function i(e,n){const t=await u(e),r=await l(t,n).catch(a=>{const o=a instanceof Error?a.message:String(a);throw new Error(`Unable to contact the ${c} service: ${o}`)});if(!r.ok)throw new Error(r.error??"Client control request failed");return r.data}function k(e,n){return new Promise((t,r)=>{e.once("error",r),e.listen(n,()=>{e.off("error",r),t()})})}function E(e){return new Promise((n,t)=>{e.close(r=>r?t(r):n())})}function l(e,n){return new Promise((t,r)=>{const a=w(e);let o="";a.setEncoding("utf8"),a.once("error",r),a.on("data",f=>{o+=f}),a.once("connect",()=>a.end(JSON.stringify(n))),a.once("end",()=>{try{t(JSON.parse(o))}catch{r(new Error(`Invalid response from the ${c} service`))}})})}export{u as readControlSocketPath,A as requestAgentRestart,D as requestClientActivity,R as requestMaintenanceCancel,M as requestMaintenanceStatus,J as requestScheduleMaintenance,I as startControlServer};
1
+ import{chmod as f,mkdir as m,rm as s}from"node:fs/promises";import{createConnection as w,createServer as g}from"node:net";import{dirname as y,join as p}from"node:path";import{readConfigYaml as v}from"./config-file.js";import{productName as c}from"./identity.js";import{defaultDataDir as S}from"./paths.js";async function u(e){const n=await v(e),t=typeof n.data_dir=="string"&&n.data_dir.trim()?n.data_dir:S;return p(t,"runtime","client.sock")}async function I(e,n){await m(y(e),{recursive:!0,mode:448}),await s(e,{force:!0});const t=g({allowHalfOpen:!0},r=>{let a="";r.setEncoding("utf8"),r.on("error",()=>{}),r.on("data",o=>{a+=o}),r.on("end",()=>{h(a,n).then(o=>r.end(`${JSON.stringify(o)}
2
+ `))})});return await k(t,e),await f(e,384),{async close(){await E(t),await s(e,{force:!0})}}}async function A(e,n){const t=await u(e),r=await l(t,{action:"restart",agent:n}).catch(a=>{const o=a instanceof Error?a.message:String(a);throw new Error(`Unable to contact the ${c} service: ${o}`)});if(!r.ok)throw new Error(r.error??`Failed to restart ${n} agent`)}async function D(e){return i(e,{action:"activity"})}async function J(e,n){return i(e,{action:"schedule-maintenance",...n})}async function M(e){return i(e,{action:"maintenance-status"})}async function R(e){return i(e,{action:"maintenance-cancel"})}async function h(e,n){try{const t=JSON.parse(e);switch(t.action){case"restart":return t.agent!=="codex"&&t.agent!=="claude"?{ok:!1,error:"Invalid control request"}:(await n.restartAgent(t.agent),{ok:!0});case"activity":return{ok:!0,data:await n.getActivity()};case"schedule-maintenance":return!q(t.operation)||!Number.isInteger(t.delaySeconds)||typeof t.allowWaiting!="boolean"?{ok:!1,error:"Invalid maintenance request"}:{ok:!0,data:await n.maintenance.schedule({operation:t.operation,delaySeconds:t.delaySeconds,allowWaiting:t.allowWaiting})};case"maintenance-status":return{ok:!0,data:n.maintenance.getTask()};case"maintenance-cancel":return{ok:!0,data:await n.maintenance.cancel()};default:return{ok:!1,error:"Invalid control request"}}}catch(t){return{ok:!1,error:t instanceof Error?t.message:String(t)}}}function q(e){return!e||typeof e!="object"||!("type"in e)?!1:e.type==="upgrade"?!("prepared"in e)&&"version"in e&&typeof e.version=="string"&&e.version.length>0:e.type==="restart"?!("agent"in e&&e.agent!==void 0&&e.agent!=="codex"&&e.agent!=="claude"):e.type==="stop"||e.type==="uninstall"}async function i(e,n){const t=await u(e),r=await l(t,n).catch(a=>{const o=a instanceof Error?a.message:String(a);throw new Error(`Unable to contact the ${c} service: ${o}`)});if(!r.ok)throw new Error(r.error??"Client control request failed");return r.data}function k(e,n){return new Promise((t,r)=>{e.once("error",r),e.listen(n,()=>{e.off("error",r),t()})})}function E(e){return new Promise((n,t)=>{e.close(r=>r?t(r):n())})}function l(e,n){return new Promise((t,r)=>{const a=w(e);let o="";a.setEncoding("utf8"),a.once("error",r),a.on("data",d=>{o+=d}),a.once("connect",()=>a.end(JSON.stringify(n))),a.once("end",()=>{try{t(JSON.parse(o))}catch{r(new Error(`Invalid response from the ${c} service`))}})})}export{u as readControlSocketPath,A as requestAgentRestart,D as requestClientActivity,R as requestMaintenanceCancel,M as requestMaintenanceStatus,J as requestScheduleMaintenance,I as startControlServer};
@@ -1,8 +1,10 @@
1
1
  import type { ClientActivityStatus, ManagedAgentName } from "./supervisor.js";
2
+ import type { RuntimePreparation } from "./runtime.js";
2
3
  export type MaintenanceOperation = {
3
4
  type: "upgrade";
4
5
  version: string;
5
6
  path?: string;
7
+ prepared?: RuntimePreparation;
6
8
  } | {
7
9
  type: "restart";
8
10
  agent?: ManagedAgentName;
package/dist/runtime.d.ts CHANGED
@@ -15,6 +15,24 @@ export type RuntimeInstallOptions = {
15
15
  hostArtifactDirectory?: string;
16
16
  clientDirectory?: string;
17
17
  };
18
+ export type RuntimePreparation = {
19
+ releaseDir: string;
20
+ currentLink: string;
21
+ wrapperPath: string;
22
+ legacyServiceWrapperPath: string;
23
+ cliWrapperPath: string;
24
+ legacyCliWrapperPath: string;
25
+ version: string;
26
+ configPath: string;
27
+ path?: string;
28
+ skillsSourceDir: string;
29
+ agentHomes: string[];
30
+ platform: "linux" | "darwin";
31
+ arch: "x64" | "arm64";
32
+ hostVersion: string;
33
+ hostReleaseDir: string;
34
+ hostCurrentLink: string;
35
+ };
18
36
  export type RuntimeInstallResult = {
19
37
  releaseDir: string;
20
38
  currentLink: string;
@@ -23,8 +41,8 @@ export type RuntimeInstallResult = {
23
41
  cliWrapperPath: string;
24
42
  legacyCliWrapperPath: string;
25
43
  version: string;
26
- previousReleaseDir?: string;
27
44
  hostCurrentLink: string;
45
+ previousReleaseDir?: string;
28
46
  previousHostReleaseDir?: string;
29
47
  previousWrappers: PreviousWrapper[];
30
48
  };
@@ -57,6 +75,8 @@ export declare function currentPackageVersion(): Promise<string>;
57
75
  export declare function currentBundledSkillsDir(moduleUrl?: string): string;
58
76
  export declare function defaultAgentHomes(): [string, string];
59
77
  export declare function installRuntime(options: RuntimeInstallOptions): Promise<RuntimeInstallResult>;
78
+ export declare function prepareRuntime(options: RuntimeInstallOptions): Promise<RuntimePreparation>;
79
+ export declare function activateRuntime(preparation: RuntimePreparation): Promise<RuntimeInstallResult>;
60
80
  export declare function rollbackRuntime(result: RuntimeInstallResult): Promise<void>;
61
81
  export declare function nodeHostPackageName(platform: "linux" | "darwin", arch: "x64" | "arm64"): string;
62
82
  export declare function nodeHostMirrorTarballUrl(platform: "linux" | "darwin", arch: "x64" | "arm64", version: string, mirrorUrl?: string): string;
package/dist/runtime.js CHANGED
@@ -1,3 +1,3 @@
1
- import{createHash as se}from"node:crypto";import{createReadStream as ce,createWriteStream as le}from"node:fs";import{access as ue,cp as j,lstat as Z,mkdir as E,readFile as S,readlink as fe,rename as k,rm as y,symlink as de,writeFile as N}from"node:fs/promises";import{homedir as q}from"node:os";import{basename as me,delimiter as we,dirname as A,isAbsolute as G,join as i,relative as pe,resolve as v}from"node:path";import{Readable as he}from"node:stream";import{pipeline as ge}from"node:stream/promises";import{fileURLToPath as Q}from"node:url";import{normalizeOptional as ye,resolveAgentBridgeUrls as $e}from"@messenger-agent/shared/agent-config";import{runCommand as P}from"./exec.js";import{cliName as ve,legacyCliName as Ee,runtimePackageScope as ke}from"./identity.js";import{defaultBinDir as Ne,defaultRuntimeDir as Pe,legacyCodingAgentPaths as xe,messengerAgentPaths as be}from"./paths.js";const O="https://registry.npmjs.org",I="@messenger-agent/client",ar=["latest","beta","alpha"];function ir(e){if(!(e==null||e==="")){if(e==="stable")return"latest";if(e==="latest"||e==="beta"||e==="alpha")return e;throw new Error(`Unknown release channel: ${String(e)} (expected latest, beta, or alpha)`)}}function W(e){return e==="stable"?"latest":e==="latest"||e==="beta"||e==="alpha"?e:void 0}function or(e,r){const t=W(e),n=r??t;return{version:t?n??t:e,channel:n}}function sr(e){return/^\d+\.\d+\.\d+-/.test(e)}function cr(e,r){const[t]=e.split("+",1),[n]=r.split("+",1),a=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/.exec(t??""),s=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/.exec(n??"");if(!a||!s)throw new Error(`Automatic upgrades require semantic versions, received: ${e} and ${r}`);for(let l=1;l<=3;l+=1){const c=Number(a[l])-Number(s[l]);if(c!==0)return Math.sign(c)}return De(a[4],s[4])}function De(e,r){if(!e&&!r)return 0;if(!e)return 1;if(!r)return-1;const t=e.split("."),n=r.split(".");for(let a=0;a<Math.max(t.length,n.length);a+=1){const s=t[a],l=n[a];if(s===void 0)return-1;if(l===void 0)return 1;const c=/^\d+$/.test(s),o=/^\d+$/.test(l);if(c&&o){const w=Number(s)-Number(l);if(w!==0)return Math.sign(w);continue}if(c)return-1;if(o)return 1;if(s!==l)return s<l?-1:1}return 0}async function Re(){const e=i(A(Q(import.meta.url)),"..","package.json");return JSON.parse(await S(e,"utf8")).version??"latest"}function lr(e=import.meta.url){const r=A(Q(e));return me(r)==="src"?i(r,"..","assets","skills"):i(r,"assets","skills")}function Se(){return[process.env.CODEX_HOME??i(q(),".codex"),process.env.CLAUDE_CONFIG_DIR??i(q(),".claude")]}async function m(e){await y(e,{recursive:!0,force:!0})}async function V(e,r){const t=`${r}.tmp-${process.pid}`;await m(t),await de(e,t,"dir"),await k(t,r)}async function z(e){try{return(await Z(e)).isSymbolicLink()}catch{return!1}}async function ur(e){const r=Ae(e.configPath),t=e.runtimeDir??r?.runtimeDir??Pe,n=e.binDir??r?.binDir??Ne,a=Ie(e.platform??process.platform),s=We(e.arch??process.arch),l=W(e.version),c=e.version==="current"?await Re():l?await Me(l,e.registryUrl):e.version,o=await Ue({runtimeDir:t,platform:a,arch:s,registryUrl:e.registryUrl,mirrorUrl:ee(e.server,e.nodeHostMirrorUrl),artifactDirectory:e.hostArtifactDirectory}),w=c.replaceAll("/","_").replaceAll(":","_"),p=i(t,"releases"),u=i(p,w),h=i(t,"current"),D=i(u,"node_modules","@messenger-agent","client","dist","index.js"),d=i(u,"node_modules","@messenger-agent","client","package.json"),_=e.skillsSourceDir??i(u,"node_modules","@messenger-agent","client","dist","assets","skills"),M=i(n,"messenger-agent-service"),U=i(n,"coding-agent-client-service"),T=i(n,ve),L=i(n,Ee),ae=[M,U,T,L];if(await E(p,{recursive:!0,mode:448}),await E(n,{recursive:!0,mode:448}),!(await F(d,c)&&(await X(o.nodeExecutable,D)).status===0)){const f=`${u}.tmp-${process.pid}`,R=i(f,"node_modules","@messenger-agent","client","dist","index.js");await m(f),await E(f,{recursive:!0,mode:448});try{if(e.clientDirectory&&await F(i(e.clientDirectory,"node_modules","@messenger-agent","client","package.json"),c))await j(e.clientDirectory,f,{recursive:!0});else{const x=i(f,".npmrc");await N(x,""),await P(o.nodeExecutable,[o.npmCli,"install","--prefix",f,"--omit=dev","--include=optional","--ignore-scripts","--no-audit","--no-fund","--registry",e.registryUrl??process.env.MESSENGER_AGENT_NPM_REGISTRY??O,"--userconfig",x,`${I}@${c}`],{env:{PATH:Le(o.nodeExecutable,e.path)},cwd:f})}if(!await F(i(f,"node_modules","@messenger-agent","client","package.json"),c))throw new Error(`Installed Messenger Agent Client does not match ${c}`);const g=await X(o.nodeExecutable,R);if(g.status!==0)throw new Error(`Messenger Agent Client self-check failed: ${g.stderr||g.stdout}`);await m(u),await k(f,u)}catch(g){throw await m(f),g}}const[ie,oe]=Se();await Ve(_,[e.codexHome??ie,e.claudeHome??oe]);const J=await ne(h),B=await ne(o.currentLink),Y=await Promise.all(ae.map(async f=>({path:f,content:await He(f)})));await z(h)||await m(h),await z(o.currentLink)||await m(o.currentLink);try{await V(o.releaseDir,o.currentLink),await V(u,h);const f=b(o.currentLink,o.manifest.node),R=i(h,"node_modules","@messenger-agent","client","dist","index.js"),g=["#!/bin/sh","set -eu",...e.path?[`export PATH=${$(e.path)}`]:[],`export AGENT_CONFIG_PATH=${$(e.configPath)}`,`exec ${$(f)} ${$(R)} run-service --config ${$(e.configPath)}`,""].join(`
2
- `),x=["#!/bin/sh","set -eu",`export AGENT_CONFIG_PATH=${$(e.configPath)}`,`exec ${$(f)} ${$(R)} "$@"`,""].join(`
3
- `);await N(M,g,{mode:448}),await N(U,g,{mode:448}),await N(T,x,{mode:448}),await N(L,x,{mode:448})}catch(f){throw await H(J,h),await H(B,o.currentLink),await K(Y),f}return{releaseDir:u,currentLink:h,wrapperPath:M,legacyServiceWrapperPath:U,cliWrapperPath:T,legacyCliWrapperPath:L,version:c,previousReleaseDir:J,hostCurrentLink:o.currentLink,previousHostReleaseDir:B,previousWrappers:Y}}async function X(e,r){return P(e,[r,"self-check"],{allowFailure:!0})}function Ae(e){const r=be();if(v(e)===v(r.configPath))return r;const t=xe();return v(e)===v(t.configPath)?t:void 0}async function fr(e){await H(e.previousReleaseDir,e.currentLink),await H(e.previousHostReleaseDir,e.hostCurrentLink),await K(e.previousWrappers)}async function H(e,r){e?await V(e,r):await m(r)}async function He(e){try{return await S(e,"utf8")}catch(r){if(r.code==="ENOENT")return;throw r}}async function K(e){await Promise.all(e.map(({path:r,content:t})=>t===void 0?m(r):N(r,t,{mode:448})))}function Ce(e,r){return`${ke}/node-host-${e}-${r}`}function _e(e,r,t,n=ee()){return`${n.replace(/\/$/,"")}/${e}/${r}/${encodeURIComponent(t)}.tgz`}function ee(e,r=process.env.MESSENGER_AGENT_NODE_HOST_MIRROR_URL){return(ye(r)??`${$e(e).server}/messenger/agent/node-host`).replace(/\/$/,"")}async function Me(e,r){return(await re(I,e,r)).version}async function Ue(e){const r=Ce(e.platform,e.arch),t=e.artifactDirectory?void 0:await je(r,"latest",e.registryUrl),a=(e.artifactDirectory?await te(i(e.artifactDirectory,"manifest.json"),{platform:e.platform,arch:e.arch}):void 0)?.version??t?.version;if(!a)throw new Error(`Unable to resolve ${r}`);const s=i(e.runtimeDir,"host"),l=i(s,"releases"),c=`${a}-${e.platform}-${e.arch}`.replaceAll("/","_").replaceAll(":","_"),o=i(l,c),w=i(s,"current"),p=i(o,"manifest.json");if(await E(l,{recursive:!0,mode:448}),!await C(p)){const d=`${o}.tmp-${process.pid}`;await m(d),await E(d,{recursive:!0,mode:448});try{e.artifactDirectory?await j(e.artifactDirectory,d,{recursive:!0}):t&&await Te(t,d,_e(e.platform,e.arch,t.version,e.mirrorUrl)),await m(o),await k(d,o)}catch(_){throw await m(d),_}}const u=await te(p,{version:a,platform:e.platform,arch:e.arch});await Oe(o,u);const h=b(o,u.node),D=b(o,u.npm);if(!await C(h)||!await C(D))throw new Error(`Node Host ${r}@${a} is incomplete`);if(u.platform==="darwin"){const d=i(o,"Messenger Agent.app");await P("codesign",["--verify","--deep","--strict",d]),await P("spctl",["--assess","--type","execute",d])}return{releaseDir:o,currentLink:w,nodeExecutable:h,npmCli:D,manifest:u}}async function Te(e,r,t){const n=`${r}.tgz`;try{const a=[];let s=!1;for(const l of new Set([t,e.tarball]))try{await y(n,{force:!0});const c=await fetch(l);if(!c.ok||!c.body)throw new Error(`HTTP ${c.status}`);await ge(he.fromWeb(c.body),le(n,{mode:384})),await Ge(n,e.integrity),s=!0;break}catch(c){a.push(`${l}: ${c instanceof Error?c.message:String(c)}`)}if(!s)throw new Error(`Unable to download ${e.packageName}@${e.version}: ${a.join("; ")}`);await P("tar",["-xzf",n,"-C",r,"--strip-components=2","package/host"])}finally{await y(n,{force:!0})}}async function F(e,r){try{const t=JSON.parse(await S(e,"utf8"));return t.name===I&&t.version===r}catch{return!1}}function Le(e,r=process.env.PATH){const t=A(e);return r?`${t}${we}${r}`:t}async function je(e,r,t=process.env.MESSENGER_AGENT_NPM_REGISTRY??O){const{metadata:n,version:a}=await re(e,r,t),s=n.versions?.[a]?.dist;if(!s?.tarball||!s.integrity)throw new Error(`Registry returned incomplete artifact metadata for ${e}@${a}`);return{packageName:e,version:a,tarball:s.tarball,integrity:s.integrity}}async function re(e,r,t=process.env.MESSENGER_AGENT_NPM_REGISTRY??O){const n=`${t.replace(/\/$/,"")}/${encodeURIComponent(e)}`,a=await fetch(n,{headers:{accept:"application/json"}});if(!a.ok)throw new Error(`Unable to resolve ${e}: HTTP ${a.status}`);const s=await a.json(),l=W(r)?s["dist-tags"]?.[r]:r;if(!l)throw new Error(`Registry has no ${r} release for ${e}`);return{metadata:s,version:l}}async function Ge(e,r){const t=r.indexOf("-");if(t<=0)throw new Error("Node Host has an invalid integrity value");const n=r.slice(0,t),a=r.slice(t+1),s=se(n);for await(const l of ce(e))s.update(l);if(s.digest("base64")!==a)throw new Error("Node Host integrity verification failed")}async function te(e,r){const t=JSON.parse(await S(e,"utf8"));if(t.schemaVersion!==1||t.product!=="messenger-agent-node-host"||r.version!==void 0&&t.version!==r.version||typeof t.version!="string"||typeof t.nodeVersion!="string"||t.platform!==r.platform||t.arch!==r.arch||typeof t.node!="string"||typeof t.npm!="string"||t.payload!==void 0&&typeof t.payload!="string")throw new Error(`Node Host manifest does not match ${r.platform}-${r.arch}${r.version?`@${r.version}`:""}`);return t}async function Oe(e,r){if(!r.payload)return;const t=b(e,r.node);if(await C(t))return;if(r.platform!=="darwin")throw new Error("Only macOS Node Hosts may contain a zip payload");const n=b(e,r.payload);await P("ditto",["-x","-k",n,e])}function b(e,r){if(!r||G(r))throw new Error(`Node Host contains an unsafe path: ${r}`);const t=v(e),n=v(e,r),a=pe(t,n);if(a.startsWith("..")||G(a))throw new Error(`Node Host contains an unsafe path: ${r}`);return n}function Ie(e){if(e==="linux"||e==="darwin")return e;throw new Error(`No Messenger Agent runtime is available for platform: ${e}`)}function We(e){if(e==="x64"||e==="arm64")return e;throw new Error(`No Messenger Agent runtime is available for architecture: ${e}`)}async function ne(e){if(!await z(e))return;const r=await fe(e);return G(r)?r:v(A(e),r)}async function C(e){try{return await ue(e),!0}catch{return!1}}async function Ve(e,r){const t="manage-messenger-agent",n="manage-coding-agent-client",a=i(e,t),s=await ze(a);for(const l of new Set(r)){const c=i(l,"skills"),o=i(c,t),w=i(c,`.${t}.tmp-${process.pid}`),p=i(c,`.${t}.old-${process.pid}`);if(await y(w,{recursive:!0,force:!0}),await y(p,{recursive:!0,force:!0}),await y(i(c,n),{recursive:!0,force:!0}),!s){await y(o,{recursive:!0,force:!0});continue}await E(c,{recursive:!0,mode:448}),await j(a,w,{recursive:!0}),await k(o,p).catch(u=>{if(u.code!=="ENOENT")throw u});try{await k(w,o),await y(p,{recursive:!0,force:!0})}catch(u){throw await k(p,o).catch(()=>{}),u}}}async function ze(e){try{return(await Z(e)).isDirectory()}catch(r){if(r.code==="ENOENT")return!1;throw r}}function $(e){return`'${e.replaceAll("'","'\\''")}'`}export{cr as compareSemverVersions,lr as currentBundledSkillsDir,Re as currentPackageVersion,Se as defaultAgentHomes,ur as installRuntime,sr as isPrereleaseVersion,_e as nodeHostMirrorTarballUrl,Ce as nodeHostPackageName,ir as normalizeReleaseChannel,or as normalizeUpgradeVersion,W as parseReleaseChannel,ar as releaseChannels,Me as resolveChannelPackageVersion,ee as resolveNodeHostMirrorUrl,fr as rollbackRuntime,Ve as syncBundledSkills};
1
+ import{createHash as ce}from"node:crypto";import{createReadStream as le,createWriteStream as ue}from"node:fs";import{access as fe,cp as V,lstat as re,mkdir as D,readFile as U,readlink as de,rename as b,rm as $,symlink as me,writeFile as R}from"node:fs/promises";import{homedir as te}from"node:os";import{basename as pe,delimiter as we,dirname as T,isAbsolute as z,join as o,relative as he,resolve as k}from"node:path";import{Readable as ge}from"node:stream";import{pipeline as ye}from"node:stream/promises";import{fileURLToPath as ae}from"node:url";import{normalizeOptional as $e,resolveAgentBridgeUrls as ve}from"@messenger-agent/shared/agent-config";import{runCommand as S}from"./exec.js";import{cliName as Ee,legacyCliName as ke,runtimePackageScope as Pe}from"./identity.js";import{defaultBinDir as Ne,defaultRuntimeDir as xe,legacyCodingAgentPaths as De,messengerAgentPaths as be}from"./paths.js";const F="https://registry.npmjs.org",J="@messenger-agent/client",ir=["latest","beta","alpha"];function sr(e){if(!(e==null||e==="")){if(e==="stable")return"latest";if(e==="latest"||e==="beta"||e==="alpha")return e;throw new Error(`Unknown release channel: ${String(e)} (expected latest, beta, or alpha)`)}}function B(e){return e==="stable"?"latest":e==="latest"||e==="beta"||e==="alpha"?e:void 0}function cr(e,r){const t=B(e),a=r??t;return{version:t?a??t:e,channel:a}}function lr(e){return/^\d+\.\d+\.\d+-/.test(e)}function ur(e,r){const[t]=e.split("+",1),[a]=r.split("+",1),n=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/.exec(t??""),i=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/.exec(a??"");if(!n||!i)throw new Error(`Automatic upgrades require semantic versions, received: ${e} and ${r}`);for(let c=1;c<=3;c+=1){const s=Number(n[c])-Number(i[c]);if(s!==0)return Math.sign(s)}return Re(n[4],i[4])}function Re(e,r){if(!e&&!r)return 0;if(!e)return 1;if(!r)return-1;const t=e.split("."),a=r.split(".");for(let n=0;n<Math.max(t.length,a.length);n+=1){const i=t[n],c=a[n];if(i===void 0)return-1;if(c===void 0)return 1;const s=/^\d+$/.test(i),l=/^\d+$/.test(c);if(s&&l){const m=Number(i)-Number(c);if(m!==0)return Math.sign(m);continue}if(s)return-1;if(l)return 1;if(i!==c)return i<c?-1:1}return 0}async function Se(){const e=o(T(ae(import.meta.url)),"..","package.json");return JSON.parse(await U(e,"utf8")).version??"latest"}function fr(e=import.meta.url){const r=T(ae(e));return pe(r)==="src"?o(r,"..","assets","skills"):o(r,"assets","skills")}function Ce(){return[process.env.CODEX_HOME??o(te(),".codex"),process.env.CLAUDE_CONFIG_DIR??o(te(),".claude")]}async function w(e){await $(e,{recursive:!0,force:!0})}async function Y(e,r){const t=`${r}.tmp-${process.pid}`;await w(t),await me(e,t,"dir"),await b(t,r)}async function Z(e){try{return(await re(e)).isSymbolicLink()}catch{return!1}}async function dr(e){return Ae(await He(e))}async function He(e){const r=_e(e.configPath),t=e.runtimeDir??r?.runtimeDir??xe,a=e.binDir??r?.binDir??Ne,n=ze(e.platform??process.platform),i=Fe(e.arch??process.arch),c=B(e.version),s=e.version==="current"?await Se():c?await je(c,e.registryUrl):e.version,l=await Ge({runtimeDir:t,platform:n,arch:i,registryUrl:e.registryUrl,mirrorUrl:oe(e.server,e.nodeHostMirrorUrl),artifactDirectory:e.hostArtifactDirectory}),m=s.replaceAll("/","_").replaceAll(":","_"),p=o(t,"releases"),u=o(p,m),N=o(t,"current"),x=o(u,"node_modules","@messenger-agent","client","dist","index.js"),f=o(u,"node_modules","@messenger-agent","client","package.json"),g=e.skillsSourceDir??o(u,"node_modules","@messenger-agent","client","dist","assets","skills"),h=o(a,"messenger-agent-service"),O=o(a,"coding-agent-client-service"),W=o(a,Ee),I=o(a,ke);if(await D(p,{recursive:!0,mode:448}),await D(a,{recursive:!0,mode:448}),!(await G(f,s)&&(await q(l.nodeExecutable,x)).status===0)){const d=`${u}.tmp-${process.pid}`,M=o(d,"node_modules","@messenger-agent","client","dist","index.js");await w(d),await D(d,{recursive:!0,mode:448});try{if(e.clientDirectory&&await G(o(e.clientDirectory,"node_modules","@messenger-agent","client","package.json"),s))await V(e.clientDirectory,d,{recursive:!0});else{const H=o(d,".npmrc");await R(H,""),await S(l.nodeExecutable,[l.npmCli,"install","--prefix",d,"--omit=dev","--include=optional","--ignore-scripts","--no-audit","--no-fund","--registry",e.registryUrl??process.env.MESSENGER_AGENT_NPM_REGISTRY??F,"--userconfig",H,`${J}@${s}`],{env:{PATH:We(l.nodeExecutable,e.path)},cwd:d})}if(!await G(o(d,"node_modules","@messenger-agent","client","package.json"),s))throw new Error(`Installed Messenger Agent Client does not match ${s}`);const y=await q(l.nodeExecutable,M);if(y.status!==0)throw new Error(`Messenger Agent Client self-check failed: ${y.stderr||y.stdout}`);await w(u),await b(d,u)}catch(y){throw await w(d),y}}const[_,L]=Ce();return{releaseDir:u,currentLink:N,wrapperPath:h,legacyServiceWrapperPath:O,cliWrapperPath:W,legacyCliWrapperPath:I,version:s,configPath:e.configPath,...e.path?{path:e.path}:{},skillsSourceDir:g,agentHomes:[e.codexHome??_,e.claudeHome??L],platform:n,arch:i,hostVersion:l.manifest.version,hostReleaseDir:l.releaseDir,hostCurrentLink:l.currentLink}}async function Ae(e){const{releaseDir:r,currentLink:t,wrapperPath:a,legacyServiceWrapperPath:n,cliWrapperPath:i,legacyCliWrapperPath:c,version:s,configPath:l,path:m,skillsSourceDir:p,agentHomes:u,platform:N,arch:x,hostVersion:f,hostReleaseDir:g,hostCurrentLink:h}=e,O=[a,n,i,c],W=o(r,"node_modules","@messenger-agent","client","dist","index.js"),I=o(r,"node_modules","@messenger-agent","client","package.json");if(!await G(I,s))throw new Error(`Prepared Messenger Agent Client does not match ${s}`);const A=await Q(o(g,"manifest.json"),{version:f,platform:N,arch:x}),_=P(g,A.node),L=P(g,A.npm);if(!await C(_)||!await C(L))throw new Error(`Prepared Node Host ${f} is incomplete`);const d=await q(_,W);if(d.status!==0)throw new Error(`Prepared Messenger Agent Client self-check failed: ${d.stderr||d.stdout}`);await Je(p,u);const M=await se(t),y=await se(h),H=await Promise.all(O.map(async E=>({path:E,content:await Me(E)})));await Z(t)||await w(t),await Z(h)||await w(h);try{await Y(g,h),await Y(r,t);const E=P(h,A.node),X=o(t,"node_modules","@messenger-agent","client","dist","index.js"),K=["#!/bin/sh","set -eu",...m?[`export PATH=${v(m)}`]:[],`export AGENT_CONFIG_PATH=${v(l)}`,`exec ${v(E)} ${v(X)} run-service --config ${v(l)}`,""].join(`
2
+ `),ee=["#!/bin/sh","set -eu",`export AGENT_CONFIG_PATH=${v(l)}`,`exec ${v(E)} ${v(X)} "$@"`,""].join(`
3
+ `);await R(a,K,{mode:448}),await R(n,K,{mode:448}),await R(i,ee,{mode:448}),await R(c,ee,{mode:448})}catch(E){throw await j(M,t),await j(y,h),await ne(H),E}return{releaseDir:r,currentLink:t,wrapperPath:a,legacyServiceWrapperPath:n,cliWrapperPath:i,legacyCliWrapperPath:c,version:s,hostCurrentLink:h,previousReleaseDir:M,previousHostReleaseDir:y,previousWrappers:H}}async function q(e,r){return S(e,[r,"self-check"],{allowFailure:!0})}function _e(e){const r=be();if(k(e)===k(r.configPath))return r;const t=De();return k(e)===k(t.configPath)?t:void 0}async function mr(e){await j(e.previousReleaseDir,e.currentLink),await j(e.previousHostReleaseDir,e.hostCurrentLink),await ne(e.previousWrappers)}async function j(e,r){e?await Y(e,r):await w(r)}async function Me(e){try{return await U(e,"utf8")}catch(r){if(r.code==="ENOENT")return;throw r}}async function ne(e){await Promise.all(e.map(({path:r,content:t})=>t===void 0?w(r):R(r,t,{mode:448})))}function Ue(e,r){return`${Pe}/node-host-${e}-${r}`}function Te(e,r,t,a=oe()){return`${a.replace(/\/$/,"")}/${e}/${r}/${encodeURIComponent(t)}.tgz`}function oe(e,r=process.env.MESSENGER_AGENT_NODE_HOST_MIRROR_URL){return($e(r)??`${ve(e).server}/messenger/agent/node-host`).replace(/\/$/,"")}async function je(e,r){return(await ie(J,e,r)).version}async function Ge(e){const r=Ue(e.platform,e.arch),t=e.artifactDirectory?void 0:await Ie(r,"latest",e.registryUrl),n=(e.artifactDirectory?await Q(o(e.artifactDirectory,"manifest.json"),{platform:e.platform,arch:e.arch}):void 0)?.version??t?.version;if(!n)throw new Error(`Unable to resolve ${r}`);const i=o(e.runtimeDir,"host"),c=o(i,"releases"),s=`${n}-${e.platform}-${e.arch}`.replaceAll("/","_").replaceAll(":","_"),l=o(c,s),m=o(i,"current"),p=o(l,"manifest.json");if(await D(c,{recursive:!0,mode:448}),!await C(p)){const f=`${l}.tmp-${process.pid}`;await w(f),await D(f,{recursive:!0,mode:448});try{e.artifactDirectory?await V(e.artifactDirectory,f,{recursive:!0}):t&&await Oe(t,f,Te(e.platform,e.arch,t.version,e.mirrorUrl)),await w(l),await b(f,l)}catch(g){throw await w(f),g}}const u=await Q(p,{version:n,platform:e.platform,arch:e.arch});await Ve(l,u);const N=P(l,u.node),x=P(l,u.npm);if(!await C(N)||!await C(x))throw new Error(`Node Host ${r}@${n} is incomplete`);if(u.platform==="darwin"){const f=o(l,"Messenger Agent.app");await S("codesign",["--verify","--deep","--strict",f]),await S("spctl",["--assess","--type","execute",f])}return{releaseDir:l,currentLink:m,nodeExecutable:N,npmCli:x,manifest:u}}async function Oe(e,r,t){const a=`${r}.tgz`;try{const n=[];let i=!1;for(const c of new Set([t,e.tarball]))try{await $(a,{force:!0});const s=await fetch(c);if(!s.ok||!s.body)throw new Error(`HTTP ${s.status}`);await ye(ge.fromWeb(s.body),ue(a,{mode:384})),await Le(a,e.integrity),i=!0;break}catch(s){n.push(`${c}: ${s instanceof Error?s.message:String(s)}`)}if(!i)throw new Error(`Unable to download ${e.packageName}@${e.version}: ${n.join("; ")}`);await S("tar",["-xzf",a,"-C",r,"--strip-components=2","package/host"])}finally{await $(a,{force:!0})}}async function G(e,r){try{const t=JSON.parse(await U(e,"utf8"));return t.name===J&&t.version===r}catch{return!1}}function We(e,r=process.env.PATH){const t=T(e);return r?`${t}${we}${r}`:t}async function Ie(e,r,t=process.env.MESSENGER_AGENT_NPM_REGISTRY??F){const{metadata:a,version:n}=await ie(e,r,t),i=a.versions?.[n]?.dist;if(!i?.tarball||!i.integrity)throw new Error(`Registry returned incomplete artifact metadata for ${e}@${n}`);return{packageName:e,version:n,tarball:i.tarball,integrity:i.integrity}}async function ie(e,r,t=process.env.MESSENGER_AGENT_NPM_REGISTRY??F){const a=`${t.replace(/\/$/,"")}/${encodeURIComponent(e)}`,n=await fetch(a,{headers:{accept:"application/json"}});if(!n.ok)throw new Error(`Unable to resolve ${e}: HTTP ${n.status}`);const i=await n.json(),c=B(r)?i["dist-tags"]?.[r]:r;if(!c)throw new Error(`Registry has no ${r} release for ${e}`);return{metadata:i,version:c}}async function Le(e,r){const t=r.indexOf("-");if(t<=0)throw new Error("Node Host has an invalid integrity value");const a=r.slice(0,t),n=r.slice(t+1),i=ce(a);for await(const c of le(e))i.update(c);if(i.digest("base64")!==n)throw new Error("Node Host integrity verification failed")}async function Q(e,r){const t=JSON.parse(await U(e,"utf8"));if(t.schemaVersion!==1||t.product!=="messenger-agent-node-host"||r.version!==void 0&&t.version!==r.version||typeof t.version!="string"||typeof t.nodeVersion!="string"||t.platform!==r.platform||t.arch!==r.arch||typeof t.node!="string"||typeof t.npm!="string"||t.payload!==void 0&&typeof t.payload!="string")throw new Error(`Node Host manifest does not match ${r.platform}-${r.arch}${r.version?`@${r.version}`:""}`);return t}async function Ve(e,r){if(!r.payload)return;const t=P(e,r.node);if(await C(t))return;if(r.platform!=="darwin")throw new Error("Only macOS Node Hosts may contain a zip payload");const a=P(e,r.payload);await S("ditto",["-x","-k",a,e])}function P(e,r){if(!r||z(r))throw new Error(`Node Host contains an unsafe path: ${r}`);const t=k(e),a=k(e,r),n=he(t,a);if(n.startsWith("..")||z(n))throw new Error(`Node Host contains an unsafe path: ${r}`);return a}function ze(e){if(e==="linux"||e==="darwin")return e;throw new Error(`No Messenger Agent runtime is available for platform: ${e}`)}function Fe(e){if(e==="x64"||e==="arm64")return e;throw new Error(`No Messenger Agent runtime is available for architecture: ${e}`)}async function se(e){if(!await Z(e))return;const r=await de(e);return z(r)?r:k(T(e),r)}async function C(e){try{return await fe(e),!0}catch{return!1}}async function Je(e,r){const t="manage-messenger-agent",a="manage-coding-agent-client",n=o(e,t),i=await Be(n);for(const c of new Set(r)){const s=o(c,"skills"),l=o(s,t),m=o(s,`.${t}.tmp-${process.pid}`),p=o(s,`.${t}.old-${process.pid}`);if(await $(m,{recursive:!0,force:!0}),await $(p,{recursive:!0,force:!0}),await $(o(s,a),{recursive:!0,force:!0}),!i){await $(l,{recursive:!0,force:!0});continue}await D(s,{recursive:!0,mode:448}),await V(n,m,{recursive:!0}),await b(l,p).catch(u=>{if(u.code!=="ENOENT")throw u});try{await b(m,l),await $(p,{recursive:!0,force:!0})}catch(u){throw await b(p,l).catch(()=>{}),u}}}async function Be(e){try{return(await re(e)).isDirectory()}catch(r){if(r.code==="ENOENT")return!1;throw r}}function v(e){return`'${e.replaceAll("'","'\\''")}'`}export{Ae as activateRuntime,ur as compareSemverVersions,fr as currentBundledSkillsDir,Se as currentPackageVersion,Ce as defaultAgentHomes,dr as installRuntime,lr as isPrereleaseVersion,Te as nodeHostMirrorTarballUrl,Ue as nodeHostPackageName,sr as normalizeReleaseChannel,cr as normalizeUpgradeVersion,B as parseReleaseChannel,He as prepareRuntime,ir as releaseChannels,je as resolveChannelPackageVersion,oe as resolveNodeHostMirrorUrl,mr as rollbackRuntime,Je as syncBundledSkills};
@@ -1 +1 @@
1
- import{spawn as x}from"node:child_process";import{randomUUID as y}from"node:crypto";import{createRequire as $}from"node:module";import{dirname as g,join as m,resolve as v}from"node:path";import{parse as b}from"yaml";import{readFile as E,unlink as A}from"node:fs/promises";import{readAgentServer as k,readClientPath as P,readUpgradeChannel as C,writeClientPath as I}from"./config-file.js";import{readControlSocketPath as R,startControlServer as L}from"./control.js";import{MaintenanceScheduler as q}from"./maintenance.js";import{currentBundledSkillsDir as N,currentPackageVersion as F,defaultAgentHomes as O,installRuntime as T,rollbackRuntime as S,syncBundledSkills as j}from"./runtime.js";import{launchdLabel as D,serviceCommandsForConfig as G,serviceName as W}from"./service.js";import{legacyLaunchdLabel as _,legacyServiceName as B}from"./identity.js";import{legacyCodingAgentPaths as M}from"./paths.js";import{runCommand as d}from"./exec.js";import{AutoUpgradeScheduler as U}from"./auto-upgrade.js";import{migrateLegacyClient as H}from"./migration.js";import{scheduleMigrationHandoff as K,shouldAttemptAutomaticMigration as Y}from"./install.js";import{isAgentActivityResponse as V}from"@messenger-agent/shared/agent-activity";import{isAgentWorkspacesReloadResponse as X}from"@messenger-agent/shared/agent-workspaces";const h=$(import.meta.url);function z(){return[{name:"codex",entry:h.resolve("@messenger-agent/codex-agent")},{name:"claude",entry:h.resolve("@messenger-agent/claude-agent")},{name:"workspace",entry:h.resolve("@messenger-agent/messenger-agent")}]}function J(a,t){let e=a;for(const r of t){if(!e||typeof e!="object"||Array.isArray(e))return;e=e[r]}return e}async function Q(a){const t=b(await E(a,"utf8")),e=J(t,["workspaces"]);if(Array.isArray(e)){const r=e.find(i=>!!i&&typeof i=="object"&&!Array.isArray(i)&&typeof i.path=="string");if(typeof r?.path=="string"&&r.path.trim())return r.path}return g(a)}class Z{options;stopping=!1;running;restartBaseMs;restartMaxMs;workspaceReloadTimeoutMs;constructor(t){this.options=t,this.running=(t.agents??z()).map(e=>({definition:e,restartAttempts:0})),this.restartBaseMs=t.restartBaseMs??1e3,this.restartMaxMs=t.restartMaxMs??3e4,this.workspaceReloadTimeoutMs=t.workspaceReloadTimeoutMs??5e3}start(){for(const t of this.running)this.startAgent(t)}async stop(){this.stopping=!0;for(const t of this.running)t.restartTimer&&clearTimeout(t.restartTimer),t.process?.kill("SIGTERM");await Promise.all(this.running.map(t=>t.process).filter(t=>!!t&&t.exitCode===null&&!t.killed).map(t=>new Promise(e=>{const r=setTimeout(()=>{t.kill("SIGKILL"),e()},8e3);t.once("exit",()=>{clearTimeout(r),e()})})))}restartAgent(t){const e=this.running.find(({definition:r})=>r.name===t);return e?(e.restartPromise||(e.restartPromise=this.restartAgentProcess(e).finally(()=>{e.restartPromise=void 0})),e.restartPromise):Promise.reject(new Error(`Agent is not managed by this client: ${t}`))}async activityStatus(t=1e3){const[e,r]=await Promise.all([this.agentActivityStatus("codex",t),this.agentActivityStatus("claude",t)]),i=[e,r].filter(s=>s.available);return{active:i.reduce((s,o)=>s+o.active,0),waiting:i.reduce((s,o)=>s+o.waiting,0),agents:{codex:e,claude:r}}}agentActivityStatus(t,e){const r=this.running.find(({definition:i})=>i.name===t)?.process;return!r||!r.connected||!r.send?Promise.resolve({available:!1,error:`${t} agent is not connected`}):new Promise(i=>{const s=y(),o={type:"client.activity.request",requestId:s};let c=!1;const l=n=>{c||(c=!0,clearTimeout(w),r.off("message",u),i(n))},u=n=>{!V(n)||n.requestId!==s||n.agent!==t||l({available:!0,...n.snapshot})},w=setTimeout(()=>l({available:!1,error:`${t} agent did not respond`}),e);r.on("message",u),r.send(o,n=>{n&&l({available:!1,error:n.message})})})}async restartAgentProcess(t){t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0);const e=t.process;if(e&&e.exitCode===null&&!e.killed&&(e.kill("SIGTERM"),await st(e)),this.stopping)throw new Error("Client service is stopping");t.restartAttempts=0,this.startAgent(t)}async reloadAgentWorkspaces(){await Promise.all([this.requestAgentWorkspacesReload("codex"),this.requestAgentWorkspacesReload("claude")])}requestAgentWorkspacesReload(t){const e=this.running.find(({definition:r})=>r.name===t)?.process;return!e||!e.connected||!e.send?Promise.reject(new Error(`${t} agent is not connected`)):new Promise((r,i)=>{const s=y(),o={type:"client.workspaces.reload.request",requestId:s};let c=!1;const l=n=>{c||(c=!0,clearTimeout(w),e.off("message",u),n?i(n):r())},u=n=>{if(!(!X(n)||n.requestId!==s||n.agent!==t)){if(!n.success){l(new Error(`${t} agent failed to reload workspaces: ${n.error??"unknown error"}`));return}console.log(`[client] reloaded ${t}-agent workspaces count=${n.workspaceCount??0}`),l()}},w=setTimeout(()=>l(new Error(`${t} agent did not reload workspaces`)),this.workspaceReloadTimeoutMs);e.on("message",u),e.send(o,n=>{n&&l(n)})})}startAgent(t){const e={...process.env,AGENT_CONFIG_PATH:this.options.configPath};t.definition.name==="workspace"&&(delete e.OPENAI_API_KEY,delete e.CODEX_API_KEY,delete e.ANTHROPIC_API_KEY);const r=(this.options.spawnProcess??x)(process.execPath,[t.definition.entry],{cwd:this.options.workspacePath,env:e,stdio:["inherit","inherit","inherit","ipc"]});t.process=r,t.definition.name==="workspace"&&r.on("message",i=>{i&&typeof i=="object"&&"type"in i&&i.type==="client.workspaces.changed"&&this.reloadAgentWorkspaces().catch(s=>{console.error("[client] failed to reload agents after workspace configuration changed",s)})}),console.log(`[client] started ${t.definition.name}-agent pid=${r.pid}`),r.once("exit",(i,s)=>{if(t.process=void 0,this.stopping||t.restartPromise)return;const o=Math.min(this.restartBaseMs*2**t.restartAttempts,this.restartMaxMs);t.restartAttempts+=1,console.error(`[client] ${t.definition.name}-agent exited with code=${i??"null"} signal=${s??"null"}; restarting in ${o}ms`),t.restartTimer=setTimeout(()=>{t.restartTimer=void 0,this.startAgent(t)},o)})}}async function Tt(a){if(await tt(a))return;await j(N(),O());const t=await Q(a),e=new Z({configPath:a,workspacePath:t}),r=await R(a),i=new q({statePath:m(g(r),"maintenance.json"),getActivity:()=>e.activityStatus(),execute:(l,u)=>et(l,a,e,u)});await i.start();const s=new U({statePath:m(g(r),"auto-upgrade.json"),maintenance:i,getChannel:()=>C(a)});await s.start();const o=await L(r,{restartAgent:l=>e.restartAgent(l),getActivity:()=>e.activityStatus(),maintenance:i});e.start();const c=async()=>{s.stop(),i.stop(),await o.close(),await e.stop(),process.exit(0)};process.once("SIGINT",()=>{c()}),process.once("SIGTERM",()=>{c()})}async function tt(a,t={}){const e=M();if(v(a)!==v(e.configPath))return!1;const r=await(t.currentVersion??F)();if(!await(t.shouldAttempt??Y)(e.rootDir,r))return!1;let i;try{const s=await(t.migrate??H)();if(!s.migrated)return!1;const o=await(t.readPath??P)(s.paths.configPath),c=await(t.readServer??k)(s.paths.configPath);return i=await(t.install??T)({version:r,configPath:s.paths.configPath,runtimeDir:s.paths.runtimeDir,binDir:s.paths.binDir,path:o,server:c}),await(t.handoff??K)(s,i,s.paths.configPath,o),!0}catch(s){return i&&await(t.rollback??S)(i).catch(()=>{}),console.error(`[client] automatic legacy migration failed: ${s instanceof Error?s.message:String(s)}`),!1}}async function et(a,t,e,r){if(a.type==="upgrade"){a.path&&await I(t,a.path);const i=await T({version:a.version,configPath:t,server:await k(t),path:a.path??await P(t)});await r("restarting");try{await f(p(t).restart)}catch(s){throw await S(i),await f(p(t).restart).catch(()=>{}),s}return}if(a.type==="restart"&&a.agent){await e.restartAgent(a.agent);return}if(a.type==="restart"){await r("restarting"),await f(p(t).restart);return}if(a.type==="stop"){await r("stopping"),await f(p(t).stop);return}await r("stopping"),await rt(t)}function p(a){return G(a)}async function f(a){const t=await d("/bin/sh",["-lc",a],{allowFailure:!0});if(t.status!==0)throw new Error(t.stderr||t.stdout||`Service command failed: ${a}`)}async function rt(a){const t=process.env.HOME??"",e=a===M().configPath,r=e?B:W,i=e?_:D;if(process.platform==="linux"){await d("systemctl",["--user","disable",`${r}.service`],{allowFailure:!0}),await A(m(t,".config","systemd","user",`${r}.service`)).catch(s=>{if(s.code!=="ENOENT")throw s}),await d("systemctl",["--user","daemon-reload"],{allowFailure:!0}),await d("systemctl",["--user","stop",`${r}.service`],{allowFailure:!0});return}if(process.platform==="darwin"){const s=process.getuid?.();if(s===void 0)throw new Error("Unable to determine current uid for launchctl");const o=m(t,"Library","LaunchAgents",`${i}.plist`);await A(o).catch(c=>{if(c.code!=="ENOENT")throw c}),await d("launchctl",["bootout",`gui/${s}/${i}`],{allowFailure:!0});return}throw new Error("Only Linux and macOS are supported")}function st(a){return new Promise(t=>{const e=setTimeout(()=>{a.kill("SIGKILL")},8e3);a.once("exit",()=>{clearTimeout(e),t()})})}export{Z as AgentSupervisor,tt as migrateLegacyServiceAtStartup,Q as readWorkspacePathFromConfig,z as resolveAgentEntries,Tt as runSupervisor};
1
+ import{spawn as $}from"node:child_process";import{randomUUID as k}from"node:crypto";import{createRequire as x}from"node:module";import{dirname as g,join as p,resolve as m}from"node:path";import{parse as E}from"yaml";import{readFile as b,unlink as P}from"node:fs/promises";import{readAgentServer as y,readClientPath as v,readUpgradeChannel as C,writeClientPath as I}from"./config-file.js";import{readControlSocketPath as R,startControlServer as L}from"./control.js";import{MaintenanceScheduler as q}from"./maintenance.js";import{activateRuntime as N,currentBundledSkillsDir as F,currentPackageVersion as O,defaultAgentHomes as j,installRuntime as T,prepareRuntime as D,rollbackRuntime as S,syncBundledSkills as G}from"./runtime.js";import{launchdLabel as W,serviceCommandsForConfig as _,serviceName as B}from"./service.js";import{legacyLaunchdLabel as U,legacyServiceName as H}from"./identity.js";import{legacyCodingAgentPaths as M}from"./paths.js";import{runCommand as d}from"./exec.js";import{AutoUpgradeScheduler as K}from"./auto-upgrade.js";import{migrateLegacyClient as Y}from"./migration.js";import{scheduleMigrationHandoff as V,shouldAttemptAutomaticMigration as X}from"./install.js";import{isAgentActivityResponse as z}from"@messenger-agent/shared/agent-activity";import{isAgentWorkspacesReloadResponse as J}from"@messenger-agent/shared/agent-workspaces";const A=x(import.meta.url);function Q(){return[{name:"codex",entry:A.resolve("@messenger-agent/codex-agent")},{name:"claude",entry:A.resolve("@messenger-agent/claude-agent")},{name:"workspace",entry:A.resolve("@messenger-agent/messenger-agent")}]}function Z(r,t){let e=r;for(const a of t){if(!e||typeof e!="object"||Array.isArray(e))return;e=e[a]}return e}async function tt(r){const t=E(await b(r,"utf8")),e=Z(t,["workspaces"]);if(Array.isArray(e)){const a=e.find(i=>!!i&&typeof i=="object"&&!Array.isArray(i)&&typeof i.path=="string");if(typeof a?.path=="string"&&a.path.trim())return a.path}return g(r)}class et{options;stopping=!1;running;restartBaseMs;restartMaxMs;workspaceReloadTimeoutMs;constructor(t){this.options=t,this.running=(t.agents??Q()).map(e=>({definition:e,restartAttempts:0})),this.restartBaseMs=t.restartBaseMs??1e3,this.restartMaxMs=t.restartMaxMs??3e4,this.workspaceReloadTimeoutMs=t.workspaceReloadTimeoutMs??5e3}start(){for(const t of this.running)this.startAgent(t)}async stop(){this.stopping=!0;for(const t of this.running)t.restartTimer&&clearTimeout(t.restartTimer),t.process?.kill("SIGTERM");await Promise.all(this.running.map(t=>t.process).filter(t=>!!t&&t.exitCode===null&&!t.killed).map(t=>new Promise(e=>{const a=setTimeout(()=>{t.kill("SIGKILL"),e()},8e3);t.once("exit",()=>{clearTimeout(a),e()})})))}restartAgent(t){const e=this.running.find(({definition:a})=>a.name===t);return e?(e.restartPromise||(e.restartPromise=this.restartAgentProcess(e).finally(()=>{e.restartPromise=void 0})),e.restartPromise):Promise.reject(new Error(`Agent is not managed by this client: ${t}`))}async activityStatus(t=1e3){const[e,a]=await Promise.all([this.agentActivityStatus("codex",t),this.agentActivityStatus("claude",t)]),i=[e,a].filter(s=>s.available);return{active:i.reduce((s,o)=>s+o.active,0),waiting:i.reduce((s,o)=>s+o.waiting,0),agents:{codex:e,claude:a}}}agentActivityStatus(t,e){const a=this.running.find(({definition:i})=>i.name===t)?.process;return!a||!a.connected||!a.send?Promise.resolve({available:!1,error:`${t} agent is not connected`}):new Promise(i=>{const s=k(),o={type:"client.activity.request",requestId:s};let l=!1;const c=n=>{l||(l=!0,clearTimeout(h),a.off("message",u),i(n))},u=n=>{!z(n)||n.requestId!==s||n.agent!==t||c({available:!0,...n.snapshot})},h=setTimeout(()=>c({available:!1,error:`${t} agent did not respond`}),e);a.on("message",u),a.send(o,n=>{n&&c({available:!1,error:n.message})})})}async restartAgentProcess(t){t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0);const e=t.process;if(e&&e.exitCode===null&&!e.killed&&(e.kill("SIGTERM"),await it(e)),this.stopping)throw new Error("Client service is stopping");t.restartAttempts=0,this.startAgent(t)}async reloadAgentWorkspaces(){await Promise.all([this.requestAgentWorkspacesReload("codex"),this.requestAgentWorkspacesReload("claude")])}requestAgentWorkspacesReload(t){const e=this.running.find(({definition:a})=>a.name===t)?.process;return!e||!e.connected||!e.send?Promise.reject(new Error(`${t} agent is not connected`)):new Promise((a,i)=>{const s=k(),o={type:"client.workspaces.reload.request",requestId:s};let l=!1;const c=n=>{l||(l=!0,clearTimeout(h),e.off("message",u),n?i(n):a())},u=n=>{if(!(!J(n)||n.requestId!==s||n.agent!==t)){if(!n.success){c(new Error(`${t} agent failed to reload workspaces: ${n.error??"unknown error"}`));return}console.log(`[client] reloaded ${t}-agent workspaces count=${n.workspaceCount??0}`),c()}},h=setTimeout(()=>c(new Error(`${t} agent did not reload workspaces`)),this.workspaceReloadTimeoutMs);e.on("message",u),e.send(o,n=>{n&&c(n)})})}startAgent(t){const e={...process.env,AGENT_CONFIG_PATH:this.options.configPath};t.definition.name==="workspace"&&(delete e.OPENAI_API_KEY,delete e.CODEX_API_KEY,delete e.ANTHROPIC_API_KEY);const a=(this.options.spawnProcess??$)(process.execPath,[t.definition.entry],{cwd:this.options.workspacePath,env:e,stdio:["inherit","inherit","inherit","ipc"]});t.process=a,t.definition.name==="workspace"&&a.on("message",i=>{i&&typeof i=="object"&&"type"in i&&i.type==="client.workspaces.changed"&&this.reloadAgentWorkspaces().catch(s=>{console.error("[client] failed to reload agents after workspace configuration changed",s)})}),console.log(`[client] started ${t.definition.name}-agent pid=${a.pid}`),a.once("exit",(i,s)=>{if(t.process=void 0,this.stopping||t.restartPromise)return;const o=Math.min(this.restartBaseMs*2**t.restartAttempts,this.restartMaxMs);t.restartAttempts+=1,console.error(`[client] ${t.definition.name}-agent exited with code=${i??"null"} signal=${s??"null"}; restarting in ${o}ms`),t.restartTimer=setTimeout(()=>{t.restartTimer=void 0,this.startAgent(t)},o)})}}async function Mt(r){if(await rt(r))return;await G(F(),j());const t=await tt(r),e=new et({configPath:r,workspacePath:t}),a=await R(r),i=new q({statePath:p(g(a),"maintenance.json"),getActivity:()=>e.activityStatus(),execute:(c,u)=>at(c,r,e,u)});await i.start();const s=new K({statePath:p(g(a),"auto-upgrade.json"),maintenance:i,getChannel:()=>C(r),prepareUpgrade:async c=>D({version:c,configPath:r,server:await y(r),path:await v(r)})});await s.start();const o=await L(a,{restartAgent:c=>e.restartAgent(c),getActivity:()=>e.activityStatus(),maintenance:i});e.start();const l=async()=>{s.stop(),i.stop(),await o.close(),await e.stop(),process.exit(0)};process.once("SIGINT",()=>{l()}),process.once("SIGTERM",()=>{l()})}async function rt(r,t={}){const e=M();if(m(r)!==m(e.configPath))return!1;const a=await(t.currentVersion??O)();if(!await(t.shouldAttempt??X)(e.rootDir,a))return!1;let i;try{const s=await(t.migrate??Y)();if(!s.migrated)return!1;const o=await(t.readPath??v)(s.paths.configPath),l=await(t.readServer??y)(s.paths.configPath);return i=await(t.install??T)({version:a,configPath:s.paths.configPath,runtimeDir:s.paths.runtimeDir,binDir:s.paths.binDir,path:o,server:l}),await(t.handoff??V)(s,i,s.paths.configPath,o),!0}catch(s){return i&&await(t.rollback??S)(i).catch(()=>{}),console.error(`[client] automatic legacy migration failed: ${s instanceof Error?s.message:String(s)}`),!1}}async function at(r,t,e,a){if(r.type==="upgrade"){if(r.path&&await I(t,r.path),r.prepared&&r.prepared.version!==r.version)throw new Error(`Prepared runtime ${r.prepared.version} does not match upgrade ${r.version}`);if(r.prepared&&m(r.prepared.configPath)!==m(t))throw new Error("Prepared runtime does not match the active client configuration");const i=r.prepared?await N(r.prepared):await T({version:r.version,configPath:t,server:await y(t),path:r.path??await v(t)});await a("restarting");try{await w(f(t).restart)}catch(s){throw await S(i),await w(f(t).restart).catch(()=>{}),s}return}if(r.type==="restart"&&r.agent){await e.restartAgent(r.agent);return}if(r.type==="restart"){await a("restarting"),await w(f(t).restart);return}if(r.type==="stop"){await a("stopping"),await w(f(t).stop);return}await a("stopping"),await st(t)}function f(r){return _(r)}async function w(r){const t=await d("/bin/sh",["-lc",r],{allowFailure:!0});if(t.status!==0)throw new Error(t.stderr||t.stdout||`Service command failed: ${r}`)}async function st(r){const t=process.env.HOME??"",e=r===M().configPath,a=e?H:B,i=e?U:W;if(process.platform==="linux"){await d("systemctl",["--user","disable",`${a}.service`],{allowFailure:!0}),await P(p(t,".config","systemd","user",`${a}.service`)).catch(s=>{if(s.code!=="ENOENT")throw s}),await d("systemctl",["--user","daemon-reload"],{allowFailure:!0}),await d("systemctl",["--user","stop",`${a}.service`],{allowFailure:!0});return}if(process.platform==="darwin"){const s=process.getuid?.();if(s===void 0)throw new Error("Unable to determine current uid for launchctl");const o=p(t,"Library","LaunchAgents",`${i}.plist`);await P(o).catch(l=>{if(l.code!=="ENOENT")throw l}),await d("launchctl",["bootout",`gui/${s}/${i}`],{allowFailure:!0});return}throw new Error("Only Linux and macOS are supported")}function it(r){return new Promise(t=>{const e=setTimeout(()=>{r.kill("SIGKILL")},8e3);r.once("exit",()=>{clearTimeout(e),t()})})}export{et as AgentSupervisor,rt as migrateLegacyServiceAtStartup,tt as readWorkspacePathFromConfig,Q as resolveAgentEntries,Mt as runSupervisor};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@messenger-agent/client",
3
- "version": "0.36.0",
3
+ "version": "0.37.0-alpha.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -21,10 +21,10 @@
21
21
  "dependencies": {
22
22
  "cac": "^7.0.0",
23
23
  "yaml": "^2.9.0",
24
- "@messenger-agent/claude-agent": "0.36.0",
25
- "@messenger-agent/codex-agent": "0.36.0",
26
- "@messenger-agent/messenger-agent": "0.36.0",
27
- "@messenger-agent/shared": "0.36.0"
24
+ "@messenger-agent/messenger-agent": "0.37.0-alpha.1",
25
+ "@messenger-agent/shared": "0.37.0-alpha.1",
26
+ "@messenger-agent/codex-agent": "0.37.0-alpha.1",
27
+ "@messenger-agent/claude-agent": "0.37.0-alpha.1"
28
28
  },
29
29
  "scripts": {
30
30
  "build": "rm -rf dist && tsc -p tsconfig.json && node ../../scripts/copy-client-assets.mjs && chmod +x dist/index.js",