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,10 +1,10 @@
1
- import { n as createConfig, t as createClient } from "./client.gen-CaaMP86o.js";
2
- import { c as mailTime, d as readMailJson, h as writeMailJson, i as mailId, l as privateMailDirectory, o as mailObject, r as mailAddress, s as mailString } from "./shared-mail-files-CZfm7E2k.js";
1
+ import { n as createConfig, t as createClient } from "./client.gen-6rZvmHfx.js";
2
+ import { c as mailTime, d as readMailJson, h as writeMailJson, i as mailId, l as privateMailDirectory, o as mailObject, r as mailAddress, s as mailString } from "./shared-mail-files-BAQSGxxz.js";
3
3
  import { Errors } from "@oclif/core";
4
4
  import { chmodSync, mkdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
5
5
  import { randomUUID } from "node:crypto";
6
6
  import { dirname, join } from "node:path";
7
- //#region ../packages/api-core/src/client.ts
7
+ // ../packages/api-core/src/client.ts
8
8
  /**
9
9
  * Host-aware Primitive API client and shared error type.
10
10
  *
@@ -38,8 +38,7 @@ var PrimitiveApiClient = class {
38
38
  return this.client.setConfig(config);
39
39
  }
40
40
  };
41
- //#endregion
42
- //#region src/oclif/connected-agent-profile.ts
41
+ // src/oclif/connected-agent-profile.ts
43
42
  const AGENT_PROFILE_ENV = "PRIMITIVE_AGENT_PROFILE";
44
43
  /**
45
44
  * The selected agent's email address, exported next to AGENT_PROFILE_ENV for
@@ -192,8 +191,7 @@ function profileAlreadyConnectedMessage(profileName, address) {
192
191
  `If they choose to disconnect it, run \`primitive agent disconnect --profile ${profileName}\` (or rerun this command with --replace-existing when it is bound to this session), then connect again. If they want a second address on purpose, rerun with a new --profile and --keep-existing.`
193
192
  ].join(" ");
194
193
  }
195
- //#endregion
196
- //#region src/oclif/chat-state.ts
194
+ // src/oclif/chat-state.ts
197
195
  const CHAT_STATE_FILE = "chat-state.json";
198
196
  const CHAT_STATE_VERSION = 2;
199
197
  const MAX_CONVERSATIONS = 50;
@@ -355,8 +353,7 @@ function saveActiveChatState(configDir, input, options = {}) {
355
353
  });
356
354
  return conversation;
357
355
  }
358
- //#endregion
359
- //#region src/oclif/auth.ts
356
+ // src/oclif/auth.ts
360
357
  const CREDENTIALS_FILE = "credentials.json";
361
358
  const CREDENTIALS_LOCK_DIR = "credentials.lock";
362
359
  const CREDENTIALS_LOCK_OWNER_FILE = "owner.json";
@@ -394,6 +391,7 @@ var LegacyApiKeyCredentialFormatError = class extends Error {
394
391
  };
395
392
  function parseCredentials(raw) {
396
393
  if (!isRecord$1(raw)) throw new Error(`Stored Primitive CLI credentials are malformed: expected a JSON object. ${MALFORMED_CREDENTIALS_HINT}`);
394
+ if (raw.auth_method === "user_grant") return parseUserGrantCredentials(raw);
397
395
  if (raw.auth_method !== "oauth") {
398
396
  if (typeof raw.api_key === "string" || typeof raw.key_id === "string" || typeof raw.base_url === "string") throw new LegacyApiKeyCredentialFormatError();
399
397
  throw new Error(`Stored Primitive CLI credentials are malformed: auth_method must be oauth. ${MALFORMED_CREDENTIALS_HINT}`);
@@ -415,6 +413,63 @@ function parseCredentials(raw) {
415
413
  created_at: requireString(raw, "created_at")
416
414
  };
417
415
  }
416
+ function malformed(detail) {
417
+ return /* @__PURE__ */ new Error(`Stored Primitive CLI credentials are malformed: ${detail}. ${MALFORMED_CREDENTIALS_HINT}`);
418
+ }
419
+ function requireText(value, key, options = {}) {
420
+ const raw = value[key];
421
+ if (typeof raw !== "string" || !options.allowEmpty && raw.trim().length === 0) throw malformed(`${key} must be a non-empty string`);
422
+ return raw;
423
+ }
424
+ function nullableText(value, key) {
425
+ const raw = value[key];
426
+ if (raw === void 0 || raw === null) return null;
427
+ if (typeof raw !== "string") throw malformed(`${key} must be a string or null`);
428
+ return raw;
429
+ }
430
+ function parseOrgToken(raw) {
431
+ if (!isRecord$1(raw)) throw malformed("user_grant.org_tokens entries must be objects");
432
+ return {
433
+ access_token: requireText(raw, "access_token"),
434
+ expires_at: requireText(raw, "expires_at"),
435
+ oauth_grant_id: requireText(raw, "oauth_grant_id"),
436
+ org_id: requireText(raw, "org_id"),
437
+ org_name: nullableText(raw, "org_name"),
438
+ role: nullableText(raw, "role")
439
+ };
440
+ }
441
+ function parseUserGrantCredentials(raw) {
442
+ const grantRaw = raw.user_grant;
443
+ if (!isRecord$1(grantRaw)) throw malformed("user_grant must be an object");
444
+ if (raw.token_type !== "Bearer") throw malformed("token_type must be Bearer");
445
+ const tokensRaw = grantRaw.org_tokens ?? {};
446
+ if (!isRecord$1(tokensRaw)) throw malformed("user_grant.org_tokens must be an object");
447
+ const orgTokens = {};
448
+ for (const [orgId, token] of Object.entries(tokensRaw)) orgTokens[orgId] = parseOrgToken(token);
449
+ const orgId = requireText(raw, "org_id", { allowEmpty: true });
450
+ return {
451
+ access_token: requireText(raw, "access_token", { allowEmpty: true }),
452
+ api_base_url: readStoredApiBaseUrl(raw),
453
+ auth_method: "user_grant",
454
+ created_at: requireText(raw, "created_at"),
455
+ expires_at: requireText(raw, "expires_at"),
456
+ oauth_client_id: requireText(raw, "oauth_client_id"),
457
+ oauth_grant_id: requireText(raw, "oauth_grant_id", { allowEmpty: true }),
458
+ org_id: orgId,
459
+ org_name: nullableText(raw, "org_name"),
460
+ refresh_token: requireText(raw, "refresh_token"),
461
+ token_type: "Bearer",
462
+ user_grant: {
463
+ access_token: requireText(grantRaw, "access_token"),
464
+ expires_at: requireText(grantRaw, "expires_at"),
465
+ org_role: nullableText(grantRaw, "org_role"),
466
+ org_tokens: orgTokens,
467
+ requested_grant: nullableText(grantRaw, "requested_grant"),
468
+ user_grant_id: requireText(grantRaw, "user_grant_id"),
469
+ user_id: requireText(grantRaw, "user_id")
470
+ }
471
+ };
472
+ }
418
473
  function credentialsPath(configDir) {
419
474
  return join(configDir, CREDENTIALS_FILE);
420
475
  }
