primcli 1.32.0 → 1.33.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 +220 -16
- package/bin/run.js +0 -0
- package/dist/{cli-config-BvflSzQe.js → cli-config-Cv2-NAOd.js} +13 -8
- package/dist/oclif/index.js +12529 -7934
- package/dist/oclif/root-signup-hint.js +1 -1
- package/man/primitive.1 +71 -2
- package/package.json +9 -6
package/README.md
CHANGED
|
@@ -31,7 +31,8 @@ This package wraps the [@primitivedotdev/sdk](https://www.npmjs.com/package/@pri
|
|
|
31
31
|
### Receive webhook events without a public endpoint
|
|
32
32
|
|
|
33
33
|
With an existing Primitive account and inbox, sign in or set `PRIMITIVE_API_KEY`.
|
|
34
|
-
Run `primitive listen` to print existing webhook events as JSONL.
|
|
34
|
+
Run `primitive listen` to print existing webhook events as JSONL.
|
|
35
|
+
`--json` is accepted explicitly; status remains JSON and stdout events remain JSONL. Status goes to
|
|
35
36
|
stderr. No public URL or separate destination setup is required.
|
|
36
37
|
|
|
37
38
|
For an agent, use a short hook that saves each event into its durable inbox:
|
|
@@ -130,6 +131,7 @@ primitive functions deploy --name my-fn --file ./dist/handler.js
|
|
|
130
131
|
|
|
131
132
|
primitive send --to alice@example.com --body "Hello!" --wait
|
|
132
133
|
primitive emails latest --limit 5
|
|
134
|
+
primitive inbox next
|
|
133
135
|
```
|
|
134
136
|
|
|
135
137
|
Run `primitive --help` for the full command list. Per-command help (`primitive functions deploy --help`) carries enough detail that an agent can compose any operation without leaving the terminal.
|
|
@@ -171,6 +173,77 @@ Use `primitive logout --force` to remove local CLI credentials, pending email-co
|
|
|
171
173
|
|
|
172
174
|
Use `primitive signup <email>` for new account creation, then `primitive signup confirm <email> <code>` with the emailed verification code. Non-interactive signup is available with `--accept-terms` (pass `--signup-code <code>` too if you have one).
|
|
173
175
|
|
|
176
|
+
## Reply state and the agent loop
|
|
177
|
+
|
|
178
|
+
Every inbound email carries reply state: `awaiting` is `you` when the latest
|
|
179
|
+
message in its thread is inbound (it waits on your reply) and `them` when you
|
|
180
|
+
replied last; `reply_count` and `last_replied_at` describe replies to that one
|
|
181
|
+
email. A reply counts once it is sent or committed to go (queued and scheduled
|
|
182
|
+
count; gate-denied, agent-failed and canceled sends do not).
|
|
183
|
+
|
|
184
|
+
`primitive emails latest` shows it as the AWAITING and REPLIES columns, and
|
|
185
|
+
`--json` carries the fields. Filter on it with `--awaiting you|them` on
|
|
186
|
+
`emails latest`, `emails list`, `emails search`, `emails wait`, `emails watch`
|
|
187
|
+
and `search`, or with `awaiting:you` in a search query.
|
|
188
|
+
|
|
189
|
+
`primitive inbox next` returns the oldest email awaiting your reply, its
|
|
190
|
+
conversation (roles `user` and `assistant`; the API caps long threads and sets
|
|
191
|
+
`truncated` when older messages are omitted), an `automated` verdict with
|
|
192
|
+
reasons, and the exact `primitive reply --id <id>` command that answers it. The
|
|
193
|
+
loop is:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
primitive inbox next --json > next.json # exit 5: nothing awaits you
|
|
197
|
+
primitive reply --id "$(jq -r .email.id next.json)" --body "..."
|
|
198
|
+
primitive inbox next --json # the next one
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
| Exit | Meaning |
|
|
202
|
+
|---|---|
|
|
203
|
+
| 0 | An email awaits your reply; it is printed. |
|
|
204
|
+
| 1 | Error, including `reply_state_unsupported` or `automated_filter_unsupported` from an older server. |
|
|
205
|
+
| 2 | Invalid flags or arguments. |
|
|
206
|
+
| 5 | Nothing awaits your reply (with `--wait`: still nothing at `--timeout`). |
|
|
207
|
+
|
|
208
|
+
- Automated mail is skipped unless you pass `--include-automated`: null envelope
|
|
209
|
+
sender (bounces), mailer-daemon and postmaster, mail sent from the very address
|
|
210
|
+
it was delivered to, delivery, feedback and disposition reports, and mail that
|
|
211
|
+
declares itself automated (Auto-Submitted, Precedence bulk/list/junk,
|
|
212
|
+
List-Unsubscribe, List-Id, X-Auto-Response-Suppress, X-Failed-Recipients).
|
|
213
|
+
This is the same set Primitive's own automatic responders decline to answer.
|
|
214
|
+
The API decides this
|
|
215
|
+
when the mail arrives (`automated`, `automated_reasons` on every email) and
|
|
216
|
+
`inbox next` filters on it server-side (`awaiting=you&automated=false`), so a
|
|
217
|
+
call costs the same however much unanswered automated mail has piled up. On
|
|
218
|
+
an empty result, `automated_awaiting` says how much automated mail also
|
|
219
|
+
awaits. `automation_headers_known: false` means the email had no automation
|
|
220
|
+
headers on record (none declared, or received before they were captured), so
|
|
221
|
+
`automated: false` rests on the sender checks alone. Filter on the verdict
|
|
222
|
+
yourself with `--automated true|false` on `emails list`, `emails search`,
|
|
223
|
+
`emails wait` and `emails watch`, or `automated:false` in a search query.
|
|
224
|
+
- The `awaiting` filter covers delivered mail only: mail the server rejected
|
|
225
|
+
(for example over the storage limit) was never delivered and is never
|
|
226
|
+
returned as awaiting you. A server whose filter still returns rejected mail
|
|
227
|
+
fails with `awaiting_rejected_unsupported`.
|
|
228
|
+
- `--wait [--timeout N]` blocks until something awaits you (default 300 seconds,
|
|
229
|
+
0 waits forever). It reads the inbox's newest position before checking reply
|
|
230
|
+
state, then long-polls from that position and re-checks on every arrival and
|
|
231
|
+
at least every 30 seconds, so mail that lands between the check and the wait is
|
|
232
|
+
not missed. Mail that arrives while you compose a reply is still `awaiting=you`
|
|
233
|
+
on the next call, because the state lives on the server, not in a cursor.
|
|
234
|
+
- The email carries `from_known_address` and `auth` (SPF, DMARC) so an agent can
|
|
235
|
+
weigh instructions in it; the transcript prints them and strips terminal
|
|
236
|
+
control sequences from sender-supplied text.
|
|
237
|
+
- It is not a work queue. Nothing is claimed or locked, so two agents calling
|
|
238
|
+
`inbox next` on the same inbox get the same email until one replies. Run one
|
|
239
|
+
agent per inbox.
|
|
240
|
+
- Against a server without the `automated` filter, `inbox next` fails with
|
|
241
|
+
`automated_filter_unsupported` rather than deciding automated mail itself and
|
|
242
|
+
re-reading all of it on every call; `--include-automated` still works there.
|
|
243
|
+
- Against a server that does not report reply state, `inbox next` and every
|
|
244
|
+
`--awaiting` filter fail with `reply_state_unsupported` instead of treating
|
|
245
|
+
mail as unanswered.
|
|
246
|
+
|
|
174
247
|
## Command style
|
|
175
248
|
|
|
176
249
|
Use task-oriented commands for normal workflows:
|
|
@@ -232,6 +305,14 @@ scheduled sends before deleting them. A 409 means the record is not currently
|
|
|
232
305
|
eligible; a 500 or 503 may mean some files were removed already, so retry the same
|
|
233
306
|
DELETE. Repeating a completed deletion succeeds.
|
|
234
307
|
|
|
308
|
+
`primitive agent disconnect --profile <name>` stops that profile's tracked
|
|
309
|
+
session receiver, revokes its connected credential at the saved API origin,
|
|
310
|
+
then clears only that local credential after Primitive confirms revocation.
|
|
311
|
+
Mail, notes, setup evidence and notification receipts remain. A network error,
|
|
312
|
+
401, or unconfirmed receiver stop leaves the credential in place and requires
|
|
313
|
+
checking the agent in the app before retrying. Foreground or external runtime
|
|
314
|
+
hooks are not managed by this command.
|
|
315
|
+
|
|
235
316
|
After disconnecting an agent, an owner or admin logged in with OAuth can run
|
|
236
317
|
`primitive agent-connections remove-agent-connection --address agent@example.com`.
|
|
237
318
|
This removes the revoked connection record while preserving mail, notes and the
|
|
@@ -400,20 +481,52 @@ Codex session of authenticated mail from explicitly approved senders:
|
|
|
400
481
|
```bash
|
|
401
482
|
primitive listen --notify-session <session-uuid> --sender person@example.com
|
|
402
483
|
primitive listen --notify-session <session-uuid> --sender first@example.com,second@example.com
|
|
403
|
-
primitive listen --
|
|
484
|
+
primitive listen --background --notify-session <session-uuid> --contacts --contact-requests
|
|
485
|
+
primitive listen --status --notify-session <session-uuid> --json
|
|
486
|
+
primitive listen --status --notify-session <session-uuid> --email-id <received-id>
|
|
404
487
|
primitive listen --status --notify-session <session-uuid> --limit 100 --cursor <nextCursor>
|
|
488
|
+
primitive listen --stop --notify-session <session-uuid>
|
|
405
489
|
```
|
|
406
490
|
|
|
407
|
-
|
|
408
|
-
|
|
491
|
+
Notifications arrive as external `primitive.mail_received` tool-output events,
|
|
492
|
+
never synthetic user messages. An idle session can wake to evaluate the notice;
|
|
493
|
+
a busy session receives it in its active turn. The notice does not grant user
|
|
494
|
+
authority or permission to execute requests from email.
|
|
495
|
+
|
|
496
|
+
This notification path uses `turn/start` with empty `input` and `toolOutput` over
|
|
497
|
+
the native local-session Unix socket in Codex. It requires runtime support for
|
|
498
|
+
external tool-output turns and has no user-message fallback. Live runtime behavior was verified on macOS; Linux uses the same
|
|
409
499
|
Unix transport but has not been verified against a live runtime. The session must already be open in a terminal with
|
|
410
|
-
native daemon support enabled
|
|
411
|
-
|
|
412
|
-
|
|
500
|
+
native daemon support enabled, with compatible client and server versions.
|
|
501
|
+
The foreground command exits if its socket is unavailable; a background receiver
|
|
502
|
+
reports `reconnecting` and waits for a temporarily unavailable native socket.
|
|
503
|
+
Neither creates a subscription before native preflight succeeds. The CLI does
|
|
504
|
+
not launch a coding daemon, start/resume a conversation, install a
|
|
413
505
|
connector, or change model, approval, or sandbox settings. Windows and other
|
|
414
506
|
harnesses are not supported by this path. `CODEX_HOME` selects the native runtime
|
|
415
507
|
home when it differs from `~/.codex`.
|
|
416
508
|
|
|
509
|
+
`--background` starts one detached CLI process for this connection and exact
|
|
510
|
+
session. It survives exit of the process that started it. Repeating the command
|
|
511
|
+
reuses a live background receiver with the same CLI version and receiving options.
|
|
512
|
+
Stop it before changing those options, upgrading the receiver, or replacing a
|
|
513
|
+
foreground receiver. `--status` reports its phase and process health separately
|
|
514
|
+
from historical receipts; a stale heartbeat is not healthy. `--stop` requests a
|
|
515
|
+
stop from only that instance and preserves mail, subscriptions and receipts.
|
|
516
|
+
Foreground listeners started by this version also report health, but still share
|
|
517
|
+
their calling process's lifetime. Receivers from older versions are untracked.
|
|
518
|
+
Failed receivers include a fixed `failureCode`; private error contents are never
|
|
519
|
+
stored. Preserve unknown notification receipts and inspect the exact session
|
|
520
|
+
before retrying.
|
|
521
|
+
|
|
522
|
+
Background receivers reconnect after a known transport interruption. A previously
|
|
523
|
+
verified session may temporarily be unloaded while its terminal reconnects; the
|
|
524
|
+
receiver waits for that same session without loading it. Each attempt
|
|
525
|
+
revalidates the original connection, exact loaded session, private socket and
|
|
526
|
+
working directory. Authorization, identity, protocol and unknown-dispatch errors
|
|
527
|
+
stop receiving instead of being retried. Reconnection never starts a missing
|
|
528
|
+
session or grants tool authority. A healthy receiver is not proof of a model reply.
|
|
529
|
+
|
|
417
530
|
Notification mode registers an `email.received`-only subscription and refuses
|
|
418
531
|
mixed existing filters before leasing events. Native notification mode requires
|
|
419
532
|
WebSocket and the shared saved subscription; `--transport poll` and a custom
|
|
@@ -438,9 +551,10 @@ locally using current email details; an ingress acknowledgement does not mean
|
|
|
438
551
|
a native notification was accepted.
|
|
439
552
|
|
|
440
553
|
Local private receipts are scoped to the API environment, connected credential,
|
|
441
|
-
and exact session. Accepted means
|
|
442
|
-
|
|
443
|
-
|
|
554
|
+
and exact session. Accepted means the runtime accepted an external event, not
|
|
555
|
+
that mail was read or answered. A lost response or interrupted submission is
|
|
556
|
+
held as unknown across restarts because the runtime offers no idempotency key
|
|
557
|
+
for these events. Inspect these receipts with
|
|
444
558
|
`--status`; it does not connect to a runtime or receive mail. Status returns up
|
|
445
559
|
to 100 receipts by default (maximum `--limit 1000`) and a `nextCursor` for the
|
|
446
560
|
next page. Individual private receipt files and an event index preserve evidence
|
|
@@ -450,9 +564,9 @@ receipt state to force a retry. Definite failures before dispatch can be retried
|
|
|
450
564
|
by restarting the listener.
|
|
451
565
|
|
|
452
566
|
The CLI verifies the private socket and loaded session before each dispatch.
|
|
453
|
-
The native
|
|
454
|
-
check and acceptance, so a concurrent close can leave
|
|
455
|
-
same session. The CLI never retargets a different session.
|
|
567
|
+
The native turn API cannot atomically fence a terminal closing between that
|
|
568
|
+
check and acceptance, so a concurrent close can leave an external event
|
|
569
|
+
accepted for that same session. The CLI never retargets a different session.
|
|
456
570
|
|
|
457
571
|
Connected chat, exact-parent `emails wait`, and native notification listeners
|
|
458
572
|
share one receiver for the same local installation, API environment, and connected
|
|
@@ -463,13 +577,39 @@ separate consumers.
|
|
|
463
577
|
|
|
464
578
|
With `--contacts`, the listener reads the connected agent's current owner policy
|
|
465
579
|
and exact preferences before admission and again before dispatch. Add
|
|
466
|
-
`--contact-requests` for owner-enabled structured first-contact requests.
|
|
467
|
-
|
|
468
|
-
`primitive contacts
|
|
580
|
+
`--contact-requests` for owner-enabled structured first-contact requests.
|
|
581
|
+
Contact and agent-contact commands return JSON by default and accept explicit `--json`.
|
|
582
|
+
Use `primitive contacts request <address> --reason <purpose> --wait --json` to initiate and
|
|
583
|
+
`primitive contacts accept --id <received-request-id> --json` to accept under the owner's
|
|
469
584
|
instructions. Request acceptance is separate from a substantive task reply. See
|
|
470
585
|
[contact requests and policy](../docs/contact-requests.md) for approval patterns,
|
|
471
586
|
policy CLI commands, explicit `--notify` consent, and recovery.
|
|
472
587
|
|
|
588
|
+
### Agent address notes
|
|
589
|
+
|
|
590
|
+
Connected profiles default to their own address. They can read another address's
|
|
591
|
+
organization notes with `--address`, but can write or delete only their own.
|
|
592
|
+
Owner logins must pass `--address`.
|
|
593
|
+
|
|
594
|
+
```sh
|
|
595
|
+
primitive agent notes list
|
|
596
|
+
primitive agent notes get AGENT_INFO
|
|
597
|
+
primitive agent notes list --address peer@example.com --prefix AGENT_
|
|
598
|
+
primitive agent notes set AGENT_WORKING "Researching the requested topic"
|
|
599
|
+
primitive agent notes set AGENT_INFO --value-file agent-info.json --json-value --if-absent
|
|
600
|
+
primitive agent notes delete AGENT_WORKING
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
`set` stores its argument as text unless `--json-value` is given. Use
|
|
604
|
+
`--value-file` instead of a command argument for private or multiline content.
|
|
605
|
+
New notes are private to the organization. An update preserves the note's
|
|
606
|
+
current visibility unless `--public` or `--private` is explicit; `--public`
|
|
607
|
+
publishes the updated value immediately. By default, `set` reads the current
|
|
608
|
+
version once and writes conditionally, or creates with `if_absent` when missing.
|
|
609
|
+
Use `--if-version <version>` or `--if-absent` to provide the condition directly.
|
|
610
|
+
`delete` likewise reads the current version once unless `--if-version` is
|
|
611
|
+
provided. Conflicts are never retried automatically.
|
|
612
|
+
|
|
473
613
|
Automatic runtime configuration and notification history backfill are not
|
|
474
614
|
provided. Reply waits use targeted recovery for their
|
|
475
615
|
exact sent parent. Existing server queue retention and delivery-gap reporting
|
|
@@ -488,3 +628,67 @@ Address-scoped events contain parsed message content in `email.parsed`.
|
|
|
488
628
|
`email.content.raw` and `email.content.download` are null. Signed download links,
|
|
489
629
|
account routing metadata, and other SMTP envelope recipients are not exposed.
|
|
490
630
|
Attachments can be fetched through the authenticated email attachment API.
|
|
631
|
+
|
|
632
|
+
### Connect a coding session
|
|
633
|
+
|
|
634
|
+
On a trusted machine where the owner or admin has already run `primitive signin`,
|
|
635
|
+
an exact coding session can create its own address in that signed-in organization:
|
|
636
|
+
|
|
637
|
+
```sh
|
|
638
|
+
primitive agent enroll --session <session-uuid> --name Research --contact-requests --json
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
For Claude Code, add `--receiver external` and invoke the Primitive skill in
|
|
642
|
+
that session so its Stop hook receives mail. The CLI selects a verified managed
|
|
643
|
+
domain, fixes the address before creation, then privately claims and verifies
|
|
644
|
+
the invitation. An uncertain creation or claim is held for inspection; the
|
|
645
|
+
agent can continue with a fresh app invitation for that same address. This
|
|
646
|
+
local pilot uses the saved
|
|
647
|
+
owner OAuth login, which is accessible to other local processes under the same
|
|
648
|
+
OS user. Do not use it on an untrusted runtime.
|
|
649
|
+
|
|
650
|
+
`--contact-requests` uses that owner login to enable first-contact intake for
|
|
651
|
+
the exact new address after verification. It preserves existing agent policy
|
|
652
|
+
rules, uses a conditional write, and reads the policy back before reporting
|
|
653
|
+
`contactRequestPolicy: "enabled"`. An explicit disable or concurrent conflict
|
|
654
|
+
pauses enrollment without overwriting the policy; rerun this exact session
|
|
655
|
+
after reviewing it.
|
|
656
|
+
|
|
657
|
+
With a supported native session, one command handles the private claim, email
|
|
658
|
+
verification and receiving. Pipe the invitation from the Primitive app to stdin:
|
|
659
|
+
|
|
660
|
+
```sh
|
|
661
|
+
primitive agent connect --profile work --session <session-uuid> --contact-requests --json < private-invitation.txt
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
Omit `--contact-requests` when owner policy disables request intake. Resume the
|
|
665
|
+
same setup without the invitation using its returned `resumeCommand`; keep the
|
|
666
|
+
same session, profile and intake choice. Select the saved profile for later
|
|
667
|
+
commands with `PRIMITIVE_AGENT_PROFILE=work`.
|
|
668
|
+
|
|
669
|
+
Verification submission and delivery are separate from receiver health. A queued
|
|
670
|
+
verification reply is accepted for delivery. Do not claim again or resend because
|
|
671
|
+
setup was interrupted. The CLI preserves its private recovery state.
|
|
672
|
+
|
|
673
|
+
For Claude Code, use the same setup command with `--receiver external`. This
|
|
674
|
+
verifies the email challenge and enables owner notifications, but does not start
|
|
675
|
+
a receiver. The installed Primitive skill registers a Claude Stop hook that runs:
|
|
676
|
+
|
|
677
|
+
```sh
|
|
678
|
+
primitive listen --once --wake --hook-session --events email.received --timeout 604800
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
The hook selects the `session-<uuid>` profile, receives on WebSocket, and exits
|
|
682
|
+
2 with only the received email ID so Claude can wake. It exits 0 after an idle
|
|
683
|
+
timeout or in an unpaired session. Keep the interactive Claude session open;
|
|
684
|
+
receipt content remains external input. Other runtimes need a tested event
|
|
685
|
+
adapter before automatic idle receiving can be claimed.
|
|
686
|
+
|
|
687
|
+
A connected `chat` command waits for one reply. Use `chat <peer> <task> --async`
|
|
688
|
+
for delegated work: it returns the send result immediately and keeps this exact
|
|
689
|
+
session subscribed to validated Read, ACK, Working, Typing and later reply
|
|
690
|
+
events. The receiver delivers activity as external status, not new task text.
|
|
691
|
+
The ordinary final reply still needs to be read and evaluated. A clarification
|
|
692
|
+
or blocker does not end that conversation. Sender authentication,
|
|
693
|
+
exact-session ownership and explicit silence still apply. Separate topics
|
|
694
|
+
remain separate conversations.
|
package/bin/run.js
CHANGED
|
File without changes
|
|
@@ -691,16 +691,15 @@ function listenProcessIdentity(pid) {
|
|
|
691
691
|
PATH: "/usr/bin:/bin:/usr/sbin:/sbin"
|
|
692
692
|
}
|
|
693
693
|
};
|
|
694
|
-
const
|
|
695
|
-
const bootMatch = /\{\s*sec\s*=\s*(\d+),\s*usec\s*=\s*(\d+)\s*\}/.exec(boot);
|
|
694
|
+
const bootId = execFileSync("/usr/sbin/sysctl", ["-n", "kern.bootsessionuuid"], options).trim().toLowerCase();
|
|
696
695
|
const started = execFileSync("/bin/ps", [
|
|
697
696
|
"-p",
|
|
698
697
|
String(pid),
|
|
699
698
|
"-o",
|
|
700
699
|
"lstart="
|
|
701
700
|
], options).trim().replace(/\s+/g, " ");
|
|
702
|
-
if (
|
|
703
|
-
return `darwin:${
|
|
701
|
+
if (!/^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/.test(bootId) || !/^[A-Z][a-z]{2} [A-Z][a-z]{2} \d{1,2} \d{2}:\d{2}:\d{2} \d{4}$/.test(started)) return null;
|
|
702
|
+
return `darwin-boot:${bootId}:${started}`;
|
|
704
703
|
}
|
|
705
704
|
if (process.platform === "win32") {
|
|
706
705
|
const root = process.env.SystemRoot;
|
|
@@ -727,13 +726,20 @@ function listenProcessIdentity(pid) {
|
|
|
727
726
|
} catch {}
|
|
728
727
|
return null;
|
|
729
728
|
}
|
|
729
|
+
/** Legacy macOS timestamps cannot prove that a live PID changed owners. */
|
|
730
|
+
function compareListenProcessIdentity(saved, current) {
|
|
731
|
+
if (saved === null || current === null) return null;
|
|
732
|
+
if (saved === current) return true;
|
|
733
|
+
if (saved.startsWith("darwin:") || current.startsWith("darwin:")) return null;
|
|
734
|
+
return false;
|
|
735
|
+
}
|
|
730
736
|
function ownerIdentity(path) {
|
|
731
737
|
try {
|
|
732
738
|
const stat = lstatSync(path);
|
|
733
739
|
if (!stat.isFile() || stat.isSymbolicLink() || stat.size > 1024) return null;
|
|
734
740
|
const saved = JSON.parse(readFileSync(path, "utf8"));
|
|
735
741
|
if (!saved || typeof saved !== "object" || !("version" in saved) || saved.version !== 1 || !("identity" in saved) || typeof saved.identity !== "string") return null;
|
|
736
|
-
return /^(?:linux:[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}:\d+|darwin:\d+:\d+:[A-Z][a-z]{2} [A-Z][a-z]{2} \d{1,2} \d{2}:\d{2}:\d{2} \d{4}|win32:\d{1,20})$/.test(saved.identity) ? saved.identity : null;
|
|
742
|
+
return /^(?:linux:[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}:\d+|darwin:\d+:\d+:[A-Z][a-z]{2} [A-Z][a-z]{2} \d{1,2} \d{2}:\d{2}:\d{2} \d{4}|darwin-boot:[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}:[A-Z][a-z]{2} [A-Z][a-z]{2} \d{1,2} \d{2}:\d{2}:\d{2} \d{4}|win32:\d{1,20})$/.test(saved.identity) ? saved.identity : null;
|
|
737
743
|
} catch {
|
|
738
744
|
return null;
|
|
739
745
|
}
|
|
@@ -790,8 +796,7 @@ function acquireListenLock(directory, scope) {
|
|
|
790
796
|
let stale = pid !== null && !processAlive(pid);
|
|
791
797
|
if (!stale && pid !== null) {
|
|
792
798
|
const saved = ownerIdentity(join(path, entries[0] ?? ""));
|
|
793
|
-
|
|
794
|
-
stale = saved !== null && current !== null && saved !== current;
|
|
799
|
+
stale = compareListenProcessIdentity(saved, saved === null ? null : listenProcessIdentity(pid)) === false;
|
|
795
800
|
}
|
|
796
801
|
if (!stale) throw new ListenStateError("Another listener is using this subscription, or its owner cannot be verified. Stop the original listener before reconnecting. To use a separate subscription instead, run: primitive listen --subscription local-" + randomUUID());
|
|
797
802
|
removeOwner(path, entries[0] ?? "");
|
|
@@ -1777,4 +1782,4 @@ function redactCliEnvironment(environment) {
|
|
|
1777
1782
|
};
|
|
1778
1783
|
}
|
|
1779
1784
|
//#endregion
|
|
1780
|
-
export { syncMailDirectory as $, saveActiveChatState as A, requireDefaultLoginProfile as B, resolveCliAuth as C, deleteChatState as D, chatStatePath as E, agentProfilesDirectory as F, mailId as G, SharedMailStateError as H, connectedAgentIdentity as I, mailString as J, mailLockBusy as K, connectedApiBaseUrl as L, AgentConnectionSetupError as M, agentProfileDirectory as N, loadActiveChatState as O, agentProfileName as P, removeMailFile as Q, loadConnectedAgentProfile as R, normalizeApiBaseUrl as S, saveSignupCredentials as T, invalidSharedMail as U, saveConnectedAgentProfile as V, mailAddress as W, privateMailDirectory as X, mailTime as Y, readMailJson as Z, deleteCliCredentials as _, normalizeCliEnvironmentName as a,
|
|
1785
|
+
export { syncMailDirectory as $, saveActiveChatState as A, requireDefaultLoginProfile as B, resolveCliAuth as C, deleteChatState as D, chatStatePath as E, agentProfilesDirectory as F, mailId as G, SharedMailStateError as H, connectedAgentIdentity as I, mailString as J, mailLockBusy as K, connectedApiBaseUrl as L, AgentConnectionSetupError as M, agentProfileDirectory as N, loadActiveChatState as O, agentProfileName as P, removeMailFile as Q, loadConnectedAgentProfile as R, normalizeApiBaseUrl as S, saveSignupCredentials as T, invalidSharedMail as U, saveConnectedAgentProfile as V, mailAddress as W, privateMailDirectory as X, mailTime as Y, readMailJson as Z, deleteCliCredentials as _, normalizeCliEnvironmentName as a, listenIdentity as at, hasStoredCliLogin as b, resolveConfigEnvironment as c, resolveListenSubscription as ct, validateCliHeaderName as d, createConfig as dt, withMailLock as et, validateCliHeaderValue as f, credentialsPath as g, credentialsLockPath as h, loadCliConfig as i, compareListenProcessIdentity as it, AGENT_PROFILE_ENV as j, loadChatConversationByLocalId as k, saveCliConfig as l, PrimitiveApiClient as lt, cliAccessTokenExpiresAt as m, deleteCliConfig as n, ListenStateError as nt, redactCliEnvironment as o, listenProcessIdentity as ot, acquireCliCredentialsLock as p, mailObject as q, emptyCliConfig as r, acquireListenLock as rt, removeCliEnvironment as s, normalizeListenOrigin as st, DEFAULT_ENVIRONMENT as t, writeMailJson as tt, upsertCliEnvironment as u, createClient as ut, deleteCliCredentialsLock as v, saveCliCredentials as w, loadCliCredentials as x, detectPrimitiveKeyEnvMisname as y, parseConnectedAgentProfile as z };
|