@mrciphersmith/keryx 0.2.154 → 0.2.156
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 +133 -17
- package/dist/cli.js +37882 -26212
- package/dist/core.js +1490 -803
- package/dist/proxy-worker.js +338 -63
- package/package.json +2 -2
- package/src/gdskills/bundled/rules/core/definition-of-done.mdc +3 -1
- package/src/gdskills/bundled/skills/orchestration/flow-orchestrator/SKILL.md +4 -4
- package/src/gdskills/bundled/skills/platform/scheduled-tasks/SKILL.md +96 -0
package/README.md
CHANGED
|
@@ -32,6 +32,11 @@ It also ships **an agent runtime of its own**, built directly on that context:
|
|
|
32
32
|
durable sessions, an allow/ask/deny policy engine, kernel-enforced sandboxing,
|
|
33
33
|
child agents and evidence-gated completion. Keep using Codex, Claude or Cursor,
|
|
34
34
|
run `keryx shell`, or do both — they all read the same project brain.
|
|
35
|
+
You can delegate the work, not the responsibility: a managed flow freezes its
|
|
36
|
+
acceptance criteria before the work starts, lets them change only through a
|
|
37
|
+
recorded update with a reason, and completes only when every one is confirmed
|
|
38
|
+
against recorded evidence — under a named owner, with every confirmation and
|
|
39
|
+
the completion itself signed.
|
|
35
40
|
|
|
36
41
|
```bash
|
|
37
42
|
npm install -g @mrciphersmith/keryx
|
|
@@ -253,19 +258,55 @@ What is in it today:
|
|
|
253
258
|
over stdio — so an ACP client (an editor, typically) can launch keryx as a
|
|
254
259
|
subprocess, open a session bound to a project, and drive a real harness turn
|
|
255
260
|
with streamed `session/update` notifications instead of one dump at the end.
|
|
261
|
+
The session gets keryx's own read-only project tools — graph, wiki, memory,
|
|
262
|
+
flow status, skills, repo map, related tests, health status and
|
|
263
|
+
`search_code` — wherever `keryx shell` would offer them (same gate, same
|
|
264
|
+
definitions), alongside file reads, `shell_exec` and `apply_patch`; web
|
|
265
|
+
tools, keryx's own MCP servers, subagents and bus tools are left out on
|
|
266
|
+
purpose. keryx advertises the commands it handles over ACP — `/help`,
|
|
267
|
+
`/model`, `/reasoning`, `/status` — and answers them itself. The model is
|
|
268
|
+
the editor's model picker (a `configOptions` entry of category `model`,
|
|
269
|
+
listing what keryx can run here): switch it there or with `/model`, and it
|
|
270
|
+
applies from the next turn without touching `keryx shell`'s saved choice.
|
|
256
271
|
A gated tool call is asked through `session/request_permission` rather than
|
|
257
272
|
approved locally — only an explicit allow runs it, and an `allow_always`
|
|
258
273
|
answer is remembered by the client, never persisted by keryx — and
|
|
259
274
|
`session/cancel`, `session/list`, and `session/load` (replaying a session
|
|
260
275
|
created anywhere, including one from `keryx shell`) are all implemented.
|
|
261
|
-
|
|
276
|
+
With no `--provider`/`--model` a session starts on the provider and model
|
|
277
|
+
`keryx shell` saved (run `keryx shell` once and pick one); with nothing configured it
|
|
278
|
+
still answers `initialize` and refuses `session/new` with a message saying
|
|
279
|
+
what to configure — it never answers with a test stand-in. The client's own
|
|
280
|
+
stdio MCP servers from `mcpServers` are started for that session, their
|
|
281
|
+
tools offered through `search_tool`/`use_tool` with every call asked, one
|
|
282
|
+
running set shared by the threads that send the same list, and stopped when
|
|
283
|
+
the connection ends or `keryx acp` is sent SIGTERM/SIGINT; `http`/`sse` entries and a server that
|
|
284
|
+
fails to start are reported to the client by name, and the session still
|
|
285
|
+
opens. Writes and shell execution stay local unconditionally (no `fs/write_text_file`
|
|
262
286
|
or `terminal/*` calls, whatever the client advertises), and there is no
|
|
263
287
|
HTTP/WebSocket transport, no authentication over this wire, and no
|
|
264
|
-
`session/resume`/`close`/`delete`/`set_mode
|
|
265
|
-
against the published v1 schema and this repo's own scripted test client
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
288
|
+
`session/resume`/`close`/`delete`/`set_mode`. Verified
|
|
289
|
+
against the published v1 schema and this repo's own scripted test client;
|
|
290
|
+
Zed has been driven against it by hand, and no shipping IDE is part of the
|
|
291
|
+
automated tests. See [the CLI
|
|
292
|
+
reference](docs/docs/cli-reference.md#acp) for the full method table, the
|
|
293
|
+
tool roster and why each exclusion, the commands, and what keryx does when a
|
|
294
|
+
capability is absent.
|
|
295
|
+
- **ACP client — foreign agents under keryx's policy.** The other direction:
|
|
296
|
+
`keryx agents external run gemini-acp --task "…"` launches an external ACP
|
|
297
|
+
agent (Gemini CLI's `--experimental-acp`) as a subprocess and drives it as
|
|
298
|
+
its client, inside a disposable git worktree. keryx advertises only what it
|
|
299
|
+
serves (`fs.readTextFile`; `fs.writeTextFile` with `--write`; never
|
|
300
|
+
`terminal`), serves every `fs/*` request itself — confined by real path to
|
|
301
|
+
the worktree — and answers every `session/request_permission` through its
|
|
302
|
+
own approval gate with the mode lowered to `ask`: only an explicit allow
|
|
303
|
+
selects `allow_once`, `allow_always` is never chosen, and an unattended run
|
|
304
|
+
refuses anything that needs a human. The agent gets keryx's context as a
|
|
305
|
+
read-only `serve-mcp` launched from the running build, and every run is a
|
|
306
|
+
keryx session with its decisions, fs requests, usage and cost (or
|
|
307
|
+
`missing`). Honest limit: an agent's own internal tools never reach ACP, so
|
|
308
|
+
keryx cannot see or gate them — the disposable worktree is what contains
|
|
309
|
+
them. See the [ACP client guide](docs/docs/guides/acp-client.md).
|
|
269
310
|
- **Plans that survive the turn.** For multi-step work, the agent can keep a
|
|
270
311
|
structured execution plan in the session's own `plan.json` — beside the
|
|
271
312
|
transcript, not inside the Slate — so closing a Slate (or a Flow reporting
|
|
@@ -394,15 +435,86 @@ Grouped by what you are trying to do, not by internal module layout.
|
|
|
394
435
|
**Operate agents**
|
|
395
436
|
|
|
396
437
|
- **tasks** — an agent-first Task Manager driven by `keryx flow`, with frozen
|
|
397
|
-
acceptance criteria and status gates.
|
|
438
|
+
acceptance criteria and status gates. Each flow can name an accountable
|
|
439
|
+
human **owner** (`flow init --owner`/`flow owner set`, never inferred), and
|
|
440
|
+
`ac confirm`/`complete` append an honest, append-only **signature** — who
|
|
441
|
+
acted, when, and what was signed, with its basis (`stated`/`derived`/
|
|
442
|
+
`unknown`) stated rather than assumed. A flow can also require a
|
|
443
|
+
terminal-minted **confirmation token** (`flow init --require-confirmation`,
|
|
444
|
+
`flow confirm`) that no agent tool can mint. It adds friction for an agent
|
|
445
|
+
but does not prove a person was present. `flow recover` returns a flow left
|
|
446
|
+
in `completing` by an interrupted run. See
|
|
447
|
+
[TM-02](docs/decisions/keryx-harness/TM-02-flow-owner-and-signed-completion.md)
|
|
448
|
+
and [TM-03](docs/decisions/keryx-harness/TM-03-terminal-confirmation-token.md).
|
|
398
449
|
- **triggers** — declared automation over `.metaproject/triggers.json` (a
|
|
399
450
|
repository event or a cron/systemd schedule): `reconcile`/`rebuild` keep the
|
|
400
|
-
graph and wiki current, `open-flow
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
`
|
|
404
|
-
|
|
405
|
-
|
|
451
|
+
graph and wiki current, `open-flow` opens Task Manager work, and `flow-next`
|
|
452
|
+
either reports a flow's next task or — with a `dispatch` block — dispatches a
|
|
453
|
+
keryx agent to work it unattended: in a throwaway worktree on a
|
|
454
|
+
`trigger/<flow>-<task>` branch that is never pushed, its commands and its
|
|
455
|
+
health gate inside a mandatory hardened sandbox (network off, home and
|
|
456
|
+
credentials hidden, allow-listed environment), every would-be-approval
|
|
457
|
+
denied and recorded, spend reserved before the first model call, tokens and
|
|
458
|
+
USD recorded, and a per-trigger spend ceiling on top of the project-wide one.
|
|
459
|
+
`keryx trigger install` extends the same hook files `sync install-hooks` and
|
|
460
|
+
`update` already write into; `keryx trigger schedule` prints a cron line or
|
|
461
|
+
systemd unit pair (with a real `OnCalendar=`) and runs no daemon of its own. Triggered runs and a manual
|
|
462
|
+
`sync --apply`/`gdgraph build` share one maintenance lock (manual waits,
|
|
463
|
+
triggered refuses). In the TUI, the sidebar's **Triggers** section lists the
|
|
464
|
+
event-fired triggers. Each row shows the last outcome and its age, and a `NET`
|
|
465
|
+
marker when the agent gets the host network. The section also shows project
|
|
466
|
+
trigger spend and any open spend reservations. `/triggers` (or a click)
|
|
467
|
+
opens a list+detail modal with the full unattended posture. There, `r` then
|
|
468
|
+
`y` runs one now as `keryx trigger run <name>` in a child process of the same
|
|
469
|
+
build, bound by the same locks, budgets and refusals as the CLI. See the
|
|
470
|
+
[CLI reference](docs/docs/cli-reference.md#trigger).
|
|
471
|
+
- **schedule**: scheduled agent tasks in the background. Say it in the shell ("schedule a task every
|
|
472
|
+
4 hours to check my open PRs"), use `/schedule`, or run `keryx schedule add`. keryx shows a
|
|
473
|
+
**confirmation card** listing the cadence and next runs, the prompt, the runner and its budget,
|
|
474
|
+
the network mode, and every granted tool with the account it acts as. It also shows exactly what
|
|
475
|
+
will be installed. Nothing is written until you say yes. After that, keryx stores the schedule in a
|
|
476
|
+
per-machine, gitignored store and installs a `systemd --user` timer (launchd on macOS, cron
|
|
477
|
+
elsewhere) that runs `keryx trigger run <name>` unattended. The run leaves a report in
|
|
478
|
+
`.metaproject/data/trigger/reports/`.
|
|
479
|
+
- **Granted tools** (`gh pr list/view/checks`, `gh issue list/view`, `gh run list`) run
|
|
480
|
+
**outside** the sandbox with your credentials. The model sees only redacted output, and the
|
|
481
|
+
token never enters the sandbox, the model context or the report.
|
|
482
|
+
- **Network:** the agent's shell network is `off`, `full`, or `allowlist` (Linux
|
|
483
|
+
only) — reaches only the domains you name, through a loopback proxy keryx runs
|
|
484
|
+
outside the sandbox; it governs only the agent's own shell commands, never the
|
|
485
|
+
model call or a granted tool. See the [CLI reference](docs/docs/cli-reference.md#schedule).
|
|
486
|
+
- **Refusals:** the unattended floor is unchanged, and an entry edited after you confirmed it is
|
|
487
|
+
refused (`grants-changed`).
|
|
488
|
+
- **Tracking:** every run is spend-bounded and appears in `keryx trigger status` and
|
|
489
|
+
`keryx governance report`.
|
|
490
|
+
- **Management:** `keryx schedule list|show|pause|resume|run|remove`. In `keryx shell`:
|
|
491
|
+
- the sidebar's **Schedules** section shows each schedule's next run and last outcome;
|
|
492
|
+
- `/schedules` (or a click) opens the detail: Overview, Grants, Runs, Report;
|
|
493
|
+
- `p` pauses or resumes, `r` then `y` runs it now, `d` then `y` deletes it;
|
|
494
|
+
- a run finished in the background shows up without a restart.
|
|
495
|
+
- **Limits:** the machine must be on. systemd and launchd catch up one missed run after a boot or
|
|
496
|
+
wake; cron does not. Without linger, a user timer does not run while you are logged out, and
|
|
497
|
+
keryx never enables linger for you. The hardened sandbox is Linux-only.
|
|
498
|
+
|
|
499
|
+
See the [CLI reference](docs/docs/cli-reference.md#schedule).
|
|
500
|
+
- **governance** — `keryx governance report`, one read-only report unifying what
|
|
501
|
+
is already recorded: review-round spend per flow (USD and tokens, with a
|
|
502
|
+
rounds-with-cost/rounds-total count for partial coverage), project-wide
|
|
503
|
+
trigger spend (never attributed to a flow — the run record carries no flow
|
|
504
|
+
reference), who confirmed each acceptance criterion and who signed
|
|
505
|
+
completion (with identity basis), and every `flow complete` attempt's gate
|
|
506
|
+
outcomes. A figure nobody recorded is reported as "not recorded", never as
|
|
507
|
+
zero. Writes `.metaproject/data/governance/artifacts/latest.{md,json}`, the
|
|
508
|
+
same convention `keryx health run` uses; `--all-projects` also covers every
|
|
509
|
+
project in the user-global registry. In the TUI, the sidebar's
|
|
510
|
+
**Governance** row shows `no report — click to run`,
|
|
511
|
+
`unreadable — click for reason`, `running…`, `last report <date>` or
|
|
512
|
+
`failed — click to retry`. With no report, a click
|
|
513
|
+
(or `/governance`) runs the report in the background, and the row updates
|
|
514
|
+
when it finishes. With a report, a click opens it in a scrollable modal,
|
|
515
|
+
where `r` re-runs it. Sessions written by `keryx agents external run` appear
|
|
516
|
+
in `/sessions` marked `acp:<agent>`. See the
|
|
517
|
+
[CLI reference](docs/docs/cli-reference.md#governance).
|
|
406
518
|
- **security** — deterministic secrets / PII / prompt-injection / egress
|
|
407
519
|
scanning, redaction, and a policy gate at agent write seams, with a committed
|
|
408
520
|
evaluation corpus.
|
|
@@ -414,7 +526,8 @@ Grouped by what you are trying to do, not by internal module layout.
|
|
|
414
526
|
(Facts / Work / Know-how) overview, evidence-linked wrap-up proposals with owner
|
|
415
527
|
review, and a fail-closed runtime policy guard. Driven by `keryx workspace`
|
|
416
528
|
(`keryx modules enable sac` to turn it on); accepting a proposal into real
|
|
417
|
-
project knowledge always passes through
|
|
529
|
+
project knowledge always passes through an approval-gated `confirm-review`
|
|
530
|
+
(friction for an agent, not proof of a person — see TM-03), which
|
|
418
531
|
refuses a security-flagged proposal until `--acknowledge-security` records
|
|
419
532
|
that someone read the findings. The TUI's `/review` modal offers the same
|
|
420
533
|
acknowledgement as an explicit `[s]` action, never as an automatic fallback
|
|
@@ -580,9 +693,12 @@ graph falls back to its deterministic resolver when a grammar is absent.
|
|
|
580
693
|
| ripgrep is external | `keryx ctx rg` needs `rg` on `PATH` | Install ripgrep, or let the agent read files directly |
|
|
581
694
|
| Model commands need a credential | Four of the five commands above exit non-zero without one; `wiki enrich` exits `0` and marks the affected pages skipped | Everything else runs deterministically offline |
|
|
582
695
|
| External agents are read-only, and unproven against a live vendor process | A delegated CLI can read and search but never write; `worktree-write` is refused with a named reason. The parent gets the child's result and nothing before it — supervision of a running external child is not implemented. Everything is verified offline against recorded transcripts | Use keryx's own child agents for work that must mutate the tree |
|
|
583
|
-
|
|
|
584
|
-
|
|
|
585
|
-
|
|
|
696
|
+
| A dispatched `flow-next` task is "done" by checks, not review | `task done` means normal end + a commit on the trigger branch + `keryx health gate` passing in the worktree; nobody has read the diff | Review and merge the `trigger/<flow>-<task>` branch yourself |
|
|
697
|
+
| `trust` dispatch needs Linux + a working bubblewrap | The hardened unattended sandbox (network off, home hidden, allow-listed env) is bwrap-only; without it — or on macOS — a `trust` dispatch refuses before starting | Use `permissionMode: "ask"` (read-only), or run triggers on a Linux host with bwrap |
|
|
698
|
+
| `dispatch.network: true` is the host's full network | The agent's commands then reach the internet and every host loopback service; the model call never needs it (it is made outside the sandbox) | Leave `network` off; review the `trigger/*` branch before installing or building it |
|
|
699
|
+
| The unattended text floor is defence in depth | It can be spelled around (quoting, `$(…)`, interpreters); the boundary is the sandbox, not the floor | Keep `dispatch.network` off unless the task truly needs it |
|
|
700
|
+
| A killed dispatch keeps its spend reserved | Its reservation counts against both ceilings until closed | `keryx trigger status`, then `keryx trigger resolve <runId> --spent <usd>` |
|
|
701
|
+
| Dispatch cost is priced from your declared rates | keryx has no price table; wrong `rates` make both ceilings wrong by the same factor | Set `rates` from your provider's price list |
|
|
586
702
|
|
|
587
703
|
Full detail, including known defects and platform caveats:
|
|
588
704
|
[limitations](docs/docs/limitations.md).
|