@drisp/cli 0.5.28 → 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 CHANGED
@@ -50,7 +50,7 @@ and model preferences. The runtime handles the rest.
50
50
 
51
51
  **Harness-agnostic** -- same workflows, same UI, same session model across Claude Code and Codex.
52
52
 
53
- **CI-native** -- `drisp exec` runs headlessly with safe defaults, JSONL output, and structured exit codes.
53
+ **CI-native** -- `drisp run` runs headlessly with safe defaults, JSONL output, and structured exit codes.
54
54
 
55
55
  <br>
56
56
 
@@ -126,19 +126,29 @@ drisp workflow install e2e-test-builder@lespaceman/athena-workflow-marketplace
126
126
 
127
127
  ## CI / Automation
128
128
 
129
- `drisp exec` is built for pipelines. Safe by default -- permission and question hooks fail unless you opt in.
129
+ `drisp run` is built for pipelines. Safe by default -- permission and question hooks fail unless you opt in.
130
+
131
+ ### Permissions with no hub attached
132
+
133
+ drisp has a single door. A permission request or a question is answered by whoever is attached to the Run: the interactive terminal, or a paired dashboard delivering decisions. With no hub attached (a headless `drisp run` with no dashboard paired) there is nobody to ask, so under `guarded` and `standard` the request **waits**: the Run holds on the pending decision, and nothing is auto-approved or auto-denied on its behalf. The hold ends one of two ways. If you set `--timeout-ms`, the run exits with the timeout exit code when it expires. If the Run belongs to a workflow, the request is **held, then parked, then replayed**:
134
+
135
+ - **Hold.** A permission request no rule answers is held for the **grace window** — `permissionGraceMs` in `~/.config/athena/config.json` or `.athena/config.json` (project wins), `--permission-grace-ms` per run, default 60 000 ms — so an attached hub can answer it. With no hub attached there is nobody to wait for, and the request is deferred at once.
136
+ - **Park.** When the window elapses unanswered, the tool call is refused with a _deferred_ result, the Turn ends, and the Run parks in `awaiting_attention` with the request recorded — its id, the tool, and a one-line input summary — in the Journal and on the run record. `drisp runs` shows the pending question and the hub receives it as a `needs_human` frame.
137
+ - **Replay.** `drisp run --continue=<session> --answer=allow|deny "<reply>"` (or an `answer` the hub sends while the Run is parked) stores the answer against that request. On continue the agent re-issues the same call and the stored answer is replayed into it without a prompt; without one, the request is held again. See [human resume](docs/guides/human-resume.md).
138
+
139
+ **`--isolation autonomous` runs with nobody watching.** A permission prompt that no **ask rule** claims is answered _allow_ by the preset's policy, within the tool surface the preset already grants, and the workflow runs to `WORKFLOW_COMPLETE`. Exactly two things park the Run as needs-human: an ask rule that fires, or a Turn that ends on `<!-- NEEDS_HUMAN: reason -->`. Ask rules are a provisional, per-workflow list of tool-name patterns in `workflow.json` whose prompts must always reach a person — `"askRules": ["Bash", "mcp__github__*"]` — and a parked Run shows in `drisp runs` as **Parked** with the rule that fired (or the marker's reason); `drisp run --continue` wakes it.
130
140
 
131
141
  ```bash
132
- drisp exec "summarize risk in this PR" # plain text
133
- drisp exec "run checks" --json --on-permission=deny --on-question=empty # JSONL
134
- drisp exec "write release notes" --output-last-message release-notes.md # artifact
142
+ drisp run "summarize risk in this PR" # plain text
143
+ drisp run "run checks" --json --on-permission=deny --on-question=empty # JSONL
144
+ drisp run "write release notes" --output-last-message release-notes.md # artifact
135
145
  ```
136
146
 
137
147
  <details>
138
148
  <summary>GitHub Actions</summary>
139
149
 
