primcli 1.74.1 → 1.75.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 (26) hide show
  1. package/README.md +49 -9
  2. package/dist/{api-command-fKP3NYa7.js → api-command-rlS3eTlZ.js} +77 -43
  3. package/dist/{cli-config-C0Y_Ppol.js → cli-config-B80p0pLk.js} +7 -12
  4. package/dist/{client.gen-CaaMP86o.js → client.gen-6rZvmHfx.js} +7 -14
  5. package/dist/{json-output-Ce10AsSb.js → json-output-BzSBR-KX.js} +1 -2
  6. package/dist/{listen-background-cD6n8VYO.js → listen-background-C0F9gNDD.js} +2 -3
  7. package/dist/{machine-session-B6V5-grn.js → machine-session-Cq_nD5eF.js} +144 -92
  8. package/dist/{notify-session-DJAb9SGm.js → notify-session-CbY4FYUt.js} +10 -30
  9. package/dist/oclif/auto-signal-worker.js +5 -6
  10. package/dist/oclif/auto-signals.js +3 -4
  11. package/dist/oclif/help.js +127 -0
  12. package/dist/oclif/index.js +414 -344
  13. package/dist/oclif/listen-supervisor.js +1 -1
  14. package/dist/oclif/proxy-auto-detect.js +2 -3
  15. package/dist/oclif/receiver-heal.js +6 -6
  16. package/dist/oclif/root-signup-hint.js +2 -3
  17. package/dist/{repeats-BL7ZC-_6-B_ESsWTH.js → repeats-Dj_o6c-X-LyCkKYjp.js} +552 -213
  18. package/dist/{scoped-chat-DAiOb622.js → scoped-chat-B0thCwME.js} +3 -5
  19. package/dist/{shared-mail-files-CZfm7E2k.js → shared-mail-files-BAQSGxxz.js} +2 -4
  20. package/dist/{shared-mail-watch-DyQB0MK0.js → shared-mail-watch-BAPMsFNv.js} +2 -3
  21. package/dist/{signal-command-Cte4mAL3.js → signal-command-DCPsJBdz.js} +14 -23
  22. package/dist/skills/primitive-connect/references/connect.md +3 -1
  23. package/dist/skills/primitive-connect/references/contacts.md +9 -4
  24. package/dist/skills/primitive-connect.json +4 -4
  25. package/man/primitive.1 +10 -3
  26. package/package.json +14 -9
@@ -1,5 +1,5 @@
1
- import { b as retryTransient, c as classifySignalContent, q as isTrustedSender } from "./repeats-BL7ZC-_6-B_ESsWTH.js";
2
- //#region src/oclif/presence-provenance.ts
1
+ import { b as retryTransient, c as classifySignalContent, q as isTrustedSender } from "./repeats-Dj_o6c-X-LyCkKYjp.js";
2
+ // src/oclif/presence-provenance.ts
3
3
  function readPresenceProjection(detail) {
4
4
  if (!detail || typeof detail !== "object") return null;
5
5
  const value = detail.presence_control;
@@ -24,8 +24,7 @@ function presenceDisposition(detail) {
24
24
  const proof = readPresenceProjection(detail);
25
25
  return !proof || proof.status === "rejected" ? "ordinary" : proof.status === "verified" ? "quiet" : "pending";
26
26
  }
27
- //#endregion
28
- //#region src/oclif/scoped-chat.ts
27
+ // src/oclif/scoped-chat.ts
29
28
  function isConnectedChatCredential(apiKey) {
30
29
  return apiKey?.startsWith("pconn_") ?? false;
31
30
  }
@@ -96,5 +95,4 @@ function isPlainChatReply(detail) {
96
95
  canonicalPartBytes: null
97
96
  }).classification === "plain";
98
97
  }
99
- //#endregion
100
98
  export { readBeforeDeadline as a, readPresenceProjection as c, readApiBeforeDeadline as i, isPlainChatReply as n, scopedChatSenderTrust as o, isScopedChatReply as r, presenceDisposition as s, isConnectedChatCredential as t };
