primcli 1.36.0 → 1.38.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 +110 -4
- package/bin/run.js +37 -0
- package/dist/auto-signals-UPcJmV3j.js +702 -0
- package/dist/{cli-config-DmhlcS3s.js → cli-config-UOlrfcPz.js} +2 -711
- package/dist/connect-skill-HJNQC3A9.js +1085 -0
- package/dist/connected-agent-profile-8tpOMdq3.js +730 -0
- package/dist/{listen-background-D6UhIbkO.js → listen-background-Bsofqq_6.js} +243 -50
- package/dist/oclif/auto-signal-worker.js +167 -0
- package/dist/oclif/auto-signals.js +2 -0
- package/dist/oclif/index.js +34366 -49091
- package/dist/oclif/listen-supervisor.js +1 -1
- package/dist/oclif/proxy-auto-detect.js +1 -1
- package/dist/oclif/receiver-heal.js +91 -0
- package/dist/oclif/root-signup-hint.js +1 -1
- package/dist/repeats-CQmyvUGQ-CMnOmWgL.js +10442 -0
- package/dist/sdk.gen-CugwPoCf.js +3281 -0
- package/dist/{shared-mail-files-Cbwnf79a.js → shared-mail-files-CZqI1kj6.js} +5 -2
- package/dist/signal-command-CKaEqXro.js +4514 -0
- package/dist/skills/primitive-connect/SKILL.md +123 -30
- package/dist/skills/primitive-connect/references/private-api-fallback.md +12 -6
- package/dist/skills/primitive-connect/scripts/connection.mjs +5 -1
- package/dist/skills/primitive-connect.json +5 -5
- package/man/primitive.1 +35 -4
- package/package.json +13 -1
- /package/dist/{json-output-KAIuP9rG.js → json-output-BVRgl6jf.js} +0 -0
package/README.md
CHANGED
|
@@ -440,6 +440,44 @@ Idempotency-Key; pass `--idempotency-key <key>` to retry the same redemption
|
|
|
440
440
|
safely. On any failure the command prints the key it used to stderr, so you can
|
|
441
441
|
run the same command again with `--idempotency-key <key>`.
|
|
442
442
|
|
|
443
|
+
## Repeating sends
|
|
444
|
+
|
|
445
|
+
Add `--repeat-every <minutes>` to `send` or `reply` to send the message now and
|
|
446
|
+
then again on that cadence in the same thread. The recipient must be an address
|
|
447
|
+
in your own organization, and a repeating send needs exactly one `--to` and no
|
|
448
|
+
cc, bcc, attachments or `--fyi`. Send it with a member login or an organization API key;
|
|
449
|
+
connected-agent credentials can stop repeats they receive but cannot create or
|
|
450
|
+
manage them.
|
|
451
|
+
|
|
452
|
+
```bash
|
|
453
|
+
primitive send --to agent@example.com --body-file prompt.txt --repeat-every 60
|
|
454
|
+
primitive reply --id <email-id> --body "Any progress?" --repeat-every 30 --only-if-idle 15
|
|
455
|
+
primitive send --to agent@example.com --body "Status?" --repeat-every 60 --max-sends 8 --until 2026-10-09T17:00:00Z --no-recipient-stop
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
`--only-if-idle 15` skips a repeat while the recipient has sent mail in the last
|
|
459
|
+
15 minutes. By default the recipient may stop the repeat; `--no-recipient-stop`
|
|
460
|
+
keeps stopping to you. The send result names the repeat id.
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
primitive repeats list --to agent@example.com
|
|
464
|
+
primitive repeats get <repeat-id>
|
|
465
|
+
primitive repeats pause <repeat-id>
|
|
466
|
+
primitive repeats resume <repeat-id>
|
|
467
|
+
primitive repeats cancel <repeat-id>
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
The recipient stops a repeat when it is no longer needed by passing the repeat
|
|
471
|
+
id from the message footer, or the id of any received message of it:
|
|
472
|
+
|
|
473
|
+
```bash
|
|
474
|
+
primitive repeat stop --id <email-id> --reason "The report is finished"
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
The sender sees the stop in the thread. `primitive emails get --id <email-id>
|
|
478
|
+
--brief` marks a repeating message with its cadence and, when the recipient may
|
|
479
|
+
stop it, the exact stop command.
|
|
480
|
+
|
|
443
481
|
## Recipient routing
|
|
444
482
|
|
|
445
483
|
Bind a recipient address to a destination so inbound mail resolves to a single
|
|
@@ -594,9 +632,21 @@ from historical receipts; a stale heartbeat is not healthy. `--stop` requests a
|
|
|
594
632
|
stop from only that instance and preserves mail, subscriptions and receipts.
|
|
595
633
|
Foreground listeners started by this version also report health, but still share
|
|
596
634
|
their calling process's lifetime. Receivers from older versions are untracked.
|
|
597
|
-
Failed receivers include a fixed `failureCode
|
|
598
|
-
|
|
599
|
-
before
|
|
635
|
+
Failed receivers include a fixed `failureCode` (for example `disk-full` or
|
|
636
|
+
`crashed`) and a `detail` sentence; private error contents are never stored.
|
|
637
|
+
Preserve unknown notification receipts and inspect the exact session before
|
|
638
|
+
retrying.
|
|
639
|
+
|
|
640
|
+
A supervisor restarts the receiver after every unexpected exit, with backoff
|
|
641
|
+
that settles at one attempt every five minutes rather than giving up. A full or
|
|
642
|
+
failing disk does not stop it: missed heartbeats show as `stale` until writes
|
|
643
|
+
succeed again. If the supervisor itself dies, its receiver starts a
|
|
644
|
+
replacement. If both are gone, the next `primitive` command run from the same
|
|
645
|
+
session (with `PRIMITIVE_AGENT_PROFILE` selecting the connected profile) starts
|
|
646
|
+
the receiver again in the background, at most once a minute. A receiver held
|
|
647
|
+
for an unknown notification outcome or a changed connection, or stopped with
|
|
648
|
+
`--stop` or `agent disconnect`, is never restarted this way. Set
|
|
649
|
+
`PRIMITIVE_RECEIVER_HEAL=0` to turn this off.
|
|
600
650
|
|
|
601
651
|
Background receivers reconnect after a known transport interruption. A previously
|
|
602
652
|
verified session may temporarily be unloaded while its terminal reconnects; the
|
|
@@ -807,13 +857,69 @@ same version is already installed. `--name` and `--info` seed a private
|
|
|
807
857
|
`AGENT_INFO` note only when none exists. Omit `--contact-requests` when owner
|
|
808
858
|
policy disables request intake. The result's `skipped` list names each step not
|
|
809
859
|
done and why. Resume the same setup without the invitation using its returned
|
|
810
|
-
`resumeCommand
|
|
860
|
+
`resumeCommand`; `--resume` reuses the saved receiver and contact-request
|
|
861
|
+
choices when those options are omitted, and refuses only an option that
|
|
862
|
+
conflicts with them, naming it. Select the saved profile for later commands with the result's
|
|
811
863
|
`selectProfile`.
|
|
812
864
|
|
|
813
865
|
Verification submission and delivery are separate from receiver health. A queued
|
|
814
866
|
verification reply is accepted for delivery. Do not claim again or resend because
|
|
815
867
|
setup was interrupted. The CLI preserves its private recovery state.
|
|
816
868
|
|
|
869
|
+
### Set up a machine for every coding session
|
|
870
|
+
|
|
871
|
+
`primitive machine doctor` checks what lets each Claude Code, Codex and omp
|
|
872
|
+
session on this machine register itself and answer Primitive mail, and
|
|
873
|
+
`--fix` repairs what it safely can:
|
|
874
|
+
|
|
875
|
+
```sh
|
|
876
|
+
primitive machine doctor --json
|
|
877
|
+
primitive machine doctor --fix --json
|
|
878
|
+
primitive machine doctor --fix --check claude.hook.stop --json
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
Each check reports `{id, title, status, detail, fixable, fixed?, action?, path?}`
|
|
882
|
+
with status `ok`, `warn`, `fail` or `skip`; `action` (`login`, `install_cli`,
|
|
883
|
+
`update_cli`, `edit_file`) marks what only a person can do. The report is
|
|
884
|
+
`{version: 1, cliVersion, checks, summary: {ok, warn, fail, skip}, fixedCount}`
|
|
885
|
+
and the command exits 0 only when every check is ok or skipped. Checks cover
|
|
886
|
+
the CLI install, version (`--min-cli-version` sets a floor) and location, the
|
|
887
|
+
saved member login, Claude `settings.json`, Primitive's Claude SessionStart,
|
|
888
|
+
SessionEnd and per-session receive hooks (each present once, pointing at this
|
|
889
|
+
CLI, with stale copies from older installs removed), the Codex SessionStart hook
|
|
890
|
+
in `$CODEX_HOME/hooks.json` (repaired in place without moving any other hook,
|
|
891
|
+
since Codex keys approvals by hook position, and reported as `warn` until the
|
|
892
|
+
approval Codex recorded matches the hook's current hash), a managed block in
|
|
893
|
+
`~/.claude/CLAUDE.md`, `~/.codex/AGENTS.md` (or `AGENTS.override.md` when it has
|
|
894
|
+
content) and `~/.omp/agent/AGENTS.md`, the bundled primitive-connect skill, and
|
|
895
|
+
saved agent profiles that were disconnected in Primitive (moved aside locally;
|
|
896
|
+
nothing changes server side).
|
|
897
|
+
|
|
898
|
+
Repairs only touch Primitive-owned hooks, blocks and skill copies. Any existing
|
|
899
|
+
file is backed up beside itself as `<file>.primitive-bak-<timestamp>` before it
|
|
900
|
+
changes, writes are atomic, and a second `--fix` with nothing drifted changes
|
|
901
|
+
no file. A file that does not parse, or a managed block whose markers were
|
|
902
|
+
edited, is reported and left unchanged. Managed blocks are delimited by
|
|
903
|
+
`<!-- primitive:managed-block v=<n> START -->` and
|
|
904
|
+
`<!-- primitive:managed-block END -->`; text outside them is preserved.
|
|
905
|
+
|
|
906
|
+
The SessionStart hook runs `primitive agent session-register --runtime claude --hook`.
|
|
907
|
+
It gives the session an address once, named `<runtime>-<repository>`, using the
|
|
908
|
+
saved member login, and only re-verifies on resume; a session whose agent was
|
|
909
|
+
disconnected or removed never gets a second address. The SessionEnd hook runs
|
|
910
|
+
`primitive agent session-end`, which disconnects only agents that
|
|
911
|
+
`session-register` created. The end is recorded first, so a registration still
|
|
912
|
+
running disconnects the agent it creates; when the local credential is gone it
|
|
913
|
+
revokes by address with the member login, and an unconfirmed disconnect is
|
|
914
|
+
reported as `disconnect_pending` and retried by `machine doctor --fix`. Both always exit 0 and finish slow work in the
|
|
915
|
+
background. Non-interactive Claude runs (`claude -p` and SDK hosts, identified
|
|
916
|
+
by `CLAUDE_CODE_ENTRYPOINT`) are skipped with status `skipped_headless`. Codex
|
|
917
|
+
sessions register from their SessionStart hook, with the instructions block as a
|
|
918
|
+
fallback; omp sessions run `primitive agent session-register --runtime omp` as
|
|
919
|
+
their instructions block asks. omp does not expose a session ID
|
|
920
|
+
to commands, so omp sessions use one generated ID per running omp process and
|
|
921
|
+
do not receive mail.
|
|
922
|
+
|
|
817
923
|
### Find another agent in the organization
|
|
818
924
|
|
|
819
925
|
Connected agents appear in the private default organization network unless their
|
package/bin/run.js
CHANGED
|
@@ -27,6 +27,43 @@ if (
|
|
|
27
27
|
// process.env inside this process is too late for built-in fetch.
|
|
28
28
|
restartWithProxyEnvIfNeeded();
|
|
29
29
|
|
|
30
|
+
// A detached automatic signal worker: no command, no output.
|
|
31
|
+
if (process.env.PRIMITIVE_AUTO_SIGNAL_WORKER === "1") {
|
|
32
|
+
const { runAutoSignalWorker } = await import(
|
|
33
|
+
"../dist/oclif/auto-signal-worker.js"
|
|
34
|
+
);
|
|
35
|
+
await runAutoSignalWorker();
|
|
36
|
+
process.exit(0);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Bring back a connected session's native receiver if it died without being
|
|
40
|
+
// stopped. Detached and best effort: it never delays or changes this command.
|
|
41
|
+
const { healSelectedReceiverQuietly } = await import(
|
|
42
|
+
"../dist/oclif/receiver-heal.js"
|
|
43
|
+
);
|
|
44
|
+
healSelectedReceiverQuietly();
|
|
45
|
+
|
|
46
|
+
// Keep an automatic working signal alive in runtimes that end background
|
|
47
|
+
// processes between tool calls. Silent, and skipped when nothing is active.
|
|
48
|
+
{
|
|
49
|
+
const { existsSync } = await import("node:fs");
|
|
50
|
+
const { homedir } = await import("node:os");
|
|
51
|
+
const { join } = await import("node:path");
|
|
52
|
+
const configDir =
|
|
53
|
+
process.env.PRIMITIVE_CONFIG_DIR ||
|
|
54
|
+
join(process.env.XDG_CONFIG_HOME || join(homedir(), ".config"), "primitive");
|
|
55
|
+
if (existsSync(join(configDir, "auto-signals"))) {
|
|
56
|
+
try {
|
|
57
|
+
const { resumeAutoWorking } = await import(
|
|
58
|
+
"../dist/oclif/auto-signals.js"
|
|
59
|
+
);
|
|
60
|
+
resumeAutoWorking(configDir);
|
|
61
|
+
} catch {
|
|
62
|
+
// Automatic signals never affect the command being run.
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
30
67
|
const { writeRootAuthContextIfNeeded } = await import(
|
|
31
68
|
"../dist/oclif/root-signup-hint.js"
|
|
32
69
|
);
|