@agentrix/cli 0.3.2

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/lib.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";var _package=require("./logger-CqEsONey.cjs");require("winston"),require("chalk"),require("node:os"),require("node:crypto"),require("node:fs"),require("node:fs/promises"),require("node:path"),require("@agentrix/shared"),require("path"),require("url"),require("zod"),require("@xmz-ai/sandbox-runtime"),require("os"),require("@xmz-ai/sandbox-runtime/dist/utils/platform.js"),exports.Machine=_package.Machine,exports.logger=_package.logger,exports.machine=_package.machine;
package/dist/lib.d.cts ADDED
@@ -0,0 +1,137 @@
1
+ import winston from 'winston';
2
+ import { FileHandle } from 'node:fs/promises';
3
+ import { AgentContext, CreateTaskEventData, ResumeTaskEventData, DeployAgentEventData } from '@agentrix/shared';
4
+ import { z } from 'zod';
5
+
6
+ /**
7
+ * Winston-based logging system for agentrix CLI
8
+ *
9
+ * Design decisions:
10
+ * - Use Winston for robust logging with file rotation
11
+ * - Three logging modes:
12
+ * 1. console-only: CLI commands (no file logging)
13
+ * 2. daemon: Single daemon.log with rotation (10MB x 10 files)
14
+ * 3. worker: Per-task logs task-{taskId}.log with rotation (5MB x 3 files)
15
+ * - File output location: ~/.agentrix/logs/
16
+ */
17
+
18
+ declare let logger: winston.Logger;
19
+
20
+ declare const SandboxSettingsSchema: z.ZodObject<{
21
+ enabled: z.ZodDefault<z.ZodBoolean>;
22
+ network: z.ZodObject<{
23
+ allowedDomains: z.ZodUnion<readonly [z.ZodLiteral<"*">, z.ZodArray<z.ZodString>]>;
24
+ deniedDomains: z.ZodUnion<readonly [z.ZodLiteral<"*">, z.ZodArray<z.ZodString>]>;
25
+ allowUnixSockets: z.ZodOptional<z.ZodArray<z.ZodString>>;
26
+ allowAllUnixSockets: z.ZodOptional<z.ZodBoolean>;
27
+ allowLocalBinding: z.ZodOptional<z.ZodBoolean>;
28
+ httpProxyPort: z.ZodOptional<z.ZodNumber>;
29
+ socksProxyPort: z.ZodOptional<z.ZodNumber>;
30
+ noProxyAddresses: z.ZodOptional<z.ZodArray<z.ZodString>>;
31
+ allowNetworkMetadata: z.ZodOptional<z.ZodBoolean>;
32
+ }, z.core.$strip>;
33
+ filesystem: z.ZodOptional<z.ZodObject<{
34
+ denyRead: z.ZodOptional<z.ZodArray<z.ZodString>>;
35
+ allowRead: z.ZodOptional<z.ZodArray<z.ZodString>>;
36
+ autoAllowSystemPaths: z.ZodOptional<z.ZodBoolean>;
37
+ allowWrite: z.ZodOptional<z.ZodArray<z.ZodString>>;
38
+ denyWrite: z.ZodOptional<z.ZodArray<z.ZodString>>;
39
+ }, z.core.$strip>>;
40
+ env: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNullable<z.ZodString>>>>;
41
+ }, z.core.$strip>;
42
+ type SandboxSettings = z.infer<typeof SandboxSettingsSchema>;
43
+
44
+ interface DaemonState {
45
+ pid: number;
46
+ port: number;
47
+ startTime: string;
48
+ cliVersion: string;
49
+ logPath: string;
50
+ }
51
+ type Credentials = {
52
+ secret?: string;
53
+ token: string;
54
+ machineId: string;
55
+ };
56
+ interface WorkspaceState {
57
+ initialized: boolean;
58
+ initializedAt?: string;
59
+ cwd: string;
60
+ initialCommitHash?: string;
61
+ repositorySourceType?: 'temporary' | 'directory' | 'git-server';
62
+ userCwd?: string;
63
+ forceUserCwd?: boolean;
64
+ gitUrl?: string;
65
+ baseBranch?: string;
66
+ taskRepositoryId?: string;
67
+ }
68
+ type MachineStatePaths = {
69
+ rootDir: string;
70
+ logsDir: string;
71
+ settingsFile: string;
72
+ credentialsFile: string;
73
+ daemonStateFile: string;
74
+ daemonLockFile: string;
75
+ };
76
+ declare class Machine implements AgentContext {
77
+ readonly serverUrl: string;
78
+ readonly webappUrl: string;
79
+ readonly isDaemonProcess: boolean;
80
+ readonly agentrixHomeDir: string;
81
+ readonly agentrixWorkspaceHomeDir: string;
82
+ readonly agentrixAgentsHomeDir: string;
83
+ readonly currentCliVersion: string;
84
+ readonly disableCaffeinate: boolean;
85
+ readonly statePaths: MachineStatePaths;
86
+ secretKey?: Uint8Array<ArrayBufferLike>;
87
+ private sandboxSettings;
88
+ constructor();
89
+ generateMachineId(): string;
90
+ metadata(): any;
91
+ getStatePaths(): MachineStatePaths;
92
+ readCredentials(): Promise<Credentials | null>;
93
+ writeCredentials(credentials: Credentials): Promise<void>;
94
+ clearCredentials(): Promise<void>;
95
+ readDaemonState(): Promise<DaemonState | null>;
96
+ writeDaemonState(state: DaemonState): void;
97
+ clearDaemonState(): Promise<void>;
98
+ acquireDaemonLock(maxAttempts?: number, delayIncrementMs?: number): Promise<FileHandle | null>;
99
+ releaseDaemonLock(lockHandle: FileHandle): Promise<void>;
100
+ ensureDir(target: string): string;
101
+ resolveUserWorkSpaceDir(userId: string): string;
102
+ resolveTaskDir(userId: string, taskId: string): string;
103
+ resolveProjectCWD(cwd: string | undefined, userId: string, taskId: string): string;
104
+ resolveProjectDir(userId: string, taskId: string): string;
105
+ resolveDataDir(userId: string, taskId: string): string;
106
+ resolveAttachmentsDir(userId: string, taskId: string): string;
107
+ resolveAgentDir(agentId: string): string;
108
+ getWorkspaceStatePath(userId: string, taskId: string): string;
109
+ getWorkspaceState(userId: string, taskId: string): WorkspaceState | null;
110
+ writeWorkspaceState(userId: string, taskId: string, state: WorkspaceState): Promise<void>;
111
+ getLastSentCommitHashPath(userId: string, taskId: string): string;
112
+ readLastSentCommitHash(userId: string, taskId: string): Promise<string | null>;
113
+ writeLastSentCommitHash(userId: string, taskId: string, hash: string): Promise<void>;
114
+ writeTaskInput(data: CreateTaskEventData | ResumeTaskEventData | DeployAgentEventData): void;
115
+ readTaskInput(userId: string, taskId: string): (CreateTaskEventData | ResumeTaskEventData);
116
+ getTaskCwd(userId: string, taskId: string): string | null;
117
+ resolveWorkspaceFilePath(userId: string, taskId: string, relativePath: string): string;
118
+ getSecretKey(): Promise<Uint8Array<ArrayBufferLike> | undefined>;
119
+ /**
120
+ * Read settings file, returns null if file doesn't exist
121
+ */
122
+ readSettings(): any | null;
123
+ /**
124
+ * Write settings to file, creating parent directories if needed
125
+ */
126
+ writeSettings(settings: any): void;
127
+ /**
128
+ * Read or initialize settings with default value
129
+ * If file doesn't exist, writes defaultSettings and returns it
130
+ */
131
+ readOrInitSettings(defaultSettings: any): any;
132
+ private loadSandboxSettings;
133
+ getSandboxSettings(): SandboxSettings;
134
+ }
135
+ declare const machine: Machine;
136
+
137
+ export { Machine, logger, machine };
package/dist/lib.d.mts ADDED
@@ -0,0 +1,137 @@
1
+ import winston from 'winston';
2
+ import { FileHandle } from 'node:fs/promises';
3
+ import { AgentContext, CreateTaskEventData, ResumeTaskEventData, DeployAgentEventData } from '@agentrix/shared';
4
+ import { z } from 'zod';
5
+
6
+ /**
7
+ * Winston-based logging system for agentrix CLI
8
+ *
9
+ * Design decisions:
10
+ * - Use Winston for robust logging with file rotation
11
+ * - Three logging modes:
12
+ * 1. console-only: CLI commands (no file logging)
13
+ * 2. daemon: Single daemon.log with rotation (10MB x 10 files)
14
+ * 3. worker: Per-task logs task-{taskId}.log with rotation (5MB x 3 files)
15
+ * - File output location: ~/.agentrix/logs/
16
+ */
17
+
18
+ declare let logger: winston.Logger;
19
+
20
+ declare const SandboxSettingsSchema: z.ZodObject<{
21
+ enabled: z.ZodDefault<z.ZodBoolean>;
22
+ network: z.ZodObject<{
23
+ allowedDomains: z.ZodUnion<readonly [z.ZodLiteral<"*">, z.ZodArray<z.ZodString>]>;
24
+ deniedDomains: z.ZodUnion<readonly [z.ZodLiteral<"*">, z.ZodArray<z.ZodString>]>;
25
+ allowUnixSockets: z.ZodOptional<z.ZodArray<z.ZodString>>;
26
+ allowAllUnixSockets: z.ZodOptional<z.ZodBoolean>;
27
+ allowLocalBinding: z.ZodOptional<z.ZodBoolean>;
28
+ httpProxyPort: z.ZodOptional<z.ZodNumber>;
29
+ socksProxyPort: z.ZodOptional<z.ZodNumber>;
30
+ noProxyAddresses: z.ZodOptional<z.ZodArray<z.ZodString>>;
31
+ allowNetworkMetadata: z.ZodOptional<z.ZodBoolean>;
32
+ }, z.core.$strip>;
33
+ filesystem: z.ZodOptional<z.ZodObject<{
34
+ denyRead: z.ZodOptional<z.ZodArray<z.ZodString>>;
35
+ allowRead: z.ZodOptional<z.ZodArray<z.ZodString>>;
36
+ autoAllowSystemPaths: z.ZodOptional<z.ZodBoolean>;
37
+ allowWrite: z.ZodOptional<z.ZodArray<z.ZodString>>;
38
+ denyWrite: z.ZodOptional<z.ZodArray<z.ZodString>>;
39
+ }, z.core.$strip>>;
40
+ env: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNullable<z.ZodString>>>>;
41
+ }, z.core.$strip>;
42
+ type SandboxSettings = z.infer<typeof SandboxSettingsSchema>;
43
+
44
+ interface DaemonState {
45
+ pid: number;
46
+ port: number;
47
+ startTime: string;
48
+ cliVersion: string;
49
+ logPath: string;
50
+ }
51
+ type Credentials = {
52
+ secret?: string;
53
+ token: string;
54
+ machineId: string;
55
+ };
56
+ interface WorkspaceState {
57
+ initialized: boolean;
58
+ initializedAt?: string;
59
+ cwd: string;
60
+ initialCommitHash?: string;
61
+ repositorySourceType?: 'temporary' | 'directory' | 'git-server';
62
+ userCwd?: string;
63
+ forceUserCwd?: boolean;
64
+ gitUrl?: string;
65
+ baseBranch?: string;
66
+ taskRepositoryId?: string;
67
+ }
68
+ type MachineStatePaths = {
69
+ rootDir: string;
70
+ logsDir: string;
71
+ settingsFile: string;
72
+ credentialsFile: string;
73
+ daemonStateFile: string;
74
+ daemonLockFile: string;
75
+ };
76
+ declare class Machine implements AgentContext {
77
+ readonly serverUrl: string;
78
+ readonly webappUrl: string;
79
+ readonly isDaemonProcess: boolean;
80
+ readonly agentrixHomeDir: string;
81
+ readonly agentrixWorkspaceHomeDir: string;
82
+ readonly agentrixAgentsHomeDir: string;
83
+ readonly currentCliVersion: string;
84
+ readonly disableCaffeinate: boolean;
85
+ readonly statePaths: MachineStatePaths;
86
+ secretKey?: Uint8Array<ArrayBufferLike>;
87
+ private sandboxSettings;
88
+ constructor();
89
+ generateMachineId(): string;
90
+ metadata(): any;
91
+ getStatePaths(): MachineStatePaths;
92
+ readCredentials(): Promise<Credentials | null>;
93
+ writeCredentials(credentials: Credentials): Promise<void>;
94
+ clearCredentials(): Promise<void>;
95
+ readDaemonState(): Promise<DaemonState | null>;
96
+ writeDaemonState(state: DaemonState): void;
97
+ clearDaemonState(): Promise<void>;
98
+ acquireDaemonLock(maxAttempts?: number, delayIncrementMs?: number): Promise<FileHandle | null>;
99
+ releaseDaemonLock(lockHandle: FileHandle): Promise<void>;
100
+ ensureDir(target: string): string;
101
+ resolveUserWorkSpaceDir(userId: string): string;
102
+ resolveTaskDir(userId: string, taskId: string): string;
103
+ resolveProjectCWD(cwd: string | undefined, userId: string, taskId: string): string;
104
+ resolveProjectDir(userId: string, taskId: string): string;
105
+ resolveDataDir(userId: string, taskId: string): string;
106
+ resolveAttachmentsDir(userId: string, taskId: string): string;
107
+ resolveAgentDir(agentId: string): string;
108
+ getWorkspaceStatePath(userId: string, taskId: string): string;
109
+ getWorkspaceState(userId: string, taskId: string): WorkspaceState | null;
110
+ writeWorkspaceState(userId: string, taskId: string, state: WorkspaceState): Promise<void>;
111
+ getLastSentCommitHashPath(userId: string, taskId: string): string;
112
+ readLastSentCommitHash(userId: string, taskId: string): Promise<string | null>;
113
+ writeLastSentCommitHash(userId: string, taskId: string, hash: string): Promise<void>;
114
+ writeTaskInput(data: CreateTaskEventData | ResumeTaskEventData | DeployAgentEventData): void;
115
+ readTaskInput(userId: string, taskId: string): (CreateTaskEventData | ResumeTaskEventData);
116
+ getTaskCwd(userId: string, taskId: string): string | null;
117
+ resolveWorkspaceFilePath(userId: string, taskId: string, relativePath: string): string;
118
+ getSecretKey(): Promise<Uint8Array<ArrayBufferLike> | undefined>;
119
+ /**
120
+ * Read settings file, returns null if file doesn't exist
121
+ */
122
+ readSettings(): any | null;
123
+ /**
124
+ * Write settings to file, creating parent directories if needed
125
+ */
126
+ writeSettings(settings: any): void;
127
+ /**
128
+ * Read or initialize settings with default value
129
+ * If file doesn't exist, writes defaultSettings and returns it
130
+ */
131
+ readOrInitSettings(defaultSettings: any): any;
132
+ private loadSandboxSettings;
133
+ getSandboxSettings(): SandboxSettings;
134
+ }
135
+ declare const machine: Machine;
136
+
137
+ export { Machine, logger, machine };
package/dist/lib.mjs ADDED
@@ -0,0 +1 @@
1
+ export{M as Machine,l as logger,m as machine}from"./logger-CEWsupCP.mjs";import"winston";import"chalk";import"node:os";import"node:crypto";import"node:fs";import"node:fs/promises";import"node:path";import"@agentrix/shared";import"path";import"url";import"zod";import"@xmz-ai/sandbox-runtime";import"os";import"@xmz-ai/sandbox-runtime/dist/utils/platform.js";
@@ -0,0 +1 @@
1
+ import e from"winston";import t from"chalk";import s from"node:os";import{randomUUID as r}from"node:crypto";import{existsSync as i,writeFileSync as n,constants as a,readFileSync as o,unlinkSync as l,mkdirSync as c}from"node:fs";import{readFile as d,writeFile as m,unlink as p,open as u}from"node:fs/promises";import{join as h}from"node:path";import{setAgentContext as g,createKeyPair as f}from"@agentrix/shared";import{join as y,dirname as x,resolve as D}from"path";import{fileURLToPath as b}from"url";import{z as k}from"zod";import{NetworkConfigSchema as S,SandboxInstanceConfigSchema as v}from"@xmz-ai/sandbox-runtime";import{homedir as w}from"os";import{getPlatform as _}from"@xmz-ai/sandbox-runtime/dist/utils/platform.js";var E="@agentrix/cli",P="0.3.2",j="Mobile and Web client for Claude Code and Codex",H="agentrix.xmz.ai",O="module",C="https://github.com/xmz-ai/agentrix-cli",I="https://github.com/xmz-ai/agentrix-cli/issues",N="xmz-ai/agentrix-cli",R={agentrix:"./bin/agentrix.mjs"},W="./dist/index.cjs",A="./dist/index.mjs",T="./dist/index.d.cts",F={".":{require:{types:"./dist/index.d.cts",default:"./dist/index.cjs"},import:{types:"./dist/index.d.mts",default:"./dist/index.mjs"}},"./lib":{require:{types:"./dist/lib.d.cts",default:"./dist/lib.cjs"},import:{types:"./dist/lib.d.mts",default:"./dist/lib.mjs"}}},L=["dist","bin","scripts","package.json"],G={"why do we need to build before running tests / dev?":"We need the binary to be built so we run daemon commands which directly run the binary",typecheck:"tsc --noEmit --skipLibCheck 2>&1 | (grep -v 'node_modules/effect' | grep -v 'Symbol.dispose' || true)",build:"shx rm -rf dist && npx tsc --noEmit --skipLibCheck 2>&1 | (grep -v 'node_modules/effect' | grep -v 'Symbol.dispose' || true) && pkgroll && shx mkdir -p dist/sandbox && shx cp src/sandbox/node-proxy-boot.js dist/sandbox/ && shx mkdir -p dist/migrations && shx cp src/worker/history/migrations/*.sql dist/migrations/ && node scripts/minify-dist.mjs && npm rebuild node-datachannel",prod:"node --env-file=.env ./bin/agentrix.mjs",test:"yarn build && tsx --env-file .env.integration-test node_modules/.bin/vitest run",dev:"yarn build && tsx --env-file .env.dev src/index.ts",local:"yarn build && tsx --env-file .env.local src/index.ts","prod-local":"yarn build && tsx --env ./bin/agentrix.mjs",prepublishOnly:"yarn build && yarn test",release:"release-it",postinstall:"npm rebuild node-datachannel && node scripts/ensure-better-sqlite3.cjs",lint:"eslint 'src/**/*.{js,ts}' --fix"},z={minify:!0,sourcemap:!1},U={"@agentrix/shared":"*","@anthropic-ai/claude-agent-sdk":"^0.2.31","@anthropic-ai/sdk":"0.71.2","@modelcontextprotocol/sdk":"^1.15.1","@openai/codex-sdk":"^0.101.0","@stablelib/base64":"^2.0.1","@stablelib/hex":"^2.0.1","@types/better-sqlite3":"^7.6.13","@types/cross-spawn":"^6.0.6","@types/http-proxy":"^1.17.16","@types/ps-list":"^6.2.1","@types/qrcode-terminal":"^0.12.2","@types/react":"^19.1.9","@types/tmp":"^0.2.6","@types/yargs":"^17.0.33","@xmz-ai/sandbox-runtime":"^0.2.5",axios:"^1.10.0","better-sqlite3":"^12.6.2",chalk:"^5.4.1","cross-spawn":"^7.0.6","expo-server-sdk":"^3.15.0",fastify:"^5.5.0","fastify-type-provider-zod":"^6.1.0","http-proxy":"^1.18.1","http-proxy-middleware":"^3.0.5",ink:"^6.1.0","ink-box":"^2.0.0","ink-select-input":"^6.0.0","ink-spinner":"^5.0.0","ink-text-input":"^6.0.0","node-datachannel":"^0.9.1","node-gyp":"^10.3.1",open:"^10.2.0","ps-list":"^8.1.1","qrcode-terminal":"^0.12.0",react:"^19.1.1","simple-git":"^3.30.0","socket.io-client":"^4.8.1",tmp:"^0.2.5",tweetnacl:"^1.0.3",undici:"^7.16.0",winston:"^3.18.3","winston-daily-rotate-file":"^5.0.0",yargs:"^17.7.2",zod:"^4.0.0","zod-to-json-schema":"^3.25.1"},X={"@eslint/compat":"^1","@types/mime-types":"^3.0.1","@types/node":">=20","cross-env":"^10.0.0",dotenv:"^16.6.1",eslint:"^9","eslint-config-prettier":"^10",pkgroll:"^2.14.2","release-it":"^19.0.4",shx:"^0.3.3",terser:"^5.39.0","ts-node":"^10",tsx:"^4.20.3",typescript:"^5",vitest:"^3.2.4"},M={"whatwg-url":"14.2.0","parse-path":"7.0.3","@types/parse-path":"7.0.3"},$={registry:"https://registry.npmjs.org"},J="yarn@1.22.22",q={name:E,version:P,description:j,author:H,type:O,homepage:C,bugs:I,repository:N,bin:R,main:W,module:A,types:T,exports:F,files:L,scripts:G,pkgroll:z,dependencies:U,devDependencies:X,resolutions:M,publishConfig:$,packageManager:J},K=Object.freeze({__proto__:null,author:H,bin:R,bugs:I,default:q,dependencies:U,description:j,devDependencies:X,exports:F,files:L,homepage:C,main:W,module:A,name:E,packageManager:J,pkgroll:z,publishConfig:$,repository:N,resolutions:M,scripts:G,type:O,types:T,version:P});const B=k.object({enabled:k.boolean().default(!0),network:S,filesystem:v.shape.filesystem.optional(),env:v.shape.env.optional()});function V(e,t){const s=w();return{enabled:!1,network:{allowedDomains:"*",deniedDomains:[]},commonWritePaths:[y(s,".codex"),y(s,"claude"),y(s,".claude.json"),y(s,".claude.json.lock")],agentrixHomeDir:t,env:{DEBUG:null,AGENTRIX_SERVER_URL:null,AGENTRIX_WEBAPP_URL:null,AGENTRIX_HOME_DIR:null,AGENTRIX_WORKSPACE_HOME_DIR:null,AGENTRIX_AGENTS_HOME_DIR:null,SRT_DEBUG:null,NODE_OPTIONS:`--require ${y(e,"dist","sandbox","node-proxy-boot.js")}`}}}const Y=x(b(import.meta.url));function Q(){return D(Y,"..")}class Z{serverUrl;webappUrl;isDaemonProcess;agentrixHomeDir;agentrixWorkspaceHomeDir;agentrixAgentsHomeDir;currentCliVersion;disableCaffeinate;statePaths;secretKey;sandboxSettings;constructor(){const e=process.argv.slice(2);this.isDaemonProcess="daemon"===e[0],this.serverUrl=process.env.AGENTRIX_SERVER_URL||"https://agentrix.xmz.ai",this.webappUrl=process.env.AGENTRIX_WEBAPP_URL||"https://agentrix.xmz.ai",this.agentrixHomeDir=process.env.AGENTRIX_HOME_DIR?process.env.AGENTRIX_HOME_DIR.replace(/^~/,s.homedir()):h(s.homedir(),".agentrix"),this.agentrixWorkspaceHomeDir=process.env.AGENTRIX_WORKSPACE_HOME_DIR?process.env.AGENTRIX_WORKSPACE_HOME_DIR.replace(/^~/,s.homedir()):h(this.agentrixHomeDir,"workspaces"),this.agentrixAgentsHomeDir=process.env.AGENTRIX_AGENTS_HOME_DIR?process.env.AGENTRIX_AGENTS_HOME_DIR.replace(/^~/,s.homedir()):h(this.agentrixHomeDir,"agents"),this.disableCaffeinate=["true","1","yes"].includes((process.env.AGENTRIX_DISABLE_CAFFEINATE??"").toLowerCase()),this.currentCliVersion=q.version,this.ensureDir(this.agentrixHomeDir),this.ensureDir(this.agentrixWorkspaceHomeDir),this.ensureDir(this.agentrixAgentsHomeDir),this.statePaths={rootDir:this.agentrixHomeDir,logsDir:this.ensureDir(h(this.agentrixHomeDir,"logs")),settingsFile:h(this.agentrixHomeDir,"settings.json"),credentialsFile:h(this.agentrixHomeDir,"credentials.json"),daemonStateFile:h(this.agentrixHomeDir,"daemon.state.json"),daemonLockFile:h(this.agentrixHomeDir,"daemon.state.json.lock")},this.sandboxSettings=this.loadSandboxSettings()}generateMachineId(){return`machine-${r()}`}metadata(){return{host:s.hostname(),platform:s.platform(),cliVersion:this.currentCliVersion,homeDir:s.homedir(),agentrixHomeDir:this.agentrixHomeDir,agentrixWorkspaceHomeDir:this.agentrixWorkspaceHomeDir}}getStatePaths(){return this.statePaths}async readCredentials(){const e=this.getStatePaths();if(!i(e.credentialsFile))return null;try{const t=await d(e.credentialsFile,"utf8"),s=JSON.parse(t);return{secret:s.secret,token:s.token,machineId:s.machineId}}catch{return null}}async writeCredentials(e){const t=this.getStatePaths();await m(t.credentialsFile,JSON.stringify(e,null,2))}async clearCredentials(){const e=this.getStatePaths();i(e.credentialsFile)&&await p(e.credentialsFile)}async readDaemonState(){const e=this.getStatePaths();try{if(!i(e.daemonStateFile))return null;const t=await d(e.daemonStateFile,"utf-8");return JSON.parse(t)}catch(t){return console.error(`[PERSISTENCE] Daemon state file corrupted: ${e.daemonStateFile}`,t),null}}writeDaemonState(e){const t=this.getStatePaths();n(t.daemonStateFile,JSON.stringify(e,null,2),"utf-8")}async clearDaemonState(){const e=this.getStatePaths();if(i(e.daemonStateFile)&&await p(e.daemonStateFile),i(e.daemonLockFile))try{await p(e.daemonLockFile)}catch{}}async acquireDaemonLock(e=5,t=200){const s=this.getStatePaths();for(let r=1;r<=e;r++)try{const e=await u(s.daemonLockFile,a.O_CREAT|a.O_EXCL|a.O_WRONLY);return await e.writeFile(String(process.pid)),e}catch(i){if("EEXIST"===i.code)try{const e=o(s.daemonLockFile,"utf-8").trim();if(e&&!Number.isNaN(Number(e)))try{process.kill(Number(e),0)}catch{l(s.daemonLockFile);continue}}catch{}if(r===e)return null;const n=r*t;await new Promise(e=>setTimeout(e,n))}return null}async releaseDaemonLock(e){const t=this.getStatePaths();try{await e.close()}catch{}try{i(t.daemonLockFile)&&l(t.daemonLockFile)}catch{}}ensureDir(e){return i(e)||c(e,{recursive:!0}),e}resolveUserWorkSpaceDir(e){const t=h(this.agentrixWorkspaceHomeDir,"users",e);return this.ensureDir(t)}resolveTaskDir(e,t){const s=h(this.agentrixWorkspaceHomeDir,"users",e,t);return this.ensureDir(s)}resolveProjectCWD(e,t,r){if(e)return this.ensureDir(e.replace(/^~/,s.homedir()));const i=h(this.agentrixWorkspaceHomeDir,"users",t,r,"project");return this.ensureDir(i)}resolveProjectDir(e,t){const s=h(this.agentrixWorkspaceHomeDir,"users",e,t,"project");return this.ensureDir(s)}resolveDataDir(e,t){const s=h(this.agentrixWorkspaceHomeDir,"users",e,t,"data");return this.ensureDir(s)}resolveAttachmentsDir(e,t){const s=h(this.resolveDataDir(e,t),"attachments");return this.ensureDir(s)}resolveAgentDir(e){return h(this.agentrixAgentsHomeDir,e)}getWorkspaceStatePath(e,t){return h(this.resolveDataDir(e,t),"workspace.json")}getWorkspaceState(e,t){const s=this.getWorkspaceStatePath(e,t);if(i(s))try{const e=o(s,"utf-8");return JSON.parse(e)}catch{return null}const r=this.resolveDataDir(e,t),a=h(r,"cwd.txt");if(!i(a))return null;try{const e=o(a,"utf-8").trim();if(!e)return null;const t={initialized:!0,initializedAt:(new Date).toISOString(),cwd:e};try{n(s,JSON.stringify(t,null,2));try{l(a)}catch{}}catch{}return t}catch{return null}}async writeWorkspaceState(e,t,s){const r=this.getWorkspaceStatePath(e,t);await m(r,JSON.stringify(s,null,2))}getLastSentCommitHashPath(e,t){return h(this.resolveDataDir(e,t),"last-sent-commit-hash.txt")}async readLastSentCommitHash(e,t){const s=this.getLastSentCommitHashPath(e,t);if(!i(s))return null;try{return(await d(s,"utf-8")).trim()}catch{return null}}async writeLastSentCommitHash(e,t,s){const r=this.getLastSentCommitHashPath(e,t);await m(r,s)}writeTaskInput(e){const t=this.resolveDataDir(e.userId,e.taskId),s=h(t,"input.json");n(s,JSON.stringify(e,null,2))}readTaskInput(e,t){const s=this.resolveDataDir(e,t),r=h(s,"input.json");if(!i(r))throw new Error(`Task input file does not exist: ${r}`);const n=o(r,"utf-8");return JSON.parse(n)}getTaskCwd(e,t){const s=this.getWorkspaceState(e,t);return s?.cwd?s.cwd:null}resolveWorkspaceFilePath(e,t,s){const r=s.replace(/^\/+/,"");if("project"===r||r.startsWith("project/")){const s=this.getTaskCwd(e,t),i=this.resolveProjectCWD(s||void 0,e,t),n="project"===r?"":r.slice(8);return n?h(i,n):i}if("data"===r||r.startsWith("data/")){const s=this.resolveDataDir(e,t),i="data"===r?"":r.slice(5);return i?h(s,i):s}const i=this.resolveTaskDir(e,t);return h(i,r)}async getSecretKey(){if(this.secretKey)return this.secretKey;const e=await this.readCredentials();if(e&&e.secret){const t=await f(e.secret);this.secretKey=t.secretKey}return this.secretKey}readSettings(){const{settingsFile:e}=this.statePaths;if(!i(e))return null;try{const t=o(e,"utf-8");return JSON.parse(t)}catch(e){throw new Error(`Failed to parse settings file: ${e}`)}}writeSettings(e){const{settingsFile:t}=this.statePaths;this.ensureDir(x(t)),n(t,JSON.stringify(e,null,2),"utf-8")}readOrInitSettings(e){let t=this.readSettings();return t||(this.writeSettings(e),t=e),t}loadSandboxSettings(){const e=function(e,t,s){return"macos"===e?function(e,t){w();const s=V(e,t);return{enabled:s.enabled,network:s.network,filesystem:{denyRead:[],allowWrite:s.commonWritePaths,denyWrite:[]},env:s.env}}(t,s):function(e,t){const s=V(e,t);return{enabled:s.enabled,network:s.network,filesystem:{allowRead:[t],autoAllowSystemPaths:!0,allowWrite:s.commonWritePaths,denyWrite:[]},env:s.env}}(t,s)}(_(),Q(),this.agentrixHomeDir),t={sandbox:e},s=this.readOrInitSettings(t);return s.sandbox?B.parse(s.sandbox):e}getSandboxSettings(){return this.sandboxSettings}}const ee=new Z;g(ee);var te=Object.freeze({__proto__:null,Machine:Z,machine:ee,projectPath:Q});const se=e.format.printf(({level:e,message:s,timestamp:r,...i})=>{const n=new Date(r).toLocaleTimeString("en-US",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit",fractionalSecondDigits:3});let a=e;switch(e){case"error":a=t.red(e.toUpperCase());break;case"warn":a=t.yellow(e.toUpperCase());break;case"info":a=t.blue(e.toUpperCase());break;case"debug":a=t.gray(e.toUpperCase())}return`[${n}] ${a}: ${s}${Object.keys(i).length>0?" "+JSON.stringify(i):""}`}),re=e.format.printf(({level:e,message:t,timestamp:s,...r})=>{const i=Object.keys(r).length>0?" "+JSON.stringify(r):"";return`[${s}] ${e.toUpperCase()}: ${t}${i}`});function ie(t){const s=ee.getStatePaths().logsDir,r=process.env.DEBUG?"debug":"info";if("console-only"===t.type)return e.createLogger({level:r,format:e.format.combine(e.format.timestamp(),se),transports:[new e.transports.Console]});const i="daemon"===t.type?"daemon.log":`task-${t.taskId}.log`,n="daemon"===t.type?3:1,a=[new e.transports.File({filename:i,dirname:s,zippedArchive:!0,maxsize:104857600,maxFiles:n,tailable:!0,format:e.format.combine(e.format.timestamp(),re)})];return process.env.DEBUG&&a.push(new e.transports.Console({format:e.format.combine(e.format.timestamp(),se)})),e.createLogger({level:r,transports:a})}let ne=ie({type:"console-only"});function ae(e){const t=ee.getStatePaths().logsDir;if("console-only"===e.type)return"";const s="daemon"===e.type?"daemon.log":`task-${e.taskId}.log`;return h(t,s)}var oe=Object.freeze({__proto__:null,createLogger:ie,getLogPath:ae,logger:ne});export{Z as M,K as _,q as a,oe as b,ie as c,te as d,ae as g,ne as l,ee as m,Q as p};
@@ -0,0 +1 @@
1
+ "use strict";var winston=require("winston"),chalk=require("chalk"),os$1=require("node:os"),node_crypto=require("node:crypto"),fs=require("node:fs"),promises=require("node:fs/promises"),path$1=require("node:path"),shared=require("@agentrix/shared"),path=require("path"),url=require("url"),zod=require("zod"),sandboxRuntime=require("@xmz-ai/sandbox-runtime"),os=require("os"),platform_js=require("@xmz-ai/sandbox-runtime/dist/utils/platform.js"),_documentCurrentScript="undefined"!=typeof document?document.currentScript:null,name="@agentrix/cli",version="0.3.2",description="Mobile and Web client for Claude Code and Codex",author="agentrix.xmz.ai",type="module",homepage="https://github.com/xmz-ai/agentrix-cli",bugs="https://github.com/xmz-ai/agentrix-cli/issues",repository="xmz-ai/agentrix-cli",bin={agentrix:"./bin/agentrix.mjs"},main="./dist/index.cjs",module$1="./dist/index.mjs",types="./dist/index.d.cts",exports$1={".":{require:{types:"./dist/index.d.cts",default:"./dist/index.cjs"},import:{types:"./dist/index.d.mts",default:"./dist/index.mjs"}},"./lib":{require:{types:"./dist/lib.d.cts",default:"./dist/lib.cjs"},import:{types:"./dist/lib.d.mts",default:"./dist/lib.mjs"}}},files=["dist","bin","scripts","package.json"],scripts={"why do we need to build before running tests / dev?":"We need the binary to be built so we run daemon commands which directly run the binary",typecheck:"tsc --noEmit --skipLibCheck 2>&1 | (grep -v 'node_modules/effect' | grep -v 'Symbol.dispose' || true)",build:"shx rm -rf dist && npx tsc --noEmit --skipLibCheck 2>&1 | (grep -v 'node_modules/effect' | grep -v 'Symbol.dispose' || true) && pkgroll && shx mkdir -p dist/sandbox && shx cp src/sandbox/node-proxy-boot.js dist/sandbox/ && shx mkdir -p dist/migrations && shx cp src/worker/history/migrations/*.sql dist/migrations/ && node scripts/minify-dist.mjs && npm rebuild node-datachannel",prod:"node --env-file=.env ./bin/agentrix.mjs",test:"yarn build && tsx --env-file .env.integration-test node_modules/.bin/vitest run",dev:"yarn build && tsx --env-file .env.dev src/index.ts",local:"yarn build && tsx --env-file .env.local src/index.ts","prod-local":"yarn build && tsx --env ./bin/agentrix.mjs",prepublishOnly:"yarn build && yarn test",release:"release-it",postinstall:"npm rebuild node-datachannel && node scripts/ensure-better-sqlite3.cjs",lint:"eslint 'src/**/*.{js,ts}' --fix"},pkgroll={minify:!0,sourcemap:!1},dependencies={"@agentrix/shared":"*","@anthropic-ai/claude-agent-sdk":"^0.2.31","@anthropic-ai/sdk":"0.71.2","@modelcontextprotocol/sdk":"^1.15.1","@openai/codex-sdk":"^0.101.0","@stablelib/base64":"^2.0.1","@stablelib/hex":"^2.0.1","@types/better-sqlite3":"^7.6.13","@types/cross-spawn":"^6.0.6","@types/http-proxy":"^1.17.16","@types/ps-list":"^6.2.1","@types/qrcode-terminal":"^0.12.2","@types/react":"^19.1.9","@types/tmp":"^0.2.6","@types/yargs":"^17.0.33","@xmz-ai/sandbox-runtime":"^0.2.5",axios:"^1.10.0","better-sqlite3":"^12.6.2",chalk:"^5.4.1","cross-spawn":"^7.0.6","expo-server-sdk":"^3.15.0",fastify:"^5.5.0","fastify-type-provider-zod":"^6.1.0","http-proxy":"^1.18.1","http-proxy-middleware":"^3.0.5",ink:"^6.1.0","ink-box":"^2.0.0","ink-select-input":"^6.0.0","ink-spinner":"^5.0.0","ink-text-input":"^6.0.0","node-datachannel":"^0.9.1","node-gyp":"^10.3.1",open:"^10.2.0","ps-list":"^8.1.1","qrcode-terminal":"^0.12.0",react:"^19.1.1","simple-git":"^3.30.0","socket.io-client":"^4.8.1",tmp:"^0.2.5",tweetnacl:"^1.0.3",undici:"^7.16.0",winston:"^3.18.3","winston-daily-rotate-file":"^5.0.0",yargs:"^17.7.2",zod:"^4.0.0","zod-to-json-schema":"^3.25.1"},devDependencies={"@eslint/compat":"^1","@types/mime-types":"^3.0.1","@types/node":">=20","cross-env":"^10.0.0",dotenv:"^16.6.1",eslint:"^9","eslint-config-prettier":"^10",pkgroll:"^2.14.2","release-it":"^19.0.4",shx:"^0.3.3",terser:"^5.39.0","ts-node":"^10",tsx:"^4.20.3",typescript:"^5",vitest:"^3.2.4"},resolutions={"whatwg-url":"14.2.0","parse-path":"7.0.3","@types/parse-path":"7.0.3"},publishConfig={registry:"https://registry.npmjs.org"},packageManager="yarn@1.22.22",packageJson={name:name,version:version,description:description,author:author,type:type,homepage:homepage,bugs:bugs,repository:repository,bin:bin,main:main,module:module$1,types:types,exports:exports$1,files:files,scripts:scripts,pkgroll:pkgroll,dependencies:dependencies,devDependencies:devDependencies,resolutions:resolutions,publishConfig:publishConfig,packageManager:packageManager},_package=Object.freeze({__proto__:null,author:author,bin:bin,bugs:bugs,default:packageJson,dependencies:dependencies,description:description,devDependencies:devDependencies,exports:exports$1,files:files,homepage:homepage,main:main,module:module$1,name:name,packageManager:packageManager,pkgroll:pkgroll,publishConfig:publishConfig,repository:repository,resolutions:resolutions,scripts:scripts,type:type,types:types,version:version});const SandboxSettingsSchema=zod.z.object({enabled:zod.z.boolean().default(!0),network:sandboxRuntime.NetworkConfigSchema,filesystem:sandboxRuntime.SandboxInstanceConfigSchema.shape.filesystem.optional(),env:sandboxRuntime.SandboxInstanceConfigSchema.shape.env.optional()});function getCommonConfig(e,t){const s=os.homedir();return{enabled:!1,network:{allowedDomains:"*",deniedDomains:[]},commonWritePaths:[path.join(s,".codex"),path.join(s,"claude"),path.join(s,".claude.json"),path.join(s,".claude.json.lock")],agentrixHomeDir:t,env:{DEBUG:null,AGENTRIX_SERVER_URL:null,AGENTRIX_WEBAPP_URL:null,AGENTRIX_HOME_DIR:null,AGENTRIX_WORKSPACE_HOME_DIR:null,AGENTRIX_AGENTS_HOME_DIR:null,SRT_DEBUG:null,NODE_OPTIONS:`--require ${path.join(e,"dist","sandbox","node-proxy-boot.js")}`}}}function getDefaultMacOSSettings(e,t){os.homedir();const s=getCommonConfig(e,t);return{enabled:s.enabled,network:s.network,filesystem:{denyRead:[],allowWrite:s.commonWritePaths,denyWrite:[]},env:s.env}}function getDefaultLinuxSettings(e,t){const s=getCommonConfig(e,t);return{enabled:s.enabled,network:s.network,filesystem:{allowRead:[t],autoAllowSystemPaths:!0,allowWrite:s.commonWritePaths,denyWrite:[]},env:s.env}}function getDefaultSandboxSettings(e,t,s){return"macos"===e?getDefaultMacOSSettings(t,s):getDefaultLinuxSettings(t,s)}const __dirname$1=path.dirname(url.fileURLToPath("undefined"==typeof document?require("url").pathToFileURL(__filename).href:_documentCurrentScript&&"SCRIPT"===_documentCurrentScript.tagName.toUpperCase()&&_documentCurrentScript.src||new URL("logger-CqEsONey.cjs",document.baseURI).href));function projectPath(){return path.resolve(__dirname$1,"..")}class Machine{serverUrl;webappUrl;isDaemonProcess;agentrixHomeDir;agentrixWorkspaceHomeDir;agentrixAgentsHomeDir;currentCliVersion;disableCaffeinate;statePaths;secretKey;sandboxSettings;constructor(){const e=process.argv.slice(2);this.isDaemonProcess="daemon"===e[0],this.serverUrl=process.env.AGENTRIX_SERVER_URL||"https://agentrix.xmz.ai",this.webappUrl=process.env.AGENTRIX_WEBAPP_URL||"https://agentrix.xmz.ai",this.agentrixHomeDir=process.env.AGENTRIX_HOME_DIR?process.env.AGENTRIX_HOME_DIR.replace(/^~/,os$1.homedir()):path$1.join(os$1.homedir(),".agentrix"),this.agentrixWorkspaceHomeDir=process.env.AGENTRIX_WORKSPACE_HOME_DIR?process.env.AGENTRIX_WORKSPACE_HOME_DIR.replace(/^~/,os$1.homedir()):path$1.join(this.agentrixHomeDir,"workspaces"),this.agentrixAgentsHomeDir=process.env.AGENTRIX_AGENTS_HOME_DIR?process.env.AGENTRIX_AGENTS_HOME_DIR.replace(/^~/,os$1.homedir()):path$1.join(this.agentrixHomeDir,"agents"),this.disableCaffeinate=["true","1","yes"].includes((process.env.AGENTRIX_DISABLE_CAFFEINATE??"").toLowerCase()),this.currentCliVersion=packageJson.version,this.ensureDir(this.agentrixHomeDir),this.ensureDir(this.agentrixWorkspaceHomeDir),this.ensureDir(this.agentrixAgentsHomeDir),this.statePaths={rootDir:this.agentrixHomeDir,logsDir:this.ensureDir(path$1.join(this.agentrixHomeDir,"logs")),settingsFile:path$1.join(this.agentrixHomeDir,"settings.json"),credentialsFile:path$1.join(this.agentrixHomeDir,"credentials.json"),daemonStateFile:path$1.join(this.agentrixHomeDir,"daemon.state.json"),daemonLockFile:path$1.join(this.agentrixHomeDir,"daemon.state.json.lock")},this.sandboxSettings=this.loadSandboxSettings()}generateMachineId(){return`machine-${node_crypto.randomUUID()}`}metadata(){return{host:os$1.hostname(),platform:os$1.platform(),cliVersion:this.currentCliVersion,homeDir:os$1.homedir(),agentrixHomeDir:this.agentrixHomeDir,agentrixWorkspaceHomeDir:this.agentrixWorkspaceHomeDir}}getStatePaths(){return this.statePaths}async readCredentials(){const e=this.getStatePaths();if(!fs.existsSync(e.credentialsFile))return null;try{const t=await promises.readFile(e.credentialsFile,"utf8"),s=JSON.parse(t);return{secret:s.secret,token:s.token,machineId:s.machineId}}catch{return null}}async writeCredentials(e){const t=this.getStatePaths();await promises.writeFile(t.credentialsFile,JSON.stringify(e,null,2))}async clearCredentials(){const e=this.getStatePaths();fs.existsSync(e.credentialsFile)&&await promises.unlink(e.credentialsFile)}async readDaemonState(){const e=this.getStatePaths();try{if(!fs.existsSync(e.daemonStateFile))return null;const t=await promises.readFile(e.daemonStateFile,"utf-8");return JSON.parse(t)}catch(t){return console.error(`[PERSISTENCE] Daemon state file corrupted: ${e.daemonStateFile}`,t),null}}writeDaemonState(e){const t=this.getStatePaths();fs.writeFileSync(t.daemonStateFile,JSON.stringify(e,null,2),"utf-8")}async clearDaemonState(){const e=this.getStatePaths();if(fs.existsSync(e.daemonStateFile)&&await promises.unlink(e.daemonStateFile),fs.existsSync(e.daemonLockFile))try{await promises.unlink(e.daemonLockFile)}catch{}}async acquireDaemonLock(e=5,t=200){const s=this.getStatePaths();for(let n=1;n<=e;n++)try{const e=await promises.open(s.daemonLockFile,fs.constants.O_CREAT|fs.constants.O_EXCL|fs.constants.O_WRONLY);return await e.writeFile(String(process.pid)),e}catch(i){if("EEXIST"===i.code)try{const e=fs.readFileSync(s.daemonLockFile,"utf-8").trim();if(e&&!Number.isNaN(Number(e)))try{process.kill(Number(e),0)}catch{fs.unlinkSync(s.daemonLockFile);continue}}catch{}if(n===e)return null;const r=n*t;await new Promise(e=>setTimeout(e,r))}return null}async releaseDaemonLock(e){const t=this.getStatePaths();try{await e.close()}catch{}try{fs.existsSync(t.daemonLockFile)&&fs.unlinkSync(t.daemonLockFile)}catch{}}ensureDir(e){return fs.existsSync(e)||fs.mkdirSync(e,{recursive:!0}),e}resolveUserWorkSpaceDir(e){const t=path$1.join(this.agentrixWorkspaceHomeDir,"users",e);return this.ensureDir(t)}resolveTaskDir(e,t){const s=path$1.join(this.agentrixWorkspaceHomeDir,"users",e,t);return this.ensureDir(s)}resolveProjectCWD(e,t,s){if(e)return this.ensureDir(e.replace(/^~/,os$1.homedir()));const n=path$1.join(this.agentrixWorkspaceHomeDir,"users",t,s,"project");return this.ensureDir(n)}resolveProjectDir(e,t){const s=path$1.join(this.agentrixWorkspaceHomeDir,"users",e,t,"project");return this.ensureDir(s)}resolveDataDir(e,t){const s=path$1.join(this.agentrixWorkspaceHomeDir,"users",e,t,"data");return this.ensureDir(s)}resolveAttachmentsDir(e,t){const s=path$1.join(this.resolveDataDir(e,t),"attachments");return this.ensureDir(s)}resolveAgentDir(e){return path$1.join(this.agentrixAgentsHomeDir,e)}getWorkspaceStatePath(e,t){return path$1.join(this.resolveDataDir(e,t),"workspace.json")}getWorkspaceState(e,t){const s=this.getWorkspaceStatePath(e,t);if(fs.existsSync(s))try{const e=fs.readFileSync(s,"utf-8");return JSON.parse(e)}catch{return null}const n=this.resolveDataDir(e,t),i=path$1.join(n,"cwd.txt");if(!fs.existsSync(i))return null;try{const e=fs.readFileSync(i,"utf-8").trim();if(!e)return null;const t={initialized:!0,initializedAt:(new Date).toISOString(),cwd:e};try{fs.writeFileSync(s,JSON.stringify(t,null,2));try{fs.unlinkSync(i)}catch{}}catch{}return t}catch{return null}}async writeWorkspaceState(e,t,s){const n=this.getWorkspaceStatePath(e,t);await promises.writeFile(n,JSON.stringify(s,null,2))}getLastSentCommitHashPath(e,t){return path$1.join(this.resolveDataDir(e,t),"last-sent-commit-hash.txt")}async readLastSentCommitHash(e,t){const s=this.getLastSentCommitHashPath(e,t);if(!fs.existsSync(s))return null;try{return(await promises.readFile(s,"utf-8")).trim()}catch{return null}}async writeLastSentCommitHash(e,t,s){const n=this.getLastSentCommitHashPath(e,t);await promises.writeFile(n,s)}writeTaskInput(e){const t=this.resolveDataDir(e.userId,e.taskId),s=path$1.join(t,"input.json");fs.writeFileSync(s,JSON.stringify(e,null,2))}readTaskInput(e,t){const s=this.resolveDataDir(e,t),n=path$1.join(s,"input.json");if(!fs.existsSync(n))throw new Error(`Task input file does not exist: ${n}`);const i=fs.readFileSync(n,"utf-8");return JSON.parse(i)}getTaskCwd(e,t){const s=this.getWorkspaceState(e,t);return s?.cwd?s.cwd:null}resolveWorkspaceFilePath(e,t,s){const n=s.replace(/^\/+/,"");if("project"===n||n.startsWith("project/")){const s=this.getTaskCwd(e,t),i=this.resolveProjectCWD(s||void 0,e,t),r="project"===n?"":n.slice(8);return r?path$1.join(i,r):i}if("data"===n||n.startsWith("data/")){const s=this.resolveDataDir(e,t),i="data"===n?"":n.slice(5);return i?path$1.join(s,i):s}const i=this.resolveTaskDir(e,t);return path$1.join(i,n)}async getSecretKey(){if(this.secretKey)return this.secretKey;const e=await this.readCredentials();if(e&&e.secret){const t=await shared.createKeyPair(e.secret);this.secretKey=t.secretKey}return this.secretKey}readSettings(){const{settingsFile:e}=this.statePaths;if(!fs.existsSync(e))return null;try{const t=fs.readFileSync(e,"utf-8");return JSON.parse(t)}catch(e){throw new Error(`Failed to parse settings file: ${e}`)}}writeSettings(e){const{settingsFile:t}=this.statePaths;this.ensureDir(path.dirname(t)),fs.writeFileSync(t,JSON.stringify(e,null,2),"utf-8")}readOrInitSettings(e){let t=this.readSettings();return t||(this.writeSettings(e),t=e),t}loadSandboxSettings(){const e=getDefaultSandboxSettings(platform_js.getPlatform(),projectPath(),this.agentrixHomeDir),t={sandbox:e},s=this.readOrInitSettings(t);return s.sandbox?SandboxSettingsSchema.parse(s.sandbox):e}getSandboxSettings(){return this.sandboxSettings}}const machine=new Machine;shared.setAgentContext(machine);var machine$1=Object.freeze({__proto__:null,Machine:Machine,machine:machine,projectPath:projectPath});const consoleFormat=winston.format.printf(({level:e,message:t,timestamp:s,...n})=>{const i=new Date(s).toLocaleTimeString("en-US",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit",fractionalSecondDigits:3});let r=e;switch(e){case"error":r=chalk.red(e.toUpperCase());break;case"warn":r=chalk.yellow(e.toUpperCase());break;case"info":r=chalk.blue(e.toUpperCase());break;case"debug":r=chalk.gray(e.toUpperCase())}return`[${i}] ${r}: ${t}${Object.keys(n).length>0?" "+JSON.stringify(n):""}`}),fileFormat=winston.format.printf(({level:e,message:t,timestamp:s,...n})=>{const i=Object.keys(n).length>0?" "+JSON.stringify(n):"";return`[${s}] ${e.toUpperCase()}: ${t}${i}`});function createLogger(e){const t=machine.getStatePaths().logsDir,s=process.env.DEBUG?"debug":"info";if("console-only"===e.type)return winston.createLogger({level:s,format:winston.format.combine(winston.format.timestamp(),consoleFormat),transports:[new winston.transports.Console]});const n="daemon"===e.type?"daemon.log":`task-${e.taskId}.log`,i="daemon"===e.type?3:1,r=[new winston.transports.File({filename:n,dirname:t,zippedArchive:!0,maxsize:104857600,maxFiles:i,tailable:!0,format:winston.format.combine(winston.format.timestamp(),fileFormat)})];return process.env.DEBUG&&r.push(new winston.transports.Console({format:winston.format.combine(winston.format.timestamp(),consoleFormat)})),winston.createLogger({level:s,transports:r})}let logger=createLogger({type:"console-only"});function getLogPath(e){const t=machine.getStatePaths().logsDir;if("console-only"===e.type)return"";const s="daemon"===e.type?"daemon.log":`task-${e.taskId}.log`;return path$1.join(t,s)}var logger$1=Object.freeze({__proto__:null,createLogger:createLogger,getLogPath:getLogPath,logger:logger});exports.Machine=Machine,exports._package=_package,exports.createLogger=createLogger,exports.getLogPath=getLogPath,exports.logger=logger,exports.logger$1=logger$1,exports.machine=machine,exports.machine$1=machine$1,exports.packageJson=packageJson,exports.projectPath=projectPath;
@@ -0,0 +1,34 @@
1
+ CREATE TABLE IF NOT EXISTS task_message (
2
+ local_sequence INTEGER PRIMARY KEY AUTOINCREMENT,
3
+ event_id TEXT UNIQUE NOT NULL,
4
+ task_id TEXT,
5
+ sender_type TEXT,
6
+ sender_id TEXT,
7
+ sender_name TEXT,
8
+ message TEXT NOT NULL,
9
+ created_at TEXT NOT NULL
10
+ );
11
+
12
+ CREATE INDEX IF NOT EXISTS idx_task_message_sequence
13
+ ON task_message(local_sequence);
14
+
15
+ CREATE TABLE IF NOT EXISTS task_event (
16
+ event_id TEXT PRIMARY KEY,
17
+ task_id TEXT NOT NULL,
18
+ chat_id TEXT NOT NULL,
19
+ sequence INTEGER,
20
+ event_type TEXT NOT NULL,
21
+ event_data TEXT NOT NULL,
22
+ created_at TEXT NOT NULL
23
+ );
24
+
25
+ CREATE INDEX IF NOT EXISTS idx_task_event_task_sequence
26
+ ON task_event(task_id, sequence);
27
+
28
+ CREATE TABLE IF NOT EXISTS task_agent_session (
29
+ agent_id TEXT PRIMARY KEY,
30
+ task_id TEXT,
31
+ session_id TEXT NOT NULL,
32
+ last_sequence INTEGER,
33
+ updated_at TEXT NOT NULL
34
+ );
@@ -0,0 +1 @@
1
+ import"global-agent/bootstrap.js";import{setGlobalDispatcher,ProxyAgent}from"undici";const proxyUrl=process.env.GLOBAL_AGENT_HTTP_PROXY||process.env.HTTP_PROXY;proxyUrl&&setGlobalDispatcher(new ProxyAgent({uri:proxyUrl,connect:{timeout:1e4}}));
package/package.json ADDED
@@ -0,0 +1,136 @@
1
+ {
2
+ "name": "@agentrix/cli",
3
+ "version": "0.3.2",
4
+ "description": "Mobile and Web client for Claude Code and Codex",
5
+ "author": "agentrix.xmz.ai",
6
+ "type": "module",
7
+ "homepage": "https://github.com/xmz-ai/agentrix-cli",
8
+ "bugs": "https://github.com/xmz-ai/agentrix-cli/issues",
9
+ "repository": "xmz-ai/agentrix-cli",
10
+ "bin": {
11
+ "agentrix": "./bin/agentrix.mjs"
12
+ },
13
+ "main": "./dist/index.cjs",
14
+ "module": "./dist/index.mjs",
15
+ "types": "./dist/index.d.cts",
16
+ "exports": {
17
+ ".": {
18
+ "require": {
19
+ "types": "./dist/index.d.cts",
20
+ "default": "./dist/index.cjs"
21
+ },
22
+ "import": {
23
+ "types": "./dist/index.d.mts",
24
+ "default": "./dist/index.mjs"
25
+ }
26
+ },
27
+ "./lib": {
28
+ "require": {
29
+ "types": "./dist/lib.d.cts",
30
+ "default": "./dist/lib.cjs"
31
+ },
32
+ "import": {
33
+ "types": "./dist/lib.d.mts",
34
+ "default": "./dist/lib.mjs"
35
+ }
36
+ }
37
+ },
38
+ "files": [
39
+ "dist",
40
+ "bin",
41
+ "scripts",
42
+ "package.json"
43
+ ],
44
+ "scripts": {
45
+ "why do we need to build before running tests / dev?": "We need the binary to be built so we run daemon commands which directly run the binary",
46
+ "typecheck": "tsc --noEmit --skipLibCheck 2>&1 | (grep -v 'node_modules/effect' | grep -v 'Symbol.dispose' || true)",
47
+ "build": "shx rm -rf dist && npx tsc --noEmit --skipLibCheck 2>&1 | (grep -v 'node_modules/effect' | grep -v 'Symbol.dispose' || true) && pkgroll && shx mkdir -p dist/sandbox && shx cp src/sandbox/node-proxy-boot.js dist/sandbox/ && shx mkdir -p dist/migrations && shx cp src/worker/history/migrations/*.sql dist/migrations/ && node scripts/minify-dist.mjs && npm rebuild node-datachannel",
48
+ "prod": "node --env-file=.env ./bin/agentrix.mjs",
49
+ "test": "yarn build && tsx --env-file .env.integration-test node_modules/.bin/vitest run",
50
+ "dev": "yarn build && tsx --env-file .env.dev src/index.ts",
51
+ "local": "yarn build && tsx --env-file .env.local src/index.ts",
52
+ "prod-local": "yarn build && tsx --env ./bin/agentrix.mjs",
53
+ "prepublishOnly": "yarn build && yarn test",
54
+ "release": "release-it",
55
+ "postinstall": "npm rebuild node-datachannel && node scripts/ensure-better-sqlite3.cjs",
56
+ "lint": "eslint 'src/**/*.{js,ts}' --fix"
57
+ },
58
+ "pkgroll": {
59
+ "minify": true,
60
+ "sourcemap": false
61
+ },
62
+ "dependencies": {
63
+ "@agentrix/shared": "*",
64
+ "@anthropic-ai/claude-agent-sdk": "^0.2.31",
65
+ "@anthropic-ai/sdk": "0.71.2",
66
+ "@modelcontextprotocol/sdk": "^1.15.1",
67
+ "@openai/codex-sdk": "^0.101.0",
68
+ "@stablelib/base64": "^2.0.1",
69
+ "@stablelib/hex": "^2.0.1",
70
+ "@types/better-sqlite3": "^7.6.13",
71
+ "@types/cross-spawn": "^6.0.6",
72
+ "@types/http-proxy": "^1.17.16",
73
+ "@types/ps-list": "^6.2.1",
74
+ "@types/qrcode-terminal": "^0.12.2",
75
+ "@types/react": "^19.1.9",
76
+ "@types/tmp": "^0.2.6",
77
+ "@types/yargs": "^17.0.33",
78
+ "@xmz-ai/sandbox-runtime": "^0.2.5",
79
+ "axios": "^1.10.0",
80
+ "better-sqlite3": "^12.6.2",
81
+ "chalk": "^5.4.1",
82
+ "cross-spawn": "^7.0.6",
83
+ "expo-server-sdk": "^3.15.0",
84
+ "fastify": "^5.5.0",
85
+ "fastify-type-provider-zod": "^6.1.0",
86
+ "http-proxy": "^1.18.1",
87
+ "http-proxy-middleware": "^3.0.5",
88
+ "ink": "^6.1.0",
89
+ "ink-box": "^2.0.0",
90
+ "ink-select-input": "^6.0.0",
91
+ "ink-spinner": "^5.0.0",
92
+ "ink-text-input": "^6.0.0",
93
+ "node-datachannel": "^0.9.1",
94
+ "node-gyp": "^10.3.1",
95
+ "open": "^10.2.0",
96
+ "ps-list": "^8.1.1",
97
+ "qrcode-terminal": "^0.12.0",
98
+ "react": "^19.1.1",
99
+ "simple-git": "^3.30.0",
100
+ "socket.io-client": "^4.8.1",
101
+ "tmp": "^0.2.5",
102
+ "tweetnacl": "^1.0.3",
103
+ "undici": "^7.16.0",
104
+ "winston": "^3.18.3",
105
+ "winston-daily-rotate-file": "^5.0.0",
106
+ "yargs": "^17.7.2",
107
+ "zod": "^4.0.0",
108
+ "zod-to-json-schema": "^3.25.1"
109
+ },
110
+ "devDependencies": {
111
+ "@eslint/compat": "^1",
112
+ "@types/mime-types": "^3.0.1",
113
+ "@types/node": ">=20",
114
+ "cross-env": "^10.0.0",
115
+ "dotenv": "^16.6.1",
116
+ "eslint": "^9",
117
+ "eslint-config-prettier": "^10",
118
+ "pkgroll": "^2.14.2",
119
+ "release-it": "^19.0.4",
120
+ "shx": "^0.3.3",
121
+ "terser": "^5.39.0",
122
+ "ts-node": "^10",
123
+ "tsx": "^4.20.3",
124
+ "typescript": "^5",
125
+ "vitest": "^3.2.4"
126
+ },
127
+ "resolutions": {
128
+ "whatwg-url": "14.2.0",
129
+ "parse-path": "7.0.3",
130
+ "@types/parse-path": "7.0.3"
131
+ },
132
+ "publishConfig": {
133
+ "registry": "https://registry.npmjs.org"
134
+ },
135
+ "packageManager": "yarn@1.22.22"
136
+ }
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { spawnSync } = require('child_process');
6
+
7
+ function resolvePackageDir(packageName, baseDir) {
8
+ try {
9
+ const pkgPath = require.resolve(`${packageName}/package.json`, { paths: [baseDir] });
10
+ return path.dirname(pkgPath);
11
+ } catch (error) {
12
+ return null;
13
+ }
14
+ }
15
+
16
+ function readPackageBin(packageDir, binName) {
17
+ const packageJsonPath = path.join(packageDir, 'package.json');
18
+ if (!fs.existsSync(packageJsonPath)) {
19
+ return null;
20
+ }
21
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
22
+ const bin = packageJson.bin;
23
+ if (!bin) {
24
+ return null;
25
+ }
26
+ if (typeof bin === 'string') {
27
+ return bin;
28
+ }
29
+ return bin[binName] ?? null;
30
+ }
31
+
32
+ function bindingPathExists(packageDir) {
33
+ const candidates = [
34
+ path.join(packageDir, 'build', 'better_sqlite3.node'),
35
+ path.join(packageDir, 'build', 'Release', 'better_sqlite3.node'),
36
+ ];
37
+ return candidates.find((candidate) => fs.existsSync(candidate)) ?? null;
38
+ }
39
+
40
+ function runNodeScript(scriptPath, args, cwd) {
41
+ if (!scriptPath || !fs.existsSync(scriptPath)) {
42
+ return { status: null };
43
+ }
44
+ return spawnSync(process.execPath, [scriptPath, ...args], {
45
+ cwd,
46
+ stdio: 'inherit',
47
+ });
48
+ }
49
+
50
+ function runPrebuildInstall(sqlitePackageDir) {
51
+ const prebuildDir = resolvePackageDir('prebuild-install', sqlitePackageDir);
52
+ if (!prebuildDir) {
53
+ return false;
54
+ }
55
+ const binRel = readPackageBin(prebuildDir, 'prebuild-install');
56
+ if (!binRel) {
57
+ return false;
58
+ }
59
+ const binPath = path.join(prebuildDir, binRel);
60
+ const result = runNodeScript(binPath, [], sqlitePackageDir);
61
+ return result.status === 0;
62
+ }
63
+
64
+ function runNodeGyp(sqlitePackageDir) {
65
+ const nodeGypDir = resolvePackageDir('node-gyp', process.cwd());
66
+ if (!nodeGypDir) {
67
+ return false;
68
+ }
69
+ const nodeGypBin = path.join(nodeGypDir, 'bin', 'node-gyp.js');
70
+ const result = runNodeScript(nodeGypBin, ['rebuild', '--release'], sqlitePackageDir);
71
+ return result.status === 0;
72
+ }
73
+
74
+ function ensureBetterSqlite3() {
75
+ const sqlitePackageDir = resolvePackageDir('better-sqlite3', process.cwd());
76
+ if (!sqlitePackageDir) {
77
+ console.warn('[better-sqlite3] Package not found; skipping native build check.');
78
+ return;
79
+ }
80
+
81
+ if (bindingPathExists(sqlitePackageDir)) {
82
+ return;
83
+ }
84
+
85
+ console.warn('[better-sqlite3] Native bindings missing. Attempting prebuild-install...');
86
+ if (runPrebuildInstall(sqlitePackageDir) && bindingPathExists(sqlitePackageDir)) {
87
+ return;
88
+ }
89
+
90
+ console.warn('[better-sqlite3] Prebuild-install failed. Attempting node-gyp rebuild...');
91
+ if (runNodeGyp(sqlitePackageDir) && bindingPathExists(sqlitePackageDir)) {
92
+ return;
93
+ }
94
+
95
+ console.warn('[better-sqlite3] Failed to install native bindings.');
96
+ console.warn('[better-sqlite3] Ensure build tools are installed (python, make, C/C++ toolchain).');
97
+ console.warn('[better-sqlite3] Then run `yarn install` to rebuild.');
98
+ }
99
+
100
+ ensureBetterSqlite3();