140
150
  ```yaml
141
- name: drisp-exec
151
+ name: drisp-run
142
152
  on: [pull_request]
143
153
  jobs:
144
154
  drisp:
@@ -149,7 +159,7 @@ jobs:
149
159
  with:
150
160
  node-version: 20
151
161
  - run: npm ci
152
- - run: npx @drisp/cli exec "summarize risk in this PR" \
162
+ - run: npx @drisp/cli run "summarize risk in this PR" \
153
163
  --json --on-permission=deny --on-question=empty \
154
164
  --output-last-message drisp-summary.md
155
165
  - uses: actions/upload-artifact@v4
@@ -164,11 +174,11 @@ jobs:
164
174
  <summary>GitLab CI</summary>
165
175
 
166
176
  ```yaml
167
- drisp_exec:
177
+ drisp_run:
168
178
  image: node:20
169
179
  script:
170
180
  - npm ci
171
- - npx @drisp/cli exec "summarize pipeline status" \
181
+ - npx @drisp/cli run "summarize pipeline status" \
172
182
  --json --on-permission=deny --on-question=empty \
173
183
  --output-last-message drisp-summary.md
174
184
  artifacts:
@@ -181,20 +191,48 @@ drisp_exec:
181
191
  <details>
182
192
  <summary>Exit codes</summary>
183
193
 
184
- | Code | Meaning |
185
- | ---- | --------------------------------- |
186
- | `0` | Success |
187
- | `2` | Usage / validation error |
188
- | `3` | Bootstrap / configuration failure |
189
- | `4` | Runtime / process failure |
190
- | `5` | Non-interactive policy failure |
191
- | `6` | Timeout exceeded |
192
- | `7` | Output write failure |
194
+ | Code | Meaning |
195
+ | ---- | ----------------------------------------------------------------------- |
196
+ | `0` | Execution returned; check workflow outcome for completion or suspension |
197
+ | `2` | Usage / validation error |
198
+ | `3` | Bootstrap / configuration failure |
199
+ | `4` | Runtime / process failure |
200
+ | `5` | Reserved legacy policy code (no longer emitted) |
201
+ | `6` | Timeout exceeded |
202
+ | `7` | Output write failure |
193
203
 
194
204
  </details>
195
205
 
196
206
  <br>
197
207
 
