primcli 1.74.1 → 3.0.0-preview.1

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 (31) hide show
  1. package/README.md +165 -72
  2. package/bin/claude-pending-mail.mjs +1 -1
  3. package/bin/run.js +14 -0
  4. package/dist/{api-command-fKP3NYa7.js → api-command-ctHBqTL5.js} +825 -95
  5. package/dist/{cli-config-C0Y_Ppol.js → cli-config-Ms_0vNjq.js} +66 -28
  6. package/dist/{client.gen-CaaMP86o.js → client.gen-6rZvmHfx.js} +7 -14
  7. package/dist/{json-output-Ce10AsSb.js → json-output-BzSBR-KX.js} +1 -2
  8. package/dist/{listen-background-cD6n8VYO.js → listen-background-C0F9gNDD.js} +2 -3
  9. package/dist/{machine-session-B6V5-grn.js → machine-session-Cp_eQ9t_.js} +164 -99
  10. package/dist/{notify-session-DJAb9SGm.js → notify-session-BN0JTPZ3.js} +341 -31
  11. package/dist/oclif/auto-signal-worker.js +5 -6
  12. package/dist/oclif/auto-signals.js +4 -5
  13. package/dist/oclif/global-org-flag.js +76 -0
  14. package/dist/oclif/help.js +127 -0
  15. package/dist/oclif/index.js +93239 -31954
  16. package/dist/oclif/listen-supervisor.js +1 -1
  17. package/dist/oclif/proxy-auto-detect.js +2 -3
  18. package/dist/oclif/receiver-heal.js +6 -6
  19. package/dist/oclif/root-signup-hint.js +3 -4
  20. package/dist/receiver.d.ts +95 -0
  21. package/dist/receiver.js +569 -0
  22. package/dist/{repeats-BL7ZC-_6-B_ESsWTH.js → repeats-Dj_o6c-X-Bf9G0xds.js} +4617 -1744
  23. package/dist/{scoped-chat-DAiOb622.js → scoped-chat-DZ42V3jq.js} +3 -5
  24. package/dist/{shared-mail-files-CZfm7E2k.js → shared-mail-files-BAQSGxxz.js} +2 -4
  25. package/dist/{shared-mail-watch-DyQB0MK0.js → shared-mail-watch-BAPMsFNv.js} +2 -3
  26. package/dist/{signal-command-Cte4mAL3.js → signal-command-CRUMUCNa.js} +19 -27
  27. package/dist/skills/primitive-connect/references/connect.md +3 -1
  28. package/dist/skills/primitive-connect/references/contacts.md +9 -4
  29. package/dist/skills/primitive-connect.json +4 -4
  30. package/man/primitive.1 +44 -3
  31. package/package.json +65 -15
@@ -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-Bf9G0xds.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 { It as getEmail, Pn as sendEmail, _ as describeApiFailure, h as sendPreparedSignal, hn as listSentEmails, p as prepareSignalEmail, pt as createEndpoint } from "./repeats-Dj_o6c-X-Bf9G0xds.js";
2
+ import { X as classifySendError, ft as successfulSendOutcome, g as bareAddress, o as extractErrorPayload } from "./api-command-ctHBqTL5.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-DZ42V3jq.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-BKmwTTyX.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;
@@ -613,7 +613,7 @@ const pullWebhookEvent = (options) => (options.client ?? client$1).post({
613
613
  /**
614
614
  * Report the outcome of a local webhook delivery attempt
615
615
  *
616
- * Report normalized handling evidence for the queue, attempt and lease. Required JSON fields: queue_id, delivery_id, lease_token, mode, duration_ms. For mode=exec include exit_code; stdout includes write_succeeded; http includes status_code and optional transport_error, error_code, confirmed. Supply this discriminated request with --raw-body in the generated CLI. The server classifies success and retry. Duplicate identical completion is idempotent; a stale lease cannot finish a newer attempt. Exec success means durable input acceptance, not completion of agent reasoning. Only successful HTTP handling with recognized confirmation evidence can confirm content discard. Never send arbitrary handler output or HTTP response bodies.
616
+ * Report normalized handling evidence for the queue, attempt and lease. Required JSON fields: queue_id, delivery_id, lease_token, mode, duration_ms. For mode=exec include exit_code; stdout includes write_succeeded; sdk includes accepted (and optional timeout/io transport_error); http includes status_code and optional transport_error, error_code, confirmed. Supply this discriminated request with --raw-body in the generated CLI. The server classifies success and retry. Duplicate identical completion is idempotent; a stale lease cannot finish a newer attempt. Exec success means durable input acceptance, not completion of agent reasoning. Only successful HTTP handling with recognized confirmation evidence can confirm content discard. Never send arbitrary handler output or HTTP response bodies.
617
617
  */
618
618
  const completeWebhookEvent = (options) => (options.client ?? client$1).post({
619
619
  security: [{
@@ -652,9 +652,9 @@ function validateOffer(value) {
652
652
  "delivery_id",
653
653
  "lease_token",
654
654
  "event_type",
655
- "body",
656
655
  "lease_expires_at"
657
- ].every((key) => typeof d[key] === "string") || !Number.isFinite(Date.parse(String(d.lease_expires_at))) || !record$1(d.headers) || !Object.values(d.headers).every((header) => typeof header === "string"))) throw new EventReceiverError("Invalid event delivery response", "invalid_response");
656
+ ].every((key) => typeof d[key] === "string") || d.body !== null && d.body !== void 0 && typeof d.body !== "string" || !Number.isFinite(Date.parse(String(d.lease_expires_at))) || !record$1(d.headers) || !Object.values(d.headers).every((header) => typeof header === "string"))) throw new EventReceiverError("Invalid event delivery response", "invalid_response");
657
+ if (d !== null && d.body === void 0) d.body = null;
658
658
  return value;
659
659
  }
