primcli 1.70.0 → 1.72.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 (30) hide show
  1. package/README.md +115 -2
  2. package/dist/{api-command-C58Oh38I.js → api-command-BrwPbyPP.js} +286 -19
  3. package/dist/{cli-config-DMszFbGn.js → cli-config--YTRdJ3t.js} +15 -4
  4. package/dist/{json-output-CEskSQJi.js → json-output-Ce10AsSb.js} +71 -3
  5. package/dist/{machine-session-CKmn5bvB.js → machine-session-Be6j29GE.js} +8 -6
  6. package/dist/{notify-session-CVZtEboh.js → notify-session-Byt5sPWW.js} +2 -2
  7. package/dist/oclif/auto-signal-worker.js +2 -2
  8. package/dist/oclif/auto-signals.js +1 -1
  9. package/dist/oclif/index.js +5266 -112
  10. package/dist/oclif/listen-supervisor.js +1 -2
  11. package/dist/oclif/proxy-auto-detect.js +1 -1
  12. package/dist/oclif/receiver-heal.js +2 -2
  13. package/dist/oclif/root-signup-hint.js +1 -1
  14. package/dist/{repeats-BL7ZC-_6-BZ-MphTV.js → repeats-BL7ZC-_6-CKMKBlx7.js} +1 -1
  15. package/dist/{scoped-chat-Dsark9hm.js → scoped-chat-DTFkP360.js} +1 -1
  16. package/dist/{signal-command-Dy_oub7_.js → signal-command-DeEEZPbQ.js} +4 -4
  17. package/dist/skills/primitive-connect/SKILL.md +162 -355
  18. package/dist/skills/primitive-connect/references/collaboration.md +39 -2
  19. package/dist/skills/primitive-connect/references/communication.md +2 -2
  20. package/dist/skills/primitive-connect/references/connect.md +234 -0
  21. package/dist/skills/primitive-connect/references/contact-requests.md +3 -3
  22. package/dist/skills/primitive-connect/references/contacts.md +4 -4
  23. package/dist/skills/primitive-connect/references/conversations.md +4 -4
  24. package/dist/skills/primitive-connect/references/external-services.md +86 -0
  25. package/dist/skills/primitive-connect/references/manual-setup.md +2 -2
  26. package/dist/skills/primitive-connect/references/presence-and-receiving.md +5 -5
  27. package/dist/skills/primitive-connect/scripts/check-cli-capabilities.mjs +13 -4
  28. package/dist/skills/primitive-connect.json +13 -11
  29. package/man/primitive.1 +17 -3
  30. package/package.json +11 -8
@@ -17,7 +17,10 @@ import { format } from "node:util";
17
17
  * - A command whose `--json` output is a bare JSON array keeps that
18
18
  * documented shape on success; its stderr notices are dropped.
19
19
  *
20
- * Commands that stream several documents (`listen`) are not guarded.
20
+ * Commands that stream several documents (`listen`, `emails wait`) are
21
+ * not guarded. `emails wait` uses `runStreamingJson` instead: one JSON
22
+ * line per result on stdout, and on failure one more JSON line carrying
23
+ * `error` and `exit_code`.
21
24
  */
22
25
  const GUARDED = Symbol.for("primitive.cli.jsonOutputGuard");
23
26
  /** True when `--json` appears before any `--` separator. */
@@ -235,7 +238,72 @@ function guardJsonOutput(cls) {
235
238
  };
236
239
  }
237
240
  /** Command ids whose `--json` streams several documents over time. */