@@ -3,7 +3,7 @@ import { createHash, randomUUID } from "node:crypto";
3
3
  import { dirname, join, win32 } from "node:path";
4
4
  import { setTimeout } from "node:timers/promises";
5
5
  import { execFileSync } from "node:child_process";
6
- //#region src/oclif/listen-state.ts
6
+ // src/oclif/listen-state.ts
7
7
  var ListenStateError = class extends Error {};
8
8
  function normalizeListenOrigin(value) {
9
9
  const url = new URL(value);
@@ -247,8 +247,7 @@ function resolveListenSubscription(configDir, identity, explicit) {
247
247
  release: acquireListenLock(directory, `subscription:${name}`)
248
248
  };
249
249
  }
250
- //#endregion
251
- //#region src/oclif/shared-mail-files.ts
250
+ // src/oclif/shared-mail-files.ts
252
251
  var SharedMailStateError = class extends ListenStateError {};
253
252
  const invalidSharedMail = () => new SharedMailStateError("Shared mail state is invalid or inconsistent. Preserve it before retrying to avoid duplicate delivery.");
254
253
  function privateMailPermissions(info, platform = process.platform) {
@@ -371,5 +370,4 @@ function mailTime(value) {
371
370
  if (!Number.isFinite(Date.parse(time))) throw invalidSharedMail();
372
371
  return new Date(time).toISOString();
373
372
  }
374
- //#endregion
375
373
  export { resolveListenSubscription as C, normalizeListenOrigin as S, acquireListenLock as _, mailLockBusy as a, listenLockHeld as b, mailTime as c, readMailJson as d, removeMailFile as f, ListenStateError as g, writeMailJson as h, mailId as i, privateMailDirectory as l, withMailLock as m, invalidSharedMail as n, mailObject as o, syncMailDirectory as p, mailAddress as r, mailString as s, SharedMailStateError as t, privateMailPermissions as u, compareListenProcessIdentity as v, listenProcessIdentity as x, listenIdentity as y };
@@ -1,8 +1,8 @@
1
- import { _ as acquireListenLock, a as mailLockBusy, c as mailTime, d as readMailJson, f as removeMailFile, h as writeMailJson, i as mailId, n as invalidSharedMail, o as mailObject, s as mailString, v as compareListenProcessIdentity, x as listenProcessIdentity } from "./shared-mail-files-CZfm7E2k.js";
1
+ import { _ as acquireListenLock, a as mailLockBusy, c as mailTime, d as readMailJson, f as removeMailFile, h as writeMailJson, i as mailId, n as invalidSharedMail, o as mailObject, s as mailString, v as compareListenProcessIdentity, x as listenProcessIdentity } from "./shared-mail-files-BAQSGxxz.js";
2
2
  import { watch } from "node:fs";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import { join } from "node:path";
5
- //#region src/oclif/shared-mail-watch.ts
5
+ // src/oclif/shared-mail-watch.ts
6
6
  function ownerRecord(value) {
7
7
  const o = mailObject(value, [
8
8
  "generation",
@@ -141,5 +141,4 @@ function waitForSharedMailChange(store, options) {
141
141
  }
142
142
  });
143
143
  }
144
- //#endregion
145
144
  export { tryOwnSharedMail as n, waitForSharedMailChange as r, readSharedMailOwner as t };
@@ -1,15 +1,15 @@
1
- import { Dn as sendEmail, Ft as getEmail, _ as describeApiFailure, cn as listSentEmails, h as sendPreparedSignal, p as prepareSignalEmail, pt as createEndpoint } from "./repeats-BL7ZC-_6-B_ESsWTH.js";
2
- import { _ as acquireListenLock, 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, x as listenProcessIdentity, y as listenIdentity } from "./shared-mail-files-CZfm7E2k.js";
3
- import { Y as classifySendError, dt as successfulSendOutcome, h as bareAddress, o as extractErrorPayload } from "./api-command-fKP3NYa7.js";
4
- import { i as readApiBeforeDeadline, n as isPlainChatReply, o as scopedChatSenderTrust } from "./scoped-chat-DAiOb622.js";
5
- import { n as tryOwnSharedMail, r as waitForSharedMailChange, t as readSharedMailOwner } from "./shared-mail-watch-DyQB0MK0.js";
1
+ import { Dn as sendEmail, Ft as getEmail, _ as describeApiFailure, cn as listSentEmails, h as sendPreparedSignal, p as prepareSignalEmail, pt as createEndpoint } from "./repeats-Dj_o6c-X-LyCkKYjp.js";
2
+ import { Y as classifySendError, dt as successfulSendOutcome, h as bareAddress, o as extractErrorPayload } from "./api-command-rlS3eTlZ.js";
6
3
  import { recordSentSignal } from "./oclif/auto-signals.js";
4
+ import { _ as acquireListenLock, 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, x as listenProcessIdentity, y as listenIdentity } from "./shared-mail-files-BAQSGxxz.js";
5
+ import { i as readApiBeforeDeadline, n as isPlainChatReply, o as scopedChatSenderTrust } from "./scoped-chat-B0thCwME.js";
6
+ import { n as tryOwnSharedMail, r as waitForSharedMailChange, t as readSharedMailOwner } from "./shared-mail-watch-BAPMsFNv.js";
7
7
  import { Errors } from "@oclif/core";
8
8
  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-DcpEJV3m.js
12
+ // ../sdk-node/dist/api-D7-k6yPG.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;
@@ -842,8 +842,7 @@ var EventConnection = class {
842
842
  if (!record$1(receipt) || !["completed", "already_completed"].includes(String(receipt.result))) throw new EventReceiverError("Invalid event receipt", "invalid_response");
843
843
  }
844
844
  };