660
660
  function retryAfter(value) {
@@ -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
  }
@@ -1933,6 +1928,7 @@ async function runSharedMailTransport(options) {
1933
1928
  const delivery = offer.delivery;
1934
1929
  if (!delivery) continue;
1935
1930
  const started = performance.now();
1931
+ if (delivery.body === null) throw invalid$1("The API withheld this event's content from the listening credential.");
1936
1932
  let body;
1937
1933
  try {
1938
1934
  body = JSON.parse(delivery.body);
@@ -1967,8 +1963,7 @@ async function runSharedMailTransport(options) {
1967
1963
  stream.close();
1968
1964
  }
1969
1965
  }
1970
- //#endregion
1971
- //#region src/oclif/shared-mail-receiver.ts
1966
+ // src/oclif/shared-mail-receiver.ts
1972
1967
  function sharedMailScope(apiKey, baseUrl) {
1973
1968
  if (!apiKey?.startsWith("pconn_")) throw new Error("Shared mail receiving requires connected credentials.");
1974
1969
  return listenIdentity(baseUrl, `connection:${scryptSync(apiKey, "primitive-listener-identity-v1", 32).toString("hex")}`);
@@ -2083,8 +2078,7 @@ async function openSharedMailReceiver(options) {
2083
2078
  }
2084
2079
  };
2085
2080
  }
2086
- //#endregion
2087
- //#region src/oclif/reconcile-chat-send.ts
2081
+ // src/oclif/reconcile-chat-send.ts
2088
2082
  /** Lookup only. An empty result never authorizes another send. */