208
+ ## Runner
209
+
210
+ `drisp runner` is the one long-lived process that pairs a machine with the hub, receives its Runs over the instance socket, and executes them. The instance socket is the default delivery path. Assignments can also request a per-run callback socket and artifact uploads; see the [delivery contract](docs/execution-contract.md#compatibility-and-delivery).
211
+
212
+ ```bash
213
+ drisp runner pair <token> --url https://hub.example.com # pair, then start the runner in the background
214
+ drisp runner # run it in the foreground (Ctrl-C stops it)
215
+ drisp runner --detach # start it in the background
216
+ drisp runner status # pairing, process, socket, token — non-zero on any unhealthy axis
217
+ drisp runner runs --active # the Runs it has handled
218
+ drisp runner logs --follow # tail its log
219
+ drisp runner stop # SIGTERM to the pid in runner.pid
220
+ drisp runner install # launchd / systemd unit so it starts on login
221
+ ```
222
+
223
+ A second `drisp runner` on the same machine exits non-zero with `already running (pid N)`. Its state lives in `~/.local/state/drisp/`:
224
+
225
+ | File | What it is |
226
+ | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
227
+ | `runner.pid` | Liveness and the single-instance lock. |
228
+ | `runner.status.json` | The runner's snapshot (socket, wire mode, active and recent Runs), rewritten on change; what `status` and `runs` read. Removed on a clean stop. |
229
+ | `runner.db` | One SQLite database: the feed outbox the runner drains to the hub and the decision inbox the hub's answers wait in. A runner killed mid-Run drains and re-delivers both on restart. |
230
+ | `runner.log` | The rotating log. |
231
+
232
+ `drisp dashboard <sub>` is a deprecated alias of `drisp runner` for one release (`dashboard daemon start` is `runner --detach`; `daemon foreground` / `connect` is bare `runner`). The pre-0.6 `dashboard-feed-outbox.db` and `dashboard-decision-inbox.db` are imported into `runner.db` on the first start and removed.
233
+
234
+ <br>
235
+
198
236
  ## Configuration
199
237
 
200
238
  Config merges in order: **global &rarr; project &rarr; CLI flags**.
@@ -216,41 +254,42 @@ Config merges in order: **global &rarr; project &rarr; CLI flags**.
216
254
  <details>
217
255
  <summary>CLI flags</summary>
218
256
 
219
- | Flag | Description |
220
- | --------------- | --------------------------------------------- |
221
- | `--project-dir` | Project directory (default: cwd) |
222
- | `--plugin` | Path to a plugin directory (repeatable) |
223
- | `--isolation` | `strict` (default) · `minimal` · `permissive` |
224
- | `--theme` | `dark` (default) · `light` · `high-contrast` |
225
- | `--ascii` | ASCII-only UI glyphs |
226
- | `--verbose` | Extra rendering detail |
227
-
228
- **exec-only:**
229
-
230
- | Flag | Description |
231
- | ----------------------- | ------------------------------------------------------ |
232
- | `--continue` | Resume most recent exec session (or `--continue=<id>`) |
233
- | `--json` | JSONL lifecycle events on stdout |
234
- | `--output-last-message` | Write final assistant message to a file |
235
- | `--ephemeral` | Disable session persistence for this run |
236
- | `--on-permission` | `allow` · `deny` · `fail` (default) |
237
- | `--on-question` | `empty` · `fail` (default) |
238
- | `--timeout-ms` | Hard timeout for the run |
257
+ | Flag | Description |
258
+ | --------------- | ----------------------------------------------- |
259
+ | `--project-dir` | Project directory (default: cwd) |
260
+ | `--plugin` | Path to a plugin directory (repeatable) |
261
+ | `--isolation` | `guarded` (default) · `standard` · `autonomous` |
262
+ | `--theme` | `dark` (default) · `light` · `high-contrast` |
263
+ | `--ascii` | ASCII-only UI glyphs |
264
+ | `--verbose` | Extra rendering detail |
265
+
266
+ **run-only:**
267
+
268
+ | Flag | Description |
269
+ | ----------------------- | ----------------------------------------------------- |
270
+ | `--continue` | Resume most recent run session (or `--continue=<id>`) |
271
+ | `--steer` | Queue a human steer for the next Turn (repeatable) |
272
+ | `--json` | JSONL lifecycle events on stdout |
273
+ | `--output-last-message` | Write final assistant message to a file |
274
+ | `--ephemeral` | Disable session persistence for this run |
275
+ | `--on-permission` | `allow` · `deny` · `fail` (default) |
276
+ | `--on-question` | `empty` · `fail` (default) |
277
+ | `--timeout-ms` | Hard timeout for the run |
239
278
 
240
279
  </details>
241
280
 
242
281
  <details>
243
282
  <summary>Commands</summary>
244
283
 
245
- | Command | Description |
246
- | ------------------- | ------------------------------------------------------------ |
247
- | _(default)_ | Start interactive session in cwd |
248
- | `setup` | Re-run setup wizard |
249
- | `sessions` | Interactive session picker |
250
- | `resume [id]` | Resume most recent or specific session |
251
- | `exec "<prompt>"` | Headless run for CI / scripting |
252
- | `workflow <sub>` | `install` · `list` · `search` · `remove` · `upgrade` · `use` |
253
- | `marketplace <sub>` | `add` · `refresh` · `remove` · `list` |
284
+ | Command | Description |
285
+ | ------------------- | -------------------------------------------------------------- |
286
+ | _(default)_ | Start interactive session in cwd |
287
+ | `setup` | Re-run setup wizard |
288
+ | `sessions` | Interactive session picker |
289
+ | `resume [id]` | Resume most recent or specific session |
290
+ | `run "<prompt>"` | Headless run for CI / scripting (`exec` is a deprecated alias) |
291
+ | `workflow <sub>` | `install` · `list` · `search` · `remove` · `upgrade` · `use` |
292
+ | `marketplace <sub>` | `add` · `refresh` · `remove` · `list` |
254
293
 
255
294
  </details>
256
295
 
@@ -284,3 +323,5 @@ Commit the output so others can build without the generator.
284
323
  ## License
285
324
 
286
325
  [MIT](LICENSE)
326
+
327
+ For a plain-English source map, see the [architecture diagrams](docs/drisp-architecture.md). The [execution contract](docs/execution-contract.md) explains continuation, configuration precedence, failures, and contributor checks.
@@ -1,14 +1,15 @@
1
1
  import {
2
2
  McpOptionsStep,
3
3
  StepStatus
4
- } from "./chunk-2HR7FV3M.js";
4
+ } from "./chunk-KPDCVR6Q.js";
5
5
  import {
6
6
  collectMcpServersWithOptions,
7
7
  installWorkflowFromSource,
8
8
  installWorkflowPlugins,
9
9
  resolveWorkflow,
10
10
  writeGlobalConfig
11
- } from "./chunk-2QV7YSX6.js";
11
+ } from "./chunk-QVRTU2MM.js";
12
+ import "./chunk-PZ5AY32C.js";
12
13
 