@@ -677,21 +732,6 @@ function detectPrimitiveKeyEnvMisname(env = process.env) {
677
732
  if ((primitiveKey?.length ?? 0) > 0 && (primitiveApiKey?.length ?? 0) === 0) return "PRIMITIVE_KEY is set but the CLI reads PRIMITIVE_API_KEY. Rename your env var, or re-run with PRIMITIVE_API_KEY=$PRIMITIVE_KEY.";
678
733
  return null;
679
734
  }
680
- /**
681
- * True when a usable OAuth login session is saved on disk. Used by `pay-email`
682
- * to decide whether it can safely ignore an env-only `PRIMITIVE_API_KEY` in
683
- * favor of the payer's logged-in account (which owns the inbound challenge
684
- * inbox). Returns false when nothing is stored or the stored credential is
685
- * unreadable/legacy, so the caller falls back to whatever key did resolve
686
- * rather than silently dropping the user's only auth.
687
- */
688
- function hasStoredCliLogin(configDir) {
689
- try {
690
- return loadCliCredentials(configDir) !== null;
691
- } catch {
692
- return false;
693
- }
694
- }
695
735
  function resolveCliAuth(params) {
696
736
  const apiKey = params.apiKey?.trim();
697
737
  const apiBaseUrl = normalizeApiBaseUrl(params.apiBaseUrl);
@@ -728,8 +768,7 @@ function resolveCliAuth(params) {
728
768
  source: "none"
729
769
  };
730
770
  }
731
- //#endregion
732
- //#region src/oclif/cli-config.ts
771
+ // src/oclif/cli-config.ts
733
772
  const CONFIG_FILE = "config.json";
734
773
  const CONFIG_VERSION = 1;
735
774
  const DEFAULT_ENVIRONMENT = "default";
@@ -907,5 +946,4 @@ function redactCliEnvironment(environment) {
907
946
  ...headers ? { headers } : {}
908
947
  };
