kylon-cli 0.2.2 → 0.2.3-next.350

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,55 +1,99 @@
1
1
  # kylon-cli
2
2
 
3
- Gateway CLI for connecting local agent providers to a P2 workspace.
3
+ Computer host CLI for running external agents on your own machine for a P2
4
+ workspace.
4
5
 
5
6
  Requires Node.js 22.15.0 or newer.
6
7
 
7
8
  ## Install
8
9
 
9
10
  The CLI is published to npm as
10
- [`kylon-cli`](https://www.npmjs.com/package/kylon-cli). The Web UI's
11
- Onboarding tab provides one opaque `npx ... onboard --url ...` command
12
- for the normal setup and re-onboarding flow. Its collapsed manual setup
13
- shows the separate install and run commands documented below for recovery
14
- and advanced operation.
11
+ [`kylon-cli`](https://www.npmjs.com/package/kylon-cli). The Web UI provides
12
+ two distinct copy-paste entry points:
13
+
14
+ - **Workspace Settings Kylon CLI** shows
15
+ `npx --yes kylon-cli@<tag> auth login --workspace <id>` — authorizes this
16
+ installation for human workspace commands. Its **Use with Your Agents**
17
+ prompt teaches Claude Code, Codex, Hermes, or OpenClaw to discover and use
18
+ `kylon workspace` commands without assuming a provider-specific interface.
19
+ - **An external agent's Onboarding tab** shows
20
+ `npx --yes kylon-cli@<version> agent link --url '<one-time link>'`. The link
21
+ embeds a short-lived credential, so the CLI does not open a browser or reuse
22
+ a human workspace credential. It checks that the selected Claude Code or
23
+ Codex CLI is installed and authenticated, shows the exact agent and
24
+ workspace for confirmation, registers this installation as a computer,
25
+ assigns the agent, and starts the host daemon. The credential expires after
26
+ 30 minutes and can be redeemed only once; rerunning the same installation's
27
+ interrupted redemption is idempotent. Because the link carries the
28
+ credential, treat the command as a secret until it is used or expires.
29
+
30
+ A machine may be registered with one Kylon server and workspace at a time.
31
+ Equivalent spellings of the same server (`https://dev.purework.ai/api` and
32
+ `https://api.purework.ai`, `https://app.kylon.io/api` and
33
+ `https://api.kylon.io`) count as the same registration; preview environments
34
+ never do, even though they serve the same workspace ids as dev. Run
35
+ `kylon computer unlink` to point a machine somewhere else — it forgets the
36
+ local registration only, revoking nothing in the workspace and unassigning no
37
+ agent.
38
+
39
+ `auth login` browser-authenticates the human operator for `kylon workspace`
40
+ commands. `agent link` authenticates only the link operation with its embedded
41
+ credential; it never creates a human CLI session. Linking mints or reuses a
42
+ machine-scoped credential stored locally with mode `0600` and starts the host
43
+ daemon. In release builds on supported hosts a user-level
44
+ `launchd` / `systemd --user` service is installed so the daemon survives
45
+ terminal exit, reboot, and sleep/wake; otherwise the daemon runs in the
46
+ foreground until `Ctrl+C`.
47
+
48
+ The dist-tag tracks the environment: production uses `@latest`, dev uses
49
+ `@next` (newest prerelease). To pin a specific build, use `kylon-cli@X.Y.Z`.
15
50
 
16
- ### Step 1 Install kylon (once per host, re-paste to upgrade)
51
+ Requirements: Node.js 22.15.0+ (npm ships with Node). Linux / macOS only
52
+ (Windows operators should use WSL).
17
53
 
18
- ```bash
19
- npm install -g kylon-cli@latest
20
- ```
54
+ ### One managed `kylon` for humans and agents
21
55
 
22
- Installs the CLI globally so the `kylon` binary lands on PATH — the
23
- gateway daemon's child `kylon workspace …` calls (issued by the
24
- provider subprocess) resolve it there. Re-run to upgrade to whatever
25
- the dist-tag now points to. If the global install needs elevated
26
- permissions, prefix it with `sudo`.
56
+ The bootstrap commands (`agent link`, `connect`, and `auth login`) pin the CLI under
57
+ `~/.kylon/bin`: the exact bundle the daemon and its agents execute, exposed as
58
+ the `kylon` command. After the bootstrap they offer to add that directory to
59
+ your shell PATH (a marker-wrapped `. "$HOME/.kylon/env"` line in your shell rc,
60
+ or a fish `conf.d` drop-in; decline with `--no-modify-path`). From then on the
61
+ human terminal, the agents, and the daemon all run the same file — one
62
+ artifact, one version, one upgrade.
27
63
 
28
- The dist-tag tracks the environment: production installs `@latest`,
29
- dev installs `@next` (newest prerelease). To pin a specific build,
30
- install `kylon-cli@X.Y.Z`.
64
+ A leftover npm-global or npx-cached copy stays harmless: when it starts and
65
+ finds a strictly newer pinned install, it defers to it automatically
66
+ (installer commands — `agent …`, `connect`, and `gateway …` — always run as invoked, so a
67
+ fresh `npx` can still install itself over an older pinned copy; set
68
+ `KYLON_PINNED_TRAMPOLINE=0` to disable the deferral).
31
69
 
32
- Requirements: Node.js 22.15.0+ (npm ships with Node). Linux / macOS only
33
- (Windows operators should use WSL).
34
-
35
- ### Step 2 — Start the gateway daemon
70
+ ### Upgrading a gateway host
36
71
 
37
72
  ```bash
38
- kylon gateway run \
39
- --session-dir ~/.kylon/agents/<agent-id> \
40
- --server-url https://<origin>/api \
41
- --provider codex \
42
- --api-key <agent-api-key>
73
+ npx --yes kylon-cli@latest gateway service upgrade
43
74
  ```
44
75
 
45
- `gateway run` registers the session inside the selected agent directory
46
- (writing `~/.kylon/agents/<agent-id>/gateway-session.json` with mode `0600`)
47
- and starts the daemon in one step. On the next invocation, pass the same
48
- `--session-dir` without connection flags to jump straight to start. See
49
- [Usage Run](#run) for the full decision table. The daemon runs
50
- in the foreground until you stop it with `Ctrl+C`; hosts that want a
51
- supervised daemon typically wrap the same command in
52
- `launchd` / `systemd` / `supervisord`.
76
+ (`@next` on dev.) The daemon and the pinned agent `kylon` both run the
77
+ installed bundle under `~/.kylon/bin`, which only this command (or a
78
+ re-connect) refreshes: the freshly-resolved CLI installs its own bundle and
79
+ drain-restarts the running daemon onto it, moving both in lockstep.
80
+ `npm install -g` alone updates the operator's terminal binary and leaves the
81
+ gateway on the old build. The update notice the CLI prints on gateway hosts
82
+ uses exactly this command; `kylon gateway service repair` is the same
83
+ reconciliation under its recovery-oriented name.
84
+
85
+ The drain waits up to five minutes for in-flight agent work, and a drain that
86
+ exhausts its window rolls the upgrade back — so a persistently busy host would
87
+ never upgrade without an operator interrupt. Two are available:
88
+
89
+ - `kylon gateway service upgrade --force` skips the drain, or escalates one
90
+ already in progress: in-flight assignments are aborted with the same
91
+ recovery semantics as a daemon crash (the durable inbox re-drives
92
+ interrupted work on the restarted daemon), and the new version activates
93
+ immediately.
94
+ - `kylon gateway service cancel` abandons an in-progress upgrade: the daemon
95
+ rolls back to the previous bundle and resumes accepting work on the old
96
+ version.
53
97
 
54
98
  ### Local development (contributors)
55
99
 
@@ -87,7 +131,7 @@ workspace's **Settings → Kylon CLI** section, expand it, and copy its setup
87
131
  command, or run:
88
132
 
89
133
  ```bash
90
- npm install -g kylon-cli@latest && kylon auth login --workspace <WORKSPACE_ID>
134
+ npx --yes kylon-cli@latest auth login --workspace <WORKSPACE_ID>
91
135
  ```
92
136
 
93
137
  The CLI opens Kylon in your browser. After you sign in, confirm the installation
@@ -97,7 +141,9 @@ request but never receives the credential. The CLI proves possession of its PKCE
97
141
  verifier while polling Kylon over HTTPS, receives the credential directly from
98
142
  the API, and saves it in the versioned credential collection at
99
143
  `~/.kylon/workspace-auth.json` with mode `0600`. No loopback listener, incoming
100
- port, or browser request to localhost is used.
144
+ port, or browser request to localhost is used. On success the CLI also pins
145
+ itself under `~/.kylon/bin` and offers to put that directory on your PATH, so
146
+ subsequent commands are plain `kylon workspace ...` with no npx.
101
147
  The collection keeps credentials separately by server and workspace, and
102
148
  `--scope-workspace` selects the matching entry.
103
149
 
@@ -128,11 +174,12 @@ state:
128
174
 
129
175
  - Use `kylon workspace secret list|set|delete` for canonical workspace secrets
130
176
  with browser authorization.
131
- - Use `kylon gateway secret list|set|delete` for agent-local records with an
132
- external-agent gateway identity.
177
+ - Use `kylon gateway secret list|set|delete --agent <agent-id>` for agent-local
178
+ records, authenticated by this machine's computer credential through the
179
+ per-agent computer routes.
133
180
 
134
181
  This separation prevents browser credentials from reaching the
135
- agent-authenticated gateway secret endpoint and avoids state-dependent command
182
+ daemon-authenticated secret endpoints and avoids state-dependent command
136
183
  routing.
137
184
 
138
185
  ```bash
@@ -143,169 +190,104 @@ Logout revokes the selected installation credential remotely before removing
143
190
  that entry from the local collection. With no `--workspace`, it selects the most
144
191
  recently authorized entry. If Kylon cannot confirm revocation, it keeps the local
145
192
  credential so you can retry. `kylon auth logout --local-only` deliberately skips
146
- the remote revocation. You can also revoke any installation independently from
147
- **Settings Kylon CLI**. Other installations, browser sessions, external-agent
148
- keys, and workspace service keys are unaffected.
193
+ the remote revocation. This logout is deliberately credential-only: it does not
194
+ disconnect a computer or unassign its agents. If that installation still hosts
195
+ external agents, it remains listed as an **Authorized device** so its host
196
+ authority can still be removed without signing the CLI in again.
197
+
198
+ You can instead remove an **Authorized device** from **Settings → Kylon CLI**.
199
+ After warning about the impact, that workspace-scoped action revokes any active
200
+ installation credential, disconnects and revokes the computer host associated
201
+ with the same installation, and unassigns every external agent hosted there.
202
+ The device's authorizations and host registrations in other workspaces, browser
203
+ sessions, and workspace service keys are unaffected.
149
204
 
150
205
  Credentials created by the earlier browser flow appear as **Legacy user API
151
206
  key** in Settings. They can be revoked there, but they are not bound to a single
152
207
  workspace; sign in again to replace one with the per-installation flow.
153
208
 
154
- ### Onboard an invited external agent
209
+ ### Register a computer for manual placement
155
210
 
156
- The Web UI provides one operator-run command after an external agent is
157
- created:
211
+ `kylon connect` remains the advanced computer-first entrypoint when the user
212
+ explicitly wants to register a host before choosing an agent:
158
213
 
159
214
  ```bash
160
- npx --yes kylon-cli@latest onboard \
161
- --url 'https://api.kylon.io/docs/agent-onboard/<opaque-token>'
215
+ npx --yes kylon-cli@latest connect --workspace <WORKSPACE_ID>
162
216
  ```
163
217
 
164
- The command resolves the invitation without printing its API key, checks the
165
- local provider, verifies Codex or Claude Code authentication, connects the
166
- gateway, binds a managed per-agent working directory, and installs or updates a
167
- user-level `launchd` / `systemd --user` service running the unified gateway. The
168
- command returns after the service is active; the gateway then survives terminal
169
- exit, crash restart, reboot, and sleep/wake reconnects. Re-onboarding the same
170
- agent preserves its registered provider and directory, safely interrupts
171
- unfinished work owned by the displaced connection, and reconciles only that
172
- agent inside the existing daemon. If Codex or Claude Code is logged out, an
173
- interactive terminal launches the provider's own login flow and verifies
174
- authentication again before connecting.
175
-
176
- External-agent onboarding is intentionally separate from human `kylon auth
177
- login`: it continues to use the agent principal's API key and gateway session.
178
- It does not create a human CLI installation credential.
179
-
180
- Each invited agent is installed below `~/.kylon/agents/<agent-id>/`, so several
181
- Claude Code, Codex, or mixed-provider agents can run on the same host without
182
- sharing credentials or provider resume state. Different agents cannot use the
183
- same canonical working directory; create a separate checkout or Git worktree for
184
- each concurrently installed agent.
185
-
186
- Use `--workdir <path>` to select a different directory or `--no-start` to
187
- configure and validate without opening the long-running connection. Generic
188
- providers can supply their one-shot command with `--agent-command <command>`;
189
- an interactive terminal prompts for it when the flag is omitted.
218
+ This browser-authenticates the operator (the same PKCE flow as `kylon auth
219
+ login`), enrolls the machine as a **computer** keyed on its stable install id
220
+ (re-running is idempotent), persists the machine-scoped credential, and starts
221
+ the host daemon. New external-agent onboarding should use the agent-specific
222
+ `agent link` command instead; creation never asks the user to select a computer.
190
223
 
191
- ### Run
224
+ The daemon then reconciles the computer's assigned agents from the server:
225
+ each agent gets an isolated state root under `~/.kylon/agents/<agent-id>/`,
226
+ provider readiness (Codex / Claude Code install + authentication) is reported
227
+ per agent, and assignments arrive over the computer's single SSE stream.
228
+ Linking or relinking an agent later happens from that agent's Onboarding tab;
229
+ the daemon picks the change up without re-running `connect`.
192
230
 
193
- `gateway run` is the recommended entrypoint for external agent operators.
194
- It composes `connect` + `start` into a single command.
231
+ Use `--no-start` to register without starting the daemon, `--json` for
232
+ machine-readable output, and `--server-url` to target a non-default API origin
233
+ for direct computer registration.
195
234
 
196
- ```bash
197
- kylon gateway run \
198
- --session-dir ~/.kylon/agents/agent_123 \
199
- --server-url https://api.p2.ai \
200
- --provider codex \
201
- --api-key pak_xxxxx
202
- ```
203
-
204
- Decision table:
205
-
206
- | Saved session in `--session-dir`? | Connection flags passed? | What `run` does |
207
- |---|---|---|
208
- | no | `--server-url` + `--api-key` + `--provider` | connect, persist session, start daemon |
209
- | no | any field missing | error — lists the missing flag |
210
- | yes | none | start the daemon from the saved session |
211
- | yes | any | reconnect with the overrides (falls back to saved values for fields you didn't pass), persist the refreshed session, start the daemon |
212
-
213
- Only CLI flags count as overrides. On first connect, `KYLON_API_KEY` is
214
- persisted and the process is immediately replaced with a credential-free
215
- daemon image. With a saved session, the saved key remains authoritative and
216
- any inherited `KYLON_API_KEY` is removed before the daemon starts.
217
-
218
- ### Connect
235
+ ### Run
219
236
 
220
- Register this machine as the gateway client for an external agent.
221
- Most operators should prefer `gateway run` above. Use `connect` on its
222
- own when scripting or when you need to register a session without
223
- immediately starting the daemon.
237
+ `gateway run` starts the host daemon from this machine's saved computer
238
+ registration. It is the command the installed `launchd` / `systemd --user`
239
+ service execs; run it manually to host agents in the foreground.
224
240
 
225
241
  ```bash
226
- kylon gateway connect \
227
- --server-url https://api.p2.ai \
228
- --api-key pak_xxxxx \
229
- --provider codex
242
+ kylon gateway run
230
243
  ```
231
244
 
232
- The agent's API key identifies which agent the daemon will serve;
233
- channels are bound separately via the "invite agent into channel" flow
234
- in the web UI.
245
+ It takes no connection flags: register first with `kylon connect`. Without a
246
+ saved computer registration it exits with an error pointing there.
235
247
 
236
- `--session-dir` selects the full isolated state root for one agent. It is
237
- not a connection override, so it must be present both when connecting and
238
- when restarting that agent.
248
+ ### Sleep, wake, and keep-awake (macOS)
239
249
 
240
- ### Bind
241
-
242
- Create or update a logical session binding for an agent. Run from the
243
- target working directory:
250
+ By default the daemon holds a macOS sleep assertion (the same mechanism as
251
+ `caffeinate`) whenever it runs: on AC power the machine can turn its display
252
+ off without ever going to sleep, so its agents stay online and dispatchable
253
+ from the web at any time. Sleep is only prevented on AC power — on battery,
254
+ and when the lid closes, normal sleep policy always wins. No effect on Linux.
244
255
 
245
256
  ```bash
246
- kylon gateway bind \
247
- --agent agent_123 \
248
- --provider codex
257
+ kylon keep-awake # show the current mode
258
+ kylon keep-awake while-busy # prevent sleep only while assignments run
259
+ kylon keep-awake off # never prevent sleep
249
260
  ```
250
261
 
251
- Switch an existing binding to a different directory:
262
+ Modes: `always` (default), `while-busy`, `off`. The setting persists in
263
+ `~/.kylon/gateway-settings.json`; a running daemon hot-applies changes within
264
+ seconds, no service restart required.
252
265
 
253
- ```bash
254
- cd /path/to/other/repo
255
- kylon gateway bind --agent agent_123 --workdir .
256
- ```
257
-
258
- Bindings are keyed by `(gateway session, agent)`. The same agent
259
- behaves the same way regardless of which channel an assignment
260
- arrives on — see
261
- [`docs/journal_docs/05_27_gateway_routing_simplification.md`](../../docs/journal_docs/05_27_gateway_routing_simplification.md).
266
+ When the machine does sleep (battery, lid closed, manual sleep), assignments
267
+ dispatched to its agents queue server-side. The daemon detects the wake
268
+ instantly (a wall-clock jump across its monitor tick) and recovers in one
269
+ pass: it force-reconnects the computer event stream with reset backoff,
270
+ re-asserts presence on the fresh connection, and claims the queued work —
271
+ instead of waiting out inactivity timeouts and heartbeat intervals.
262
272
 
263
273
  ### Commands
264
274
 
265
275
  | Command | Description |
266
276
  |---|---|
267
- | `kylon gateway run` | **Recommended.** Connect + start in one step; idempotent when a session already exists. |
268
- | `kylon gateway connect` | Register this machine as the gateway client for an agent (API key identifies which), without starting the daemon. |
269
- | `kylon gateway bind` | Create or update a logical session binding. |
270
- | `kylon gateway start` | Start the gateway daemon from a saved session opens the SSE stream and executes assignments. Credential/server overrides are rejected on this long-running entrypoint. |
271
-
272
- ### Run Options
273
-
274
- | Flag | Description |
275
- |---|---|
276
- | `--server-url <url>` | P2 server URL (required for the first run; override otherwise) |
277
- | `--api-key <key>` | Agent API key, e.g. `pak_xxx` (required for first run; override otherwise. `KYLON_API_KEY` satisfies first-run setup and is removed from the daemon environment after the key is persisted) |
278
- | `--provider <name>` | Provider CLI: `codex`, `claude-code`, `hermes`, `openclaw`, `generic` (required for first run; override otherwise) |
279
- | `--session-dir <path>` | Isolated state directory for this agent (normally `~/.kylon/agents/<agent-id>`) |
277
+ | `kylon connect` | **Recommended.** Register this computer (browser auth + enrollment) and run the host daemon. `--url` also assigns one agent. |
278
+ | `kylon computer unlink` | Forget this machine's saved computer registration so it can be linked elsewhere. Local only: revokes nothing and unassigns no agent. |
279
+ | `kylon gateway run` | Run the host daemon from the saved computer registration (service entrypoint). |
280
+ | `kylon keep-awake [mode]` | Show or set macOS sleep prevention (`always` (default) / `while-busy` / `off`). |
280
281
 
281
282
  ### Connect Options
282
283
 
283
284
  | Flag | Description |
284
285
  |---|---|
285
- | `--server-url <url>` | P2 server URL (required) |
286
- | `--api-key <key>` | Agent API key, e.g. `pak_xxx` (required, or set `KYLON_API_KEY`) |
287
- | `--provider <name>` | Provider CLI: `codex`, `claude-code`, `hermes`, `openclaw`, `generic` (required) |
288
- | `--session-dir <path>` | Isolated state directory for this agent |
289
-
290
- ### Bind Options
291
-
292
- | Flag | Description |
293
- |---|---|
294
- | `--agent <id>` | Agent ID (required) |
295
- | `--provider <name>` | Provider CLI (required for new, optional for update) |
296
- | `--workdir <path>` | Working directory (default: current directory) |
297
- | `--session-dir <path>` | Isolated state directory for this agent |
298
-
299
- ### Start Options
300
-
301
- | Flag | Description |
302
- |---|---|
303
- | `--session-dir <path>` | Isolated state directory containing this agent's saved session, bindings, and provider runtime cache |
304
-
305
- `gateway start` accepts credentials and the server origin only from the saved
306
- session. Use `gateway run` when a credential or origin must be supplied or
307
- changed; it persists the session and replaces the process with a credential-free
308
- daemon image before opening SSE.
286
+ | `--workspace <id>` | Workspace to register this computer with |
287
+ | `--url <setup url>` | Agent setup link from Kylon; implies the workspace and assigns that agent after enrollment (alternative to `--workspace`) |
288
+ | `--server-url <url>` | API server URL (defaults to `https://api.kylon.io`; ignored in favor of the origin resolved from `--url`) |
289
+ | `--no-start` | Register only; do not start the daemon |
290
+ | `--json` | Emit machine-readable JSON |
309
291
 
310
292
  ### Supported Providers
311
293
 
@@ -609,6 +591,7 @@ npm dist-tag add kylon-cli@<last-good> latest # move the channel back
609
591
  npm deprecate kylon-cli@<bad> "Broken release — use <last-good>."
610
592
  ```
611
593
 
612
- Operators on `@latest` pick up the re-pointed version the next time they
613
- `npm install -g kylon-cli@latest`; in-flight daemons keep their current CLI
614
- until they restart. Do not `npm unpublish`.
594
+ Operators on `@latest` pick up the re-pointed version the next time they run
595
+ `npx --yes kylon-cli@latest gateway service upgrade` (the command the update
596
+ notice prints on gateway hosts); in-flight daemons keep their current pinned
597
+ bundle until that drain-restart. Do not `npm unpublish`.