238
- const STREAMING_JSON_COMMAND_IDS = /* @__PURE__ */ new Set(["listen"]);
241
+ const STREAMING_JSON_COMMAND_IDS = /* @__PURE__ */ new Set(["emails:wait", "listen"]);
242
+ /**
243
+ * Run the body of a command whose `--json` output is newline-delimited
244
+ * JSON, one line per result, written to stdout as each result is found.
245
+ *
246
+ * stdout stays live. Everything the body writes to stderr is held back,
247
+ * so a caller reading `2>&1` still gets only JSON lines. On success the
248
+ * held lines are dropped. On failure one more line is printed on stdout:
249
+ * an object with `error`, `exit_code` and, when there were any, the held
250
+ * lines as `warnings`, built the same way as a guarded command's error
251
+ * document. `failure` may supply a more specific `error` body and extra
252
+ * top-level fields. The exit code is unchanged.
253
+ */
254
+ async function runStreamingJson(body, failure) {
255
+ const stderr = [];
256
+ const originalStderrWrite = process.stderr.write;
257
+ const originalConsole = {
258
+ debug: console.debug,
259
+ error: console.error,
260
+ warn: console.warn
261
+ };
262
+ const toStderr = (...args) => {
263
+ stderr.push(`${format(...args)}\n`);
264
+ };
265
+ process.stderr.write = capturingWrite(stderr);
266
+ console.debug = toStderr;
267
+ console.error = toStderr;
268
+ console.warn = toStderr;
269
+ let thrown;
270
+ try {
271
+ await body();
272
+ } catch (error) {
273
+ thrown = { error };
274
+ } finally {
275
+ process.stderr.write = originalStderrWrite;
276
+ console.debug = originalConsole.debug;
277
+ console.error = originalConsole.error;
278
+ console.warn = originalConsole.warn;
279
+ }
280
+ const exitCode = thrown ? isExitSignal(thrown.error) ? errorExitCode(thrown.error) ?? 0 : errorExitCode(thrown.error) ?? 1 : typeof process.exitCode === "number" ? process.exitCode : 0;
281
+ if (exitCode !== 0) {
282
+ const document = composeJsonDocument({
283
+ exitCode,
284
+ stderr,
285
+ stdout: "",
286
+ thrown
287
+ });
288
+ const specific = failure?.();
289
+ const line = specific ? {
290
+ ...document,
291
+ ...specific.fields,
292
+ error: specific.error
293
+ } : document;
294
+ const message = line.error?.message;
295
+ if (Array.isArray(line.warnings)) {
296
+ const warnings = line.warnings.filter((warning) => warning !== message);
297
+ if (warnings.length > 0) line.warnings = warnings;
298
+ else delete line.warnings;
299
+ }
300
+ process.stdout.write(`${JSON.stringify(line)}\n`);
301
+ }
302
+ if (thrown) {
303
+ if (thrown.error !== null && typeof thrown.error === "object") thrown.error.skipOclifErrorHandling = true;
304
+ throw thrown.error;
305
+ }
306
+ }
239
307
  /**
240
308
  * Guard every command in `commands` that accepts `--json`, except the
241
309
  * streaming ones. Called once by the command registry.
@@ -251,4 +319,4 @@ function guardJsonOutputCommands(commands) {
251
319
  }
252
320
  }
253
321
  //#endregion
254
- export { jsonOutputRequested as n, guardJsonOutputCommands as t };
322
+ export { jsonOutputRequested as n, runStreamingJson as r, guardJsonOutputCommands as t };
@@ -1,9 +1,9 @@
1
- import { S as __exportAll } from "./repeats-BL7ZC-_6-BZ-MphTV.js";
2
- import { B as parseOwnerMemberAddress, F as agentProfilesDirectory, I as connectedAgentIdentity, L as connectedApiBaseUrl, M as AgentConnectionSetupError, N as agentProfileDirectory, P as agentProfileName, R as loadConnectedAgentProfile, U as saveConnectedAgentProfile, V as profileAlreadyConnectedMessage, W as PrimitiveApiClient, j as AGENT_PROFILE_ENV, x as loadCliCredentials, z as parseConnectedAgentProfile } from "./cli-config-DMszFbGn.js";
3
- import { Ct as cliInvocation, Jn as putAgentContactPolicy, Jt as refreshStoredCliCredentials, Pn as listDomains, Tt as defaultConnectionName, Vn as listSentEmails, Yn as putContact, an as deleteAgentContact, ar as sendEmail, jn as listContacts, kn as listAgentContacts, mn as getContact, nr as searchEmails, on as deleteContact, pn as getAgentContactPolicy, qn as putAgentContact, vn as getEmail } from "./api-command-C58Oh38I.js";
1
+ import { S as __exportAll } from "./repeats-BL7ZC-_6-CKMKBlx7.js";
2
+ import { B as parseConnectedAgentProfile, F as agentProfileName, G as PrimitiveApiClient, H as profileAlreadyConnectedMessage, I as agentProfilesDirectory, L as connectedAgentIdentity, M as AGENT_PROFILE_ENV, N as AgentConnectionSetupError, P as agentProfileDirectory, R as connectedApiBaseUrl, V as parseOwnerMemberAddress, W as saveConnectedAgentProfile, x as loadCliCredentials, z as loadConnectedAgentProfile } from "./cli-config--YTRdJ3t.js";
3
+ import { $t as refreshStoredCliCredentials, Bn as listAgentContacts, Dt as defaultConnectionName, Gn as listDomains, Hn as listContacts, Tn as getContact, Tt as cliInvocation, cr as putContact, er as listSentEmails, fn as deleteAgentContact, hr as searchEmails, kn as getEmail, or as putAgentContact, pn as deleteContact, sr as putAgentContactPolicy, vr as sendEmail, wn as getAgentContactPolicy } from "./api-command-BrwPbyPP.js";
4
4
  import { _ as acquireListenLock, c as mailTime, d as readMailJson, f as removeMailFile, g as ListenStateError, h as writeMailJson, i as mailId, l as privateMailDirectory, o as mailObject, r as mailAddress, s as mailString } from "./shared-mail-files-MwlVE90c.js";
5
- import { _ as detectAgentRuntime, a as NotificationRetryError, d as defaultSessionSocket, f as NativeSessionDisconnectedError, l as SESSION_UUID, t as notificationScope, u as connectNativeSession, v as installConnectSkill, x as readBundledConnectSkill } from "./notify-session-CVZtEboh.js";
6
- import { a as scopedChatSenderTrust } from "./scoped-chat-Dsark9hm.js";
5
+ import { _ as detectAgentRuntime, a as NotificationRetryError, d as defaultSessionSocket, f as NativeSessionDisconnectedError, l as SESSION_UUID, t as notificationScope, u as connectNativeSession, v as installConnectSkill, x as readBundledConnectSkill } from "./notify-session-Byt5sPWW.js";
6
+ import { a as scopedChatSenderTrust } from "./scoped-chat-DTFkP360.js";
7
7
  import { l as stopBackgroundListen, r as backgroundListenStatus } from "./listen-background--0peztKE.js";
8
8
  import { t as readSharedMailOwner } from "./shared-mail-watch-DtKpsgg8.js";
9
9
  import { accessSync, chmodSync, closeSync, constants, copyFileSync, existsSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, rmdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
@@ -4724,7 +4724,7 @@ async function enrollAgent(params) {
4724
4724
  const receiverMode = params.receiverMode ?? "native";
4725
4725
  const contactRequests = Boolean(params.contactRequests);
4726
4726
  const env = params.env ?? process.env;
4727
- if (env["PRIMITIVE_AGENT_PROFILE"]?.trim() || env.PRIMITIVE_API_KEY?.trim() || env.PRIMITIVE_KEY?.trim()) throw refuse("Enrollment requires the saved member OAuth login. Unset agent-profile and API-key environment overrides.");
4727
+ if (env["PRIMITIVE_AGENT_PROFILE"]?.trim() || env.PRIMITIVE_API_KEY?.trim() || env.PRIMITIVE_KEY?.trim()) throw refuse("Enrollment uses only the saved member login; rerun it under `env -u PRIMITIVE_AGENT_PROFILE -u PRIMITIVE_API_KEY -u PRIMITIVE_KEY` so no agent profile or API key override applies.");
4728
4728
  const saved = loadCliCredentials(params.configDir);
4729
4729
  if (!saved) throw refuse("Sign in with `primitive signin` as a member of this organization first.");
4730
4730
  const apiBaseUrl = connectedApiBaseUrl(saved.api_base_url);
@@ -5588,6 +5588,7 @@ async function registerSession(options) {
5588
5588
  receiving: RECEIVING[runtime],
5589
5589
  status: "already_registered",
5590
5590
  ...resumeNote,
5591
+ ...hooked === "held" ? { receiverHeld: true } : {},
5591
5592
  detail: hooked === "installed" ? "This session is already connected." : hooked === "held" ? HELD_DETAIL : "This session is already connected, but its receive hook could not be installed. Run `primitive machine doctor`."
5592
5593
  };
5593
5594
  }
@@ -5672,6 +5673,7 @@ async function registerSession(options) {
5672
5673
  name,
5673
5674
  nameIsDefault: name === record.name,
5674
5675
  ...resumeNote,
5676
+ ...hooked === "held" ? { receiverHeld: true } : {},
5675
5677
  detail: hooked === "installed" ? `Connected as ${address}.` : hooked === "held" ? `Connected as ${address}. ${HELD_DETAIL}` : `Connected as ${address}, but the receive hook could not be installed. Run \`primitive machine doctor\`.`
5676
5678
  };
5677
5679
  if (status === "revoked" || status === "owner_inactive") return {
@@ -1,5 +1,5 @@
1
- import { b as parseWebhookEvent, c as classifySignalContent, v as isEmailReceivedEvent, y as isTrustedSender } from "./repeats-BL7ZC-_6-BZ-MphTV.js";
2
- import { F as wakeReadCommand, P as skillFirstLine, Y as wakeInteractionSentence, dn as downloadEmailAttachmentPart } from "./api-command-C58Oh38I.js";
1
+ import { b as parseWebhookEvent, c as classifySignalContent, v as isEmailReceivedEvent, y as isTrustedSender } from "./repeats-BL7ZC-_6-CKMKBlx7.js";
2
+ import { I as skillFirstLine, L as wakeReadCommand, Z as wakeInteractionSentence, bn as downloadEmailAttachmentPart } from "./api-command-BrwPbyPP.js";
3
3
  import { _ as acquireListenLock, g as ListenStateError, y as listenIdentity } from "./shared-mail-files-MwlVE90c.js";
4
4
  import { closeSync, copyFileSync, existsSync, fsyncSync, lstatSync, mkdirSync, openSync, opendirSync, readFileSync, readdirSync, readlinkSync, renameSync, rmSync, statSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
5
5
  import { createHash, randomUUID, scryptSync } from "node:crypto";
@@ -1,6 +1,6 @@
1
- import { A as readThreadContext, En as getSentEmail, Kt as createAuthenticatedCliApiClient } from "../api-command-C58Oh38I.js";
1
+ import { Ln as getSentEmail, M as readThreadContext, Zt as createAuthenticatedCliApiClient } from "../api-command-BrwPbyPP.js";
2
2
  import { _ as acquireListenLock } from "../shared-mail-files-MwlVE90c.js";
3
- import { t as sendSignal } from "../signal-command-Dy_oub7_.js";
3
+ import { t as sendSignal } from "../signal-command-DeEEZPbQ.js";
4
4
  import { AUTO_SIGNAL_KIND_ENV, AUTO_WORKING_RENEW_MS, autoSignalsDisabled, clearWorkingSending, markWorkingSending, readAutoClaim, readWorkingLease, recordRenewer, stopWorkingLease, writeWorkingLease } from "./auto-signals.js";
5
5
  import { join } from "node:path";
6
6
  import { homedir } from "node:os";
@@ -1,5 +1,5 @@
1
1
  import { d as readMailJson, h as writeMailJson, i as mailId, l as privateMailDirectory, r as mailAddress } from "../shared-mail-files-MwlVE90c.js";
2
- import { a as scopedChatSenderTrust, n as isPlainChatReply } from "../scoped-chat-Dsark9hm.js";
2
+ import { a as scopedChatSenderTrust, n as isPlainChatReply } from "../scoped-chat-DTFkP360.js";
3
3
  import { existsSync, readFileSync, readdirSync, unlinkSync, writeFileSync } from "node:fs";
4
4
  import { randomUUID } from "node:crypto";
5
5
  import { join } from "node:path";