909
948
  }
910
- //#endregion
911
- export { saveActiveChatState as A, parseConnectedAgentProfile as B, resolveCliAuth as C, deleteChatState as D, chatStatePath as E, agentProfileName as F, PrimitiveApiClient as G, profileAlreadyConnectedMessage as H, agentProfilesDirectory as I, connectedAgentIdentity as L, AGENT_PROFILE_ENV as M, AgentConnectionSetupError as N, loadActiveChatState as O, agentProfileDirectory as P, connectedApiBaseUrl as R, normalizeApiBaseUrl as S, saveSignupCredentials as T, requireDefaultLoginProfile as U, parseOwnerMemberAddress as V, saveConnectedAgentProfile as W, deleteCliCredentials as _, normalizeCliEnvironmentName as a, hasStoredCliLogin as b, resolveConfigEnvironment as c, validateCliHeaderName as d, validateCliHeaderValue as f, credentialsPath as g, credentialsLockPath as h, loadCliConfig as i, AGENT_ADDRESS_ENV as j, loadChatConversationByLocalId as k, saveCliConfig as l, cliAccessTokenExpiresAt as m, deleteCliConfig as n, redactCliEnvironment as o, acquireCliCredentialsLock as p, emptyCliConfig as r, removeCliEnvironment as s, DEFAULT_ENVIRONMENT as t, upsertCliEnvironment as u, deleteCliCredentialsLock as v, saveCliCredentials as w, loadCliCredentials as x, detectPrimitiveKeyEnvMisname as y, loadConnectedAgentProfile as z };
949
+ export { AGENT_ADDRESS_ENV as A, parseOwnerMemberAddress as B, saveCliCredentials as C, loadActiveChatState as D, deleteChatState as E, agentProfilesDirectory as F, requireDefaultLoginProfile as H, connectedAgentIdentity as I, connectedApiBaseUrl as L, AgentConnectionSetupError as M, agentProfileDirectory as N, loadChatConversationByLocalId as O, agentProfileName as P, loadConnectedAgentProfile as R, resolveCliAuth as S, chatStatePath as T, saveConnectedAgentProfile as U, profileAlreadyConnectedMessage as V, PrimitiveApiClient as W, deleteCliCredentials as _, normalizeCliEnvironmentName as a, loadCliCredentials as b, resolveConfigEnvironment as c, validateCliHeaderName as d, validateCliHeaderValue as f, credentialsPath as g, credentialsLockPath as h, loadCliConfig as i, AGENT_PROFILE_ENV as j, saveActiveChatState as k, saveCliConfig as l, cliAccessTokenExpiresAt as m, deleteCliConfig as n, redactCliEnvironment as o, acquireCliCredentialsLock as p, emptyCliConfig as r, removeCliEnvironment as s, DEFAULT_ENVIRONMENT as t, upsertCliEnvironment as u, deleteCliCredentialsLock as v, saveSignupCredentials as w, normalizeApiBaseUrl as x, detectPrimitiveKeyEnvMisname as y, parseConnectedAgentProfile as z };
@@ -1,7 +1,6 @@
1
- //#region ../packages/api-core/src/api/core/bodySerializer.gen.ts
1
+ // ../packages/api-core/src/api/core/bodySerializer.gen.ts
2
2
  const jsonBodySerializer = { bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value) };
