@aipoch/open-science 0.0.0-stage → 1.0.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/CLI.md ADDED
@@ -0,0 +1,814 @@
1
+ # Open-Science CLI
2
+
3
+ The `open-science` command controls the local Open-Science service and submits research tasks without
4
+ requiring browser interaction.
5
+
6
+ The [release compatibility policy](https://github.com/aipoch/open-science/blob/main/docs/compatibility.md)
7
+ defines the 1.x contract for commands, machine-readable output and exit codes.
8
+
9
+ ## Installation
10
+
11
+ ### From npm
12
+
13
+ Install the published [standalone CLI](https://www.npmjs.com/package/@aipoch/open-science)
14
+ with Node.js **22.13.0 or later**:
15
+
16
+ ```bash
17
+ npm install --global @aipoch/open-science
18
+ open-science start --no-open
19
+ open-science url
20
+ ```
21
+
22
+ The registry package installs the matching native backend, Web UI and resources through npm
23
+ optional dependencies. It runs without Electron or an installed desktop app. Supported targets
24
+ are macOS ARM64/x64, glibc Linux ARM64/x64 and Windows x64; musl Linux and Windows ARM64 are not
25
+ supported. Do not omit optional dependencies. If startup reports a missing native package, run
26
+ `npm install --global @aipoch/open-science --include=optional`.
27
+
28
+ Open the printed authenticated URL to configure an Agent runtime, model provider and optional
29
+ Python/R Notebook runtime, or follow [First-run setup (Codex)](#first-run-setup-codex) from the
30
+ terminal. See the [standalone runtime guide](https://github.com/aipoch/open-science/blob/main/docs/standalone-runtime.md#linux-prerequisites)
31
+ for Linux credential storage and sandbox prerequisites.
32
+
33
+ ### Locally built standalone tarball
34
+
35
+ Install the target-specific standalone tarball built with `npm run pack:backend`, using ordinary
36
+ Node >=22.13.0. It includes the backend, Web UI, resources and native dependencies; Electron and
37
+ a graphical display are not required.
38
+
39
+ ```bash
40
+ npm install --global ./aipoch-open-science-VERSION.tgz # Replace VERSION with the downloaded version.
41
+ open-science start --no-open
42
+ open-science url
43
+ ```
44
+
45
+ Linux secure storage requires an unlocked OS vault and user D-Bus session. See the
46
+ [standalone runtime guide](https://github.com/aipoch/open-science/blob/main/docs/standalone-runtime.md)
47
+ for build dependencies, compatibility and desktop-only capabilities.
48
+
49
+ ### Desktop package launchers (including Debian/WSL)
50
+
51
+ Installing the `.deb` package registers `/usr/bin/open-science` automatically. No separate
52
+ desktop Settings interaction or `cli install` command is needed to use the launcher.
53
+ It starts or reuses the bundled ordinary Node backend without opening Electron:
54
+
55
+ ```bash
56
+ sudo apt install ./open-science.deb # Use the downloaded package's actual filename.
57
+ open-science init
58
+ open-science start --no-open
59
+ open-science url
60
+ ```
61
+
62
+ The desktop shortcut continues to launch the application directly. Debian maintains the CLI entry
63
+ through upgrades and removal. Upgrades migrate only the old package-owned system alternative;
64
+ existing user launchers and unrelated manually selected alternatives are preserved. The installer
65
+ reports a conflict instead of overwriting an unmanaged `/usr/bin/open-science` file or symlink.
66
+ The desktop Settings controls manage the optional user launcher, not the
67
+ Debian-owned system entry; remove the Debian package to remove that entry.
68
+
69
+ ### From other application packages
70
+
71
+ Open **Settings > General > Command line tool** in Open-Science and choose **Install command**. This
72
+ adds an `open-science` launcher to your PATH (`~/.local/bin` on macOS and Linux, or a per-user
73
+ directory added to PATH on Windows). The launcher uses the application's bundled runtime, so it does
74
+ not require a separate Node.js installation.
75
+
76
+ If the launcher directory is not yet on PATH, the Settings panel shows the line to add. Open a new
77
+ terminal after updating PATH. Choose **Uninstall command** in the same panel to remove the launcher.
78
+
79
+ ### From a source checkout
80
+
81
+ Replace `open-science` in the examples below with:
82
+
83
+ ```bash
84
+ node packages/open-science/cli.mjs
85
+ ```
86
+
87
+ ## Local information and help
88
+
89
+ These commands work without starting or connecting to the service:
90
+
91
+ ```bash
92
+ open-science --version
93
+ open-science -v
94
+ open-science version --json
95
+ open-science help
96
+ open-science help run
97
+ open-science paths --json
98
+ open-science paths --profile /absolute/path/to/profile
99
+ ```
100
+
101
+ `--version`, `-v`, and `version` print the invoked CLI's application version, including any
102
+ nightly suffix. `version --json` prints `{ "version": "..." }`. Source checkouts use the root
103
+ application version; installed distributions use their own release metadata. This is not the
104
+ version of a running service. The version flags are standalone commands, not options for `run`,
105
+ `start`, or other commands.
106
+
107
+ `help` is equivalent to `--help`; `help <command>` is equivalent to `<command> --help`.
108
+ For example, `help project` lists Project commands. Unknown command names and unsupported
109
+ arguments fail with the existing usage-error exit code `2`.
110
+
111
+ `paths` prints human-readable locations; `paths --json` prints one object with:
112
+
113
+ | Field | Meaning |
114
+ | ---------------------- | ---------------------------------------------------------------------------------------- |
115
+ | `cliPath` | The CLI implementation file used by this invocation. |
116
+ | `nodePath` | The Node executable running the CLI. |
117
+ | `startupConfigRoot` | The configuration directory selected by the installation's default or explicit override. |
118
+ | `discoveryConfigRoots` | Ordered candidate configuration directories searched for an existing service. |
119
+
120
+ Source checkouts default to `~/.open-science-project` for startup; installations default to
121
+ `~/.open-science`. Without an override, service discovery checks the development directory first,
122
+ then the production directory. `--config-root` (or `--profile`) takes precedence over
123
+ `OPEN_SCIENCE_CONFIG_ROOT`, then `OPEN_SCIENCE_STORAGE_ROOT`; an override selects a single
124
+ absolute directory for both startup and discovery. Paths are reported even when they do not exist.
125
+ The output does not identify an active service or a research-data directory, which may differ.
126
+
127
+ These commands do not create profiles, modify settings, read credentials, or print authenticated
128
+ URLs. Successful queries exit `0`; missing or invalid version metadata produces an error rather
129
+ than a fallback version. `paths` accepts only the profile, JSON, and help options; `version`
130
+ accepts only JSON and help options, and `help` accepts only one optional command name and help flags.
131
+
132
+ ## Service lifecycle
133
+
134
+ Initialize the local configuration directory from a terminal. This is safe to repeat and does not
135
+ start the desktop application:
136
+
137
+ ```bash
138
+ open-science init
139
+ open-science init --config-root /absolute/path/to/profile --json
140
+ ```
141
+
142
+ `init` prepares the profile directory; the first `start` creates the authenticated service state and
143
+ token. It does not migrate or modify an existing profile beyond creating the directory when needed.
144
+ Use `--profile` as an alias for `--config-root`. Both accept an absolute configuration directory,
145
+ including in packaged distributions.
146
+
147
+ Start the service without opening a browser, check its status, or stop it:
148
+
149
+ ```bash
150
+ open-science start --no-open
151
+ open-science status --json
152
+ open-science stop
153
+ ```
154
+
155
+ To open the Web UI later, request its authenticated URL explicitly:
156
+
157
+ ```bash
158
+ open-science url
159
+ ```
160
+
161
+ `open-science url` is the only command that intentionally prints an authenticated browser URL. Normal
162
+ human-readable, JSON, and JSONL output never includes the local token.
163
+
164
+ Use `--port <port>` to override `OPEN_SCIENCE_WEB_PORT`, or the default port of `44100` when neither is set. `start` discovers the matching npm platform package, the standalone
165
+ Node entry bundled beside the CLI, or `out/backend/index.cjs` in a source checkout. Build the
166
+ source entry with `npm run build:backend` and Web UI with `npm run build:web` first.
167
+ `--app-path` and `OPEN_SCIENCE_APP_PATH` no longer select a hidden Electron backend.
168
+ `--no-sandbox` does not apply to Node startup; existing Notebook/process permissions still apply.
169
+
170
+ An already running Node runtime is reused through authenticated discovery, including one started
171
+ by the desktop. Electron attaches to an existing same-version Node server without adding another
172
+ writer. Quitting a desktop stops only a server it started; a desktop attached to a CLI-started
173
+ server only detaches. Closing a Web tab or SDK connection does not stop the server. Use
174
+ `open-science stop` for an explicit global stop affecting every connected client.
175
+
176
+ `open-science stop` requests an authenticated graceful shutdown and waits for the service to exit. If
177
+ the request cannot be accepted or a dedicated daemon remains alive after the shutdown deadline, the
178
+ command fails without signalling the PID recorded in `web-service.json`; a stale PID may have been
179
+ reused by an unrelated process. The state file is retained for diagnosis and can be replaced by a
180
+ later `open-science start`.
181
+
182
+ Automatic discovery tries the development config directory before the production directory, skipping
183
+ dead or unhealthy candidates until it finds a healthy service. An explicit `--config-root`,
184
+ `OPEN_SCIENCE_CONFIG_ROOT`, or `OPEN_SCIENCE_STORAGE_ROOT` limits discovery to that directory. Live
185
+ unhealthy records are retained; failed authentication never authorizes signalling a recorded PID.
186
+
187
+ `open-science stop --json` prints exactly one result object on success:
188
+
189
+ | `result` | Meaning |
190
+ | --------------------- | ---------------------------------------------------------------------------- |
191
+ | `already-stopped` | No live service record was found. |
192
+ | `daemon-stopped` | The authenticated Node daemon exited (desktop-started or CLI-started). |
193
+ | `web-service-stopped` | Legacy desktop-host protocol only: Web stopped; old desktop remains running. |
194
+
195
+ Among lifecycle commands, `status` and `stop` support `--json`. `start` and `url` reject
196
+ it; run `start --no-open` followed by `status --json` for machine-readable startup status. Errors
197
+ with `--json` are reported on stderr as a JSON error object with a nonzero exit code.
198
+
199
+ ## Readiness checks
200
+
201
+ Inspect the running service without changing runtime, provider, credential, onboarding, or Skill
202
+ settings:
203
+
204
+ ```bash
205
+ open-science doctor --json
206
+ ```
207
+
208
+ The command prints one JSON object. `ready` requires both the selected Agent runtime and active
209
+ provider to be ready. A check is `missing` when its resource is absent and `not_ready` when it is
210
+ configured but unusable; provider failures may include a stable `reason`, such as
211
+ `credential_invalid`.
212
+
213
+ Codex credential inspection checks supported material in the app-owned `auth.json` without launching
214
+ Codex or validating expiry/revocation remotely; historical provider validation remains a separate gate.
215
+
216
+ `checks.skills.enabled` contains the sorted IDs of enabled, available Skills; Skills do not block
217
+ overall readiness. `next` contains stable action codes such as
218
+ `runtime_missing` and `provider_not_ready`, with an additive `argv` recovery command for the Codex bootstrap path. A completed inspection
219
+ exits with code `0` even when `ready` is false; connection and command failures keep the existing
220
+ nonzero CLI error codes.
221
+
222
+ ## First-run setup (Codex)
223
+
224
+ Install the npm package, a standalone artifact or a desktop package containing the ordinary Node backend first.
225
+ `init` creates a configuration directory only; `--profile` selects an absolute configuration directory.
226
+
227
+ ```bash
228
+ open-science start --no-open
229
+ open-science runtime install codex --json
230
+ open-science codex login
231
+ open-science connector configure literature --openalex-key-env OPENALEX_API_KEY --json
232
+ open-science doctor --json
233
+ open-science project create "First review" --json
234
+ open-science run --project "First review" --skill literature-review \
235
+ --prompt "Review the evidence for the research question in the project context" --wait --jsonl
236
+ ```
237
+
238
+ Place credentials in the named environment variables through your existing secret-management flow.
239
+ Do not put secret values in command arguments. The CLI reads only the variable explicitly named by
240
+ `--api-key-env` or `--openalex-key-env`; it never imports external Codex credentials.
241
+
242
+ For an OpenAI API-key provider instead of subscription login, prepare the runtime and then use:
243
+
244
+ ```bash
245
+ open-science provider add --type official --vendor openai --model gpt-5.4 \
246
+ --api-key-env OPENAI_API_KEY --json
247
+ ```
248
+
249
+ Use a model supported by the installed application's OpenAI catalog. Setup probes that exact model
250
+ before saving its protected credential reference and validation record. This initial command creates
251
+ `cli-openai`; repeating it with the same key and currently selected model revalidates that target.
252
+ If Settings changed the active model, Doctor suggests the selected model; revalidation preserves the
253
+ provider default model and active selection. Different existing credentials,
254
+ providers, or framework selections produce `configuration_conflict`, without overwriting them.
255
+ Later account edits remain in Settings. Other runtime/provider bootstrap combinations are not yet
256
+ supported. Existing run-time selection commands are unchanged.
257
+
258
+ OpenAlex keys are validated before persistence and Literature Graph enablement. Rejected keys or a
259
+ configuration changed during the probe are not saved. A recognized key may still have exhausted
260
+ quota (the existing probe accepts HTTP 429); a successful probe is not a completed literature run.
261
+
262
+ All writes use existing Settings/runtime/credential owners and formats. No onboarding completion
263
+ flag or database migration is added. OS storage remains the default; Linux file storage still
264
+ requires the existing explicit `start --credential-store file` option on every start.
265
+
266
+ `doctor` keeps existing readiness/reason fields. If the daemon is absent, the CLI prints a report
267
+ with `checks.daemon.status: "missing"` and `next: [{ code: "daemon_unavailable", argv: ["start",
268
+ "--no-open"] }]`, exiting 3. This includes a stale state file whose loopback connection is refused; HTTP health
269
+ rejections (including authorization failures) remain errors rather than missing-daemon reports.
270
+ When probing both default profiles, a later refused connection does not hide an earlier HTTP or
271
+ configuration error; a healthy later profile can still be selected. A running-daemon report still exits 0 even when readiness is false.
272
+ Append the same development `--profile` argument when executing a suggested argv in an isolated
273
+ profile. Doctor reports readiness, not a live third-party authorization or research-run guarantee.
274
+
275
+ `bootstrap` SDK requests return `{ ok: true, providerId? }` or `{ ok: false, code }`. Codes are
276
+ `invalid_request` (including unknown model/input), `configuration_conflict`, `runtime_unavailable`,
277
+ `credential_invalid`, or `bootstrap_failed`. The CLI exits nonzero for failures; results never
278
+ include the submitted secret or raw upstream error. Bootstrap/launcher writes require an
279
+ authenticated local connection and are not exposed as research-agent tools.
280
+
281
+ For desktop packages without an automatically registered command, use **Settings > General >
282
+ Command line tool > Install command**. To invoke the bundled ordinary Node CLI directly on macOS:
283
+
284
+ ```bash
285
+ "/Applications/Open-Science.app/Contents/Resources/node-runtime/node" \
286
+ "/Applications/Open-Science.app/Contents/Resources/backend/cli.mjs" start --no-open
287
+ ```
288
+
289
+ The native Settings controls own launcher installation/removal. `cli install`/`cli uninstall` over
290
+ the Node service are unavailable; npm owns standalone launchers. Reinstall historical Electron-as-Node
291
+ launchers in desktop Settings. AppImage launchers retain a private immutable backend/Node cache so
292
+ an independently started server survives the invocation's temporary mount. Existing ownership
293
+ receipts and unrelated executables remain protected.
294
+
295
+ ## Agent runtimes
296
+
297
+ List the supported Agent runtimes and inspect their readiness without exposing executable paths:
298
+
299
+ ```bash
300
+ open-science runtime list
301
+ open-science runtime list --json
302
+ ```
303
+
304
+ ## Upgrading installations
305
+
306
+ Stop the backend before upgrading an installation, then restart it with the same profile.
307
+ For a global npm installation:
308
+
309
+ ```bash
310
+ open-science stop
311
+ npm install --global @aipoch/open-science@latest
312
+ open-science start --no-open
313
+ ```
314
+
315
+ Stop every profile started by that installation before updating it; use `--config-root` for
316
+ custom profiles. To uninstall, stop those services and run
317
+ `npm uninstall --global @aipoch/open-science`. Research data and credentials are retained.
318
+ See [release compatibility](https://github.com/aipoch/open-science/blob/main/docs/compatibility.md)
319
+ before downgrading; reinstalling an older package does not undo data migrations.
320
+
321
+ Use the installation channel that owns the CLI: Homebrew for a Formula, the new downloaded
322
+ package for deb/rpm or a local npm tarball, or a verified new Release archive in a new directory
323
+ with PATH/the symlink updated.
324
+ The desktop update UI discovers and downloads packages. Automatic replacement remains closed for
325
+ macOS ZIP, Linux AppImage and Debian until each channel passes complete installed-package
326
+ acceptance. Windows automatic installation remains disabled; artifact checks and same-version copy tests do not certify a cross-version upgrade.
327
+ For an accepted channel, use the desktop application's native update UI. A Desktop
328
+ that adopts an orphaned Desktop-launched Runtime can stop it through the normal update gate.
329
+ For a CLI-launched service, explicitly confirm stopping the service and switching to Desktop;
330
+ all connected clients will disconnect, and future Desktop Quit stops the replacement Runtime.
331
+ Cancel keeps the service running. The switch preserves supported configuration and refuses
332
+ unsupported credential/profile settings before stopping. It does not upgrade standalone files.
333
+ Installation recovery may require the original installer when file integrity cannot be verified.
334
+
335
+ ## Codex subscription sign-in
336
+
337
+ Sign the Open-Science Codex profile in from a terminal without opening Settings:
338
+
339
+ ```bash
340
+ open-science codex login
341
+ ```
342
+
343
+ For first-run setup, start the daemon with `open-science start --no-open`. The command prepares
344
+ the managed runtime and app-owned provider, then runs native Codex OAuth device-code authentication. It prints a verification URL and one-time code in the current terminal; open the URL
345
+ on any browser-capable device, enter the code, and keep the terminal open until Codex reports
346
+ success. Credentials are written only to the app-owned
347
+ <code>codex-subscription/auth.json</code> profile.
348
+
349
+ The native login follows the profile's saved Network proxy mode. Manual uses the configured proxy,
350
+ Direct clears inherited proxy variables, and System uses the environment that launched the CLI.
351
+
352
+ When that profile already contains credentials, the command validates and registers them without
353
+ replacing them. Successful validation activates the initial provider; a different active provider is
354
+ never replaced. Start a
355
+ new device-code flow explicitly with:
356
+
357
+ ```bash
358
+ open-science codex login --force
359
+ ```
360
+
361
+ The login command is interactive and intentionally does not support <code>--json</code> or
362
+ <code>--jsonl</code>. Setup and readiness registration use the local daemon; the one-time code stays
363
+ in the terminal process. Already configured profiles can still sign in while the daemon is stopped,
364
+ but must repeat the command with an updated daemon running to register readiness. A running older daemon
365
+ without the bootstrap endpoint also permits this configured native-login path; it cannot register
366
+ provider readiness. An empty profile instead receives `bootstrap_unavailable` with an instruction to
367
+ update and restart the application. HTTP authorization failures do not trigger this fallback.
368
+
369
+ ### AppImage and Node startup
370
+
371
+ The desktop launcher starts ordinary Node. Chromium's `--no-sandbox` option is rejected by
372
+ `open-science start`; it is not a fallback for starting or updating this backend. Desktop
373
+ Chromium launch troubleshooting is separate from CLI service startup.
374
+
375
+ ## Projects
376
+
377
+ Create a project and list the projects available to task runs:
378
+
379
+ ```bash
380
+ open-science project create "Systematic review" \
381
+ --description "Evidence review workspace" \
382
+ --agent-context-file ./agent-context.md \
383
+ --json
384
+ open-science project list --json
385
+ ```
386
+
387
+ Commands that accept `--project` allow either a project ID or an exact project name. The CLI resolves
388
+ a unique display name to its ID before calling the Task API; use the ID when names are duplicated.
389
+
390
+ Project Agent Context contains persistent instructions that are added when Open-Science sets up an
391
+ agent Session. Supply it directly with `--agent-context <text>` or read multiline instructions from a
392
+ strict UTF-8 file with `--agent-context-file <path>`; the two options are mutually exclusive. The
393
+ existing 16,000-character limit applies to both forms.
394
+
395
+ Update Project metadata or replace its Agent Context later using an ID or exact name:
396
+
397
+ ```bash
398
+ open-science project update "Systematic review" \
399
+ --name "Evidence synthesis" \
400
+ --description "Updated evidence review workspace" \
401
+ --agent-context-file ./revised-agent-context.md \
402
+ --json
403
+
404
+ open-science project update <project-id> --clear-agent-context --json
405
+ ```
406
+
407
+ `--name` renames the Project and requires a non-empty value. `--clear-agent-context` is explicit so
408
+ an omitted option keeps the existing value. An update affects
409
+ newly created Sessions and provider Sessions that are set up again after the update. It does not
410
+ rebuild an already attached Session. Project list, create, and update output reports only the boolean
411
+ `hasAgentContext`; Agent Context contents are not returned through the public Task API or CLI output.
412
+
413
+ ### Project Session defaults
414
+
415
+ Inspect or update the configuration copied into each newly created Session:
416
+
417
+ ```bash
418
+ open-science project session-defaults show <project-id> --json
419
+ open-science project session-defaults update <project-id> \
420
+ --provider anthropic --model claude-sonnet-4-5 --reasoning-effort high \
421
+ --approval-profile auto --auto-review --memory --delegation allow \
422
+ --enable-compute-host ssh:cluster-a --compute-host ssh:cluster-a --json
423
+ ```
424
+
425
+ Updates use the Project's current `updatedAt` value as a compare-and-swap revision. They fail on a
426
+ concurrent Project edit instead of overwriting it. Use the corresponding `--clear-*` option to
427
+ remove an optional default, or `--clear-compute-hosts` to remove both enabled and selected Compute
428
+ Hosts. Omitted options are preserved.
429
+
430
+ The precedence for a new Session is explicit `run` options, then Project Session defaults, then
431
+ application settings, then the provider-owned default. Defaults are snapshotted into the new
432
+ Session; changing them never rewrites an existing Session.
433
+
434
+ ## Run a task
435
+
436
+ Provide a prompt directly, read it from a UTF-8 file, or pipe it through stdin:
437
+
438
+ ```bash
439
+ open-science run --project "Systematic review" --prompt "Summarize the evidence" --wait
440
+ open-science run --project <project-id> --prompt-file ./task.md --wait --json
441
+ open-science run --project <project-id> --cwd ./research --prompt-file ./task.md --wait --json
442
+ printf '%s\n' "Summarize the evidence" | open-science run --project <project-id> --wait --json
443
+ ```
444
+
445
+ Use repeatable `--compute-host <provider-id>` options to select Compute Host execution targets for
446
+ the Session:
447
+
448
+ ```bash
449
+ open-science run --project <project-id> --prompt-file ./task.md \
450
+ --compute-host ssh:cluster-a --compute-host ssh:cluster-b --wait --json
451
+ ```
452
+
453
+ On a new Session, `--enable-compute-host` adds Available hosts, `--compute-host` enables and selects
454
+ its explicit list, and `--clear-compute-hosts` overrides Project defaults with empty Enabled and
455
+ Selected lists. With `--session`, `--compute-host` replaces the selected target pool and enables any
456
+ newly named hosts without disabling other Available hosts. Existing-Session runs reject
457
+ `--enable-compute-host` and `--clear-compute-hosts`; use `session config update` for those access
458
+ changes. Omitting every Compute Host option preserves both access and selection. SDK and Task API
459
+ callers can explicitly send an empty `computeHostIds` array to clear Selected while preserving
460
+ Enabled hosts. JSON output uses the server's compatibility-named
461
+ `preferredComputeHostIds` authority result, not a copy inferred from the command line.
462
+
463
+ When the selection is non-empty, the agent is instructed to run tool-backed task work on one of
464
+ those hosts and not silently fall back to local execution or another Available Compute Host. Pure answers
465
+ and lightweight orchestration do not require remote execution. Each provider ID must refer to a
466
+ host already configured in Open-Science. This option does not create a host, configure SSH or
467
+ credentials, probe a connection, or pin scratch storage.
468
+
469
+ `--cwd <path>` selects an externally owned working directory for the Session. The CLI resolves a
470
+ relative path from the directory where the command is invoked. Open-Science then resolves the real
471
+ path, verifies that it exists, is a directory, and is readable and writable, and persists that
472
+ canonical path on a newly created Session. Open-Science does not take ownership of or remove an
473
+ external working directory. Without `--cwd`, Open-Science allocates its usual managed workspace.
474
+
475
+ The working directory is a Session boundary, not a per-Run override. When `--session` and `--cwd`
476
+ are used together, the requested path must resolve to the Session's recorded working directory. A
477
+ different, missing, or otherwise invalid recorded directory is rejected; it is not migrated,
478
+ replaced, or repaired by the Run request.
479
+
480
+ Without `--wait`, the command returns as soon as the run starts. Use the returned `id` and `sessionId`
481
+ to poll its state:
482
+
483
+ ```bash
484
+ open-science run --project <project-id> --prompt-file ./task.md --json
485
+ open-science run status <run-id> --json
486
+ open-science run cancel <run-id> --json
487
+ open-science session status <session-id> --json
488
+ ```
489
+
490
+ Use `--timeout-ms <milliseconds>` with `--wait` to bound how long the client waits. A timeout stops the
491
+ CLI wait and returns exit code `1`; it does not cancel the run, which can still be inspected with
492
+ `open-science run status <run-id>`. Add `--cancel-on-timeout` to explicitly cancel the server run after
493
+ the timeout; the command still reports the original timeout and returns exit code `1`. Explicit
494
+ cancellation waits for provider work and application finalization to drain, and preserves partial
495
+ output and successfully finalized artifacts. When the `ask` approval profile needs permission,
496
+ human-readable output directs the user to approve the request in Open-Science Desktop or the Web UI.
497
+
498
+ Pass an existing session ID to continue a conversation. Approval profiles are `ask`, `auto`, and
499
+ `full`; `--skill` is repeatable:
500
+
501
+ ```bash
502
+ open-science run \
503
+ --project <project-id> \
504
+ --session <session-id> \
505
+ --prompt-file ./follow-up.md \
506
+ --approval-profile auto \
507
+ --skill literature-review \
508
+ --skill citation-check \
509
+ --wait \
510
+ --json
511
+ ```
512
+
513
+ For a new Session, an explicit approval profile overrides Project Session defaults, then the saved global
514
+ default; only when all are absent does it fall back to `ask`. Resumed Sessions retain their saved profile unless explicitly changed. For unattended execution, explicitly add
515
+ `--permission-prompts none`. This keeps the selected approval profile and existing grants;
516
+ it denies any remaining request that would require a person. `auto` can still require approval,
517
+ and `full` does not answer questions or approve Plans on the user's behalf.
518
+
519
+ ```bash
520
+ open-science run --project <project-id> --prompt-file ./task.md \
521
+ --approval-profile auto --permission-prompts none --wait --jsonl
522
+ ```
523
+
524
+ This option applies only to this Run and its delegated work. It is not a saved Session or Project
525
+ preference. Ordinary questions are declined, and generating a Plan that requires approval is
526
+ rejected; combining it with `--plan-first` fails before starting work. The agent can use an already
527
+ authorized alternative or report that it could not finish. A completed Run means the agent finished
528
+ its turn, not that every requested operation succeeded. JSONL events include declined tool results;
529
+ inspect those and the final output when deciding whether the task achieved its goal.
530
+
531
+ The CLI checks host support before starting an unattended Run. An older daemon without the
532
+ `permission-prompts-none` capability returns `unsupported_capability`; update the host rather than
533
+ silently running a task that might wait for a person. Omitting the option retains existing behavior,
534
+ including Desktop/Web approval for unresolved ordinary permissions. There are no ordinary
535
+ `permission list/show/approve` CLI commands. `--return-on-attention` only covers Plan approval.
536
+
537
+ ### Execution controls
538
+
539
+ The run command exposes five provider-neutral controls:
540
+
541
+ ```bash
542
+ open-science run \
543
+ --project "Systematic review" \
544
+ --prompt-file ./task.md \
545
+ --plan-first \
546
+ --auto-review \
547
+ --memory \
548
+ --specialist literature-reviewer \
549
+ --delegation deny \
550
+ --wait \
551
+ --return-on-attention \
552
+ --json
553
+ ```
554
+
555
+ - `--plan-first` marks this turn as Plan First. The Run remains running while its generated Plan
556
+ waits for an explicit response.
557
+ - `--auto-review` and `--no-auto-review` update the Session automatic-review setting. When enabled, a
558
+ successful turn starts the existing reviewer workflow before the Run becomes terminal; the Run
559
+ `review` property reports whether it started and its final lifecycle/outcome.
560
+ - `--memory` and `--no-memory` set Memory for a new Session; the two flags are mutually exclusive.
561
+ With `--session`, provider/model/reasoning, Memory and enabled Compute Host changes are rejected.
562
+ Use `session config update` on the idle Session before resuming it.
563
+ - `--specialist` accepts a Specialist UUID or stable Profile name. It binds only a new Session. An
564
+ existing Session cannot be rebound, and a presentation `displayName` is not an identifier.
565
+ - `--delegation allow|deny` updates whether the Session may create new delegated children. `deny`
566
+ does not cancel, hide, or prevent collection/messaging of children admitted earlier.
567
+
568
+ Ordinary `--wait` retains its terminal-only behavior. Add `--return-on-attention` to return a
569
+ still-running Run when its Plan needs approval. Plan approval is the only structured Run attention
570
+ in this release; permission and delegated-question events do not cause an attention return.
571
+
572
+ Inspect and respond to an active Plan with its exact version and revision:
573
+
574
+ ```bash
575
+ open-science plan show <session-id> --json
576
+ open-science plan approve <session-id> --artifact-version <id> --revision <number> --json
577
+ open-science plan reject <session-id> --artifact-version <id> --revision <number> --json
578
+ open-science plan revise <session-id> --feedback "Split the validation step" --json
579
+ ```
580
+
581
+ Version/revision matching prevents a stale automation client from deciding a newer Plan. Approval
582
+ persists the exact decision and triggers a one-time Agent wakeup; feedback asks the live Plan
583
+ interaction for a revision.
584
+
585
+ ## Session configuration
586
+
587
+ Read the persisted and effective configuration, including referenced provider, model, Specialist,
588
+ and Compute Host availability:
589
+
590
+ ```bash
591
+ open-science session config show <session-id> --json
592
+ ```
593
+
594
+ Update an idle Session with the revision returned by `show`:
595
+
596
+ ```bash
597
+ open-science session config update <session-id> --revision 7 \
598
+ --provider openai --provider-default-model --reasoning-effort medium \
599
+ --approval-profile ask --no-auto-review --memory --delegation deny \
600
+ --clear-compute-hosts --json
601
+ ```
602
+
603
+ The Main provider, model, and reasoning effort are one compound configuration. A provider change
604
+ must therefore include either `--model` or `--provider-default-model`. An update affects future
605
+ turns only and is rejected while root-agent, subagent, or Notebook work is active. Reviewer work
606
+ does not block the update. Stale revisions fail with `session_revision_conflict`; invalid or
607
+ unavailable references fail with `invalid_configuration`.
608
+
609
+ ## Agent routing settings
610
+
611
+ Inspect or atomically update the global Agent framework plus Reviewer and Subagent model routing:
612
+
613
+ ```bash
614
+ open-science settings agent-routing show --json
615
+ open-science settings agent-routing update --framework codex \
616
+ --reviewer-provider openai --reviewer-model gpt-5 \
617
+ --subagent-inherit --json
618
+ ```
619
+
620
+ Use `--reviewer-inherit` or `--subagent-inherit` to follow the applicable Main model. Fixed routes
621
+ require both provider and model; reasoning effort is optional. The command validates all three
622
+ settings against the target framework before saving them together. It returns identifiers and
623
+ availability only, never provider credentials.
624
+
625
+ A framework change applies to new Sessions and future Reviewer work. Existing idle Sessions migrate
626
+ lazily on their next turn, replaying their visible transcript when a fresh provider Session is
627
+ needed. In-flight Main, Reviewer, and Subagent work remains pinned to the runtime generation and
628
+ model snapshot admitted at its start. In Reviewer inherit mode, admission freezes the model name;
629
+ the provider is resolved when the Reviewer session is created. Fixed Reviewer routing freezes its
630
+ explicit provider/framework target. Reviewer and Subagent route changes affect future work.
631
+
632
+ ### Session persistence and compatibility
633
+
634
+ Session configuration continues to use the Session JSON authority; it does not add a Session
635
+ schema migration:
636
+
637
+ - Session JSON stores `delegationPolicy` with values `allow` or `deny`. Historical Session files
638
+ that omit it, and malformed values, restore as `allow`.
639
+ - autoReviewEnabled and specialistId already existed and are reused. Historical
640
+ autoReviewEnabled omissions remain disabled; an omitted specialistId remains Main Agent.
641
+ - Plan artifacts, persisted approval, active context, and delivery receipts remain under
642
+ runtimeContext.plan. The originating Conversation Turn remains the Plan owner; related later
643
+ ordinary or application Attempts on the same durable Message Branch receive it as active context
644
+ without taking ownership. Delegated attempts, messages, and questions remain under
645
+ runtimeContext.delegatedWork.
646
+
647
+ Project Session defaults add one `sessionDefaults` JSON-text column to the Project table. Existing
648
+ rows migrate to `{}` and therefore retain prior behavior. Agent routing reuses the existing Settings
649
+ JSON fields.
650
+
651
+ No persistent Session status enum value is added. Existing waiting-plan-approval remains the
652
+ durable Session status, while a public Run remains running and carries an attention discriminant.
653
+ Plan delivery receipts may persist `accepted` after the provider boundary so restart recovery can
654
+ settle that one-shot wakeup without replaying it.
655
+
656
+ ## Machine-readable output
657
+
658
+ Use `--json` to emit one result. `--jsonl` requires `run --wait` and emits progress events followed by
659
+ the final run object, one JSON value per line:
660
+
661
+ Every Run object includes its effective `cwd`; progress events and Session summaries do not.
662
+
663
+ The event stream includes `run.progress` phase changes and ten-second liveness heartbeats before the
664
+ first visible provider output. Each progress payload includes `runId`, `sessionId`, `projectId`,
665
+ `phase`, `timestamp`, `elapsedMs`, and `heartbeat`. Its timer starts after Task has prepared the
666
+ Session and registered its Run; Session creation or resume time before registration is outside this
667
+ stream. Every emitted Run event also carries top-level `sequence`, `runId`, `sessionId`, and
668
+ `projectId` fields. The client reconnects with its last sequence after an unexpected disconnect. If
669
+ the bounded, process-local replay suffix is unavailable, JSON Lines output includes a
670
+ `stream.resync-required` control event and final Run state still comes from the Task HTTP API.
671
+
672
+ ```bash
673
+ open-science run \
674
+ --project <project-id> \
675
+ --prompt-file ./task.md \
676
+ --approval-profile auto \
677
+ --wait \
678
+ --jsonl
679
+ ```
680
+
681
+ `--json` and `--jsonl` cannot be used together. Structured errors use this shape:
682
+
683
+ ```json
684
+ { "error": { "code": "invalid_cli_usage", "message": "--project is required." }, "exitCode": 2 }
685
+ ```
686
+
687
+ Exit codes form part of the automation contract:
688
+
689
+ | Exit code | Meaning |
690
+ | --------- | ----------------------------------------------------------------------------- |
691
+ | `0` | The command succeeded, including a completed waited run. |
692
+ | `1` | A run failed, status found no service, or a general command failure occurred. |
693
+ | `2` | CLI usage was invalid. |
694
+ | `3` | The local daemon was unavailable. |
695
+ | `4` | A requested project, run, session, artifact, or Specialist was not found. |
696
+
697
+ Codex login can propagate the native login process exit code (a signal without a code becomes `1`).
698
+ A successfully cancelled Run is not itself a CLI failure; inspect its `cancelled` status.
699
+
700
+ Timeouts and `session_busy` conflicts use exit code `1` and retain their distinct `timeout` and
701
+ `session_busy` error codes in structured output.
702
+
703
+ ## Artifacts
704
+
705
+ List the artifacts produced for a session and download one by ID:
706
+
707
+ ```bash
708
+ open-science artifacts list <session-id> --json
709
+ open-science artifacts download <artifact-id> --output ./report.md --json
710
+ ```
711
+
712
+ Artifact output paths are resolved relative to the current working directory.
713
+
714
+ ## Current scope
715
+
716
+ The CLI does not expose file/directory attachments or per-run Agent framework selection.
717
+ New Sessions accept provider/model selection; resumed Sessions use `session config update`.
718
+ The help listing still includes `cli install`, but the Node host cannot perform this desktop-only
719
+ operation. Use Settings in the desktop application to install a desktop launcher.
720
+
721
+ ## Connector management
722
+
723
+ Connector commands use the running backend and the same saved Settings as the desktop and web UI.
724
+ Use `--config-root` to select the intended instance. Custom MCP and credential mutations require a
725
+ local authenticated connection; run the CLI on the server itself, including through SSH.
726
+
727
+ ```sh
728
+ open-science connector list --json
729
+ open-science connector show context7 --json
730
+ open-science connector enable context7
731
+ open-science connector disable context7
732
+ open-science connector add --json < connector.json
733
+ open-science connector update context7 --json < connector-update.json
734
+ open-science connector remove context7
735
+ open-science connector test context7 --json
736
+ ```
737
+
738
+ `add` reads an object with `name`, `displayName`, `transport`, and `command` (stdio) or `url`
739
+ (`streamable_http` or `sse`). Optional fields include `args`, `description`, `envCredentialIds`,
740
+ `headerCredentialIds`, and `oauthCredentialId`. Names and IDs remain stable on update. `update`
741
+ requires `transport`; omitted credential bindings retain their saved values. Use an empty binding
742
+ object to clear environment/header bindings. Only custom MCP Connectors can be added, edited, or removed.
743
+
744
+ ```json
745
+ {
746
+ "name": "context7",
747
+ "displayName": "Context7",
748
+ "transport": "streamable_http",
749
+ "url": "https://mcp.example.test/mcp"
750
+ }
751
+ ```
752
+
753
+ `list` and `show` expose safe Settings views, not raw credential material. `enabled` is a selection
754
+ preference, not proof of connectivity or a global revocation of Specialist access. `availability`,
755
+ `checking`, credential-presence fields, and `skillProjectionStatus` retain their Settings meanings.
756
+ Changes reuse existing agent refresh behavior. Start a new session if its tool list remains unchanged;
757
+ these commands do not force-reset active conversations.
758
+
759
+ `test` opens a separate MCP connection, discovers tools, and closes it. It does not enable a disabled
760
+ Connector or execute business tools. Its result is `{ success, toolCount?, message, stage?, code? }`; failure exits
761
+ nonzero. Discovery is bounded to ten seconds. Bundled Connector live diagnostics are unsupported.
762
+ OAuth refresh may update existing encrypted token state; testing does not perform first-time browser login.
763
+
764
+ ### Credentials
765
+
766
+ ```sh
767
+ open-science credential list --json
768
+ open-science credential add --json < credential.json
769
+ open-science credential update <credential-id> --json < credential-update.json
770
+ ```
771
+
772
+ Credential writes read JSON exclusively from stdin. Do not put secrets in command arguments or shell
773
+ history. Protect any input file and remove it when no longer needed. A token input has the shape
774
+ `{ "displayName": "Service token", "kind": "token", "secret": "..." }`; `api_key` is also supported.
775
+ The returned `createdCredential.id` can be bound in `envCredentialIds` or `headerCredentialIds`.
776
+ Updates accept `displayName` and/or `secret`. Existing OAuth registration can be created with `kind:
777
+ "oauth"`, `resourceUri`, remote `transport`, and an `oauth` registration object, then authenticated
778
+ through Settings. First-time browserless OAuth login is outside these commands.
779
+
780
+ Secrets use the OS-protected store by default. Linux headless deployments without a usable keyring
781
+ can explicitly opt into unencrypted local file storage:
782
+
783
+ ```sh
784
+ open-science start --credential-store=file --no-open
785
+ ```
786
+
787
+ Continue using the normal Settings forms and credential commands. The selected mode applies to new
788
+ and updated Settings-managed secrets: provider API keys and app-managed subscription tokens, GitHub
789
+ and literature keys, shared connector credentials, custom MCP secret environment/header values,
790
+ and Settings-managed OAuth client secrets and token state. Compute passwords and protected Compute
791
+ data keep their independent OS-storage requirement; external framework login stores keep their own
792
+ behavior. This flag does not disable any sandbox.
793
+
794
+ File mode reuses `settings.json` and `credentials.json` under the application's configuration root.
795
+ Secret refs use `file:v1:` followed by base64 **encoding, not encryption**. The existing atomic writer
796
+ creates files and temporary replacements with POSIX mode `0600`. Keep the configuration directory
797
+ private; anyone who can read these files can recover the secrets. Do not copy them into images,
798
+ repositories, logs, or support reports. A disposable container filesystem discards them when the
799
+ container is removed; a persistent volume retains them. A tmpfs mount can be used when disk
800
+ persistence is unwanted. Open-Science does not delete configuration automatically on shutdown.
801
+
802
+ Specify the option at every startup, including after updates. It is a startup choice, not a saved
803
+ preference. The default (or `--credential-store=os`) requires OS protection. An already-running
804
+ backend rejects explicit mode selection: stop it before restarting with the desired option. File
805
+ mode is supported only by the Linux headless backend, not desktop launches or macOS/Windows.
806
+
807
+ Legacy `plain:` refs remain readable in explicit file mode without rewriting them.
808
+ Existing encrypted refs are not automatically migrated or downgraded. They still require the original
809
+ OS vault to read, even in file mode; otherwise re-enter the credential. New/refreshed values saved in
810
+ file mode use the file format. File refs require explicit file mode to read and are unreadable by
811
+ older releases. To switch a file credential back to OS storage, restart in OS mode and explicitly
812
+ replace it with the key while the vault is available. Existing unreadable records remain intact.
813
+ These commands do not migrate historical configuration or store diagnostic history. Older backends that
814
+ lack the endpoints return an endpoint error; the CLI never falls back to editing Settings files directly.