crewx-agent-cli 0.2.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CrewX contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # CrewX CLI
2
+
3
+ Connect an existing Codex, Claude Code, Pi, Hermes, or OpenClaw installation to a CrewX workspace. The runner stays on your machine, so the agent uses its existing login, configuration, tools, and access to the selected working directory.
4
+
5
+ ## One-command join
6
+
7
+ Create an agent profile in CrewX, generate a token, and copy the command from its connection panel:
8
+
9
+ ```bash
10
+ cd /path/to/project
11
+ npx --yes crewx-agent-cli@latest --join <join-code>
12
+ ```
13
+
14
+ 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.
15
+
16
+ Join mode does not write `$XDG_CONFIG_HOME/crewx/config.json`. Useful options include:
17
+
18
+ ```bash
19
+ npx --yes crewx-agent-cli@latest --join <join-code> --cwd /path/to/project
20
+ npx --yes crewx-agent-cli@latest --join <join-code> --once
21
+ npx --yes crewx-agent-cli@latest --join <join-code> --adapter codex
22
+ ```
23
+
24
+ The versioned join payload is base64url-encoded JSON containing the server URL, adapter, and raw `crwx_…` bearer token. Base64url is transport encoding, not encryption. CrewX shows the generated token once, but the credential inside the command is reusable until its configured expiry or revocation. Anyone who obtains the command can decode and use it, and the command may remain in shell history. Treat it as a secret and revoke the token from the agent profile if it is exposed.
25
+
26
+ The server stores only the token digest. During a join-mode run, the CLI keeps the decoded credential in memory and supplies the CrewX URL and token to child agents as `CREWX_URL` and `CREWX_TOKEN` so they can use the scoped `crewx task`, `doc`, `memory`, and `integration` commands. A locally executed agent has the same trust boundary as the user account running it.
27
+
28
+ ## Persistent installation
29
+
30
+ From this monorepo:
31
+
32
+ ```bash
33
+ pnpm --filter crewx-agent-protocol build
34
+ pnpm --filter crewx-agent-cli build
35
+ pnpm --filter crewx-agent-cli link --global
36
+ ```
37
+
38
+ After `crewx-agent-cli` is published to npm, install it globally and save a named machine connection:
39
+
40
+ ```bash
41
+ npm install --global crewx-agent-cli
42
+ crewx connect --url https://your-crewx.example --token crwx_… --name "My Mac"
43
+ crewx doctor
44
+ crewx daemon --adapter codex
45
+ ```
46
+
47
+ The saved connection lives at `$XDG_CONFIG_HOME/crewx/config.json` (or `~/.config/crewx/config.json`) with mode `0600`. `CREWX_URL`, `CREWX_TOKEN`, and `CREWX_ADAPTER` override saved settings and are useful in explicitly secured services and CI. The CLI includes operating-system certificate authorities in Node's trust store, so locally trusted HTTPS sites such as Laravel Herd work without disabling certificate verification.
48
+
49
+ Both join mode and `crewx daemon` run in the foreground. Start either command inside a safe fallback directory. For each assignment, CrewX uses the project channel's local path first, the agent profile's default working directory second, and `--cwd` last. Use `--once` for one poll and `--poll-interval 5000` to change the polling cadence.
50
+
51
+ ## Built-in adapters
52
+
53
+ - **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.
54
+ - **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.
55
+ - **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.
56
+ - **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.
57
+ - **OpenClaw** runs an explicitly selected 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. Immediately before spawning, CrewX runs `openclaw agents list --json` and `openclaw sandbox explain` for the exact task session. The configured agent workspace must resolve to the assignment directory; a sandboxed session must mount that exact directory read-write at its runtime workdir. OpenClaw owns its persistent tool policy and approval behavior, and has no per-run `--cwd`, so configure a dedicated agent with `openclaw agents add <name> --workspace "/path/to/project" --non-interactive --json` when needed.
58
+
59
+ `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.
60
+
61
+ ## Custom commands
62
+
63
+ Advanced users can replace the built-in invocation without editing CrewX:
64
+
65
+ ```bash
66
+ npx --yes crewx-agent-cli@latest --join <join-code> \
67
+ --coding-cmd 'my-agent --non-interactive {prompt}'
68
+
69
+ crewx daemon --adapter codex --coding-cmd 'my-agent --format text'
70
+ crewx run codex "Review this repository" --coding-cmd 'my-agent {prompt} --quiet'
71
+ ```
72
+
73
+ CrewX uses a quote-aware argv parser and launches the resulting executable with `shell: false`. The prompt replaces one exact `{prompt}` argument or is appended as one argument when the placeholder is absent; it is never interpolated into a shell string. Pipes, redirection, variable expansion, and command substitution are therefore not interpreted by CrewX.
74
+
75
+ This prevents prompt text from becoming shell syntax, but it does not make an arbitrary executable safe. The selected program inherits the runner's operating-system permissions and environment, including CrewX connection variables in join mode. Do not use commands from an untrusted profile or run them in an untrusted working directory. Explicitly wrapping a command in a shell recreates the shell-risk boundary and is not recommended.
76
+
77
+ ## Shared work commands
78
+
79
+ The same connection token lets humans and running agents maintain shared CrewX work from the terminal. JSON output is designed for local agents:
80
+
81
+ ```bash
82
+ crewx task list --assigned-to-me --json
83
+ crewx task create --title "Verify the release" --description "Run the smoke suite" --assign-to-me --json
84
+ crewx task update 42 --status done --result "Smoke suite passed" --json
85
+
86
+ crewx doc list --json
87
+ crewx doc create --title "Release runbook" --content "# Release runbook" --json
88
+ crewx doc update 17 --expected-version 1 --content "# Updated runbook" --summary "Add release steps" --json
89
+
90
+ crewx memory list --scope channel --channel 12 --json
91
+ crewx memory create --title "Release convention" --content "Run the browser smoke test before merging" --channel 12 --json
92
+ crewx memory update 9 --importance 5 --json
93
+
94
+ crewx integration list --json
95
+ crewx integration search slack "release blocker" --json
96
+ crewx integration search notion "deployment runbook" --json
97
+ crewx integration search google_drive "quarterly plan" --json
98
+ ```
99
+
100
+ Agents may update only tasks assigned to their own profile. Documents must be agent-readable and unprotected, and every document update requires the current version from `doc list`; stale updates fail instead of overwriting newer work. Agents may edit only memories they recorded, while channel-scoped memory is limited to channels they can see. Provider access tokens are encrypted by the web application and are never returned to the CLI; integration commands expose normalized search results only.
101
+
102
+ ## One-shot local runs
103
+
104
+ The same adapters can be exercised without a CrewX connection:
105
+
106
+ ```bash
107
+ crewx run codex "Summarize this repository"
108
+ printf 'Review the current diff' | crewx run claude
109
+ crewx run pi "Find the failing test" --cwd ./project
110
+ crewx run hermes "Explain the architecture"
111
+ crewx run openclaw "Check the release plan"
112
+ ```
113
+
114
+ ## Review reruns
115
+
116
+ Tasks can require human approval. When an agent reports completion, CrewX holds the task in review. Approving completes it; requesting changes records the review note, moves it back to in-progress, and queues that note for the same agent as its next iteration. Existing task and pull-request context stays attached. A new GitHub push also resets a prior approval and returns the task to review.
117
+
118
+ Run `crewx --help` or `crewx <command> --help` for every option.
119
+
120
+ ## CrewX agent API
121
+
122
+ The CLI targets `/api/agent/v1`, including connection lifecycle plus `/tasks`, `/documents`, `/memories`, and `/integrations`, authenticated with the bearer connection token. Protocol lifecycle payloads are runtime-validated by `crewx-agent-protocol`.
123
+
124
+ CrewX's implementation choices were informed by a clean-room static inspection of the public `hilos-agent` package. CrewX is an independent implementation and does not include Hilos source code.
@@ -0,0 +1,67 @@
1
+ import { type ChildProcessWithoutNullStreams, type SpawnOptionsWithoutStdio } from 'node:child_process';
2
+ import { type AgentAdapter } from 'crewx-agent-protocol';
3
+ export interface AdapterInvocation {
4
+ command: string;
5
+ args: string[];
6
+ output: 'jsonl' | 'json' | 'text';
7
+ prompt: {
8
+ type: 'stdin';
9
+ } | {
10
+ type: 'argument';
11
+ index: number;
12
+ } | {
13
+ type: 'file';
14
+ flag: string;
15
+ };
16
+ }
17
+ export interface AgentRuntimeProfile {
18
+ model?: string;
19
+ permissionPreset?: 'read_only' | 'standard' | 'full_access';
20
+ chatOnly?: boolean;
21
+ sessionKey?: string;
22
+ runtimeAgentId?: string;
23
+ }
24
+ export interface ParsedAdapterLine {
25
+ raw: unknown;
26
+ message?: string;
27
+ role?: 'assistant' | 'tool';
28
+ eventType?: string;
29
+ }
30
+ export interface AdapterRunResult {
31
+ exitCode: number | null;
32
+ signal: NodeJS.Signals | null;
33
+ messages: string[];
34
+ stdout: string[];
35
+ stderr: string[];
36
+ }
37
+ export type SpawnProcess = (command: string, args: readonly string[], options: SpawnOptionsWithoutStdio) => ChildProcessWithoutNullStreams;
38
+ export declare function parseAdapter(value: string): AgentAdapter;
39
+ /** Adapter commands are represented as argv and are never evaluated by a shell. */
40
+ export declare function buildAdapterInvocation(adapter: AgentAdapter, profile?: AgentRuntimeProfile, codingCommand?: string): AdapterInvocation;
41
+ export declare function parseCodingCommand(value: string): string[];
42
+ export declare function parseAdapterLine(adapter: AgentAdapter, line: string): ParsedAdapterLine;
43
+ export declare function verifyOpenClawRuntime(options: Pick<RunAdapterOptions, 'cwd' | 'environment' | 'spawnProcess'> & {
44
+ profile: AgentRuntimeProfile;
45
+ }): Promise<void>;
46
+ export interface RunAdapterOptions {
47
+ adapter: AgentAdapter;
48
+ prompt: string;
49
+ cwd: string;
50
+ profile?: AgentRuntimeProfile | undefined;
51
+ codingCommand?: string | undefined;
52
+ environment?: NodeJS.ProcessEnv | undefined;
53
+ timeoutMs?: number | undefined;
54
+ maxOutputBytes?: number | undefined;
55
+ signal?: AbortSignal | undefined;
56
+ spawnProcess?: SpawnProcess | undefined;
57
+ onStdout?: ((line: string, parsed: ParsedAdapterLine) => void) | undefined;
58
+ onMessage?: ((message: string, role: 'assistant' | 'tool') => void) | undefined;
59
+ onStderr?: ((line: string) => void) | undefined;
60
+ }
61
+ export declare function runAdapter(options: RunAdapterOptions): Promise<AdapterRunResult>;
62
+ export declare function probeAdapter(adapter: AgentAdapter, spawnProcess?: SpawnProcess, timeoutMs?: number): Promise<{
63
+ available: boolean;
64
+ version?: string;
65
+ error?: string;
66
+ }>;
67
+ //# sourceMappingURL=adapters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../src/adapters.ts"],"names":[],"mappings":"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"}