13
14
  // src/setup/steps/WorkflowInstallWizard.tsx
14
15
  import { useState, useEffect, useCallback, useRef } from "react";
@@ -92,4 +93,4 @@ function WorkflowInstallWizard({ source, onDone }) {
92
93
  export {
93
94
  WorkflowInstallWizard as default
94
95
  };
95
- //# sourceMappingURL=WorkflowInstallWizard-7OSOOVS2.js.map
96
+ //# sourceMappingURL=WorkflowInstallWizard-JLB7P37Y.js.map
@@ -0,0 +1,56 @@
1
+ import {
2
+ startRunnerProcess
3
+ } from "./chunk-PMRYQUBV.js";
4
+
5
+ // src/app/entry/runnerDaemon.ts
6
+ import path from "path";
7
+ import { fileURLToPath } from "url";
8
+ async function runRunnerDaemonEntry() {
9
+ if (startedViaDeprecatedEntry()) {
10
+ process.stderr.write(
11
+ 'drisp runner: started through the deprecated drisp-dashboard-daemon entry (removed in 0.7.0); run "drisp runner install" to refresh the service unit.\n'
12
+ );
13
+ }
14
+ let runner;
15
+ try {
16
+ runner = await startRunnerProcess();
17
+ } catch (err) {
18
+ process.stderr.write(
19
+ `drisp runner: ${err instanceof Error ? err.message : String(err)}
20
+ `
21
+ );
22
+ return 1;
23
+ }
24
+ const reason = await new Promise((resolve) => {
25
+ const onSignal = (signal) => {
26
+ process.off("SIGINT", onSignal);
27
+ process.off("SIGTERM", onSignal);
28
+ resolve(signal);
29
+ };
30
+ process.on("SIGINT", onSignal);
31
+ process.on("SIGTERM", onSignal);
32
+ });
33
+ await runner.stop(reason);
34
+ return 0;
35
+ }
36
+ function startedViaDeprecatedEntry() {
37
+ try {
38
+ return path.basename(fileURLToPath(import.meta.url)).startsWith("dashboard-daemon");
39
+ } catch {
40
+ return false;
41
+ }
42
+ }
43
+ if (process.argv.includes("--help")) {
44
+ process.stdout.write(
45
+ 'Usage: drisp-runner\n\nStarts the paired runner service. Use "drisp runner" to pair, install, inspect, or stop it.\n'
46
+ );
47
+ } else {
48
+ void runRunnerDaemonEntry().then((code) => {
49
+ process.exit(code);
50
+ });
51
+ }
52
+
53
+ export {
54
+ runRunnerDaemonEntry
55
+ };
56
+ //# sourceMappingURL=chunk-GMB4EJLK.js.map
@@ -499,4 +499,4 @@ export {
499
499
  StepStatus,
500
500
  McpOptionsStep
501
501
  };
502
- //# sourceMappingURL=chunk-2HR7FV3M.js.map
502
+ //# sourceMappingURL=chunk-KPDCVR6Q.js.map