2089
2083
  async function reconcileChatSend(params) {
2090
2084
  const result = await readApiBeforeDeadline(params.deadline, (signal) => listSentEmails({
@@ -2105,8 +2099,7 @@ async function reconcileChatSend(params) {
2105
2099
  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
2100
  return sent;
2107
2101
  }
2108
- //#endregion
2109
- //#region src/oclif/signal-command.ts
2102
+ // src/oclif/signal-command.ts
2110
2103
  const sendStatuses = /* @__PURE__ */ new Set([
2111
2104
  "queued",
2112
2105
  "submitted_to_agent",
@@ -2227,7 +2220,7 @@ async function sendSignal(context, options) {
2227
2220
  to: context.identity.agentAddress,
2228
2221
  messageId: detail.message_id,
2229
2222
  subject: detail.subject ?? null,
2230
- references: detail.parsed.references ?? []
2223
+ references: detail.parsed?.references ?? []
2231
2224
  };
2232
2225
  const key = createHash("sha256").update(JSON.stringify([
2233
2226
  scope,
@@ -2345,5 +2338,4 @@ async function sendSignal(context, options) {
2345
2338
  release();
2346
2339
  }
2347
2340
  }
2348
- //#endregion
2349
2341
  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
@@ -186,6 +190,40 @@ Run
186
190
  .B primitive logout --force
187
191
  to remove local credentials, pending email-code auth state, and stale credential locks without contacting Primitive.
188
192
  .PP
193
+ Where the server supports it, browser login logs you in as yourself. Run
194
+ .B primitive orgs
195
+ to list your organizations and whether the CLI may be used in each, and
196
+ .B primitive org use ORG
197
+ to switch by name or id. Pass
198
+ .B --org ORG
199
+ to any command, or set
200
+ .BR PRIMITIVE_CLI_ORG ,
201
+ to act in another organization for that command.
202
+ .B primitive memories
203
+ keeps its own boolean
204
+ .B --org
205
+ flag. A login saved by an earlier CLI, an API key and a connected agent
206
+ profile are bound to one organization and refuse a different one.
207
+ .PP
208
+ Run
209
+ .B primitive keys list
210
+ to list API key metadata; it never shows a secret. API keys are created,
211
+ rotated and revoked in the dashboard for now. CLI commands for this are
212
+ planned.
213
+ .B primitive whoami --check PERMISSION
214
+ reports whether the current credential may use a permission.
215
+ .PP
216
+ Run
217
+ .B primitive org leave
218
+ to leave the organization you are signed in to. It asks for confirmation first;
219
+ pass --yes to skip the prompt in scripts. Leaving is final. Only a person
220
+ signed in with
221
+ .B primitive login
222
+ can leave; API keys are refused. The only owner of an organization cannot leave
223
+ it. If the server asks for a dashboard confirmation, open the page it names and
224
+ paste the token at the prompt, or pass it with --step-up-token. Refusals from
225
+ the server are printed as returned.
226
+ .PP
189
227
  Run
190
228
  .B primitive whoami
191
229
  to verify account authentication. With PRIMITIVE_AGENT_PROFILE selected, it
@@ -345,8 +383,11 @@ Use an explicit Primitive API key for this command.
345
383
  .B --time
346
384
  Print command duration to standard error after completion.
347
385
  .TP
348
- .B --help
349
- Show command help.
386
+ .B -h, --help
387
+ Show short command help: a summary, usage, one line per flag, and two examples.
388
+ .TP
389
+ .B --help-full
390
+ Show the complete command help, with full flag descriptions and every example.
350
391
  .SH EXIT STATUS
351
392
  .B primitive chat,
352
393
  .B primitive chat reply,
package/package.json CHANGED
@@ -1,9 +1,22 @@
1
1
  {
2
2
  "name": "primcli",
3
- "version": "1.74.1",
3
+ "version": "3.0.0-preview.1",
4
+ "publishConfig": {
5
+ "tag": "preview"
6
+ },
4
7
  "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
8
  "type": "module",
6
9
  "sideEffects": false,
10
+ "exports": {
11
+ "./receiver": {
12
+ "types": "./dist/receiver.d.ts",
13
+ "default": "./dist/receiver.js"
14
+ },
15
+ "./package.json": "./package.json",
16
+ "./bin/*": "./bin/*",
17
+ "./dist/*": "./dist/*",
18
+ "./man/*": "./man/*"
19
+ },
7
20
  "files": [
8
21
  "bin",
9
22
  "dist",
@@ -18,6 +31,11 @@
18
31
  ],
19
32
  "oclif": {
20
33
  "bin": "primitive",
34
+ "helpClass": "./dist/oclif/help.js",
35
+ "additionalHelpFlags": [
36
+ "-h",
37
+ "--help-full"
38
+ ],
21
39
  "commands": {
22
40
  "strategy": "explicit",
23
41
  "target": "./dist/oclif/index.js",
@@ -64,9 +82,6 @@
64
82
  "domains": {
65
83
  "description": "Claim, verify, manage email domains, and download DNS zone files"
66
84
  },
67
- "registries": {
68
- "description": "Create and manage agent registries, publish and resolve agents by handle, and moderate publication requests"
69
- },
70
85
  "network": {
71
86
  "description": "Discover same-organization agents by email address and manage default network visibility. Use `primitive network` to see the commands."
72
87
  },
@@ -123,13 +138,49 @@
123
138
  "description": "Browse and install Function templates. Use `primitive templates list-templates`, `primitive templates get-template`, `primitive templates install-template`, and `primitive templates get-template-install`."
124
139
  },
125
140
  "org": {
126
- "description": "Manage org-level (global) resources shared across functions"
141
+ "description": "Switch the CLI between your organizations (`primitive org use <org>`, list them with `primitive orgs`), manage org-level (global) resources shared across functions, or leave the organization"
127
142
  },
128
143
  "org:secrets": {
129
144
  "description": "Global secrets shared across every function. Use `primitive org secrets list|set|remove`. Changes land in a function on its next redeploy; a function secret of the same name overrides the global."
130
145
  },
131
- "payments": {
132
- "description": "Collect and pay x402 stablecoin (USDC) payments. Start with `primitive payments register-payout-address`, then `primitive payments create-challenge` to request a payment and `primitive payments pay` to settle one. Settlement is non-custodial; signing happens locally with your wallet key. Manage caps with `primitive payments get-policy|update-spend-policy`."
146
+ "keys": {
147
+ "description": "List organization API keys (metadata only, never secrets) with `primitive keys list`. API keys are created, rotated and revoked in the dashboard for now. CLI commands for this are planned."
148
+ },
149
+ "roles": {
150
+ "description": "Read roles, groups, mailbox access and the access mode. Use `primitive roles list|groups|mailbox-access|access-mode`; generated API names remain available."
151
+ },
152
+ "projects": {
153
+ "description": "Organization people, shared projects and project invitations"
154
+ },
155
+ "organizations": {
156
+ "description": "Organization invitations"
157
+ },
158
+ "mailbox-access": {
159
+ "description": "Who may read, draft and send for each mailbox, and the groups access can be given to"
160
+ },
161
+ "credentials": {
162
+ "description": "API keys, the credential inventory, the credential audit trail and the credential policy"
163
+ },
164
+ "organization-settings": {
165
+ "description": "Your connected apps and CLI logins, the organization's connected apps, name, logo, search settings and billing"
166
+ },
167
+ "roles-and-members": {
168
+ "description": "Roles, member roles and removal, the mailbox access mode, break-glass, transfers and suspensions, and leaving the organization"
169
+ },
170
+ "agent-work": {
171
+ "description": "Agent work records: create, list and read them, report status, and propose, agree or withdraw deadlines"
172
+ },
173
+ "address-notes": {
174
+ "description": "Private organization notes and public JSON notes about email addresses"
175
+ },
176
+ "interactions": {
177
+ "description": "Typed multi-step protocols carried over email between agents"
178
+ },
179
+ "stats": {
180
+ "description": "Received and sent mail per hour, and how webhook deliveries ended"
181
+ },
182
+ "email-rules": {
183
+ "description": "Rules written in plain English that pick out received mail"
133
184
  },
134
185
  "routes": {
135
186
  "description": "Manage recipient routes. Bind an address pattern to an endpoint or function: `primitive routes add alice@d --function <id>`, `primitive routes list`, `primitive routes test <recipient>`, `primitive routes remove <id>`."
@@ -192,25 +243,24 @@
192
243
  "node": ">=22"
193
244
  },
194
245
  "dependencies": {
195
- "@oclif/core": "^5.1.7",
196
- "@oclif/plugin-autocomplete": "^4.0.4",
246
+ "@oclif/core": "^5.1.11",
247
+ "@oclif/plugin-autocomplete": "^4.0.6",
197
248
  "@oclif/plugin-help": "^7.0.4",
198
249
  "@oclif/plugin-warn-if-update-available": "^4.0.1",
199
- "viem": "^2.57.7",
200
250
  "ws": "^8.22.0"
201
251
  },
202
252
  "devDependencies": {
203
- "@biomejs/biome": "^2.5.15",
253
+ "@biomejs/biome": "^2.6.4",
204
254
  "@primitivedotdev/api-core": "workspace:*",
205
255
  "@primitivedotdev/sdk": "workspace:*",
206
- "@types/node": "^26.6.5",
256
+ "@types/node": "^26.6.6",
207
257
  "@types/ws": "^8.18.2",
208
258
  "@vitest/coverage-v8": "^5.0.5",
209
- "oclif": "^6.0.10",
210
- "tsdown": "^0.23.1",
259
+ "oclif": "^6.0.15",
260
+ "tsdown": "^0.23.4",
211
261
  "tsx": "4.23.14",
212
262
  "typescript": "^5.7.2",
213
- "vite": "^8.3.4",
263
+ "vite": "^8.3.5",
214
264
  "vitest": "^5.0.5"
215
265
  }
216
266
  }