845
- //#endregion
846
- //#region src/oclif/email-participants.ts
845
+ // src/oclif/email-participants.ts
847
846
  /**
848
847
  * Everyone else an email was addressed to: its parsed To and Cc, as bare
849
848
  * lowercase addresses, without `self` (the mailbox reading it) or the sender,
@@ -878,8 +877,7 @@ function otherParticipants(detail, self) {
878
877
  }
879
878
  return named ? out : [];
880
879
  }
881
- //#endregion
882
- //#region src/oclif/conversation-follow.ts
880
+ // src/oclif/conversation-follow.ts
883
881
  function directory(context) {
884
882
  const key = createHash("sha256").update(JSON.stringify([context.scope, mailAddress(context.recipient)])).digest("hex");
885
883
  return join(context.configDir, "conversation-follows", key);
@@ -943,8 +941,7 @@ async function followEmailConversation(context, detail) {
943
941
  return follow;
944
942
  });
945
943
  }
946
- //#endregion
947
- //#region src/oclif/shared-mail-state.ts
944
+ // src/oclif/shared-mail-state.ts
948
945
  function createSharedMailWaiter() {
949
946
  return {
950
947
  token: randomUUID(),
@@ -1830,8 +1827,7 @@ async function openSharedMailStore(options) {
1830
1827
  }
1831
1828
  };
1832
1829
  }
1833
- //#endregion
1834
- //#region src/oclif/listen-credential.ts
1830
+ // src/oclif/listen-credential.ts
1835
1831
  /** The API's code for an account credential creating a pull subscription. */
1836
1832
  const AGENT_CONNECTION_REQUIRED = "pull_subscription_requires_agent_connection";
1837
1833
  const AGENT_CONNECTION_REQUIRED_MESSAGE = "primitive listen needs a connected agent credential, which limits the subscription to one address. Connect one with primitive agent connect and select its profile. With an account API key, watch mail with primitive emails watch or receive it at an HTTP webhook endpoint instead.";
