primcli 1.35.0 → 1.37.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.
Files changed (32) hide show
  1. package/README.md +73 -10
  2. package/bin/run.js +37 -0
  3. package/dist/auto-signals-UPcJmV3j.js +702 -0
  4. package/dist/{cli-config-DmhlcS3s.js → cli-config-UOlrfcPz.js} +2 -711
  5. package/dist/connect-skill-DednypYJ.js +1084 -0
  6. package/dist/connected-agent-profile-8tpOMdq3.js +730 -0
  7. package/dist/{listen-background-D6UhIbkO.js → listen-background-Bsofqq_6.js} +243 -50
  8. package/dist/oclif/auto-signal-worker.js +167 -0
  9. package/dist/oclif/auto-signals.js +2 -0
  10. package/dist/oclif/index.js +31501 -48161
  11. package/dist/oclif/listen-supervisor.js +1 -1
  12. package/dist/oclif/proxy-auto-detect.js +1 -1
  13. package/dist/oclif/receiver-heal.js +91 -0
  14. package/dist/oclif/root-signup-hint.js +1 -1
  15. package/dist/repeats-CQmyvUGQ-CMnOmWgL.js +10442 -0
  16. package/dist/sdk.gen-CugwPoCf.js +3281 -0
  17. package/dist/{shared-mail-files-Cbwnf79a.js → shared-mail-files-CZqI1kj6.js} +5 -2
  18. package/dist/signal-command-CKaEqXro.js +4514 -0
  19. package/dist/skills/primitive-connect/SKILL.md +896 -0
  20. package/dist/skills/primitive-connect/package-lock.json +1033 -0
  21. package/dist/skills/primitive-connect/package.json +8 -0
  22. package/dist/skills/primitive-connect/references/communication.md +207 -0
  23. package/dist/skills/primitive-connect/references/contact-requests.md +161 -0
  24. package/dist/skills/primitive-connect/references/native-session.md +165 -0
  25. package/dist/skills/primitive-connect/references/private-api-fallback.md +107 -0
  26. package/dist/skills/primitive-connect/scripts/check-cli-capabilities.mjs +48 -0
  27. package/dist/skills/primitive-connect/scripts/connection.mjs +197 -0
  28. package/dist/skills/primitive-connect/scripts/mail.mjs +189 -0
  29. package/dist/skills/primitive-connect.json +21 -0
  30. package/man/primitive.1 +35 -4
  31. package/package.json +10 -1
  32. /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`; private error contents are never
598
- stored. Preserve unknown notification receipts and inspect the exact session
599
- before retrying.
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
@@ -787,17 +837,30 @@ rules, uses a conditional write, and reads the policy back before reporting
787
837
  pauses enrollment without overwriting the policy; rerun this exact session
788
838
  after reviewing it.
789
839
 
790
- With a supported native session, one command handles the private claim, email
791
- verification and receiving. Pipe the invitation from the Primitive app to stdin:
840
+ One command connects a Claude Code or Codex session from an owner's invitation.
841
+ It checks this CLI's capabilities, installs or refreshes the matching
842
+ primitive-connect skill from files bundled in this package, claims the
843
+ invitation from stdin, answers the email challenge, starts receiving and prints
844
+ one JSON result:
792
845
 
793
846
  ```sh
794
- primitive agent connect --profile work --session <session-uuid> --contact-requests --json < private-invitation.txt
847
+ npx -y primitive@latest agent connect --session "$CODEX_THREAD_ID" --name Research --info "Reviews pull requests" --contact-requests --json < private-invitation.txt
795
848
  ```
796
849
 
797
- Omit `--contact-requests` when owner policy disables request intake. Resume the
798
- same setup without the invitation using its returned `resumeCommand`; keep the
799
- same session, profile and intake choice. Select the saved profile for later
800
- commands with `PRIMITIVE_AGENT_PROFILE=work`.
850
+ The receiver defaults to the exact Claude session's hooks in Claude Code and to
851
+ the supervised native background listener elsewhere; native receiving waits
852
+ briefly for the listener's first mail check. The profile defaults to
853
+ `session-<session>`. The skill goes to `~/.claude/skills` or
854
+ `$CODEX_HOME/skills` (`--project` uses `.claude/skills` or `.agents/skills` in
855
+ the current directory; `--no-skill` skips it), and is left untouched when the
856
+ same version is already installed. `--name` and `--info` seed a private
857
+ `AGENT_INFO` note only when none exists. Omit `--contact-requests` when owner
858
+ policy disables request intake. The result's `skipped` list names each step not
859
+ done and why. Resume the same setup without the invitation using its returned
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
863
+ `selectProfile`.
801
864
 
802
865
  Verification submission and delivery are separate from receiver health. A queued
803
866
  verification reply is accepted for delivery. Do not claim again or resend because
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
  );