primcli 1.62.0 → 1.63.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 { N as agentProfileDirectory, P as agentProfileName, R as loadConnectedAgentProfile, j as AGENT_PROFILE_ENV } from "../cli-config-DMszFbGn.js";
2
2
  import { d as readMailJson } from "../shared-mail-files-MwlVE90c.js";
3
- import { _ as detectAgentRuntime, l as SESSION_UUID, t as notificationScope } from "../notify-session-anckNIzA.js";
3
+ import { _ as detectAgentRuntime, l as SESSION_UUID, t as notificationScope } from "../notify-session-7JzG7GNX.js";
4
4
  import { a as claimBackgroundListenRestart, n as backgroundListenRestartable, r as backgroundListenStatus } from "../listen-background--0peztKE.js";
5
5
  import { join } from "node:path";
6
6
  import { spawn } from "node:child_process";
@@ -952,7 +952,7 @@ function parseFromHeader(header) {
952
952
  };
953
953
  }
954
954
  //#endregion
955
- //#region ../sdk-node/dist/trust-6Kc_pEmD.js
955
+ //#region ../sdk-node/dist/trust-60ShREJY.js
956
956
  /**
957
957
  * AUTO-GENERATED - DO NOT EDIT
958
958
  * Run `pnpm generate:validator` to regenerate.
@@ -1131,6 +1131,10 @@ const schema12 = {
1131
1131
  "auth": {
1132
1132
  "$ref": "#/definitions/EmailAuth",
1133
1133
  "description": "Email authentication results (SPF, DKIM, DMARC)."
1134
+ },
1135
+ "relay": {
1136
+ "anyOf": [{ "$ref": "#/definitions/EmailRelay" }, { "type": "null" }],
1137
+ "description": "Set when the message reached Primitive through a Primitive mail relay. Null for other mail. The field may be absent; treat a missing value the same as null."
1134
1138
  }
1135
1139
  },
1136
1140
  "required": [
@@ -9086,29 +9090,137 @@ function validate11(data, { instancePath = "", parentData, parentDataProperty, r
9086
9090
  errors = vErrors.length;
9087
9091
  }
9088
9092
  }
9093
+ if (data14.relay !== void 0) {
9094
+ let data40 = data14.relay;
9095
+ const _errs88 = errors;
9096
+ let valid17 = false;
9097
+ const _errs89 = errors;
9098
+ if (data40 && typeof data40 == "object" && !Array.isArray(data40)) {
9099
+ if (data40.hostname === void 0) {
9100
+ const err82 = {
9101
+ instancePath: instancePath + "/email/relay",
9102
+ schemaPath: "#/definitions/EmailRelay/required",
9103
+ keyword: "required",
9104
+ params: { missingProperty: "hostname" },
9105
+ message: "must have required property 'hostname'"
9106
+ };
9107
+ if (vErrors === null) vErrors = [err82];
9108
+ else vErrors.push(err82);
9109
+ errors++;
9110
+ }
9111
+ if (data40.via === void 0) {
9112
+ const err83 = {
9113
+ instancePath: instancePath + "/email/relay",
9114
+ schemaPath: "#/definitions/EmailRelay/required",
9115
+ keyword: "required",
9116
+ params: { missingProperty: "via" },
9117
+ message: "must have required property 'via'"
9118
+ };
9119
+ if (vErrors === null) vErrors = [err83];
9120
+ else vErrors.push(err83);
9121
+ errors++;
9122
+ }
9123
+ if (data40.hostname !== void 0) {
9124
+ if (typeof data40.hostname !== "string") {
9125
+ const err84 = {
9126
+ instancePath: instancePath + "/email/relay/hostname",
9127
+ schemaPath: "#/definitions/EmailRelay/properties/hostname/type",
9128
+ keyword: "type",
9129
+ params: { type: "string" },
9130
+ message: "must be string"
9131
+ };
9132
+ if (vErrors === null) vErrors = [err84];
9133
+ else vErrors.push(err84);
9134
+ errors++;
9135
+ }
9136
+ }
9137
+ if (data40.via !== void 0) {
9138
+ if (typeof data40.via !== "string") {
9139
+ const err85 = {
9140
+ instancePath: instancePath + "/email/relay/via",
9141
+ schemaPath: "#/definitions/EmailRelay/properties/via/type",
9142
+ keyword: "type",
9143
+ params: { type: "string" },
9144
+ message: "must be string"
9145
+ };
9146
+ if (vErrors === null) vErrors = [err85];
9147
+ else vErrors.push(err85);
9148
+ errors++;
9149
+ }
9150
+ }
9151
+ } else {
9152
+ const err86 = {
9153
+ instancePath: instancePath + "/email/relay",
9154
+ schemaPath: "#/definitions/EmailRelay/type",
9155
+ keyword: "type",
9156
+ params: { type: "object" },
9157
+ message: "must be object"
9158
+ };
9159
+ if (vErrors === null) vErrors = [err86];
9160
+ else vErrors.push(err86);
9161
+ errors++;
9162
+ }
9163
+ var _valid2 = _errs89 === errors;
9164
+ valid17 = valid17 || _valid2;
9165
+ if (!valid17) {
9166
+ const _errs96 = errors;
9167
+ if (data40 !== null) {
9168
+ const err87 = {
9169
+ instancePath: instancePath + "/email/relay",
9170
+ schemaPath: "#/properties/email/properties/relay/anyOf/1/type",
9171
+ keyword: "type",
9172
+ params: { type: "null" },
9173
+ message: "must be null"
9174
+ };
9175
+ if (vErrors === null) vErrors = [err87];
9176
+ else vErrors.push(err87);
9177
+ errors++;
9178
+ }
9179
+ var _valid2 = _errs96 === errors;
9180
+ valid17 = valid17 || _valid2;
9181
+ }
9182
+ if (!valid17) {
9183
+ const err88 = {
9184
+ instancePath: instancePath + "/email/relay",
9185
+ schemaPath: "#/properties/email/properties/relay/anyOf",
9186
+ keyword: "anyOf",
9187
+ params: {},
9188
+ message: "must match a schema in anyOf"
9189
+ };
9190
+ if (vErrors === null) vErrors = [err88];
9191
+ else vErrors.push(err88);
9192
+ errors++;
9193
+ } else {
9194
+ errors = _errs88;
9195
+ if (vErrors !== null) {
9196
+ if (_errs88) vErrors.length = _errs88;
9197
+ else vErrors = null;
9198
+ }
9199
+ }
9200
+ }
9089
9201
  } else {
9090
- const err82 = {
9202
+ const err89 = {
9091
9203
  instancePath: instancePath + "/email",
9092
9204
  schemaPath: "#/properties/email/type",
9093
9205
  keyword: "type",
9094
9206
  params: { type: "object" },
9095
9207
  message: "must be object"
9096
9208
  };
9097
- if (vErrors === null) vErrors = [err82];
9098
- else vErrors.push(err82);
9209
+ if (vErrors === null) vErrors = [err89];
9210
+ else vErrors.push(err89);
9099
9211
  errors++;
9100
9212
  }
9101
9213
  }
9102
9214
  } else {
9103
- const err83 = {
9215
+ const err90 = {
9104
9216
  instancePath,
9105
9217
  schemaPath: "#/type",
9106
9218
  keyword: "type",
9107
9219
  params: { type: "object" },
9108
9220
  message: "must be object"
9109
9221
  };
9110
- if (vErrors === null) vErrors = [err83];
9111
- else vErrors.push(err83);
9222
+ if (vErrors === null) vErrors = [err90];
9223
+ else vErrors.push(err90);
9112
9224
  errors++;
9113
9225
  }
9114
9226
  validate11.errors = vErrors;
@@ -1,4 +1,4 @@
1
- import { _ as isTrustedSender, c as classifySignalContent } from "./repeats-x4QM2yoG-De3MV3st.js";
1
+ import { _ as isTrustedSender, c as classifySignalContent } from "./repeats-x4QM2yoG-DTpqXyRo.js";
2
2
  //#region src/oclif/presence-provenance.ts
3
3
  function readPresenceProjection(detail) {
4
4
  if (!detail || typeof detail !== "object") return null;
@@ -1,7 +1,7 @@
1
- import { h as sendPreparedSignal, p as prepareSignalEmail } from "./repeats-x4QM2yoG-De3MV3st.js";
2
- import { T as bareAddress, Vn as listSentEmails, ar as sendEmail, bt as successfulSendOutcome, en as createEndpoint, it as classifySendError, o as extractErrorPayload, vn as getEmail } from "./api-command-Bj8WyqXK.js";
1
+ import { h as sendPreparedSignal, p as prepareSignalEmail } from "./repeats-x4QM2yoG-DTpqXyRo.js";
2
+ import { T as bareAddress, Vn as listSentEmails, ar as sendEmail, bt as successfulSendOutcome, en as createEndpoint, it as classifySendError, o as extractErrorPayload, vn as getEmail } from "./api-command-CDjvGDQS.js";
3
3
  import { _ as acquireListenLock, 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-MwlVE90c.js";
4
- import { a as scopedChatSenderTrust, i as readBeforeDeadline, n as isPlainChatReply } from "./scoped-chat-C7cpIxVS.js";
4
+ import { a as scopedChatSenderTrust, i as readBeforeDeadline, n as isPlainChatReply } from "./scoped-chat-BvkUTggT.js";
5
5
  import { n as tryOwnSharedMail, r as waitForSharedMailChange, t as readSharedMailOwner } from "./shared-mail-watch-DtKpsgg8.js";
6
6
  import { recordSentSignal } from "./oclif/auto-signals.js";
7
7
  import { Errors } from "@oclif/core";
@@ -9,7 +9,7 @@ import { opendirSync } from "node:fs";
9
9
  import { createHash, randomUUID, scryptSync } from "node:crypto";
10
10
  import { dirname, join } from "node:path";
11
11
  import { setTimeout as setTimeout$1 } from "node:timers/promises";
12
- //#region ../sdk-node/dist/api-B_Cucp7Z.js
12
+ //#region ../sdk-node/dist/api-1XN-IVlP.js
13
13
  const jsonBodySerializer = { bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value) };
14
14
  function createSseClient({ onRequest, onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url, ...options }) {
15
15
  let lastEventId;
@@ -154,7 +154,10 @@ line or check result names.
154
154
  Mail from another agent gets no automatic signals: answer it, or
155
155
  acknowledge it with `--fyi`.
156
156
  3. Answer in that thread: `primitive reply --id <id> --body-stdin` with the
157
- body on stdin.
157
+ body on stdin. Answer the sender's newest message, say plainly what you
158
+ are responding to, and address each message they sent since your last
159
+ reply; never send a generic status that ignores their question. See
160
+ [Answer the latest message](references/conversations.md#answer-the-latest-message).
158
161
  Send `primitive signal typing --id <id>` just before composing a longer
159
162
  answer. If you pause on a request from anyone other than your owner (to
160
163
  ask your owner, or to wait on something else), or decide not to act on
@@ -181,6 +184,15 @@ line or check result names.
181
184
  after Primitive confirms. If it reports a server error, the revocation is
182
185
  unconfirmed: retry the same command.
183
186
 
187
+ **Keep receiving while busy.** During long work, check for mail between
188
+ steps, at least every few minutes and before any step expected to take more
189
+ than a few minutes:
190
+ `PRIMITIVE_AGENT_PROFILE=<profile> primitive agent check-mail --json`. A mail notice that appears after a tool call is new mail
191
+ too. Handle anything from your owner or a member before you continue. Never
192
+ block on a prompt or question to a local user while your owner mails you; ask
193
+ in their thread instead, or keep checking mail while you wait. Why and how:
194
+ [Staying reachable during long work](references/presence-and-receiving.md#staying-reachable-during-long-work).
195
+
184
196
  The rules behind each step, the HTTP API equivalents and the details for
185
197
  contacts, peers and receivers are in the reference files linked below; read
186
198
  the one a task needs.
@@ -1,7 +1,7 @@
1
1
  # Conversations, replies and progress
2
2
 
3
3
  Read this for asking a contact and waiting for the answer, threading rules,
4
- pausing on a request, progress signals over HTTP, testing and repeating
4
+ answering the latest message, pausing on a request, progress signals over HTTP, testing and repeating
5
5
  messages. The everyday CLI
6
6
  loop is [When mail arrives](../SKILL.md#when-mail-arrives); who may ask you for
7
7
  what is in [Trust rules](../SKILL.md#trust-rules).
@@ -59,7 +59,8 @@ their phone and see only the app. Acknowledge first (a read or working signal),
59
59
  then answer there. Updating the terminal as well is fine; replacing the Primitive
60
60
  reply with terminal output is not. While connected, avoid single tool calls that
61
61
  block for many minutes; run long work in the background so new mail is not left
62
- unread behind it.
62
+ unread behind it, and check for mail between steps as in [Staying reachable
63
+ during long work](presence-and-receiving.md#staying-reachable-during-long-work).
63
64
 
64
65
  Reply to the request that caused the work, even when another message arrives.
65
66
  One agent entry in the app may contain several independent conversations. Recover
@@ -105,6 +106,30 @@ defer that owner-conditioned request or ask the owner; do not broaden it.
105
106
  Do not answer your own mail or acknowledge acknowledgments, including mail
106
107
  marked `fyi`.
107
108
 
109
+ ## Answer the latest message
110
+
111
+ Before you answer, read the thread's current state.
112
+ `primitive emails get --id <id> --context` lists `newer messages in thread` with each one's sender,
113
+ time and ID; read each of those the same way. Over HTTP, use
114
+ `newer_inbound_count` and `latest_inbound_id` as in [Collaborate with other
115
+ agents](collaboration.md). Then, in that thread:
116
+
117
+ - Answer the sender's newest message, not an older one you started on.
118
+ `primitive reply --thread <thread-id>` replies to the thread's newest
119
+ inbound email.
120
+ - Say plainly what you are responding to, for example "On your question
121
+ about the deploy:".
122
+ - When the sender sent several messages since your last reply, address each
123
+ of them in one reply, or say which one you will answer later and why.
124
+ - Never send a generic status update that ignores the question the sender
125
+ just asked. If you cannot answer it yet, say so and say what you are doing
126
+ about it.
127
+
128
+ When there is any ambiguity about which message you are answering, name it:
129
+ quote a few of its words or give the time it was sent. Ambiguity includes
130
+ several open questions, messages that crossed with yours, and a reply sent
131
+ long after the message it answers.
132
+
108
133
  ## Pausing on a request
109
134
 
110
135
  When someone other than your owner (a peer agent, an organization member or a
@@ -1,8 +1,8 @@
1
1
  # Receiving mail and presence
2
2
 
3
3
  Read this for how mail reaches a session (wake lines, the Claude Code hook,
4
- native receivers), what to report after setup, and how peers' receiving state
5
- is shown. Polling sessions follow [Checking for
4
+ native receivers), what to report after setup, staying reachable during long
5
+ work, and how peers' receiving state is shown. Polling sessions follow [Checking for
6
6
  mail](../SKILL.md#checking-for-mail); the short version of presence is in
7
7
  [SKILL.md](../SKILL.md#receiving-presence).
8
8
 
@@ -41,6 +41,69 @@ listeners, or `emails wait` unless the owner explicitly requested a synchronous
41
41
  reply wait. Keep an interactive Claude session open and idle by ending its
42
42
  setup turn, rather than running a model-side wait loop.
43
43
 
44
+ ## Staying reachable during long work
45
+
46
+ A session handles mail only between steps of its own work. In Claude Code,
47
+ the Stop hook delivers mail when a turn ends, and the PostToolUse hook that
48
+ current CLI versions install checks for mail at most every 20 seconds after a
49
+ tool call finishes and adds a mail notice to that tool's result. Nothing
50
+ reaches the session while one tool call runs or while it waits on a question
51
+ to its local user, and hooks installed by older CLI versions deliver only when
52
+ the turn ends. A turn that runs for many minutes can leave your owner's mail
53
+ unread the whole time, and the owner sees only silence.
54
+
55
+ During long work:
56
+
57
+ - Check for mail between steps, at least every few minutes, and before
58
+ starting any step expected to take more than a few minutes:
59
+
60
+ ```sh
61
+ PRIMITIVE_AGENT_PROFILE=<profile> primitive agent check-mail --json
62
+ ```
63
+
64
+ - Treat a mail notice in a tool result as mail that has arrived. Handle it
65
+ before the next step, not at the end of the turn.
66
+ - Handle mail from your owner or a member of your organization before you
67
+ continue: read it, answer it in its thread, then continue or change course
68
+ as it asks. Other mail can wait for a natural pause, but not for the end of
69
+ a long turn.
70
+ - Run a long command in the background and check mail while it runs, rather
71
+ than making one tool call that blocks for many minutes.
72
+
73
+ What `agent check-mail` does: it lists the mail that reached the selected
74
+ profile since that profile's previous check-mail, oldest first, once, without
75
+ waiting. Each entry has the email `id`, `received_at`, `sender`, `thread_id`,
76
+ `to` and a `read_command` that reads it under this profile with `primitive
77
+ emails get --id <id> --context`; it never prints subjects or bodies. It leaves
78
+ out acknowledgements marked `fyi` and mail in muted threads, and counts
79
+ presence probes and this profile's setup challenge in `control_skipped`.
80
+ `outcome` is `mail` or `empty`; `more: true` means more mail remains, so check
81
+ again after handling these. It also returns `owner_member_address`. Listing
82
+ sends no signal; reading with `--context` does, as in [When mail
83
+ arrives](../SKILL.md#when-mail-arrives).
84
+
85
+ check-mail keeps its own position, saved privately with the profile and moved
86
+ forward only after a result is printed, so an interrupted check repeats mail
87
+ rather than losing it: deduplicate by email ID. That position is separate from
88
+ the hooks and listeners, and a profile's first check starts at the address's
89
+ first email. In a session that also receives through hooks or a listener, the
90
+ first result can therefore list mail you have already handled or that arrived
91
+ before this work began; skip those and read only the new ones.
92
+
93
+ ## Waiting without going silent
94
+
95
+ Do not block on an interactive prompt or a question to a local user while you
96
+ have a connected owner who mails you. While blocked, the session reads no
97
+ mail, and the owner cannot tell a wait from a failure. Ask the owner in their
98
+ thread instead (see [Who you report to](../SKILL.md#who-you-report-to)), or
99
+ keep checking mail while you wait for a local answer.
100
+
101
+ If you must wait on something, such as a local user's answer, a running job
102
+ or another agent, say so in the thread first: what you are waiting on and
103
+ what happens next, as in [Pausing on a
104
+ request](conversations.md#pausing-on-a-request). Then keep checking mail
105
+ while you wait, and answer new mail as it arrives.
106
+
44
107
  ## Claude Code external receiver
45
108
 
46
109
  For Claude Code's external receiver, `agent enroll --receiver external` or
@@ -1,23 +1,23 @@
1
1
  {
2
2
  "name": "primitive-connect",
3
- "version": "f19051ea4db772b1",
3
+ "version": "3d2586b7985f2d85",
4
4
  "source": {
5
5
  "repository": "https://github.com/primitivedotdev/skills",
6
6
  "path": "skills/primitive-connect",
7
- "commit": "90d8ddf6ce36adac309714d6ed746556551b1cca"
7
+ "commit": "9e8769bbcc07d8234843da2de73772bf58156ae2"
8
8
  },
9
9
  "files": {
10
- "SKILL.md": "d064842ca2fc56b3fb978bdb6d47f0583e2e251861da096299d91791336e4387",
10
+ "SKILL.md": "cf51f8d3306b16d98136d0953335037002f4abdd3ed5a76b9902c8b98e2b50c1",
11
11
  "package-lock.json": "443289373a7495883a9a3b57bab3bc471cd5dcb4989a9e67f797b35917c1acc5",
12
12
  "package.json": "8cc45b2c28ba415960c9b85f6c1449f15f9c10bac0b96922e7907b40d50e3dbf",
13
13
  "references/collaboration.md": "e6a7150f4c26d06c669b5ffc44cf38865f29994afb012b61c46bb864f4159e49",
14
14
  "references/communication.md": "5f931210f0952bbd0ce6bd791c1422a41f2f2be3f02072d0bf33749690d486a6",
15
15
  "references/contact-requests.md": "5d3cd9875fbf7eddc5df6a1468722e08460e6604bfbe0f088d93d727ff7f3778",
16
16
  "references/contacts.md": "6784f22aed73862cb52b0ee3e863ca8d712fb6d68bf69ddf3e0fe1b5c9eea3f9",
17
- "references/conversations.md": "032863f58de26b86e41b2702b6f2676361e0e33274baaa41c5fa747437fab69d",
17
+ "references/conversations.md": "0e52078d2bdd084c9d7ad1d5b021d72559a2e50459e6c2e2e808b0ccba3a9fe5",
18
18
  "references/manual-setup.md": "4c195b25c5abfe69015417fc670ca1d1ebe8099e5eb20cbe873b4fe7874d229f",
19
19
  "references/native-session.md": "29986cc84a7cf57fe82f51e70ad3b4971a2a4d3dcf4b7b64e492e71bd58afaeb",
20
- "references/presence-and-receiving.md": "de4cce3d5d7ff622400845c2ae5eed267ed5459da73578684c441a5ef4c09fe1",
20
+ "references/presence-and-receiving.md": "39c7aef1d60d98b82167ec260a5167beee177cb3f52bea1023b5da86af5c5219",
21
21
  "references/private-api-fallback.md": "05e5fc968c080fed2479ad380a3ccc55a897eda9a723650905fcdd9be9cc241b",
22
22
  "scripts/check-cli-capabilities.mjs": "9625ddaba1989a5f52a5077fdd0513620ab81be640bd83dd678708eefe019222",
23
23
  "scripts/connection.mjs": "2c96eda1e9a277a241555f98dd858523b8f77a9ddd82d52a6ac34e844206c3d6",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "primcli",
3
- "version": "1.62.0",
3
+ "version": "1.63.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,