primcli 1.75.0 → 3.0.0-preview.10

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 +1 @@
1
- export { s as runBackgroundListenSupervisor } from "../listen-background-C0F9gNDD.js";
1
+ export { l as runBackgroundListenSupervisor } from "../listen-background-DyBYca28.js";
@@ -1,4 +1,4 @@
1
- import { n as jsonOutputRequested } from "../json-output-BzSBR-KX.js";
1
+ import { r as jsonOutputRequested } from "../json-output-ch756TXV.js";
2
2
  import { spawnSync } from "node:child_process";
3
3
  // src/oclif/proxy-auto-detect.ts
4
4
  const PROXY_ENV_VARS = [
@@ -1,7 +1,7 @@
1
- import { F as agentProfileName, M as AGENT_PROFILE_ENV, P as agentProfileDirectory, z as loadConnectedAgentProfile } from "../cli-config-B80p0pLk.js";
2
- import { a as claimBackgroundListenRestart, n as backgroundListenRestartable, r as backgroundListenStatus } from "../listen-background-C0F9gNDD.js";
3
- import { l as SESSION_UUID, t as notificationScope } from "../notify-session-CbY4FYUt.js";
4
- import { xt as detectAgentRuntime } from "../api-command-rlS3eTlZ.js";
1
+ import { N as agentProfileDirectory, P as agentProfileName, R as loadConnectedAgentProfile, j as AGENT_PROFILE_ENV } from "../cli-config-Ms_0vNjq.js";
2
+ import { a as backgroundListenStatus, i as backgroundListenRestartable, s as claimBackgroundListenRestart, t as BACKGROUND_LISTEN_RELAUNCH_ENV } from "../listen-background-DyBYca28.js";
3
+ import { d as SESSION_UUID, t as notificationScope } from "../notify-session-DN8tSfAi.js";
4
+ import { Lt as detectAgentRuntime } from "../api-command-D0KHkqhA.js";
5
5
  import { d as readMailJson } from "../shared-mail-files-BAQSGxxz.js";
6
6
  import { join } from "node:path";
7
7
  import { spawn } from "node:child_process";
@@ -66,6 +66,7 @@ function healSelectedReceiver(options = {}) {
66
66
  PRIMITIVE_CONFIG_DIR: configDir,
67
67
  [RECEIVER_HEAL_ENV]: "0"
68
68
  };
69
+ delete childEnv[BACKGROUND_LISTEN_RELAUNCH_ENV];
69
70
  (options.spawnListener ?? spawnDetached)(listenArgv, childEnv);
70
71
  return {
71
72
  action: "restarting",
@@ -1,4 +1,4 @@
1
- import { S as normalizeApiBaseUrl, c as resolveConfigEnvironment, i as loadCliConfig } from "../cli-config-B80p0pLk.js";
1
+ import { c as resolveConfigEnvironment, i as loadCliConfig, x as normalizeApiBaseUrl } from "../cli-config-Ms_0vNjq.js";
2
2
  import { existsSync, readFileSync } from "node:fs";
3
3
  import { join } from "node:path";
4
4
  import { homedir } from "node:os";
@@ -19,7 +19,7 @@ function readRootCredentials(configDir) {
19
19
  }
20
20
  try {
21
21
  const parsed = JSON.parse(raw);
22
- if (parsed.auth_method !== "oauth") return null;
22
+ if (parsed.auth_method !== "oauth" && parsed.auth_method !== "user_grant") return null;
23
23
  if (typeof parsed.access_token !== "string" || !parsed.access_token.trim()) return null;
24
24
  const apiBaseUrl = parsed.api_base_url ?? parsed.api_base_url_1;
25
25
  if (typeof apiBaseUrl !== "string" || !apiBaseUrl.trim()) return null;
@@ -31,23 +31,23 @@ function readRootCredentials(configDir) {
31
31
  return null;
32
32
  }
33
33
  }
34
- function accountEndpoint(apiBaseUrl) {
35
- return `${apiBaseUrl.replace(/\/+$/, "")}/account`;
34
+ function whoamiEndpoint(apiBaseUrl) {
35
+ return `${apiBaseUrl.replace(/\/+$/, "")}/whoami`;
36
36
  }
37
- function parseRootAccount(payload) {
37
+ function parseRootIdentity(payload) {
38
38
  if (payload === null || typeof payload !== "object" || Array.isArray(payload)) return null;
39
39
  const data = payload.data;
40
40
  if (data === null || typeof data !== "object" || Array.isArray(data)) return null;
41
- const account = data;
42
- if (typeof account.email !== "string" || !account.email.trim()) return null;
43
- if (typeof account.id !== "string" || !account.id.trim()) return null;
41
+ const identity = data;
42
+ if (typeof identity.org_id !== "string" || !identity.org_id.trim()) return null;
43
+ const member = identity.member_address;
44
44
  return {
45
- email: account.email,
46
- id: account.id
45
+ memberAddress: member && typeof member.address === "string" && member.address.trim() ? member.address : null,
46
+ orgId: identity.org_id
47
47
  };
48
48
  }
49
- function rootAuthLine(account) {
50
- return `Signed in as ${account.email} (org ${account.id})\n\n`;
49
+ function rootAuthLine(identity) {
50
+ return identity.memberAddress ? `Signed in as ${identity.memberAddress} (org ${identity.orgId})\n\n` : `Signed in (org ${identity.orgId})\n\n`;
51
51
  }
52
52
  function rootRequestConfig(configDir, env) {
53
53
  const config = loadCliConfig(configDir);
@@ -60,11 +60,11 @@ function rootRequestConfig(configDir, env) {
60
60
  headers: currentEnvironment?.config.headers
61
61
  };
62
62
  }
63
- async function fetchRootAccount(params) {
63
+ async function fetchRootIdentity(params) {
64
64
  const controller = new AbortController();
65
65
  const timer = setTimeout(() => controller.abort(), params.timeoutMs);
66
66
  try {
67
- const response = await params.fetch(accountEndpoint(params.apiBaseUrl), {
67
+ const response = await params.fetch(whoamiEndpoint(params.apiBaseUrl), {
68
68
  headers: {
69
69
  ...params.headers ?? {},
70
70
  accept: "application/json",
@@ -73,7 +73,7 @@ async function fetchRootAccount(params) {
73
73
  signal: controller.signal
74
74
  });
75
75
  if (!response.ok) return null;
76
- return parseRootAccount(await response.json().catch(() => null));
76
+ return parseRootIdentity(await response.json().catch(() => null));
77
77
  } catch {
78
78
  return null;
79
79
  } finally {
@@ -95,14 +95,14 @@ async function rootSignedInSummary(options = {}) {
95
95
  const stored = explicitApiKey ? null : readRootCredentials(configDir);
96
96
  const apiKey = explicitApiKey || stored?.accessToken;
97
97
  if (!apiKey) return null;
98
- const account = await fetchRootAccount({
98
+ const identity = await fetchRootIdentity({
99
99
  apiBaseUrl: stored?.apiBaseUrl ?? requestConfig.apiBaseUrl,
100
100
  apiKey,
101
101
  fetch: options.fetch ?? fetch,
102
102
  headers: requestConfig.headers,
103
103
  timeoutMs: options.timeoutMs ?? ROOT_AUTH_TIMEOUT_MS
104
104
  });
105
- return account ? rootAuthLine(account) : null;
105
+ return identity ? rootAuthLine(identity) : null;
106
106
  }
107
107
  function shouldShowLoggedOutSignupHint(options = {}) {
108
108
  if ((options.argv ?? process.argv.slice(2)).length > 0) return false;
@@ -0,0 +1,95 @@
1
+ /** One page of `listAgentContacts` (`primitive agent contacts list`). */
2
+ export type ContactPage = {
3
+ readonly data: readonly unknown[];
4
+ /** The cursor for the next page, or null on the last page. */
5
+ readonly cursor: string | null;
6
+ };
7
+ /**
8
+ * The `checkDefaultNetworkContactAdmission` result for one email
9
+ * (`primitive agent-networks check-default-network-contact-admission`).
10
+ */
11
+ export type NetworkAdmission = {
12
+ readonly allowed: boolean;
13
+ readonly allowed_since: string | null;
14
+ readonly pending: boolean;
15
+ readonly member_policy_required: boolean;
16
+ readonly sender_relation?: "owner" | "member" | undefined;
17
+ };
18
+ /**
19
+ * Reads the policy from the API as the connected address. A reader that hits
20
+ * a temporary failure, such as a rate limit, a 5xx response or a dropped
21
+ * connection, throws `new WakePolicyError("policy_read_failed")`. Any other
22
+ * error from a reader makes the policy unavailable.
23
+ */
24
+ export type WakePolicyOptions = {
25
+ /** The connected address that receives the mail. */
26
+ readonly recipient: string;
27
+ /**
28
+ * Admit first mail from unknown senders as `request` when the owner allows
29
+ * contact requests. Defaults to false.
30
+ */
31
+ readonly contactRequests?: boolean | undefined;
32
+ /** The `data` of `getAgentContactPolicy` for the recipient. */
33
+ readonly readContactPolicy: (signal: AbortSignal) => Promise<unknown>;
34
+ /** One page of the recipient's contacts, 100 rows at most. */
35
+ readonly readContactPage: (cursor: string | undefined, signal: AbortSignal) => Promise<ContactPage>;
36
+ /** The network admission decision for one exact email. */
37
+ readonly readNetworkAdmission: (emailId: string, sender: string, signal: AbortSignal) => Promise<NetworkAdmission>;
38
+ };
39
+ /** The facts of one received email, from the email detail. */
40
+ export type InboundEmail = {
41
+ readonly emailId: string;
42
+ /** The authenticated sender address. Check it before admission. */
43
+ readonly sender: string;
44
+ readonly receivedAt: string;
45
+ };
46
+ /**
47
+ * `allowed` may wake the session. `request` is a first-contact request from
48
+ * an unknown sender: show it as a request, never as a task.
49
+ */
50
+ export type WakeAdmission = (InboundEmail & {
51
+ readonly kind: "allowed";
52
+ }) | (InboundEmail & {
53
+ readonly kind: "request";
54
+ });
55
+ /** `denied` must not wake the session. */
56
+ export type WakeDecision = WakeAdmission | {
57
+ readonly kind: "denied";
58
+ };
59
+ /**
60
+ * Call synchronously immediately before you wake the session. It throws
61
+ * `WakePolicyError` with `permission_changed` when the permission it confirms
62
+ * was refreshed or is older than 30 seconds; recheck and try again.
63
+ */
64
+ export type ConfirmWake = () => void;
65
+ export type WakePolicy = {
66
+ /** Decide whether one email may wake the session. */
67
+ admit(email: InboundEmail, signal: AbortSignal): Promise<WakeDecision>;
68
+ /**
69
+ * Read the policy again for an admission from this policy's `admit`, right
70
+ * before dispatch. Throws `permission_changed` if the admission no longer
71
+ * holds.
72
+ */
73
+ recheck(admission: WakeAdmission, signal: AbortSignal): Promise<ConfirmWake>;
74
+ };
75
+ /**
76
+ * - `policy_read_failed`: a policy read failed temporarily. Retry later; the
77
+ * policy paces repeated reads itself.
78
+ * - `network_admission_pending`: the server has not settled network admission
79
+ * for this email. Retry in a few seconds.
80
+ * - `permission_changed`: permission changed or expired before dispatch.
81
+ * Admit the email again.
82
+ * - `policy_unavailable`: the policy is invalid or access is lost. Do not
83
+ * wake; retrying will not help until access is restored.
84
+ */
85
+ export type WakePolicyErrorCode = "policy_read_failed" | "network_admission_pending" | "permission_changed" | "policy_unavailable";
86
+ export declare class WakePolicyError extends Error {
87
+ readonly code: WakePolicyErrorCode;
88
+ /** Whether the same email may be admitted later without operator action. */
89
+ readonly retryable: boolean;
90
+ constructor(code: WakePolicyErrorCode, options?: {
91
+ cause?: unknown;
92
+ });
93
+ }
94
+ /** Create the contact admission policy for one connected address. */
95
+ export declare function createWakePolicy(options: WakePolicyOptions): WakePolicy;