@messenger-agent/client 0.33.0-alpha.4 → 0.33.0-alpha.5
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.
- package/dist/args.d.ts +5 -1
- package/dist/args.js +3 -3
- package/dist/exec.d.ts +1 -0
- package/dist/exec.js +2 -2
- package/dist/index.js +3 -3
- package/dist/install.d.ts +7 -0
- package/dist/install.js +2 -1
- package/dist/migration.js +2 -2
- package/dist/native-dependencies.d.ts +1 -0
- package/dist/native-dependencies.js +1 -0
- package/dist/runtime.js +3 -3
- package/dist/service.js +3 -3
- package/package.json +5 -5
package/dist/args.d.ts
CHANGED
|
@@ -26,6 +26,10 @@ export type VersionArgs = {
|
|
|
26
26
|
export type SelfCheckArgs = {
|
|
27
27
|
command: "self-check";
|
|
28
28
|
};
|
|
29
|
+
export type CompleteMigrationArgs = {
|
|
30
|
+
command: "complete-migration";
|
|
31
|
+
handoffPath: string;
|
|
32
|
+
};
|
|
29
33
|
export type SessionsArgs = {
|
|
30
34
|
command: "sessions";
|
|
31
35
|
json: boolean;
|
|
@@ -63,7 +67,7 @@ export type UninstallArgs = {
|
|
|
63
67
|
delaySeconds?: number;
|
|
64
68
|
allowWaiting: boolean;
|
|
65
69
|
};
|
|
66
|
-
export type CliArgs = InstallArgs | UpgradeArgs | VersionArgs | SelfCheckArgs | SessionsArgs | MaintenanceArgs | RunServiceArgs | StatusArgs | StartArgs | RestartArgs | StopArgs | UninstallArgs;
|
|
70
|
+
export type CliArgs = InstallArgs | UpgradeArgs | VersionArgs | SelfCheckArgs | CompleteMigrationArgs | SessionsArgs | MaintenanceArgs | RunServiceArgs | StatusArgs | StartArgs | RestartArgs | StopArgs | UninstallArgs;
|
|
67
71
|
export declare class UsageError extends Error {
|
|
68
72
|
}
|
|
69
73
|
export declare function parseCliArgs(argv: string[], env?: NodeJS.ProcessEnv): CliArgs;
|
package/dist/args.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import U from"cac";import{defaultConfigPath as u,defaultDataDir as $,resolvePath as d}from"./paths.js";import{normalizeReleaseChannel as C}from"./runtime.js";import{cliName as m,productName as p}from"./identity.js";const N="MESSENGER_AGENT_TUNNEL_SERVER_URL",E="CODING_AGENT_TUNNEL_SERVER_URL",W=["install","upgrade","sessions","maintenance","status","start","restart","stop","uninstall"],b=[...W,"run-service","self-check"];class r extends Error{}function L(n,t=process.env){if(n[0]==="--version"||n[0]==="-v"){if(n.length>1)throw new r(`Unknown option for version: ${n[1]}`);return{command:"version"}}const o=n[0];if(!o||o==="--help"||o==="-h")throw new r(
|
|
1
|
+
import U from"cac";import{defaultConfigPath as u,defaultDataDir as $,resolvePath as d}from"./paths.js";import{normalizeReleaseChannel as C}from"./runtime.js";import{cliName as m,productName as p}from"./identity.js";const N="MESSENGER_AGENT_TUNNEL_SERVER_URL",E="CODING_AGENT_TUNNEL_SERVER_URL",W=["install","upgrade","sessions","maintenance","status","start","restart","stop","uninstall"],b=[...W,"run-service","self-check","complete-migration"];class r extends Error{}function L(n,t=process.env){if(n[0]==="--version"||n[0]==="-v"){if(n.length>1)throw new r(`Unknown option for version: ${n[1]}`);return{command:"version"}}const o=n[0];if(!o||o==="--help"||o==="-h")throw new r(P());if(n.includes("--"))throw new r(`Unknown option for ${o}: --`);I(n);let a;const e=g({env:t,includeInternalCommands:!0,onParsed(i){a=i}});try{e.parse(["node",m,...n])}catch(i){const s=i instanceof Error?i.message:String(i);throw new r(A(s,n))}if(!a)throw new r(`Unknown command: ${o}`);return a}function P(){const n=g({includeInternalCommands:!1});return n.help(),`${x(()=>n.outputHelp())}
|
|
2
2
|
|
|
3
3
|
Global Options:
|
|
4
|
-
-v, --version Show the installed client version`}function g(n){const t=U(m),o=n.env??process.env,a=n.onParsed??(()=>{});t.command("install",`Install and configure the local ${p} service`).option("--tunnel-id <id>","Tunnel id").option("--token <token>","Tunnel token").option("--workspace <path>","Workspace path (default: ~/messenger-workspace)").option("--server <url>","Agent bridge server URL").option("--server-url <wss-url>","Tunnel server URL").option("--config <path>","Config file path",{default:u}).option("--data-dir <path>","Data directory",{default:$}).option("--workspace-id <id>","Workspace id").option("--workspace-name <name>","Workspace display name").option("--channel <channel>","Auto-upgrade release channel: latest, beta, or alpha").action(e=>{const i=c(e.tunnelId),s=c(e.token),l=c(e.workspace);a({command:"install",tunnelId:i,token:s,workspace:l?d(l):void 0,server:c(e.server),serverUrl:c(e.serverUrl)??o[N]??o[E],configPath:d(f(e.config,"--config")),dataDir:d(f(e.dataDir,"--data-dir")),workspaceId:c(e.workspaceId),workspaceName:c(e.workspaceName),channel:k(e.channel)})}),t.command("upgrade",`Upgrade the local ${p} runtime`).option("--version <version>","Runtime version or release channel",{default:"latest"}).option("--channel <channel>","Auto-upgrade release channel: latest, beta, or alpha").option("--config <path>","Config file path",{default:u}).option("--delay <seconds>","Schedule the upgrade after a delay").option("--allow-waiting","Allow upgrade while sessions wait for user input").action(e=>{const i=
|
|
5
|
-
`)}function S(n){return`${n.charAt(0).toUpperCase()}${n.slice(1)}`}export{r as UsageError,L as parseCliArgs,
|
|
4
|
+
-v, --version Show the installed client version`}function g(n){const t=U(m),o=n.env??process.env,a=n.onParsed??(()=>{});t.command("install",`Install and configure the local ${p} service`).option("--tunnel-id <id>","Tunnel id").option("--token <token>","Tunnel token").option("--workspace <path>","Workspace path (default: ~/messenger-workspace)").option("--server <url>","Agent bridge server URL").option("--server-url <wss-url>","Tunnel server URL").option("--config <path>","Config file path",{default:u}).option("--data-dir <path>","Data directory",{default:$}).option("--workspace-id <id>","Workspace id").option("--workspace-name <name>","Workspace display name").option("--channel <channel>","Auto-upgrade release channel: latest, beta, or alpha").action(e=>{const i=c(e.tunnelId),s=c(e.token),l=c(e.workspace);a({command:"install",tunnelId:i,token:s,workspace:l?d(l):void 0,server:c(e.server),serverUrl:c(e.serverUrl)??o[N]??o[E],configPath:d(f(e.config,"--config")),dataDir:d(f(e.dataDir,"--data-dir")),workspaceId:c(e.workspaceId),workspaceName:c(e.workspaceName),channel:k(e.channel)})}),t.command("upgrade",`Upgrade the local ${p} runtime`).option("--version <version>","Runtime version or release channel",{default:"latest"}).option("--channel <channel>","Auto-upgrade release channel: latest, beta, or alpha").option("--config <path>","Config file path",{default:u}).option("--delay <seconds>","Schedule the upgrade after a delay").option("--allow-waiting","Allow upgrade while sessions wait for user input").action(e=>{const i=h(e.delay),s=e.allowWaiting===!0;w(s,i),a({command:"upgrade",version:f(e.version,"--version"),configPath:d(f(e.config,"--config")),delaySeconds:i,allowWaiting:s,channel:k(e.channel)})}),t.command("sessions","Show active and waiting client sessions").option("--json","Print machine-readable JSON").option("--config <path>","Config file path",{default:u}).action(e=>{a({command:"sessions",json:e.json===!0,configPath:d(f(e.config,"--config"))})}),t.command("maintenance <action>","Inspect or cancel scheduled maintenance").option("--json","Print machine-readable JSON").option("--config <path>","Config file path",{default:u}).action((e,i)=>{if(e!=="status"&&e!=="cancel")throw new r(`Unknown maintenance action: ${e}`);a({command:"maintenance",action:e,json:i.json===!0,configPath:d(f(i.config,"--config"))})});for(const e of["status","start"])t.command(e,`${S(e)} the local ${p} service`).action(()=>{a({command:e})});t.command("restart [agent]","Restart the local service or a specific agent").option("--delay <seconds>","Schedule the restart after a delay").option("--allow-waiting","Allow restart while sessions wait for user input").action((e,i)=>{if(e!==void 0&&e!=="codex"&&e!=="claude")throw new r(`Unknown agent for restart: ${e}`);const s=h(i.delay),l=i.allowWaiting===!0;w(l,s),a({command:"restart",agent:e,delaySeconds:s,allowWaiting:l})});for(const e of["stop","uninstall"])t.command(e,`${S(e)} the local ${p} service`).option("--delay <seconds>",`Schedule the ${e} after a delay`).option("--allow-waiting",`Allow ${e} while sessions wait for user input`).action(i=>{const s=h(i.delay),l=i.allowWaiting===!0;w(l,s),a({command:e,delaySeconds:s,allowWaiting:l})});return n.includeInternalCommands&&(t.command("run-service","Run the managed service supervisor").option("--config <path>","Config file path").action(e=>{const i=c(e.config);a({command:"run-service",configPath:i?d(i):void 0})}),t.command("self-check","Validate the bundled runtime").action(()=>{a({command:"self-check"})}),t.command("complete-migration","Complete a prepared service migration").option("--handoff <path>","Migration handoff state").action(e=>{a({command:"complete-migration",handoffPath:d(f(e.handoff,"--handoff"))})})),t}function f(n,t){const o=c(n);if(!o)throw new r(`Missing value for ${t}`);return o}function c(n){return typeof n=="string"?n:void 0}function k(n){const t=c(n);if(t!==void 0)try{return C(t)}catch{throw new r(`Unknown release channel for --channel: ${t} (expected latest, beta, or alpha)`)}}function h(n){if(n===void 0)return;const t=typeof n=="number"?String(n):f(n,"--delay");if(!/^\d+$/.test(t))throw new r("--delay must be an integer between 1 and 86400 seconds");const o=Number.parseInt(t,10);if(o<1||o>86400)throw new r("--delay must be an integer between 1 and 86400 seconds");return o}function w(n,t){if(n&&t===void 0)throw new r("--allow-waiting requires --delay")}function A(n,t){if(n.startsWith("Unknown option `")){const o=y(t);if(o)return`Unknown option for ${t[0]}: ${o}`}if(n.startsWith("option `")){const o=/^option `([^` ]+)/.exec(n);if(o)return`Missing value for ${o[1]}`}if(n.startsWith("Unused args:")){const o=t.slice(1).find(a=>!a.startsWith("-"));if(o)return`Unknown option for ${t[0]}: ${o}`}return n}function y(n){const t=n[0];if(!t||!v(t))return n.find(a=>a.startsWith("-"));const o=R(t);for(const a of n.slice(1)){if(!a.startsWith("-"))continue;const e=a.includes("=")?a.slice(0,a.indexOf("=")):a;if(!o.has(e))return e}}function I(n){const t=n[0];if(!t||!v(t))return;const o=y(n);if(o)throw new r(`Unknown option for ${t}: ${o}`)}function R(n){switch(n){case"install":return new Set(["--tunnel-id","--token","--workspace","--server","--server-url","--config","--data-dir","--workspace-id","--workspace-name","--channel"]);case"upgrade":return new Set(["--version","--channel","--config","--delay","--allow-waiting"]);case"sessions":case"maintenance":return new Set(["--json","--config"]);case"restart":case"stop":case"uninstall":return new Set(["--delay","--allow-waiting"]);case"run-service":return new Set(["--config"]);case"complete-migration":return new Set(["--handoff"]);default:return new Set}}function v(n){return b.includes(n)}function x(n){const t=console.info,o=[];console.info=(...a)=>{o.push(a.map(String).join(" "))};try{n()}finally{console.info=t}return o.join(`
|
|
5
|
+
`)}function S(n){return`${n.charAt(0).toUpperCase()}${n.slice(1)}`}export{r as UsageError,L as parseCliArgs,P as usage};
|
package/dist/exec.d.ts
CHANGED
package/dist/exec.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{spawn as f}from"node:child_process";function
|
|
2
|
-
${i.stderr||i.stdout}`));return}c(i)})})}export{
|
|
1
|
+
import{spawn as f}from"node:child_process";function a(e,o,r={}){return new Promise((c,s)=>{console.log(`$ ${e} ${o.join(" ")}`);const n=f(e,o,{stdio:r.interactive?"inherit":["ignore","pipe","pipe"],env:{...process.env,...r.env},cwd:r.cwd}),u=[],d=[];n.stdout?.on("data",t=>{u.push(t)}),n.stderr?.on("data",t=>{d.push(t)}),n.on("error",s),n.on("close",t=>{const i={status:t,stdout:Buffer.concat(u).toString("utf8"),stderr:Buffer.concat(d).toString("utf8")};if(!r.allowFailure&&t!==0){s(new Error(`${e} ${o.join(" ")} failed with status ${t}
|
|
2
|
+
${i.stderr||i.stdout}`));return}c(i)})})}export{a as runCommand};
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{parseCliArgs as S,UsageError as
|
|
3
|
-
`)}function
|
|
4
|
-
`):"No maintenance task has been scheduled"}function
|
|
2
|
+
import{parseCliArgs as S,UsageError as N,usage as d}from"./args.js";import{activateMigratedService as A,completeMigrationHandoff as T,installClient as W}from"./install.js";import{currentPackageVersion as f,installRuntime as b,normalizeUpgradeVersion as G,rollbackRuntime as O}from"./runtime.js";import{serviceCommandsForConfig as p,serviceName as h,uninstallLegacyService as _,uninstallService as E,verifyServiceHealth as H}from"./service.js";import{runSupervisor as M}from"./supervisor.js";import{runCommand as D}from"./exec.js";import{defaultConfigPath as r,preferredClientPaths as l}from"./paths.js";import{readClientPath as F,writeClientPath as w,writeUpgradeChannel as $}from"./config-file.js";import{requestAgentRestart as I,requestClientActivity as R,requestMaintenanceCancel as U,requestMaintenanceStatus as k,requestScheduleMaintenance as q}from"./control.js";import{cliName as L,productName as j}from"./identity.js";import{migrateLegacyClient as x}from"./migration.js";import{assertPlatformNativeDependencies as z}from"./native-dependencies.js";async function B(){const e=S(process.argv.slice(2));if(e.command==="version"){console.log(`${L} ${await f()}`);return}if(e.command==="self-check"){await f(),z(),console.log(`${j} runtime is healthy`);return}if(e.command==="complete-migration"){await T(e.handoffPath);return}if(e.command==="run-service"){await M(e.configPath??process.env.AGENT_CONFIG_PATH??r);return}if(e.command==="install"){const t=await W(e);console.log(`Installed ${h}`),console.log(`Config: ${t.configPath}`),console.log(`Data: ${t.dataDir}`),console.log(`Runtime: ${t.runtime.currentLink}`),console.log(`Command: ${t.runtime.cliWrapperPath}`),console.log(`Service file: ${t.service.servicePath}`),console.log(`Upgrade: ${t.runtime.cliWrapperPath} upgrade`),console.log(`Restart: ${t.runtime.cliWrapperPath} restart`),console.log(`Status: ${t.runtime.cliWrapperPath} status`),console.log(`Logs: ${t.service.commands.logs}`);for(const n of t.service.warnings)console.warn(`Warning: ${n}`);return}if(e.command==="upgrade"){const{version:t,channel:n}=G(e.version,e.channel),a=process.env.PATH,o=e.configPath===r?l().configPath:e.configPath;if(a&&await w(o,a),n&&(await $(o,n),console.log(`Auto-upgrade channel: ${n}`)),e.delaySeconds!==void 0){await m(o,{type:"upgrade",version:t,path:a},e.delaySeconds,e.allowWaiting);return}const c=await x(),i=o===c.legacyPaths.configPath?c.paths.configPath:o;a&&i!==o&&await w(i,a),n&&i!==o&&await $(i,n);const s=await b({version:t,configPath:i,runtimeDir:c.paths.runtimeDir,binDir:c.paths.binDir,path:a??await F(i)});if(!await A(c,s,i,a)){const u=p(i);try{await g(u.restart),await H()}catch(y){throw await O(s),await g(u.restart).catch(()=>{}),y}}console.log(`Upgraded runtime to ${s.version}`),console.log(`Runtime: ${s.currentLink}`),console.log(`Command: ${s.cliWrapperPath}`),console.log(`Status: ${s.cliWrapperPath} status`);return}if(e.command==="sessions"){const t=await R(P(e.configPath));console.log(e.json?JSON.stringify(t):J(t));return}if(e.command==="maintenance"){const t=P(e.configPath),n=e.action==="cancel"?await U(t):await k(t);console.log(e.json?JSON.stringify(n??null):V(n));return}if(e.command==="restart"&&e.agent){if(e.delaySeconds!==void 0){await m(process.env.AGENT_CONFIG_PATH??r,{type:"restart",agent:e.agent},e.delaySeconds,e.allowWaiting);return}await I(process.env.AGENT_CONFIG_PATH??r,e.agent),console.log(`Restarted ${e.agent} agent`);return}if(e.command==="status"||e.command==="start"||e.command==="restart"||e.command==="stop"){if((e.command==="restart"||e.command==="stop")&&e.delaySeconds!==void 0){await m(process.env.AGENT_CONFIG_PATH??r,{type:e.command},e.delaySeconds,e.allowWaiting);return}const t=l().configPath,n=p(t),a=e.command==="status"?n.status:e.command==="start"?n.start:e.command==="restart"?n.restart:n.stop;await g(a);return}if(e.command==="uninstall"){if(e.delaySeconds!==void 0){await m(process.env.AGENT_CONFIG_PATH??r,{type:"uninstall"},e.delaySeconds,e.allowWaiting);return}l().configPath===r?await E():await _(),console.log(`Uninstalled ${h}`);return}}function P(e){return e===r?l().configPath:e}async function m(e,t,n,a){const o=await q(e,{operation:t,delaySeconds:n,allowWaiting:a});console.log(`Scheduled maintenance task ${o.id}`),console.log(`Operation: ${v(o.operation)}`),console.log(`Not before: ${o.notBefore}`)}function J(e){const t=[`Active sessions: ${e.active}`,`Waiting sessions: ${e.waiting}`];for(const n of["codex","claude"]){const a=e.agents[n];t.push(a.available?`${C(n)}: active=${a.active}, waiting=${a.waiting}`:`${C(n)}: unavailable (${a.error})`)}return t.join(`
|
|
3
|
+
`)}function V(e){return e?[`Task: ${e.id}`,`Operation: ${v(e.operation)}`,`Status: ${e.status}`,`Not before: ${e.notBefore}`,...e.message?[`Message: ${e.message}`]:[]].join(`
|
|
4
|
+
`):"No maintenance task has been scheduled"}function v(e){return e.type==="upgrade"?`upgrade to ${e.version}`:e.type==="restart"?e.agent?`restart ${e.agent}`:"restart client":e.type}function C(e){return`${e.charAt(0).toUpperCase()}${e.slice(1)}`}async function g(e){const t=await D("/bin/sh",["-lc",e],{allowFailure:!0});if(t.stdout&&process.stdout.write(t.stdout),t.stderr&&process.stderr.write(t.stderr),t.status!==0)throw new Error(t.stderr||t.stdout||`Command failed: ${e}`)}B().catch(e=>{if(e instanceof N){const n=e.message===d()?e.message:`${e.message}
|
|
5
5
|
|
|
6
6
|
${d()}`;console.error(n),process.exit(2)}const t=e instanceof Error?e.message:String(e);console.error(t),process.exit(1)});
|
package/dist/install.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type RuntimeInstallResult } from "./runtime.js";
|
|
2
2
|
import { type ServiceInstallResult } from "./service.js";
|
|
3
3
|
import { type InstallArgs } from "./args.js";
|
|
4
|
+
import { runCommand } from "./exec.js";
|
|
4
5
|
import { type ClientMigrationResult } from "./migration.js";
|
|
5
6
|
export type InstallResult = {
|
|
6
7
|
configPath: string;
|
|
@@ -10,6 +11,12 @@ export type InstallResult = {
|
|
|
10
11
|
service: ServiceInstallResult;
|
|
11
12
|
};
|
|
12
13
|
export declare function activateMigratedService(migration: ClientMigrationResult, runtime: RuntimeInstallResult, configPath: string, path?: string): Promise<boolean>;
|
|
14
|
+
export declare function scheduleDarwinMigrationHandoff(migration: ClientMigrationResult, runtime: RuntimeInstallResult, configPath: string, path?: string, dependencies?: {
|
|
15
|
+
run?: typeof runCommand;
|
|
16
|
+
wait?: (milliseconds: number) => Promise<unknown>;
|
|
17
|
+
attempts?: number;
|
|
18
|
+
}): Promise<boolean>;
|
|
19
|
+
export declare function completeMigrationHandoff(handoffPath: string): Promise<void>;
|
|
13
20
|
type ResolvedInstallArgs = Omit<InstallArgs, "tunnelId" | "token" | "workspace" | "workspaceId" | "workspaceName"> & {
|
|
14
21
|
tunnelId: string;
|
|
15
22
|
token: string;
|
package/dist/install.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import{randomUUID as
|
|
1
|
+
import{randomUUID as I}from"node:crypto";import{mkdir as M,readFile as N,realpath as T,rename as $,stat as x,writeFile as O}from"node:fs/promises";import{join as _}from"node:path";import{setTimeout as C}from"node:timers/promises";import{normalizeAgentServer as L}from"@messenger-agent/shared/agent-config";import{readConfigYaml as h,updateClientConfig as H,writeUpgradeChannel as j}from"./config-file.js";import{installRuntime as R,rollbackRuntime as l}from"./runtime.js";import{installService as g,startLegacyService as y,stopLegacyService as v,uninstallLegacyService as k,uninstallService as P}from"./service.js";import{UsageError as f}from"./args.js";import{defaultWorkspacePath as A,legacyCodingAgentPaths as W,messengerAgentPaths as U}from"./paths.js";import{runCommand as G}from"./exec.js";import{completeLegacyMigration as S,migrateLegacyClient as z,rollbackLegacyMigration as F}from"./migration.js";const V="vip.elevo.messenger.agent.migration";async function ut(t,e,r,o){if(!t.migrated)return!1;if(process.platform==="darwin")return q(t,e,r,o);try{return await D(t,e,r,o),!0}catch(n){throw await l(e).catch(()=>{}),await b(t),n}}async function D(t,e,r,o){const n=await h(r),i=u(n,"data_dir")??t.paths.dataDir,s=Array.isArray(n.workspaces)?n.workspaces.find(c=>!!c&&typeof c=="object"&&!Array.isArray(c)&&typeof c.path=="string"):void 0,a=u(s,"path");if(!a)throw new Error("Migrated config does not contain a workspace path");await v(),await g({configPath:r,dataDir:i,workspacePath:a,serviceCommandPath:e.wrapperPath,path:o}),await k(),await S(t)}async function q(t,e,r,o,n={}){const i=n.run??G,s=n.wait??C,a=n.attempts??1200,c=_(t.paths.rootDir,"migration-handoff.json"),d=`${V}.${process.pid}`;await p(c,{schemaVersion:1,status:"scheduled",helperLabel:d,migration:t,runtime:e,configPath:r,...o?{path:o}:{},updatedAt:new Date().toISOString()}),await i("launchctl",["submit","-l",d,"--",e.cliWrapperPath,"complete-migration","--handoff",c]);for(let m=0;m<a;m+=1){const w=await E(c);if(w.status==="completed")return await i("launchctl",["remove",d],{allowFailure:!0}),!0;if(w.status==="failed")throw new Error(w.message??"macOS service migration failed");await s(100)}throw new Error(`Timed out waiting for macOS service migration; inspect ${c}`)}async function wt(t){const e=await E(t);await p(t,{...e,status:"running",updatedAt:new Date().toISOString()});try{await D(e.migration,e.runtime,e.configPath,e.path),await p(t,{...e,status:"completed",updatedAt:new Date().toISOString()})}catch(r){const o=[];await l(e.runtime).catch(i=>{o.push(`runtime rollback failed: ${String(i)}`)}),await P().catch(i=>{o.push(`new service cleanup failed: ${String(i)}`)}),await y().catch(i=>{o.push(`legacy service restart failed: ${String(i)}`)});const n=[r instanceof Error?r.message:String(r),...o].join("; ");throw await p(t,{...e,status:"failed",message:n,updatedAt:new Date().toISOString()}),r}}async function E(t){const e=JSON.parse(await N(t,"utf8"));if(e.schemaVersion!==1||!e.migration||!e.runtime||typeof e.configPath!="string"||typeof e.helperLabel!="string"||e.status!=="scheduled"&&e.status!=="running"&&e.status!=="completed"&&e.status!=="failed")throw new Error(`Invalid Messenger Agent migration handoff: ${t}`);return e}async function p(t,e){const r=`${t}.${process.pid}.tmp`;await O(r,`${JSON.stringify(e,null,2)}
|
|
2
|
+
`,{mode:384}),await $(r,t)}function B(t=process.platform){if(t!=="linux"&&t!=="darwin")throw new Error("Only Linux and macOS are supported")}function J(t=process.versions.node){const e=/^(\d+)\.(\d+)\.(\d+)(?:[.-]|$)/.exec(t),r=Number(e?.[1]),o=Number(e?.[2]);if(!(r>22||r===22&&o>=19))throw new Error("Node.js 22.19.0 or newer is required")}function Z(t){if(t.server)try{L(t.server)}catch{throw new Error("--server must be a valid HTTP or HTTPS server address")}if(t.tunnelId&&!/^[A-Za-z0-9._:-]+$/.test(t.tunnelId))throw new Error("--tunnel-id may only contain letters, numbers, '.', '_', ':', and '-'");if(t.workspaceId&&!/^[A-Za-z0-9._:-]+$/.test(t.workspaceId))throw new Error("--workspace-id may only contain letters, numbers, '.', '_', ':', and '-'");if(t.workspaceName&&(t.workspaceName.trim().length===0||t.workspaceName.trim().length>128))throw new Error("--workspace-name must be between 1 and 128 characters")}async function Y(t,e=!1){e&&await M(t,{recursive:!0});const r=await T(t);if(!(await x(r)).isDirectory())throw new Error("--workspace must point to an existing directory");return r}async function lt(t){B(),J();const e=U(),r=W(),n=t.configPath===e.configPath||t.configPath===r.configPath?await z():void 0;let i;try{const s=n?{...t,configPath:t.configPath===n.legacyPaths.configPath?n.paths.configPath:t.configPath,dataDir:t.dataDir===n.legacyPaths.dataDir?n.paths.dataDir:t.dataDir}:t,a=await K(s);Z(a);const c=await Y(a.workspace,a.createWorkspace);await H({configPath:a.configPath,dataDir:a.dataDir,workspacePath:c,workspaceId:a.workspaceId,workspaceName:a.workspaceName,tunnelId:a.tunnelId,token:a.token,server:a.server,serverUrl:a.serverUrl,preserveWorkspaces:a.preserveWorkspaces,path:process.env.PATH}),t.channel&&await j(a.configPath,t.channel),i=await R({version:"current",configPath:a.configPath,runtimeDir:n?.paths.runtimeDir,binDir:n?.paths.binDir,path:process.env.PATH,hostArtifactDirectory:process.env.MESSENGER_AGENT_BOOTSTRAP_HOST_DIR,clientDirectory:process.env.MESSENGER_AGENT_BOOTSTRAP_CLIENT_DIR}),n?.migrated&&await v();const d=await g({configPath:a.configPath,dataDir:a.dataDir,workspacePath:c,serviceCommandPath:i.wrapperPath,path:process.env.PATH});return n?.migrated&&(await k(),await S(n)),{configPath:a.configPath,dataDir:a.dataDir,workspacePath:c,runtime:i,service:d}}catch(s){throw i&&await l(i).catch(()=>{}),n?.migrated&&await b(n),s}}async function b(t){await P().catch(()=>{}),await F(t),await y().catch(()=>{})}async function K(t){const e=await h(t.configPath),r=X(e,"tunnel"),o=t.tunnelId??u(r,"tunnel_id"),n=t.token??u(r,"token"),i=Q(e,t.workspaceId,o),s=t.workspace??i?.path??A,a=t.workspaceId??i?.id??I(),c=t.workspaceName??i?.name??(o?`${o} Default`:void 0),d=s===A;if(!o)throw new f("Missing required option: --tunnel-id");if(!n)throw new f("Missing required option: --token");if(!a)throw new f("Missing required option: --workspace-id");if(!c)throw new f("Missing required option: --workspace-name");return{...t,tunnelId:o,token:n,workspace:s,workspaceId:a,workspaceName:c,preserveWorkspaces:!t.workspace&&!!i,createWorkspace:d}}function Q(t,e,r){const o=t.workspaces;if(!Array.isArray(o))return;const n=o.filter(a=>!!a&&typeof a=="object"&&!Array.isArray(a)&&typeof a.path=="string");if(e){const a=n.find(c=>c.id===e);return!a||typeof a.path!="string"?void 0:{id:e,name:typeof a.name=="string"&&a.name?a.name:`${r??e} Default`,path:a.path}}const i=e??(r?`${r}--default`:void 0),s=(i?n.find(a=>a.id===i):void 0)??n.find(a=>a.id==="default")??n[0];if(!(!s||typeof s.path!="string"))return{id:typeof s.id=="string"&&s.id?s.id:i??"default",name:typeof s.name=="string"&&s.name?s.name:`${r??i??"default"} Default`,path:s.path}}function X(t,e){const r=t[e];if(!(!r||typeof r!="object"||Array.isArray(r)))return r}function u(t,e){const r=t?.[e];return typeof r=="string"&&r?r:void 0}export{ut as activateMigratedService,J as assertNodeVersion,B as assertSupportedPlatform,wt as completeMigrationHandoff,lt as installClient,K as resolveInstallArgs,Y as resolveWorkspacePath,q as scheduleDarwinMigrationHandoff,Z as validateInstallArgs};
|
package/dist/migration.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{constants as
|
|
2
|
-
`,{mode:384}),await
|
|
1
|
+
import{constants as O}from"node:fs";import{access as $,chmod as u,lstat as m,mkdir as M,readFile as y,readlink as D,rename as s,symlink as N,unlink as _,writeFile as l}from"node:fs/promises";import{dirname as f,isAbsolute as P,join as w,relative as k,resolve as e}from"node:path";import{parse as x,stringify as C}from"yaml";import{legacyCodingAgentPaths as v,messengerAgentPaths as j}from"./paths.js";async function K(t){const r=j(t),a=v(t);if(await d(r.configPath)){const i=w(r.rootDir,"migration.json"),n=await F(i);return n?.status==="prepared"&&e(n.sourceRoot)===e(a.rootDir)&&e(n.targetRoot)===e(r.rootDir)?(await A(a.rootDir,r.rootDir),{paths:r,migrated:!0,legacyPaths:a,statePath:i}):{paths:r,migrated:!1,legacyPaths:a}}if(!await d(a.configPath))return{paths:r,migrated:!1,legacyPaths:a};if(await d(r.rootDir))throw new Error(`Messenger Agent migration target already exists without a config file: ${r.rootDir}`);await s(a.rootDir,r.rootDir);const o=w(r.rootDir,"migration.json");try{return await A(a.rootDir,r.rootDir),await E(r.configPath,a,r),await h(o,{schemaVersion:1,status:"prepared",sourceRoot:a.rootDir,targetRoot:r.rootDir,updatedAt:new Date().toISOString()}),{paths:r,migrated:!0,legacyPaths:a,statePath:o}}catch(i){throw await b(a.rootDir,r.rootDir).catch(()=>{}),await s(r.rootDir,a.rootDir).catch(()=>{}),i}}async function Y(t){!t.migrated||!t.statePath||await h(t.statePath,{schemaVersion:1,status:"completed",sourceRoot:t.legacyPaths.rootDir,targetRoot:t.paths.rootDir,updatedAt:new Date().toISOString()})}async function q(t){if(t.migrated){if(await b(t.legacyPaths.rootDir,t.paths.rootDir),await d(t.legacyPaths.rootDir))throw new Error(`Cannot roll back Messenger Agent migration because the legacy directory exists: ${t.legacyPaths.rootDir}`);t.statePath&&await h(t.statePath,{schemaVersion:1,status:"rolled-back",sourceRoot:t.legacyPaths.rootDir,targetRoot:t.paths.rootDir,updatedAt:new Date().toISOString()}),await E(t.paths.configPath,t.paths,t.legacyPaths),await s(t.paths.rootDir,t.legacyPaths.rootDir)}}async function F(t){try{const r=JSON.parse(await y(t,"utf8"));if(r.schemaVersion!==1||r.status!=="prepared"&&r.status!=="completed"&&r.status!=="rolled-back"||typeof r.sourceRoot!="string"||typeof r.targetRoot!="string"||typeof r.updatedAt!="string")throw new Error(`Invalid Messenger Agent migration state: ${t}`);return r}catch(r){if(r.code==="ENOENT")return;throw r}}async function A(t,r){try{if((await m(t)).isSymbolicLink()&&e(f(t),await D(t))===e(r))return;throw new Error(`Legacy migration path is occupied: ${t}`)}catch(a){if(a.code!=="ENOENT")throw a}await N(r,t,"dir")}async function b(t,r){try{if(!(await m(t)).isSymbolicLink()||e(f(t),await D(t))!==e(r))return;await _(t)}catch(a){if(a.code!=="ENOENT")throw a}}async function E(t,r,a){const o=x(await y(t,"utf8"));if(!S(o))throw new Error(`Config file must contain a YAML object: ${t}`);c(o,["data_dir"],r.rootDir,a.rootDir),c(o,["file_uploads","temp_dir"],r.rootDir,a.rootDir);for(const n of["codex","claude","workspace"])c(o,[n,"data_dir"],r.rootDir,a.rootDir),c(o,[n,"log_file"],r.rootDir,a.rootDir),c(o,[n,"file_uploads","temp_dir"],r.rootDir,a.rootDir);const i=`${t}.${process.pid}.tmp`;await l(i,C(o),{mode:384}),await u(i,384),await s(i,t),await u(t,384)}function c(t,r,a,o){let i=t;for(const L of r.slice(0,-1)){const p=i[L];if(!S(p))return;i=p}const n=r.at(-1);if(!n)return;const g=i[n];typeof g!="string"||!I(g,a)||(i[n]=w(o,k(e(a),e(g))))}function I(t,r){if(!P(t))return!1;const a=k(e(r),e(t));return a===""||!a.startsWith("..")&&!P(a)}async function h(t,r){await M(f(t),{recursive:!0,mode:448});const a=`${t}.${process.pid}.tmp`;await l(a,`${JSON.stringify(r,null,2)}
|
|
2
|
+
`,{mode:384}),await s(a,t)}async function d(t){try{return await $(t,O.F_OK),!0}catch{return!1}}function S(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}export{Y as completeLegacyMigration,K as migrateLegacyClient,q as rollbackLegacyMigration};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function assertPlatformNativeDependencies(platform?: NodeJS.Platform, arch?: string, resolvePackage?: (request: string) => string, isFile?: (path: string) => boolean): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{statSync as l}from"node:fs";import{createRequire as p}from"node:module";import{dirname as s,join as x}from"node:path";const m=p(import.meta.url),g={"linux-x64":[{packageName:"@openai/codex-linux-x64",executable:"vendor/x86_64-unknown-linux-musl/bin/codex"},{packageName:"@anthropic-ai/claude-agent-sdk-linux-x64",executable:"claude"}],"linux-arm64":[{packageName:"@openai/codex-linux-arm64",executable:"vendor/aarch64-unknown-linux-musl/bin/codex"},{packageName:"@anthropic-ai/claude-agent-sdk-linux-arm64",executable:"claude"}],"darwin-x64":[{packageName:"@openai/codex-darwin-x64",executable:"vendor/x86_64-apple-darwin/bin/codex"},{packageName:"@anthropic-ai/claude-agent-sdk-darwin-x64",executable:"claude"}],"darwin-arm64":[{packageName:"@openai/codex-darwin-arm64",executable:"vendor/aarch64-apple-darwin/bin/codex"},{packageName:"@anthropic-ai/claude-agent-sdk-darwin-arm64",executable:"claude"}]};function h(e=process.platform,t=process.arch,i=m.resolve,o=k){const a=`${e}-${t}`,r=g[a];if(!r)throw new Error(`Unsupported native dependency target: ${a}`);const c=r.filter(({packageName:n,executable:d})=>{try{const u=i(`${n}/package.json`);return!o(x(s(u),d))}catch{return!0}});if(c.length>0)throw new Error(`Missing native Agent dependencies for ${a}: ${c.map(({packageName:n})=>n).join(", ")}`)}function k(e){try{return l(e).isFile()}catch{return!1}}export{h as assertPlatformNativeDependencies};
|
package/dist/runtime.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{createHash as oe}from"node:crypto";import{createReadStream as se,createWriteStream as ce}from"node:fs";import{access as le,cp as
|
|
2
|
-
`),
|
|
3
|
-
`);await N(
|
|
1
|
+
import{createHash as oe}from"node:crypto";import{createReadStream as se,createWriteStream as ce}from"node:fs";import{access as le,cp as j,lstat as Z,mkdir as k,readFile as S,readlink as ue,rename as E,rm as $,symlink as fe,writeFile as N}from"node:fs/promises";import{homedir as q}from"node:os";import{basename as de,delimiter as me,dirname as C,isAbsolute as G,join as a,relative as we,resolve as v}from"node:path";import{Readable as pe}from"node:stream";import{pipeline as he}from"node:stream/promises";import{fileURLToPath as Q}from"node:url";import{runCommand as P}from"./exec.js";import{cliName as ge,legacyCliName as ye,runtimePackageScope as $e}from"./identity.js";import{defaultBinDir as ve,defaultRuntimeDir as ke,legacyCodingAgentPaths as Ee,messengerAgentPaths as Ne}from"./paths.js";const O="https://registry.npmjs.org",I="@messenger-agent/client",Ke=["latest","beta","alpha"];function et(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 tt(e,t){const r=W(e),n=t??r;return{version:r?n??r:e,channel:n}}function rt(e){return/^\d+\.\d+\.\d+-/.test(e)}function at(e,t){const[r]=e.split("+",1),[n]=t.split("+",1),o=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/.exec(r??""),s=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/.exec(n??"");if(!o||!s)throw new Error(`Automatic upgrades require semantic versions, received: ${e} and ${t}`);for(let c=1;c<=3;c+=1){const l=Number(o[c])-Number(s[c]);if(l!==0)return Math.sign(l)}return Pe(o[4],s[4])}function Pe(e,t){if(!e&&!t)return 0;if(!e)return 1;if(!t)return-1;const r=e.split("."),n=t.split(".");for(let o=0;o<Math.max(r.length,n.length);o+=1){const s=r[o],c=n[o];if(s===void 0)return-1;if(c===void 0)return 1;const l=/^\d+$/.test(s),i=/^\d+$/.test(c);if(l&&i){const w=Number(s)-Number(c);if(w!==0)return Math.sign(w);continue}if(l)return-1;if(i)return 1;if(s!==c)return s<c?-1:1}return 0}async function xe(){const e=a(C(Q(import.meta.url)),"..","package.json");return JSON.parse(await S(e,"utf8")).version??"latest"}function nt(e=import.meta.url){const t=C(Q(e));return de(t)==="src"?a(t,"..","assets","skills"):a(t,"assets","skills")}function be(){return[process.env.CODEX_HOME??a(q(),".codex"),process.env.CLAUDE_CONFIG_DIR??a(q(),".claude")]}async function m(e){await $(e,{recursive:!0,force:!0})}async function V(e,t){const r=`${t}.tmp-${process.pid}`;await m(r),await fe(e,r,"dir"),await E(r,t)}async function F(e){try{return(await Z(e)).isSymbolicLink()}catch{return!1}}async function it(e){const t=De(e.configPath),r=e.runtimeDir??t?.runtimeDir??ke,n=e.binDir??t?.binDir??ve,o=Ue(e.platform??process.platform),s=je(e.arch??process.arch),c=W(e.version),l=e.version==="current"?await xe():c?await Ce(c,e.registryUrl):e.version,i=await He({runtimeDir:r,platform:o,arch:s,registryUrl:e.registryUrl,artifactDirectory:e.hostArtifactDirectory}),w=l.replaceAll("/","_").replaceAll(":","_"),p=a(r,"releases"),u=a(p,w),h=a(r,"current"),D=a(u,"node_modules","@messenger-agent","client","dist","index.js"),d=a(u,"node_modules","@messenger-agent","client","package.json"),_=e.skillsSourceDir??a(u,"node_modules","@messenger-agent","client","dist","assets","skills"),M=a(n,"messenger-agent-service"),T=a(n,"coding-agent-client-service"),L=a(n,ge),U=a(n,ye),ae=[M,T,L,U];if(await k(p,{recursive:!0,mode:448}),await k(n,{recursive:!0,mode:448}),!(await z(d,l)&&(await X(i.nodeExecutable,D)).status===0)){const f=`${u}.tmp-${process.pid}`,A=a(f,"node_modules","@messenger-agent","client","dist","index.js");await m(f),await k(f,{recursive:!0,mode:448});try{if(e.clientDirectory&&await z(a(e.clientDirectory,"node_modules","@messenger-agent","client","package.json"),l))await j(e.clientDirectory,f,{recursive:!0});else{const x=a(f,".npmrc");await N(x,""),await P(i.nodeExecutable,[i.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}@${l}`],{env:{PATH:_e(i.nodeExecutable,e.path)},cwd:f})}if(!await z(a(f,"node_modules","@messenger-agent","client","package.json"),l))throw new Error(`Installed Messenger Agent Client does not match ${l}`);const g=await X(i.nodeExecutable,A);if(g.status!==0)throw new Error(`Messenger Agent Client self-check failed: ${g.stderr||g.stdout}`);await m(u),await E(f,u)}catch(g){throw await m(f),g}}const[ne,ie]=be();await Ge(_,[e.codexHome??ne,e.claudeHome??ie]);const J=await re(h),B=await re(i.currentLink),Y=await Promise.all(ae.map(async f=>({path:f,content:await Ae(f)})));await F(h)||await m(h),await F(i.currentLink)||await m(i.currentLink);try{await V(i.releaseDir,i.currentLink),await V(u,h);const f=b(i.currentLink,i.manifest.node),A=a(h,"node_modules","@messenger-agent","client","dist","index.js"),g=["#!/bin/sh","set -eu",...e.path?[`export PATH=${y(e.path)}`]:[],`export AGENT_CONFIG_PATH=${y(e.configPath)}`,`exec ${y(f)} ${y(A)} run-service --config ${y(e.configPath)}`,""].join(`
|
|
2
|
+
`),x=["#!/bin/sh","set -eu",`export AGENT_CONFIG_PATH=${y(e.configPath)}`,`exec ${y(f)} ${y(A)} "$@"`,""].join(`
|
|
3
|
+
`);await N(M,g,{mode:448}),await N(T,g,{mode:448}),await N(L,x,{mode:448}),await N(U,x,{mode:448})}catch(f){throw await H(J,h),await H(B,i.currentLink),await K(Y),f}return{releaseDir:u,currentLink:h,wrapperPath:M,legacyServiceWrapperPath:T,cliWrapperPath:L,legacyCliWrapperPath:U,version:l,previousReleaseDir:J,hostCurrentLink:i.currentLink,previousHostReleaseDir:B,previousWrappers:Y}}async function X(e,t){return P(e,[t,"self-check"],{allowFailure:!0})}function De(e){const t=Ne();if(v(e)===v(t.configPath))return t;const r=Ee();return v(e)===v(r.configPath)?r:void 0}async function ot(e){await H(e.previousReleaseDir,e.currentLink),await H(e.previousHostReleaseDir,e.hostCurrentLink),await K(e.previousWrappers)}async function H(e,t){e?await V(e,t):await m(t)}async function Ae(e){try{return await S(e,"utf8")}catch(t){if(t.code==="ENOENT")return;throw t}}async function K(e){await Promise.all(e.map(({path:t,content:r})=>r===void 0?m(t):N(t,r,{mode:448})))}function Se(e,t){return`${$e}/node-host-${e}-${t}`}async function Ce(e,t){return(await ee(I,e,t)).version}async function He(e){const t=Se(e.platform,e.arch),r=e.artifactDirectory?void 0:await Me(t,"latest",e.registryUrl),o=(e.artifactDirectory?await te(a(e.artifactDirectory,"manifest.json"),{platform:e.platform,arch:e.arch}):void 0)?.version??r?.version;if(!o)throw new Error(`Unable to resolve ${t}`);const s=a(e.runtimeDir,"host"),c=a(s,"releases"),l=`${o}-${e.platform}-${e.arch}`.replaceAll("/","_").replaceAll(":","_"),i=a(c,l),w=a(s,"current"),p=a(i,"manifest.json");if(await k(c,{recursive:!0,mode:448}),!await R(p)){const d=`${i}.tmp-${process.pid}`;await m(d),await k(d,{recursive:!0,mode:448});try{e.artifactDirectory?await j(e.artifactDirectory,d,{recursive:!0}):r&&await Re(r,d),await m(i),await E(d,i)}catch(_){throw await m(d),_}}const u=await te(p,{version:o,platform:e.platform,arch:e.arch});await Le(i,u);const h=b(i,u.node),D=b(i,u.npm);if(!await R(h)||!await R(D))throw new Error(`Node Host ${t}@${o} is incomplete`);if(u.platform==="darwin"){const d=a(i,"Messenger Agent.app");await P("codesign",["--verify","--deep","--strict",d]),await P("spctl",["--assess","--type","execute",d])}return{releaseDir:i,currentLink:w,nodeExecutable:h,npmCli:D,manifest:u}}async function Re(e,t){const r=`${t}.tgz`;try{const n=await fetch(e.tarball);if(!n.ok||!n.body)throw new Error(`Unable to download ${e.packageName}@${e.version}: HTTP ${n.status}`);await he(pe.fromWeb(n.body),ce(r,{mode:384})),await Te(r,e.integrity),await P("tar",["-xzf",r,"-C",t,"--strip-components=2","package/host"])}finally{await $(r,{force:!0})}}async function z(e,t){try{const r=JSON.parse(await S(e,"utf8"));return r.name===I&&r.version===t}catch{return!1}}function _e(e,t=process.env.PATH){const r=C(e);return t?`${r}${me}${t}`:r}async function Me(e,t,r=process.env.MESSENGER_AGENT_NPM_REGISTRY??O){const{metadata:n,version:o}=await ee(e,t,r),s=n.versions?.[o]?.dist;if(!s?.tarball||!s.integrity)throw new Error(`Registry returned incomplete artifact metadata for ${e}@${o}`);return{packageName:e,version:o,tarball:s.tarball,integrity:s.integrity}}async function ee(e,t,r=process.env.MESSENGER_AGENT_NPM_REGISTRY??O){const n=`${r.replace(/\/$/,"")}/${encodeURIComponent(e)}`,o=await fetch(n,{headers:{accept:"application/json"}});if(!o.ok)throw new Error(`Unable to resolve ${e}: HTTP ${o.status}`);const s=await o.json(),c=W(t)?s["dist-tags"]?.[t]:t;if(!c)throw new Error(`Registry has no ${t} release for ${e}`);return{metadata:s,version:c}}async function Te(e,t){const r=t.indexOf("-");if(r<=0)throw new Error("Node Host has an invalid integrity value");const n=t.slice(0,r),o=t.slice(r+1),s=oe(n);for await(const c of se(e))s.update(c);if(s.digest("base64")!==o)throw new Error("Node Host integrity verification failed")}async function te(e,t){const r=JSON.parse(await S(e,"utf8"));if(r.schemaVersion!==1||r.product!=="messenger-agent-node-host"||t.version!==void 0&&r.version!==t.version||typeof r.version!="string"||typeof r.nodeVersion!="string"||r.platform!==t.platform||r.arch!==t.arch||typeof r.node!="string"||typeof r.npm!="string"||r.payload!==void 0&&typeof r.payload!="string")throw new Error(`Node Host manifest does not match ${t.platform}-${t.arch}${t.version?`@${t.version}`:""}`);return r}async function Le(e,t){if(!t.payload)return;const r=b(e,t.node);if(await R(r))return;if(t.platform!=="darwin")throw new Error("Only macOS Node Hosts may contain a zip payload");const n=b(e,t.payload);await P("ditto",["-x","-k",n,e])}function b(e,t){if(!t||G(t))throw new Error(`Node Host contains an unsafe path: ${t}`);const r=v(e),n=v(e,t),o=we(r,n);if(o.startsWith("..")||G(o))throw new Error(`Node Host contains an unsafe path: ${t}`);return n}function Ue(e){if(e==="linux"||e==="darwin")return e;throw new Error(`No Messenger Agent runtime is available for platform: ${e}`)}function je(e){if(e==="x64"||e==="arm64")return e;throw new Error(`No Messenger Agent runtime is available for architecture: ${e}`)}async function re(e){if(!await F(e))return;const t=await ue(e);return G(t)?t:v(C(e),t)}async function R(e){try{return await le(e),!0}catch{return!1}}async function Ge(e,t){const r="manage-messenger-agent",n="manage-coding-agent-client",o=a(e,r),s=await Oe(o);for(const c of new Set(t)){const l=a(c,"skills"),i=a(l,r),w=a(l,`.${r}.tmp-${process.pid}`),p=a(l,`.${r}.old-${process.pid}`);if(await $(w,{recursive:!0,force:!0}),await $(p,{recursive:!0,force:!0}),await $(a(l,n),{recursive:!0,force:!0}),!s){await $(i,{recursive:!0,force:!0});continue}await k(l,{recursive:!0,mode:448}),await j(o,w,{recursive:!0}),await E(i,p).catch(u=>{if(u.code!=="ENOENT")throw u});try{await E(w,i),await $(p,{recursive:!0,force:!0})}catch(u){throw await E(p,i).catch(()=>{}),u}}}async function Oe(e){try{return(await Z(e)).isDirectory()}catch(t){if(t.code==="ENOENT")return!1;throw t}}function y(e){return`'${e.replaceAll("'","'\\''")}'`}export{at as compareSemverVersions,nt as currentBundledSkillsDir,xe as currentPackageVersion,be as defaultAgentHomes,it as installRuntime,rt as isPrereleaseVersion,Se as nodeHostPackageName,et as normalizeReleaseChannel,tt as normalizeUpgradeVersion,W as parseReleaseChannel,Ke as releaseChannels,Ce as resolveChannelPackageVersion,ot as rollbackRuntime,Ge as syncBundledSkills};
|
package/dist/service.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{access as A,chmod as h,mkdir as g,unlink as d,writeFile as f}from"node:fs/promises";import{userInfo as P}from"node:os";import{dirname as y,join as a}from"node:path";import{runCommand as n}from"./exec.js";import{legacyCodingAgentPaths as $}from"./paths.js";import{launchdLabel as
|
|
2
|
-
`)}function v(e){return e.replaceAll("\\","\\\\").replaceAll(" ","\\x20")}function E(e,t){return`${e}="${t.replaceAll("\\","\\\\").replaceAll('"','\\"')}"`}function l(e){return e.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}function S(e){const t=a(e.dataDir,"logs","client-service.out.log"),r=a(e.dataDir,"logs","client-service.err.log");return['<?xml version="1.0" encoding="UTF-8"?>','<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">','<plist version="1.0">',"<dict>"," <key>Label</key>",` <string>${l(
|
|
3
|
-
`)}async function p(e){const t=(process.env.PATH??"").split(":").filter(Boolean);for(const r of t)try{return await A(a(r,e)),!0}catch{}return!1}const F={commandExists:p,runCommand:n};async function C(e,t=F){if(!await t.commandExists("loginctl"))throw new Error(`loginctl is required to keep the user service running after logout. Enable linger for ${e} and retry installation.`);if(await b(e,t.runCommand))return;if(console.log(`Enabling login persistence for ${e}`),(await t.runCommand("loginctl",["enable-linger",e],{allowFailure:!0,interactive:!0})).status!==0)throw new Error(`Unable to enable login persistence for ${e}. Run 'sudo loginctl enable-linger ${e}' and retry installation.`);if(!await b(e,t.runCommand))throw new Error(`Login persistence is still disabled for ${e}. Run 'sudo loginctl enable-linger ${e}' and retry installation.`)}async function b(e,t){const r=await t("loginctl",["show-user",e,"-p","Linger"],{allowFailure:!0});return r.status===0&&r.stdout.trim()==="Linger=yes"}async function G(e){const t=e.platform??process.platform;if(t==="linux")return N(e);if(t==="darwin")return T(e);throw new Error("Only Linux and macOS are supported")}async function N(e){if(!await p("systemctl"))throw new Error("systemctl is required to install the user service");const t=e.user??process.env.USER??P().username;await C(t);const r=a(process.env.HOME??"",".config","systemd","user",`${s}.service`);return await g(y(r),{recursive:!0,mode:448}),await f(r,O(e),{mode:384}),await h(r,384),await n("systemctl",["--user","daemon-reload"]),await n("systemctl",["--user","enable","--now",`${s}.service`]),await n("systemctl",["--user","restart",`${s}.service`]),await L("linux"),{servicePath:r,commands:
|
|
1
|
+
import{access as A,chmod as h,mkdir as g,unlink as d,writeFile as f}from"node:fs/promises";import{userInfo as P}from"node:os";import{dirname as y,join as a}from"node:path";import{runCommand as n}from"./exec.js";import{legacyCodingAgentPaths as $}from"./paths.js";import{launchdLabel as c,legacyLaunchdLabel as u,legacyServiceName as i,productName as w,serviceName as s}from"./identity.js";import{launchdLabel as J,serviceName as Q}from"./identity.js";function m(e){return`'${e.replaceAll("'","'\\''")}'`}function O(e){return["[Unit]",`Description=${w}`,"After=network-online.target","","[Service]","Type=simple",`ExecStart=${v(e.serviceCommandPath)}`,"Restart=always","RestartSec=5",`WorkingDirectory=${v(e.workspacePath)}`,`Environment=${E("AGENT_CONFIG_PATH",e.configPath)}`,...e.path?[`Environment=${E("PATH",e.path)}`]:[],"","[Install]","WantedBy=default.target",""].join(`
|
|
2
|
+
`)}function v(e){return e.replaceAll("\\","\\\\").replaceAll(" ","\\x20")}function E(e,t){return`${e}="${t.replaceAll("\\","\\\\").replaceAll('"','\\"')}"`}function l(e){return e.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}function S(e){const t=a(e.dataDir,"logs","client-service.out.log"),r=a(e.dataDir,"logs","client-service.err.log");return['<?xml version="1.0" encoding="UTF-8"?>','<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">','<plist version="1.0">',"<dict>"," <key>Label</key>",` <string>${l(c)}</string>`," <key>ProgramArguments</key>"," <array>",` <string>${l(e.serviceCommandPath)}</string>`," </array>"," <key>WorkingDirectory</key>",` <string>${l(e.workspacePath)}</string>`," <key>EnvironmentVariables</key>"," <dict>"," <key>AGENT_CONFIG_PATH</key>",` <string>${l(e.configPath)}</string>`,...e.path?[" <key>PATH</key>",` <string>${l(e.path)}</string>`]:[]," </dict>"," <key>RunAtLoad</key>"," <true/>"," <key>KeepAlive</key>"," <true/>"," <key>StandardOutPath</key>",` <string>${l(t)}</string>`," <key>StandardErrorPath</key>",` <string>${l(r)}</string>`,"</dict>","</plist>",""].join(`
|
|
3
|
+
`)}async function p(e){const t=(process.env.PATH??"").split(":").filter(Boolean);for(const r of t)try{return await A(a(r,e)),!0}catch{}return!1}const F={commandExists:p,runCommand:n};async function C(e,t=F){if(!await t.commandExists("loginctl"))throw new Error(`loginctl is required to keep the user service running after logout. Enable linger for ${e} and retry installation.`);if(await b(e,t.runCommand))return;if(console.log(`Enabling login persistence for ${e}`),(await t.runCommand("loginctl",["enable-linger",e],{allowFailure:!0,interactive:!0})).status!==0)throw new Error(`Unable to enable login persistence for ${e}. Run 'sudo loginctl enable-linger ${e}' and retry installation.`);if(!await b(e,t.runCommand))throw new Error(`Login persistence is still disabled for ${e}. Run 'sudo loginctl enable-linger ${e}' and retry installation.`)}async function b(e,t){const r=await t("loginctl",["show-user",e,"-p","Linger"],{allowFailure:!0});return r.status===0&&r.stdout.trim()==="Linger=yes"}async function G(e){const t=e.platform??process.platform;if(t==="linux")return N(e);if(t==="darwin")return T(e);throw new Error("Only Linux and macOS are supported")}async function N(e){if(!await p("systemctl"))throw new Error("systemctl is required to install the user service");const t=e.user??process.env.USER??P().username;await C(t);const r=a(process.env.HOME??"",".config","systemd","user",`${s}.service`);return await g(y(r),{recursive:!0,mode:448}),await f(r,O(e),{mode:384}),await h(r,384),await n("systemctl",["--user","daemon-reload"]),await n("systemctl",["--user","enable","--now",`${s}.service`]),await n("systemctl",["--user","restart",`${s}.service`]),await L("linux"),{servicePath:r,commands:x(),warnings:[]}}async function T(e){if(!await p("launchctl"))throw new Error("launchctl is required to install the LaunchAgent");const t=a(process.env.HOME??"","Library","LaunchAgents",`${c}.plist`);await g(y(t),{recursive:!0,mode:448}),await f(t,S(e),{mode:384}),await h(t,384);const r=e.uid??process.getuid?.();if(r===void 0)throw new Error("Unable to determine current uid for launchctl");const o=`gui/${r}`;return await n("launchctl",["bootout",o,t],{allowFailure:!0}),await n("launchctl",["bootstrap",o,t]),await L("darwin",e.uid),{servicePath:t,commands:k(),warnings:[]}}async function L(e=process.platform,t=process.getuid?.()){if(e==="linux"){if((await n("systemctl",["--user","is-active","--quiet",`${s}.service`],{allowFailure:!0})).status!==0)throw new Error(`${w} systemd service did not become active`);return}if(e==="darwin"){if(t===void 0)throw new Error("Unable to determine current uid for launchctl");const r=await n("launchctl",["print",`gui/${t}/${c}`],{allowFailure:!0});if(r.status!==0||!r.stdout.includes("state = running"))throw new Error(`${w} LaunchAgent did not become active`);return}throw new Error("Only Linux and macOS are supported")}function x(){return{status:`systemctl --user status ${s}.service`,logs:`journalctl --user -u ${s}.service -n 100 -f`,start:`systemctl --user start ${s}.service`,restart:`systemctl --user restart ${s}.service`,stop:`systemctl --user stop ${s}.service`,uninstall:`systemctl --user disable --now ${s}.service && rm -f ~/.config/systemd/user/${s}.service && systemctl --user daemon-reload`}}function D(){return{status:`systemctl --user status ${i}.service`,logs:`journalctl --user -u ${i}.service -n 100 -f`,start:`systemctl --user start ${i}.service`,restart:`systemctl --user restart ${i}.service`,stop:`systemctl --user stop ${i}.service`,uninstall:`systemctl --user disable --now ${i}.service && rm -f ~/.config/systemd/user/${i}.service && systemctl --user daemon-reload`}}function k(e=a(process.env.HOME??"",".messenger-agent","data")){const t="gui/$(id -u)",r=`~/Library/LaunchAgents/${c}.plist`;return{status:`launchctl print ${t}/${c}`,logs:`tail -f ${m(a(e,"logs","client-service.out.log"))} ${m(a(e,"logs","client-service.err.log"))}`,start:`launchctl bootstrap ${t} ${r}`,restart:`launchctl kickstart -k ${t}/${c} 2>/dev/null || launchctl bootstrap ${t} ${r}`,stop:`launchctl bootout ${t} ${r}`,uninstall:`launchctl bootout ${t} ${r}; rm -f ${r}`}}function H(){const e="gui/$(id -u)",t=`~/Library/LaunchAgents/${u}.plist`,r=$().dataDir;return{status:`launchctl print ${e}/${u}`,logs:`tail -f ${m(a(r,"logs","client-service.out.log"))} ${m(a(r,"logs","client-service.err.log"))}`,start:`launchctl bootstrap ${e} ${t}`,restart:`launchctl kickstart -k ${e}/${u} 2>/dev/null || launchctl bootstrap ${e} ${t}`,stop:`launchctl bootout ${e} ${t}`,uninstall:`launchctl bootout ${e} ${t}; rm -f ${t}`}}function _(e){const t=e===$().configPath;return process.platform==="darwin"?t?H():k():t?D():x()}async function B(e=process.platform){if(e==="linux"){await n("systemctl",["--user","disable","--now",`${i}.service`],{allowFailure:!0}),await d(a(process.env.HOME??"",".config","systemd","user",`${i}.service`)).catch(t=>{if(t.code!=="ENOENT")throw t}),await n("systemctl",["--user","daemon-reload"],{allowFailure:!0});return}if(e==="darwin"){const t=process.getuid?.();if(t===void 0)throw new Error("Unable to determine current uid for launchctl");const r=a(process.env.HOME??"","Library","LaunchAgents",`${u}.plist`);await n("launchctl",["bootout",`gui/${t}`,r],{allowFailure:!0}),await d(r).catch(o=>{if(o.code!=="ENOENT")throw o});return}throw new Error("Only Linux and macOS are supported")}async function W(e=process.platform){if(e==="linux"){await n("systemctl",["--user","stop",`${i}.service`],{allowFailure:!0});return}if(e==="darwin"){const t=process.getuid?.();if(t===void 0)throw new Error("Unable to determine current uid for launchctl");const r=a(process.env.HOME??"","Library","LaunchAgents",`${u}.plist`);await n("launchctl",["bootout",`gui/${t}`,r],{allowFailure:!0});return}throw new Error("Only Linux and macOS are supported")}async function K(e=process.platform){if(e==="linux"){await n("systemctl",["--user","start",`${i}.service`],{allowFailure:!0});return}if(e==="darwin"){const t=process.getuid?.();if(t===void 0)throw new Error("Unable to determine current uid for launchctl");const r=a(process.env.HOME??"","Library","LaunchAgents",`${u}.plist`);await n("launchctl",["bootstrap",`gui/${t}`,r],{allowFailure:!0});return}throw new Error("Only Linux and macOS are supported")}async function V(e=process.platform){if(e==="linux"){await n("systemctl",["--user","disable","--now",`${s}.service`],{allowFailure:!0}),await d(a(process.env.HOME??"",".config","systemd","user",`${s}.service`)).catch(t=>{if(t.code!=="ENOENT")throw t}),await n("systemctl",["--user","daemon-reload"],{allowFailure:!0});return}if(e==="darwin"){const t=process.getuid?.();if(t===void 0)throw new Error("Unable to determine current uid for launchctl");const r=a(process.env.HOME??"","Library","LaunchAgents",`${c}.plist`);await n("launchctl",["bootout",`gui/${t}`,r],{allowFailure:!0}),await d(r).catch(o=>{if(o.code!=="ENOENT")throw o});return}throw new Error("Only Linux and macOS are supported")}export{S as createLaunchdPlist,O as createSystemdService,k as darwinCommands,C as ensureSystemdUserLinger,G as installService,J as launchdLabel,H as legacyDarwinCommands,D as legacyLinuxCommands,x as linuxCommands,_ as serviceCommandsForConfig,Q as serviceName,m as shellEscape,K as startLegacyService,W as stopLegacyService,B as uninstallLegacyService,V as uninstallService,L as verifyServiceHealth};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@messenger-agent/client",
|
|
3
|
-
"version": "0.33.0-alpha.
|
|
3
|
+
"version": "0.33.0-alpha.5",
|
|
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/
|
|
25
|
-
"@messenger-agent/
|
|
26
|
-
"@messenger-agent/
|
|
27
|
-
"@messenger-agent/shared": "0.33.0-alpha.
|
|
24
|
+
"@messenger-agent/codex-agent": "0.33.0-alpha.5",
|
|
25
|
+
"@messenger-agent/messenger-agent": "0.33.0-alpha.5",
|
|
26
|
+
"@messenger-agent/claude-agent": "0.33.0-alpha.5",
|
|
27
|
+
"@messenger-agent/shared": "0.33.0-alpha.5"
|
|
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",
|