@@ -1839,8 +1835,7 @@ const AGENT_CONNECTION_REQUIRED_MESSAGE = "primitive listen needs a connected ag
1839
1835
  function isConnectedAgentKey(apiKey) {
1840
1836
  return apiKey?.startsWith("pconn_") === true;
1841
1837
  }
1842
- //#endregion
1843
- //#region src/oclif/shared-mail-transport.ts
1838
+ // src/oclif/shared-mail-transport.ts
1844
1839
  function invalid$1(message) {
1845
1840
  return new EventReceiverError(message, "invalid_response");
1846
1841
  }
@@ -1967,8 +1962,7 @@ async function runSharedMailTransport(options) {
1967
1962
  stream.close();
1968
1963
  }
1969
1964
  }
1970
- //#endregion
1971
- //#region src/oclif/shared-mail-receiver.ts
1965
+ // src/oclif/shared-mail-receiver.ts
1972
1966
  function sharedMailScope(apiKey, baseUrl) {
1973
1967
  if (!apiKey?.startsWith("pconn_")) throw new Error("Shared mail receiving requires connected credentials.");
1974
1968
  return listenIdentity(baseUrl, `connection:${scryptSync(apiKey, "primitive-listener-identity-v1", 32).toString("hex")}`);
@@ -2083,8 +2077,7 @@ async function openSharedMailReceiver(options) {
2083
2077
  }
2084
2078
  };
2085
2079
  }
2086
- //#endregion
2087
- //#region src/oclif/reconcile-chat-send.ts
2080
+ // src/oclif/reconcile-chat-send.ts
2088
2081
  /** Lookup only. An empty result never authorizes another send. */
