crewx-agent-cli 0.2.6 → 0.2.7

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/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # CrewX CLI
2
2
 
3
- Connect an existing Codex, Claude Code, Pi, Hermes, or OpenClaw installation to
4
- a CrewX workspace. The runner stays on your machine, so the agent uses its
3
+ Connect local coding harnesses to a CrewX workspace through native adapters or
4
+ the embedded Agent Client Protocol runtime. The runner stays on your machine, so the agent uses its
5
5
  existing login, configuration, tools, and access to the selected working
6
6
  directory.
7
7
 
@@ -18,7 +18,7 @@ cd /path/to/project
18
18
  npx --yes crewx-agent-cli@latest --join <join-code>
19
19
  ```
20
20
 
21
- Node.js 22 or newer is required. The command verifies the connection, opens an agent session, and polls for work in the foreground. Closing the terminal or pressing `Ctrl+C` disconnects it. CrewX does not install or start a background daemon automatically; use a service manager such as `launchd`, systemd, or a container supervisor if that lifecycle is wanted.
21
+ Node.js 22.13 or newer is required. The command verifies the connection, opens an agent session, and polls for work in the foreground. Closing the terminal or pressing `Ctrl+C` disconnects it. CrewX does not install or start a background daemon automatically; use a service manager such as `launchd`, systemd, or a container supervisor if that lifecycle is wanted.
22
22
 
23
23
  Join mode does not write `$XDG_CONFIG_HOME/crewx/config.json`. Useful options include:
24
24
 
@@ -72,6 +72,14 @@ second, and `--cwd` last. Use `--once` for one poll and
72
72
  period the runner backs off with jitter to at most 8 seconds, honors server
73
73
  retry guidance, and resets to the base cadence as soon as work appears.
74
74
 
75
+ Compatible CrewX servers may lease multiple assignments in one acknowledged
76
+ page. The daemon runs at most two independent conversations at once by default,
77
+ while replies belonging to the same durable conversation remain serialized in
78
+ arrival order. Set `CREWX_MAX_CONCURRENT_ASSIGNMENTS` to a value from 1 through
79
+ 8 to tune that local process bound. The delivery cursor advances only after
80
+ every assignment in the page has a delivered terminal outcome, so parallel
81
+ execution does not weaken outbox replay or claim fencing.
82
+
75
83
  Assignments carry an opaque claim-fencing token. The runner includes it on
76
84
  heartbeats, messages, errors, and lifecycle events; CrewX rotates it when work
77
85
  is reassigned so a replaced runner cannot apply late results. The token is
@@ -101,15 +109,47 @@ inherited pipe that closes immediately after startup, rather than through the
101
109
  exec environment. This reduces accidental exposure but does not change the OS
102
110
  account trust boundary.
103
111
 
104
- ## Built-in adapters
112
+ ## Embedded ACP runtime
113
+
114
+ New CrewX profiles use the pinned `acpx@0.13.0` embedded runtime. Its canonical
115
+ harness IDs are `pi`, `openclaw`, `codex`, `claude`, `gemini`, `cursor`,
116
+ `copilot`, `droid`, `fast-agent`, `grok-build`, `iflow`, `kilocode`, `kimi`,
117
+ `kiro`, `mux`, `opencode`, `pool`, `qoder`, `qwen`, `trae`, and `zeroclaw`.
118
+ The corresponding harness executable and its normal authentication must be
119
+ available to the Bridge OS user. Some acpx adapters use pinned/ranged npm
120
+ launchers on first use and therefore require npm registry access.
121
+
122
+ CrewX embeds `acpx/runtime` in an assignment-scoped worker rather than invoking
123
+ the acpx CLI. Conversations receive stable persistent ACP session keys;
124
+ cancellation calls ACP session cancellation; text, status, tool, usage, and
125
+ terminal results are normalized into CrewX events. Session records and event
126
+ logs stay below `${ACPX_STATE_HOME:-${XDG_STATE_HOME:-~/.local/state}}/crewx/acpx`
127
+ in owner-only directories and never persist the assignment proxy credential.
128
+
129
+ ACP permission prompts map `read_only` and chat-only profiles to approved reads
130
+ with non-read requests rejected. `standard` and `full_access` approve harness
131
+ permission requests non-interactively. ACP approval is not an operating-system
132
+ sandbox and ACP does not define a portable workspace-write boundary: use the
133
+ harness's own sandbox plus a dedicated OS account, container, or VM when that
134
+ boundary matters.
135
+
136
+ Exercise any ACP harness locally with, for example:
137
+
138
+ ```bash
139
+ crewx run gemini "Summarize this repository"
140
+ crewx run claude "Review the current diff" --transport acp
141
+ ```
142
+
143
+ ## Native compatibility adapters
105
144
 
106
145
  - **Codex** runs `codex exec --json … -`. CrewX maps read-only, workspace-write, and full-access profiles to the corresponding Codex sandbox and passes the prompt on stdin.
107
146
  - **Claude Code** runs `claude --print --output-format stream-json --verbose`. CrewX maps its profile to plan mode, non-interactive workspace edits, or skipped permission prompts and passes the prompt on stdin.
108
147
  - **Pi** runs `pi --mode json --no-approve`. CrewX deliberately ignores project-local Pi settings, extensions, skills, prompts, and themes on each daemon run. Read-only and chat-only profiles receive a restricted tool allowlist. Global Pi configuration still applies. Pi itself is not an operating-system sandbox.
109
148
  - **Hermes** runs `hermes acp` and speaks ACP v1 over stdio for session creation, model selection, prompt delivery, progress, permission requests, and cancellation. Workspace-write maps to Hermes `accept_edits`; full access maps to `dont_ask`. Hermes does not expose a trustworthy read-only or chat-only ACP mode, so CrewX rejects those profiles instead of presenting a false boundary. CrewX passes a configured model to Hermes for resolution.
110
- - **OpenClaw** uses a persistent agent with JSON output, a collision-resistant CrewX assignment session key, and a mode-`0600` temporary prompt file that is removed after the run. New CrewX profiles receive a managed OpenClaw ID; when that ID is missing locally, CrewX creates it inside the Bridge-approved assignment folder with OpenClaw's non-interactive agent command. Advanced profiles may select an existing OpenClaw agent instead. Before connecting and before every assignment, CrewX verifies the exact agent workspace and task-session sandbox. A sandboxed session must mount the approved directory read-write at its runtime workdir. OpenClaw continues to own its persistent tool policy and approval behavior.
149
+ - **OpenClaw** uses a persistent agent with JSON output, a collision-resistant CrewX conversation session key, and a mode-`0600` temporary prompt file that is removed after the run. Replies in one CrewX thread reuse that session key, while separate top-level asks remain isolated. New CrewX profiles receive a managed OpenClaw ID; when that ID is missing locally, CrewX creates it inside the Bridge-approved assignment folder with OpenClaw's non-interactive agent command. Advanced profiles may select an existing OpenClaw agent instead. Before connecting and before every assignment, CrewX verifies the exact agent workspace and task-session sandbox. A sandboxed session must mount the approved directory read-write at its runtime workdir. OpenClaw continues to own its persistent tool policy and approval behavior.
111
150
 
112
- `crewx doctor` probes all five binaries. Runtime profile changes are read before every assignment, so supported model, permission, chat-only, working-directory, token, and deactivation changes do not require reconnecting. Chat-only and deactivated agents cannot receive task runs.
151
+ Existing `runtime=local` profiles retain the native adapters above. `crewx doctor`
152
+ probes all 22 supported harness IDs. Runtime profile changes are read before every assignment, so supported model, permission, chat-only, working-directory, token, and deactivation changes do not require reconnecting. Chat-only and deactivated agents cannot receive task runs.
113
153
 
114
154
  The assignment capability proxy enforces the server profile locally:
115
155
  `read_only` and chat-only profiles may use only GET operations; `standard` and
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=acp-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acp-worker.d.ts","sourceRoot":"","sources":["../src/acp-worker.ts"],"names":[],"mappings":""}
@@ -0,0 +1,176 @@
1
+ #!/usr/bin/env node
2
+ import { randomUUID } from "node:crypto";
3
+ import { chmod, mkdir } from "node:fs/promises";
4
+ import { homedir } from "node:os";
5
+ import { join, resolve } from "node:path";
6
+ import { createAcpRuntime, createAgentRegistry, createRuntimeStore, } from "acpx/runtime";
7
+ import { ACPX_HARNESSES } from "crewx-agent-protocol";
8
+ const READ_KINDS = new Set(["read", "search", "fetch", "think"]);
9
+ function workerStateDir(environment = process.env) {
10
+ const base = environment.ACPX_STATE_HOME?.trim() ||
11
+ environment.XDG_STATE_HOME?.trim() ||
12
+ join(homedir(), ".local", "state");
13
+ return resolve(base, "crewx", "acpx");
14
+ }
15
+ function secureRuntimeStore(stateDir) {
16
+ const store = createRuntimeStore({ stateDir });
17
+ const secureEventPath = (record) => {
18
+ record.eventLog.active_path = join(stateDir, "events", `${encodeURIComponent(record.acpxRecordId)}.stream.ndjson`);
19
+ return record;
20
+ };
21
+ return {
22
+ async load(sessionId) {
23
+ const record = await store.load(sessionId);
24
+ return record ? secureEventPath(record) : undefined;
25
+ },
26
+ async save(record) {
27
+ await store.save(secureEventPath(record));
28
+ },
29
+ };
30
+ }
31
+ async function readRequest() {
32
+ process.stdin.setEncoding("utf8");
33
+ let raw = "";
34
+ for await (const chunk of process.stdin)
35
+ raw += chunk;
36
+ const value = JSON.parse(raw);
37
+ if (typeof value.harness !== "string" ||
38
+ !ACPX_HARNESSES.includes(value.harness) ||
39
+ typeof value.prompt !== "string" ||
40
+ !value.prompt.trim() ||
41
+ typeof value.cwd !== "string" ||
42
+ !value.cwd.trim() ||
43
+ typeof value.sessionKey !== "string" ||
44
+ !/^crewx-[a-f0-9]{48}$/.test(value.sessionKey) ||
45
+ typeof value.timeoutMs !== "number" ||
46
+ !Number.isSafeInteger(value.timeoutMs) ||
47
+ value.timeoutMs <= 0) {
48
+ throw new Error("CrewX supplied an invalid ACP worker request.");
49
+ }
50
+ return value;
51
+ }
52
+ function emit(value) {
53
+ process.stdout.write(`${JSON.stringify(value)}\n`);
54
+ }
55
+ function publicEvent(event) {
56
+ if (event.type !== "tool_call")
57
+ return event;
58
+ return {
59
+ type: event.type,
60
+ text: event.text,
61
+ ...(event.tag ? { tag: event.tag } : {}),
62
+ ...(event.toolCallId ? { toolCallId: event.toolCallId } : {}),
63
+ ...(event.status ? { status: event.status } : {}),
64
+ ...(event.title ? { title: event.title } : {}),
65
+ ...(event.kind ? { kind: event.kind } : {}),
66
+ ...(event.locations ? { locations: event.locations } : {}),
67
+ };
68
+ }
69
+ async function restrictedPermissionDecision(request) {
70
+ return READ_KINDS.has(request.inferredKind ?? "")
71
+ ? { outcome: "allow_once" }
72
+ : { outcome: "reject_once" };
73
+ }
74
+ async function main() {
75
+ process.umask(0o077);
76
+ const request = await readRequest();
77
+ const stateDir = workerStateDir();
78
+ await mkdir(stateDir, { recursive: true, mode: 0o700 });
79
+ await chmod(stateDir, 0o700);
80
+ await mkdir(join(stateDir, "events"), { recursive: true, mode: 0o700 });
81
+ await chmod(join(stateDir, "events"), 0o700);
82
+ const restricted = request.profile?.chatOnly === true ||
83
+ request.profile?.permissionPreset === "read_only";
84
+ const controller = new AbortController();
85
+ let turn;
86
+ let handle;
87
+ const stop = () => {
88
+ controller.abort();
89
+ void turn?.cancel({ reason: "CrewX assignment cancelled" });
90
+ };
91
+ process.once("SIGINT", stop);
92
+ process.once("SIGTERM", stop);
93
+ const runtime = createAcpRuntime({
94
+ cwd: request.cwd,
95
+ sessionStore: secureRuntimeStore(stateDir),
96
+ agentRegistry: createAgentRegistry(),
97
+ permissionMode: restricted ? "approve-reads" : "approve-all",
98
+ nonInteractivePermissions: "deny",
99
+ timeoutMs: request.timeoutMs,
100
+ probeAgent: request.harness,
101
+ ...(restricted
102
+ ? { onPermissionRequest: restrictedPermissionDecision }
103
+ : {}),
104
+ });
105
+ try {
106
+ handle = await runtime.ensureSession({
107
+ sessionKey: request.sessionKey,
108
+ agent: request.harness,
109
+ mode: "persistent",
110
+ cwd: request.cwd,
111
+ sessionOptions: {
112
+ ...(request.profile?.model ? { model: request.profile.model } : {}),
113
+ ...(request.profile?.chatOnly ? { allowedTools: [] } : {}),
114
+ },
115
+ });
116
+ if (request.profile?.model) {
117
+ const status = await runtime.getStatus({
118
+ handle,
119
+ signal: controller.signal,
120
+ });
121
+ if (status.models &&
122
+ status.models.currentModelId !== request.profile.model &&
123
+ status.models.availableModelIds.includes(request.profile.model)) {
124
+ await runtime.setConfigOption({
125
+ handle,
126
+ key: "model",
127
+ value: request.profile.model,
128
+ });
129
+ }
130
+ }
131
+ turn = runtime.startTurn({
132
+ handle,
133
+ text: request.prompt,
134
+ mode: "prompt",
135
+ requestId: randomUUID(),
136
+ timeoutMs: request.timeoutMs,
137
+ signal: controller.signal,
138
+ });
139
+ for await (const event of turn.events) {
140
+ emit({ type: "event", event: publicEvent(event) });
141
+ }
142
+ const result = await turn.result;
143
+ emit({ type: "result", result });
144
+ if (result.status === "failed")
145
+ process.exitCode = 1;
146
+ }
147
+ finally {
148
+ process.removeListener("SIGINT", stop);
149
+ process.removeListener("SIGTERM", stop);
150
+ if (handle) {
151
+ await runtime
152
+ .close({
153
+ handle,
154
+ reason: "CrewX turn complete",
155
+ discardPersistentState: false,
156
+ })
157
+ .catch(() => undefined);
158
+ }
159
+ }
160
+ }
161
+ main().catch((error) => {
162
+ emit({
163
+ type: "error",
164
+ error: {
165
+ message: error instanceof Error ? error.message : String(error),
166
+ ...(typeof error === "object" &&
167
+ error !== null &&
168
+ "code" in error &&
169
+ typeof error.code === "string"
170
+ ? { code: error.code }
171
+ : {}),
172
+ },
173
+ });
174
+ process.exitCode = 1;
175
+ });
176
+ //# sourceMappingURL=acp-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acp-worker.js","sourceRoot":"","sources":["../src/acp-worker.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { type ChildProcessWithoutNullStreams, type SpawnOptionsWithoutStdio } from 'node:child_process';
2
- import { type AgentAdapter } from 'crewx-agent-protocol';
1
+ import { type ChildProcessWithoutNullStreams, type SpawnOptionsWithoutStdio } from "node:child_process";
2
+ import { type AgentAdapter } from "crewx-agent-protocol";
3
3
  export declare function adapterProbePlan(adapter: AgentAdapter): {
4
4
  args: readonly string[];
5
5
  timeoutMs: number;
@@ -7,28 +7,29 @@ export declare function adapterProbePlan(adapter: AgentAdapter): {
7
7
  export interface AdapterInvocation {
8
8
  command: string;
9
9
  args: string[];
10
- output: 'jsonl' | 'json' | 'text';
10
+ output: "jsonl" | "json" | "text";
11
11
  prompt: {
12
- type: 'stdin';
12
+ type: "stdin";
13
13
  } | {
14
- type: 'argument';
14
+ type: "argument";
15
15
  index: number;
16
16
  } | {
17
- type: 'file';
17
+ type: "file";
18
18
  flag: string;
19
19
  };
20
20
  }
21
21
  export interface AgentRuntimeProfile {
22
22
  model?: string;
23
- permissionPreset?: 'read_only' | 'standard' | 'full_access';
23
+ permissionPreset?: "read_only" | "standard" | "full_access";
24
24
  chatOnly?: boolean;
25
25
  sessionKey?: string;
26
26
  runtimeAgentId?: string;
27
+ transport?: "native" | "acp";
27
28
  }
28
29
  export interface ParsedAdapterLine {
29
30
  raw: unknown;
30
31
  message?: string;
31
- role?: 'assistant' | 'tool';
32
+ role?: "assistant" | "tool";
32
33
  eventType?: string;
33
34
  }
34
35
  export interface AdapterRunResult {
@@ -45,7 +46,7 @@ export declare function buildAdapterInvocation(adapter: AgentAdapter, profile?:
45
46
  export declare function parseCodingCommand(value: string): string[];
46
47
  export declare function parseAdapterLine(adapter: AgentAdapter, line: string): ParsedAdapterLine;
47
48
  export declare function publicOpenClawDiagnostic(value: string): string;
48
- export declare function verifyOpenClawRuntime(options: Pick<RunAdapterOptions, 'cwd' | 'environment' | 'spawnProcess'> & {
49
+ export declare function verifyOpenClawRuntime(options: Pick<RunAdapterOptions, "cwd" | "environment" | "spawnProcess"> & {
49
50
  profile: AgentRuntimeProfile;
50
51
  }): Promise<void>;
51
52
  export interface RunAdapterOptions {
@@ -61,7 +62,7 @@ export interface RunAdapterOptions {
61
62
  signal?: AbortSignal | undefined;
62
63
  spawnProcess?: SpawnProcess | undefined;
63
64
  onStdout?: ((line: string, parsed: ParsedAdapterLine) => void) | undefined;
64
- onMessage?: ((message: string, role: 'assistant' | 'tool') => void) | undefined;
65
+ onMessage?: ((message: string, role: "assistant" | "tool") => void) | undefined;
65
66
  onStderr?: ((line: string) => void) | undefined;
66
67
  }
67
68
  /**
@@ -71,6 +72,7 @@ export interface RunAdapterOptions {
71
72
  * supplied separately by the assignment executor.
72
73
  */
73
74
  export declare function runtimeEnvironment(environment?: NodeJS.ProcessEnv, controlEnvironment?: NodeJS.ProcessEnv, inherited?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
75
+ export declare function usesAcpRuntime(adapter: AgentAdapter, profile?: AgentRuntimeProfile): boolean;
74
76
  export declare function runAdapter(options: RunAdapterOptions): Promise<AdapterRunResult>;
75
77
  export declare function probeAdapter(adapter: AgentAdapter, spawnProcess?: SpawnProcess, timeoutMs?: number): Promise<{
76
78
  available: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../src/adapters.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../src/adapters.ts"],"names":[],"mappings":"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"}