3
- //#endregion
4
- //#region ../packages/api-core/src/api/core/serverSentEvents.gen.ts
3
+ // ../packages/api-core/src/api/core/serverSentEvents.gen.ts
5
4
  function createSseClient({ onRequest, onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url, ...options }) {
6
5
  let lastEventId;
7
6
  const sleep = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
@@ -93,8 +92,7 @@ function createSseClient({ onRequest, onSseError, onSseEvent, responseTransforme
93
92
  };
94
93
  return { stream: createStream() };
95
94
  }
96
- //#endregion
97
- //#region ../packages/api-core/src/api/core/pathSerializer.gen.ts
95
+ // ../packages/api-core/src/api/core/pathSerializer.gen.ts
98
96
  const separatorArrayExplode = (style) => {
99
97
  switch (style) {
100
98
  case "label": return ".";
@@ -172,8 +170,7 @@ const serializeObjectParam = ({ allowReserved, explode, name, style, value, valu
172
170
  })).join(separator);
173
171
  return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
174
172
  };
175
- //#endregion
176
- //#region ../packages/api-core/src/api/core/utils.gen.ts
173
+ // ../packages/api-core/src/api/core/utils.gen.ts
177
174
  const PATH_PARAM_RE = /\{[^{}]+\}/g;
178
175
  const defaultPathSerializer = ({ path, url: _url }) => {
179
176
  let url = _url;
@@ -246,8 +243,7 @@ function getValidRequestBody(options) {
246
243
  }
247
244
  if (hasBody) return options.body;
248
245
  }
249
- //#endregion
250
- //#region ../packages/api-core/src/api/core/auth.gen.ts
246
+ // ../packages/api-core/src/api/core/auth.gen.ts
251
247
  const getAuthToken = async (auth, callback) => {
252
248
  const token = typeof callback === "function" ? await callback(auth) : callback;
253
249
  if (!token) return;
@@ -255,8 +251,7 @@ const getAuthToken = async (auth, callback) => {
255
251
  if (auth.scheme === "basic") return `Basic ${btoa(token)}`;
256
252
  return token;
257
253
  };
258
- //#endregion
259
- //#region ../packages/api-core/src/api/client/utils.gen.ts
254
+ // ../packages/api-core/src/api/client/utils.gen.ts
260
255
  const createQuerySerializer = ({ parameters = {}, ...args } = {}) => {
261
256
  const querySerializer = (queryParams) => {
262
257
  const search = [];
@@ -425,8 +420,7 @@ const createConfig = (override = {}) => ({
425
420
  querySerializer: defaultQuerySerializer,
426
421
  ...override
427
422
  });
428
- //#endregion
429
- //#region ../packages/api-core/src/api/client/client.gen.ts
423
+ // ../packages/api-core/src/api/client/client.gen.ts
430
424
  const createClient = (config = {}) => {
431
425
  let _config = mergeConfigs(createConfig(), config);
432
426
  const getConfig = () => ({ ..._config });
@@ -593,5 +587,4 @@ const createClient = (config = {}) => {
593
587
  trace: makeMethodFn("TRACE")
594
588
  };
595
589
  };
596
- //#endregion
597
590
  export { createConfig as n, createClient as t };
@@ -1,5 +1,5 @@
1
1
  import { format } from "node:util";
2
- //#region src/oclif/json-output.ts
2
+ // src/oclif/json-output.ts
3
3
  /**
4
4
  * Parse-safe `--json` output.
5
5
  *
@@ -318,5 +318,4 @@ function guardJsonOutputCommands(commands) {
318
318
  if (flags && "json" in flags || enableJsonFlag === true) guardJsonOutput(command);
319
319
  }
320
320
  }
321
- //#endregion
322
321
  export { jsonOutputRequested as n, runStreamingJson as r, guardJsonOutputCommands as t };
@@ -1,10 +1,10 @@
1
- import { _ as acquireListenLock, a as mailLockBusy, d as readMailJson, f as removeMailFile, g as ListenStateError, h as writeMailJson, i as mailId, l as privateMailDirectory, 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, d as readMailJson, f as removeMailFile, g as ListenStateError, h as writeMailJson, i as mailId, l as privateMailDirectory, o as mailObject, s as mailString, v as compareListenProcessIdentity, x as listenProcessIdentity } from "./shared-mail-files-BAQSGxxz.js";
2
2
  import { lstatSync, realpathSync } from "node:fs";
3
3
  import { createHash, randomUUID } from "node:crypto";
4
4
  import { join } from "node:path";
5
5
  import { setTimeout as setTimeout$1 } from "node:timers/promises";
6
6
  import { spawn } from "node:child_process";
7
- //#region src/oclif/listen-background.ts
7
+ // src/oclif/listen-background.ts
8
8
  const BACKGROUND_LISTEN_TOKEN_ENV = "PRIMITIVE_LISTEN_BACKGROUND_TOKEN";
9
9
  const BACKGROUND_LISTEN_TARGET_ENV = "PRIMITIVE_LISTEN_BACKGROUND_TARGET";
10
10
  const SUPERVISOR_ENV = "PRIMITIVE_LISTEN_SUPERVISOR";
@@ -837,5 +837,4 @@ async function startBackgroundListen(options) {
837
837
  release();
838
838
  }
839
839
  }
840
- //#endregion
841
840
  export { claimBackgroundListenRestart as a, startBackgroundListen as c, backgroundListenToken as i, stopBackgroundListen as l, backgroundListenRestartable as n, runBackgroundListen as o, backgroundListenStatus as r, runBackgroundListenSupervisor as s, BACKGROUND_LISTEN_TOKEN_ENV as t, verifyBackgroundListenTarget as u };