2089
2082
  async function reconcileChatSend(params) {
2090
2083
  const result = await readApiBeforeDeadline(params.deadline, (signal) => listSentEmails({
@@ -2105,8 +2098,7 @@ async function reconcileChatSend(params) {
2105
2098
  if (sent.client_idempotency_key !== params.idempotencyKey || typeof sent.from_address !== "string" || sent.from_address.trim().toLowerCase() !== params.from.trim().toLowerCase() || typeof sent.to_address !== "string" || sent.to_address.trim().toLowerCase() !== params.recipient.trim().toLowerCase() || typeof sent.id !== "string" || !sent.id) throw new Errors.CLIError("The saved send lookup returned conflicting identity metadata. Inspect the existing send before retrying.", { exit: 1 });
2106
2099
  return sent;
2107
2100
  }
2108
- //#endregion
2109
- //#region src/oclif/signal-command.ts
2101
+ // src/oclif/signal-command.ts
2110
2102
  const sendStatuses = /* @__PURE__ */ new Set([
2111
2103
  "queued",
2112
2104
  "submitted_to_agent",
@@ -2345,5 +2337,4 @@ async function sendSignal(context, options) {
2345
2337
  release();
2346
2338
  }
2347
2339
  }
2348
- //#endregion
2349
2340
  export { ensureSharedMailSubscription as a, isConnectedAgentKey as c, reserveSharedMailSubscription as d, followEmailConversation as f, EventReceiverError as g, EventConnection as h, sharedMailScope as i, createSharedMailWaiter as l, otherParticipants as m, reconcileChatSend as n, AGENT_CONNECTION_REQUIRED as o, readConversationFollow as p, openSharedMailReceiver as r, AGENT_CONNECTION_REQUIRED_MESSAGE as s, sendSignal as t, openSharedMailStore as u };
@@ -61,7 +61,9 @@ Add `--contact-requests` only when the owner asked this address to receive
61
61
  first-contact requests from unknown senders. Add `--name "<short name>"` and
62
62
  `--info "<role and useful capabilities>"` to seed this address's private
63
63
  `AGENT_INFO` note for peers; an existing note is never overwritten, and the text
64
- must not contain secrets or transcript content.
64
+ must not contain secrets or transcript content. Other connected agents in the
65
+ organization can read your `AGENT_INFO`, `AGENT_WORKING` and `AGENT_RUNTIME`
66
+ notes, but not your other notes.
65
67
 
66
68
  Do not install the skill separately, check the CLI version, read command help,
67
69
  start a listener or write `AGENT_INFO` yourself; the command does each of these
@@ -65,11 +65,16 @@ sender able to see peers and the recipient listed;
65
65
  the sender need not be listed and the recipient need not see peers. Explicit
66
66
  silence overrides network wake. Known-address email remains separate.
67
67
  Inspect names, addresses, and last recorded activity, which is not proof of a
68
- running receiver. If several agents match, read `AGENT_INFO`, `AGENT_USES`, and
69
- `AGENT_WORKING` for plausible peers with `GET /address-notes?address=<agent-address>`
70
- (CLI: `primitive agent notes get <name> --address <agent-address>`) before choosing
68
+ running receiver. If several agents match, read `AGENT_INFO` and `AGENT_WORKING`
69
+ for plausible peers with `GET /address-notes?address=<agent-address>` (CLI:
70
+ `primitive agent notes get AGENT_INFO --address <agent-address>` and
71
+ `primitive agent working get --address <agent-address>`) before choosing
71
72
  whom to email. Ask the owner only if the choice remains ambiguous. These notes
72
- may be stale and do not grant task authority. Keep your own `AGENT_WORKING`
73
+ may be stale and do not grant task authority. From a connected agent, the
74
+ notes of another agent in its organization are limited to `AGENT_INFO`,
75
+ `AGENT_WORKING` and `AGENT_RUNTIME`. Reading any other note there returns 403,
76
+ which does not mean the note is absent, and list reads leave those notes out.
77
+ Keep your own `AGENT_WORKING`
73
78
  note in the claim form described under [Collaborate with other
74
79
  agents](collaboration.md), not as a running log. Existing profiles may seed
75
80
  `AGENT_INFO` once if absent, as in [Manual and HTTP
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "primitive-connect",
3
- "version": "38229bc689e6b37b",
3
+ "version": "078bd8f84619ab6c",
4
4
  "source": {
5
5
  "repository": "https://github.com/primitivedotdev/skills",
6
6
  "path": "skills/primitive-connect",
7
- "commit": "a737d72b70ad813a5539a3f492546da52998ec0e"
7
+ "commit": "46bd9ca38d9edea664d78d08a4cae0a8536438b3"
8
8
  },
9
9
  "files": {
10
10
  "SKILL.md": "37d40b66010319c6a176bc8eb66affd93cab0968c609ad523dac087d3077d29d",
@@ -12,9 +12,9 @@
12
12
  "package.json": "3ea7cf130139b3106b3e4909032bc53571e6e4cdbde48ab572262e3b4a250ca4",
13
13
  "references/collaboration.md": "b9c599bf66ae58ea8c779cdceddb11882cc9f0da2fba0e4ca363ad8d01d64d5b",
14
14
  "references/communication.md": "d9599e3c563a4cd1c7dd658f730306b669f7ad6522b3632dc55fd5feee60cd30",
15
- "references/connect.md": "dc39fb8bbaffa69e30a3895f195beb12cfc95c991140ab5a7adb6e1e3293272a",
15
+ "references/connect.md": "46d3e62e6b021100a0ddf84269bcb59a1725a3da4e360c797f378ce13cf5c4ec",
16
16
  "references/contact-requests.md": "a6afb51ec2cd0bf807095e034942c6e81c82c8b8489a3e2464cd8ce9f4c28d43",
17
- "references/contacts.md": "11af5638bd4799f10bfa6fdc1c1cebf90db7c8a43d4ed5498b96c14779f1a482",
17
+ "references/contacts.md": "f85c7feea0e426f4f33b45df25016130b5766265fe10cdbe79d6cd8c45361763",
18
18
  "references/conversations.md": "c8a1125db76e40e8bf2e550223e4d4e1a86536ca43ccdd835024f6d6502098a7",
19
19
  "references/external-services.md": "211e03cec546d2f83c78bd38985cc64203272df47eb52cf1bdce885bceee3089",
20
20
  "references/manual-setup.md": "433f111c425cb976d153e22c851064e2e730f45229d8747ec91827f3a76b5d0e",
package/man/primitive.1 CHANGED
@@ -12,6 +12,10 @@ primitive \- command line interface for Primitive email and Functions
12
12
  .B primitive
13
13
  .I command
14
14
  .B --help
15
+ .br
16
+ .B primitive
17
+ .I command
18
+ .B --help-full
15
19
  .SH DESCRIPTION
16
20
  .B primitive
17
21
  is the command line interface for Primitive. It sends mail, inspects inbound and outbound email, manages domains and webhook endpoints, deploys Primitive Functions, and exposes generated API operations for scripting.
@@ -116,7 +120,7 @@ The generated commands
116
120
  and
117
121
  .B endpoints complete-webhook-event
118
122
  expose local webhook delivery on API hosts where it is enabled. Each command
119
- makes one API request. Use their --help output for the input fields. Consumers
123
+ makes one API request. Use their --help-full output for the input fields. Consumers
120
124
  deduplicate event IDs and report the outcome with the returned attempt and lease.
121
125
  Queue retention does not extend source-content retention; inspect gap counts.
122
126
  .SH AGENT LOOP
@@ -345,8 +349,11 @@ Use an explicit Primitive API key for this command.
345
349
  .B --time
346
350
  Print command duration to standard error after completion.
347
351
  .TP
348
- .B --help
349
- Show command help.
352
+ .B -h, --help
353
+ Show short command help: a summary, usage, one line per flag, and two examples.
354
+ .TP
355
+ .B --help-full
356
+ Show the complete command help, with full flag descriptions and every example.
350
357
  .SH EXIT STATUS
351
358
  .B primitive chat,
352
359
  .B primitive chat reply,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "primcli",
3
- "version": "1.74.1",
3
+ "version": "1.75.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,
@@ -18,6 +18,11 @@
18
18
  ],
19
19
  "oclif": {
20
20
  "bin": "primitive",
21
+ "helpClass": "./dist/oclif/help.js",
22
+ "additionalHelpFlags": [
23
+ "-h",
24
+ "--help-full"
25
+ ],
21
26
  "commands": {
22
27
  "strategy": "explicit",
23
28
  "target": "./dist/oclif/index.js",
@@ -192,25 +197,25 @@
192
197
  "node": ">=22"
193
198
  },
194
199
  "dependencies": {
195
- "@oclif/core": "^5.1.7",
196
- "@oclif/plugin-autocomplete": "^4.0.4",
200
+ "@oclif/core": "^5.1.11",
201
+ "@oclif/plugin-autocomplete": "^4.0.6",
197
202
  "@oclif/plugin-help": "^7.0.4",
198
203
  "@oclif/plugin-warn-if-update-available": "^4.0.1",
199
- "viem": "^2.57.7",
204
+ "viem": "^2.57.14",
200
205
  "ws": "^8.22.0"
201
206
  },
202
207
  "devDependencies": {
203
- "@biomejs/biome": "^2.5.15",
208
+ "@biomejs/biome": "^2.6.4",
204
209
  "@primitivedotdev/api-core": "workspace:*",
205
210
  "@primitivedotdev/sdk": "workspace:*",
206
- "@types/node": "^26.6.5",
211
+ "@types/node": "^26.6.6",
207
212
  "@types/ws": "^8.18.2",
208
213
  "@vitest/coverage-v8": "^5.0.5",
209
- "oclif": "^6.0.10",
210
- "tsdown": "^0.23.1",
214
+ "oclif": "^6.0.15",
215
+ "tsdown": "^0.23.4",
211
216
  "tsx": "4.23.14",
212
217
  "typescript": "^5.7.2",
213
- "vite": "^8.3.4",
218
+ "vite": "^8.3.5",
214
219
  "vitest": "^5.0.5"
215
220
  }
216
221
  }