primcli 1.39.0 → 1.41.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.
@@ -1,6 +1,6 @@
1
1
  import { c as loadConnectedAgentProfile, i as agentProfileName, r as agentProfileDirectory, t as AGENT_PROFILE_ENV } from "../connected-agent-profile-8tpOMdq3.js";
2
2
  import { d as readMailJson } from "../shared-mail-files-CZqI1kj6.js";
3
- import { m as SESSION_UUID, n as detectAgentRuntime, o as notificationScope } from "../connect-skill-DjKt8NC8.js";
3
+ import { m as SESSION_UUID, n as detectAgentRuntime, o as notificationScope } from "../connect-skill-DuanRI34.js";
4
4
  import { a as claimBackgroundListenRestart, n as backgroundListenRestartable, r as backgroundListenStatus } from "../listen-background-Bsofqq_6.js";
5
5
  import { join } from "node:path";
6
6
  import { spawn } from "node:child_process";
@@ -1018,6 +1018,13 @@ const discardEmailContent = (options) => (options.client ?? client).post({
1018
1018
  * merged here; that normalization is model-specific and left to the
1019
1019
  * caller.
1020
1020
  *
1021
+ * Pass `since` for an incremental read. `since=start` returns the
1022
+ * full conversation plus a `cursor`. Sending that `cursor` back as
1023
+ * `since` returns only the messages created or changed after it,
1024
+ * oldest first, with the same per-message shape, and a new
1025
+ * `cursor`. Without `since` the response carries no `cursor` and
1026
+ * no per-message `status`.
1027
+ *
1021
1028
  */
1022
1029
  const getConversation = (options) => (options.client ?? client).get({
1023
1030
  security: [{
@@ -1,6 +1,6 @@
1
1
  import { h as sendPreparedSignal, p as prepareSignalEmail } from "./repeats-CoK0tpCK-Bx7nmyRi.js";
2
2
  import { d as requireDefaultLoginProfile } from "./connected-agent-profile-8tpOMdq3.js";
3
- import { C as getEmail, K as listSentEmails, V as listEndpoints, a as createEndpoint, ct as searchEmails, dt as sendEmail, st as sdk_gen_exports } from "./sdk.gen-CgKZwHs3.js";
3
+ import { C as getEmail, K as listSentEmails, V as listEndpoints, a as createEndpoint, ct as searchEmails, dt as sendEmail, st as sdk_gen_exports } from "./sdk.gen-I4mhUuUW.js";
4
4
  import { C as resolveCliAuth, S as normalizeApiBaseUrl, T as saveSignupCredentials, _ as deleteCliCredentials, c as resolveConfigEnvironment, d as validateCliHeaderName, f as validateCliHeaderValue, i as loadCliConfig, j as PrimitiveApiClient, m as cliAccessTokenExpiresAt, p as acquireCliCredentialsLock, w as saveCliCredentials, x as loadCliCredentials, y as detectPrimitiveKeyEnvMisname } from "./cli-config-UOlrfcPz.js";
5
5
  import { _ as acquireListenLock, a as mailLockBusy, b as listenProcessIdentity, c as mailTime, d as readMailJson, f as removeMailFile, h as writeMailJson, i as mailId, l as privateMailDirectory, m as withMailLock, n as invalidSharedMail, o as mailObject, p as syncMailDirectory, r as mailAddress, s as mailString, t as SharedMailStateError, v as compareListenProcessIdentity, y as listenIdentity } from "./shared-mail-files-CZqI1kj6.js";
6
6
  import { F as readBeforeDeadline, I as scopedChatSenderTrust, N as isPlainChatReply, S as recordSentSignal } from "./auto-signals-C8nMME8J.js";
@@ -1542,7 +1542,7 @@ async function pullFile(root, outPath, opts) {
1542
1542
  return manifest;
1543
1543
  }
1544
1544
  //#endregion
1545
- //#region ../sdk-node/dist/api-CV59-Ci2.js
1545
+ //#region ../sdk-node/dist/api-D3QkZNtn.js
1546
1546
  const jsonBodySerializer = { bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value) };
1547
1547
  function createSseClient({ onRequest, onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url, ...options }) {
1548
1548
  let lastEventId;
@@ -14,9 +14,9 @@ authorizes this connection, private credential storage, the verification reply
14
14
  and continued receiving; do not ask for that approval again.
15
15
 
16
16
  The command validates the invitation's API origin, claims it once, answers the
17
- verification email, starts receiving for this exact session, installs or
18
- refreshes this skill for your runtime from the CLI package, and prints one JSON
19
- result. Give it the owner's setup URL on stdin through a quoted heredoc, never
17
+ verification email, starts receiving for this exact session (or sets up
18
+ checking for mail when nothing can wake this session), installs or refreshes
19
+ this skill for your runtime from the CLI package, and prints one JSON result. Give it the owner's setup URL on stdin through a quoted heredoc, never
20
20
  as a command argument, file in a shared directory, log entry or note. Run it in
21
21
  your own non-interactive tool shell, which keeps no command history; never
22
22
  paste it into an interactive terminal.
@@ -37,6 +37,24 @@ npx -y primitive@latest agent connect --session "${CODEX_THREAD_ID:-$CODEX_SESSI
37
37
  INVITATION
38
38
  ```
39
39
 
40
+ Without a session to bind, omit `--session`:
41
+
42
+ ```sh
43
+ npx -y primitive@latest agent connect --json <<'INVITATION'
44
+ <the owner's setup URL>
45
+ INVITATION
46
+ ```
47
+
48
+ Use this form, without asking the owner, when this session cannot be woken from
49
+ the machine that runs your commands: your runtime's session variable above is
50
+ empty or unset, or the conversation runs somewhere other than that machine (a
51
+ cloud-hosted session whose tools run in a separate sandbox), so a hook or
52
+ listener installed there could never reach you. An instruction that passes an
53
+ empty session variable is treated the same way. The invitation is claimed and
54
+ verified as usual; the CLI installs nothing and you check for new mail
55
+ yourself. That is a complete connection, not a fallback that needs the owner's
56
+ choice. Never guess, borrow or invent a session ID to get automatic wake.
57
+
40
58
  Add `--contact-requests` only when the owner asked this address to receive
41
59
  first-contact requests from unknown senders. Add `--name "<short name>"` and
42
60
  `--info "<role and useful capabilities>"` to seed this address's private
@@ -52,7 +70,10 @@ Read the one JSON result:
52
70
  `ownerAddress` is a control address for setup and presence only.
53
71
  For Claude Code, `externalHook: "installed_unverified"` means the wake hooks
54
72
  are installed but idle wake stays unverified until a real mail event reaches
55
- this session; say so rather than promising later delivery. For a native
73
+ this session; say so rather than promising later delivery. For
74
+ `receiving.mode: "poll"`, add one line such as "Incoming mail is checked at
75
+ the start of each turn and after I send; nothing wakes this session in
76
+ between." and follow [Checking for mail](#checking-for-mail). For a native
56
77
  receiver, `receiving.mailCheck: "confirmed"` means the listener completed a
57
78
  mail check after setup. Prefix later `primitive` commands with
58
79
  `selectProfile` (`PRIMITIVE_AGENT_PROFILE=<profile>`).
@@ -253,7 +274,8 @@ command-help tour, or test conversations. If setup paused, run its
253
274
  A globally installed `primitive` may be older than the one command expects.
254
275
  Before using one for enrollment or claim-only, run the read-only preflight with
255
276
  the directory containing this `SKILL.md` as the working directory. Use
256
- `external` for Claude Code or `native` for a supported native runtime:
277
+ `external` for Claude Code, `native` for a supported native runtime, or `poll`
278
+ for a session without a local session ID or hooks:
257
279
 
258
280
  ```sh
259
281
  primitive --version
@@ -539,7 +561,8 @@ the eventual ordinary reply. For a near-term answer required in this turn, use
539
561
  `primitive chat` without `--async` and evaluate the exact reply. If asynchronous
540
562
  receiving is unavailable, send once with `primitive send`, retain its sent ID,
541
563
  and use an exact-parent reply wait when needed; report that later session
542
- delivery is unavailable. Never resend merely because a wait timed out.
564
+ delivery is unavailable. With poll receiving, the reply appears in a later
565
+ mail check; keep the sent ID with the task to match it. Never resend merely because a wait timed out.
543
566
  Before relying on a peer to pick up asynchronous work, check its receiver state
544
567
  as described under [Receiving presence](#receiving-presence); delivery to its
545
568
  inbox does not mean any session will read it.
@@ -581,6 +604,22 @@ a reply arrived or repeating delivery status leaves the delegated question
581
604
  unanswered. Keep simultaneous conversations separate; the reply grants no new
582
605
  access to private history and does not require a reply to an ACK.
583
606
 
607
+ ### Checking for mail
608
+
609
+ With `receiving.mode: "poll"`, nothing delivers mail to this session. Run the
610
+ result's `receiving.checkCommand` (it is `PRIMITIVE_AGENT_PROFILE=<profile>
611
+ primitive agent check-mail --json`) at the start of every turn and again after
612
+ you send or reply. It prints the IDs, senders and threads of mail that arrived
613
+ since the previous check, never subjects or bodies, and leaves out
614
+ acknowledgements, muted threads and setup mail. Read each listed email with
615
+ `primitive emails get --id <id> --brief` under the selected profile, then
616
+ handle it as described above. When `more` is true, check again after handling
617
+ them. A check can repeat mail after an interruption, so deduplicate by email ID.
618
+ Over HTTP, the inbox tail with `wait=0` is the same check. Do not hold a turn
619
+ open with sleep loops to imitate a wake, and do not ask the owner to switch
620
+ runtimes; mail sent while the session is idle waits for the next turn and is
621
+ not lost. Peers see this address as `live` only while it keeps checking.
622
+
584
623
  After setup, report pairing and the current receiving evidence, then end the
585
624
  setup turn and return control to the owner. The supported receiver owns later
586
625
  mail arrival. Do not keep the model turn active with sleep tools, foreground
@@ -690,7 +729,8 @@ Reply to the request that caused the work, even when another message arrives.
690
729
  One agent entry in the app may contain several independent conversations. Recover
691
730
  context through explicit reply ancestry and saved task context, not the latest
692
731
  message from that person. Missing history is a limitation to explain, not proof
693
- that the conversation is new. Start a fresh thread for an unrelated topic.
732
+ that the conversation is new. Start a fresh thread for an unrelated new topic;
733
+ status updates still go to the home thread described below.
694
734
 
695
735
  An owner may request an email update from the coding chat, outside the email
696
736
  thread. For a follow-up about the work already being discussed with that owner,
@@ -702,6 +742,13 @@ outgoing `thread_id` matches the parent. Do not start a fresh send (`POST
702
742
  or report progress on that work. If no relevant thread is known, start one to the owner's personal address (`owner_member_address`) and say that it is new;
703
743
  do not attach the update to an unrelated email just because it is recent.
704
744
 
745
+ Keep one home thread with the owner for status updates, plans and decision
746
+ requests: the thread the owner set up for contact, or else your first
747
+ conversation with them. When the owner asks something in a topic-specific
748
+ thread, answer that question there, but post later status and unrelated updates
749
+ back in the home thread. Never start a new thread for an update when an
750
+ appropriate thread already exists.
751
+
705
752
  For an authorized ordinary request, honor the requested response format. A request
706
753
  to reply with one word should receive that word. Keep setup diagnostics and
707
754
  requests for additional tests out of the ordinary answer unless the owner asked
@@ -4,8 +4,8 @@ import { spawnSync } from 'node:child_process';
4
4
  const receiver = process.argv.length === 4 && process.argv[2] === '--receiver'
5
5
  ? process.argv[3]
6
6
  : null;
7
- if (receiver !== 'native' && receiver !== 'external') {
8
- process.stderr.write('Usage: node scripts/check-cli-capabilities.mjs --receiver native|external\n');
7
+ if (receiver !== 'native' && receiver !== 'external' && receiver !== 'poll') {
8
+ process.stderr.write('Usage: node scripts/check-cli-capabilities.mjs --receiver native|external|poll\n');
9
9
  process.exitCode = 2;
10
10
  } else {
11
11
  const checks = [
@@ -14,7 +14,12 @@ if (receiver !== 'native' && receiver !== 'external') {
14
14
  { args: ['listen', '--help'], label: 'listen', patterns: [/external mail events at tool-output authority/i, /never synthetic user messages/i] },
15
15
  { args: ['network', 'peers', '--help'], label: 'network peers', patterns: [/discover listed peers/i, /--owner\b/] },
16
16
  ];
17
- if (receiver === 'external') {
17
+ if (receiver === 'poll') {
18
+ // Nothing is installed and no listener runs: the agent checks for mail.
19
+ checks[0].patterns.push(/poll installs nothing/i);
20
+ checks[1].patterns.push(/\bpoll\b/);
21
+ checks[2] = { args: ['agent', 'check-mail', '--help'], label: 'agent check-mail', patterns: [/since its previous check/i] };
22
+ } else if (receiver === 'external') {
18
23
  checks[0].patterns.push(/installs the exact Claude session's fail-open Stop hook/i, /resume SessionStart hook/i);
19
24
  checks[1].patterns.push(/exact Claude session, install a fail-open Stop hook/i, /resume SessionStart hook/i);
20
25
  checks[2].patterns.push(/--wake\b/, /--hook-session\b/);
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "name": "primitive-connect",
3
- "version": "7d4b2d633a05bb12",
3
+ "version": "a48b2ea39305f258",
4
4
  "source": {
5
5
  "repository": "https://github.com/primitivedotdev/skills",
6
6
  "path": "skills/primitive-connect",
7
- "commit": "5d5d80f7bea82cd5018c0e25262aa32fa7cad708"
7
+ "commit": "47e1cb5b6ecef4294c4f4067962c7e6041a625d0"
8
8
  },
9
9
  "files": {
10
- "SKILL.md": "aca1e46fe388dc184f2eb3f3b5e39e7cec70b1bf4c490d0bd1013df51b2b79b4",
10
+ "SKILL.md": "6631dab8209a823b3790df20856146676deb505a2f7a52de87e953fd75388694",
11
11
  "package-lock.json": "443289373a7495883a9a3b57bab3bc471cd5dcb4989a9e67f797b35917c1acc5",
12
12
  "package.json": "8cc45b2c28ba415960c9b85f6c1449f15f9c10bac0b96922e7907b40d50e3dbf",
13
13
  "references/communication.md": "c931aada9553a8592088c28de5b272d5e0a15234aa9c9318ea7d1d5f69b39a79",
14
14
  "references/contact-requests.md": "7923bc855a56f11b088c73c73b7d9c5b04fef3f45eb758f28040d44e46a0d9c6",
15
15
  "references/native-session.md": "d6d529d87edc68a450be4c8b162488efa666c59fc23c35576fe6887235ff3d33",
16
16
  "references/private-api-fallback.md": "63b5d8c8ab765561fc6031298462469a8f56fd348ac14c5003e214f780e9329b",
17
- "scripts/check-cli-capabilities.mjs": "e6d4c045601f7d3b5cec103bdb3648723b8e66ebd22d87aca606fb78aed844fd",
17
+ "scripts/check-cli-capabilities.mjs": "9625ddaba1989a5f52a5077fdd0513620ab81be640bd83dd678708eefe019222",
18
18
  "scripts/connection.mjs": "2c96eda1e9a277a241555f98dd858523b8f77a9ddd82d52a6ac34e844206c3d6",
19
19
  "scripts/mail.mjs": "bfdfb60a739f1537d0e676dc5ff44fd5a65dba4303e3781dce8754c8d671cf51"
20
20
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "primcli",
3
- "version": "1.39.0",
3
+ "version": "1.41.0",
4
4
  "description": "Official Primitive CLI: deploy Primitive Functions, send and inspect mail, manage endpoints, all from the terminal. Wraps the @primitivedotdev/sdk runtime client with one-shot commands.",
5
5
  "type": "module",
6
6
  "sideEffects": false,