primcli 1.47.0 → 1.49.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.
- package/README.md +2 -2
- package/dist/{api-command-C1JvJqV0.js → api-command-BixHVNwQ.js} +21 -25
- package/dist/{connect-skill-CH2pq436.js → connect-skill-DBkhFAkO.js} +3 -3
- package/dist/{machine-session-Dr5W2fHb.js → machine-session-BEkDi4_N.js} +590 -130
- package/dist/oclif/auto-signal-worker.js +2 -2
- package/dist/oclif/auto-signals.js +1 -1
- package/dist/oclif/index.js +245 -109
- package/dist/oclif/listen-supervisor.js +1 -1
- package/dist/oclif/receiver-heal.js +2 -2
- package/dist/oclif/root-signup-hint.js +0 -1
- package/dist/{scoped-chat-DhxtuNXs.js → scoped-chat-DSLrmgWQ.js} +1 -1
- package/dist/{signal-command-Dbyqyas9.js → signal-command-D0Rig6eA.js} +5 -5
- package/dist/skills/primitive-connect/SKILL.md +16 -266
- package/dist/skills/primitive-connect/references/manual-setup.md +294 -0
- package/dist/skills/primitive-connect.json +4 -3
- package/man/primitive.1 +1 -1
- package/package.json +1 -1
- /package/dist/{listen-background-CyLc8VBn.js → listen-background-CMfxkeVP.js} +0 -0
- /package/dist/{repeats-D2xtLium-DdiJECLI.js → repeats-D2xtLium-B8Wq41vG.js} +0 -0
- /package/dist/{shared-mail-watch-BUfUaq6j.js → shared-mail-watch-CWhpfJ0N.js} +0 -0
package/dist/oclif/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { A as saveActiveChatState, C as resolveCliAuth, D as deleteChatState, E as chatStatePath, F as agentProfilesDirectory, H as requireDefaultLoginProfile, M as AgentConnectionSetupError, N as agentProfileDirectory, O as loadActiveChatState, P as agentProfileName, R as loadConnectedAgentProfile, T as saveSignupCredentials, W as PrimitiveApiClient, _ as deleteCliCredentials, a as normalizeCliEnvironmentName, b as hasStoredCliLogin, c as resolveConfigEnvironment, g as credentialsPath, h as credentialsLockPath, i as loadCliConfig, j as AGENT_PROFILE_ENV, k as loadChatConversationByLocalId, l as saveCliConfig, m as cliAccessTokenExpiresAt, n as deleteCliConfig, o as redactCliEnvironment, p as acquireCliCredentialsLock, r as emptyCliConfig, s as removeCliEnvironment, u as upsertCliEnvironment, v as deleteCliCredentialsLock, w as saveCliCredentials, x as loadCliCredentials, y as detectPrimitiveKeyEnvMisname } from "../cli-config-DGrZCUfw.js";
|
|
2
|
-
import { $ as buildThrownSendFailureEnvelope, $n as stopRepeatFromEmail, $t as getAgentContactPolicy, A as readThreadContext, An as listWakeSchedules, At as queryUsesAutomated, B as recordPendingMail, Bn as resendAgentSignupVerification, Bt as createEndpoint, C as queryUsesAwaiting, Cn as listFunctionLogs, Ct as AutomatedFilterUnsupportedError, D as displayAddress, Dn as listSentEmails, Dt as expectedAutomatedVerdicts, E as describeWake, En as listRoutes, Et as ensureSearchReportsAutomated, F as wakeRecipientField, Ft as resolveCliApiRequestConfig, G as replyExpectation, Gn as sendEmail, H as interactionHumanLine, Hn as searchEmails, Ht as createRoute, I as wakeRelationship, In as redeemCreditCode, It as addDefaultNetworkMember, J as IDEMPOTENCY_KEY_FLAG_DESCRIPTION, Jn as setMemory, Jt as deleteRoute, K as replyInteractionWarning, Kn as setFunctionRoute, L as clearReadPendingMail, Ln as removeDefaultNetworkMember, Lt as checkDefaultNetworkContactAdmission, M as serverMuted, Mn as pullWebhookEvent, Mt as createAuthenticatedCliApiClient, N as serverRelationship, Nt as createCliApiClient, O as formatWakeContext, On as listWakeAuthorizations, Ot as hasAutomatedVerdict, P as wakeReadCommand, Pt as refreshStoredCliCredentials, Q as buildFollowUpCommand, Qn as startCliLogin, Qt as getAccount, R as pendingMailPath, Rn as reorderRoutes, Rt as cliLogout, S as isAwaitingRejectedError, Sn as listEndpoints, St as AUTOMATED_VALUES, T as bareAddress, Tn as listRepeatingSends, Tt as automatedRejectedError, U as interactionNextActions, Un as searchMemories, Ut as createWakeAuthorization, V as removePendingMail, Vn as runWakeSchedule, Vt as createFunction, W as readEmailInteraction, Wn as semanticSearch, Wt as createWakeSchedule, X as apiResultHttpStatus, Xn as startAgentClaim, Xt as deleteWakeSchedule, Y as SEND_OUTCOME_HELP, Yn as simulateRoute, Yt as deleteWakeAuthorization, Z as assertValidIdempotencyKey, Zn as startAgentSignup, _ as awaitingRejectedError, _t as formatAlreadySentNotice, a as extractErrorCode, an as getFunction, ar as updateRoute, at as formatPriorRepliesWarning, b as formatRepliesCell, bn as listDomains, bt as AUTOMATED_FILTER_UNSUPPORTED_CODE, c as readTextFileFlag, cn as getInboxStatus, cr as verifyAgentClaim, ct as priorRepliesThatWentOut, d as writeErrorWithHints, dn as getRepeatingSend, dt as sendOutcomeExitCode, er as testFunction, et as checkPriorReplies, f as AWAITING_FLAG_DESCRIPTION, fn as getSentEmail, ft as sentHistoryWindowStart, g as assertAwaitingFilterRows, gn as listAgentNetworks, gt as currentMailSessionKey, h as ReplyStateUnsupportedError, hn as listAgentContacts, ht as thrownErrorExitCode, i as createOperationCommand, in as getEmail, ir as updateRepeatingSend, it as formatPriorRepliesCheckSkipped, j as sentInThread, jn as pollCliLogin, k as latestOwnOutbound, kn as listWakeDispatches, kt as isAutomatedRejectedError, l as runWithTiming, ln as getMemory, lr as verifyAgentSignup, lt as reportSendCommandResult, m as REPLY_STATE_UNSUPPORTED_CODE, mn as getWakeSchedule, mt as successfulSendOutcome, n as API_ERROR_CODES, nn as getCreditBalance, nr as updateDefaultNetworkMember, nt as deriveSendIdempotencyKey, o as extractErrorPayload, on as getFunctionRouting, or as updateWakeAuthorization, ot as formatSendFailureSummary, p as AWAITING_VALUES, pn as getThread, pt as serializeErrorPayload, q as wakeInteractionSentence, qn as setFunctionSecret, qt as deleteMemory, r as TIME_FLAG_DESCRIPTION, rn as getDefaultNetworkAgent, rr as updateFunction, rt as formatDeletedEarlierSendNotice, s as formatErrorPayload, sn as getFunctionTestRunTrace, sr as updateWakeSchedule, st as formatSendRecordFailureSummary, t as API_BASE_URL_FLAG_DESCRIPTION, tn as getConversation, tr as unsetFunctionRoute, tt as classifySendError, u as surfaceUnauthorizedHint, un as getOrgRoutingTopology, ut as sendIdentityFields, v as ensureSearchReportsReplyState, vn as listDefaultNetworkAgents, vt as writeIdempotentReplayBannerIfReplay, w as explainPendingMailNotFound, wn as listFunctions, wt as assertAutomatedVerdict, x as hasReplyState, xn as listEmails, xt as AUTOMATED_FLAG_DESCRIPTION, y as formatAwaitingCell, yn as listDefaultNetworkMembers, yt as withFlagSuggestion, z as readPendingMail, zn as replyToEmail, zt as completeWebhookEvent } from "../api-command-
|
|
2
|
+
import { $ as buildThrownSendFailureEnvelope, $n as stopRepeatFromEmail, $t as getAgentContactPolicy, A as readThreadContext, An as listWakeSchedules, At as queryUsesAutomated, B as recordPendingMail, Bn as resendAgentSignupVerification, Bt as createEndpoint, C as queryUsesAwaiting, Cn as listFunctionLogs, Ct as AutomatedFilterUnsupportedError, D as displayAddress, Dn as listSentEmails, Dt as expectedAutomatedVerdicts, E as describeWake, En as listRoutes, Et as ensureSearchReportsAutomated, F as wakeRecipientField, Ft as resolveCliApiRequestConfig, G as replyExpectation, Gn as sendEmail, H as interactionHumanLine, Hn as searchEmails, Ht as createRoute, I as wakeRelationship, In as redeemCreditCode, It as addDefaultNetworkMember, J as IDEMPOTENCY_KEY_FLAG_DESCRIPTION, Jn as setMemory, Jt as deleteRoute, K as replyInteractionWarning, Kn as setFunctionRoute, L as clearReadPendingMail, Ln as removeDefaultNetworkMember, Lt as checkDefaultNetworkContactAdmission, M as serverMuted, Mn as pullWebhookEvent, Mt as createAuthenticatedCliApiClient, N as serverRelationship, Nt as createCliApiClient, O as formatWakeContext, On as listWakeAuthorizations, Ot as hasAutomatedVerdict, P as wakeReadCommand, Pt as refreshStoredCliCredentials, Q as buildFollowUpCommand, Qn as startCliLogin, Qt as getAccount, R as pendingMailPath, Rn as reorderRoutes, Rt as cliLogout, S as isAwaitingRejectedError, Sn as listEndpoints, St as AUTOMATED_VALUES, T as bareAddress, Tn as listRepeatingSends, Tt as automatedRejectedError, U as interactionNextActions, Un as searchMemories, Ut as createWakeAuthorization, V as removePendingMail, Vn as runWakeSchedule, Vt as createFunction, W as readEmailInteraction, Wn as semanticSearch, Wt as createWakeSchedule, X as apiResultHttpStatus, Xn as startAgentClaim, Xt as deleteWakeSchedule, Y as SEND_OUTCOME_HELP, Yn as simulateRoute, Yt as deleteWakeAuthorization, Z as assertValidIdempotencyKey, Zn as startAgentSignup, _ as awaitingRejectedError, _t as formatAlreadySentNotice, a as extractErrorCode, an as getFunction, ar as updateRoute, at as formatPriorRepliesWarning, b as formatRepliesCell, bn as listDomains, bt as AUTOMATED_FILTER_UNSUPPORTED_CODE, c as readTextFileFlag, cn as getInboxStatus, cr as verifyAgentClaim, ct as priorRepliesThatWentOut, d as writeErrorWithHints, dn as getRepeatingSend, dt as sendOutcomeExitCode, er as testFunction, et as checkPriorReplies, f as AWAITING_FLAG_DESCRIPTION, fn as getSentEmail, ft as sentHistoryWindowStart, g as assertAwaitingFilterRows, gn as listAgentNetworks, gt as currentMailSessionKey, h as ReplyStateUnsupportedError, hn as listAgentContacts, ht as thrownErrorExitCode, i as createOperationCommand, in as getEmail, ir as updateRepeatingSend, it as formatPriorRepliesCheckSkipped, j as sentInThread, jn as pollCliLogin, k as latestOwnOutbound, kn as listWakeDispatches, kt as isAutomatedRejectedError, l as runWithTiming, ln as getMemory, lr as verifyAgentSignup, lt as reportSendCommandResult, m as REPLY_STATE_UNSUPPORTED_CODE, mn as getWakeSchedule, mt as successfulSendOutcome, n as API_ERROR_CODES, nn as getCreditBalance, nr as updateDefaultNetworkMember, nt as deriveSendIdempotencyKey, o as extractErrorPayload, on as getFunctionRouting, or as updateWakeAuthorization, ot as formatSendFailureSummary, p as AWAITING_VALUES, pn as getThread, pt as serializeErrorPayload, q as wakeInteractionSentence, qn as setFunctionSecret, qt as deleteMemory, r as TIME_FLAG_DESCRIPTION, rn as getDefaultNetworkAgent, rr as updateFunction, rt as formatDeletedEarlierSendNotice, s as formatErrorPayload, sn as getFunctionTestRunTrace, sr as updateWakeSchedule, st as formatSendRecordFailureSummary, t as API_BASE_URL_FLAG_DESCRIPTION, tn as getConversation, tr as unsetFunctionRoute, tt as classifySendError, u as surfaceUnauthorizedHint, un as getOrgRoutingTopology, ut as sendIdentityFields, v as ensureSearchReportsReplyState, vn as listDefaultNetworkAgents, vt as writeIdempotentReplayBannerIfReplay, w as explainPendingMailNotFound, wn as listFunctions, wt as assertAutomatedVerdict, x as hasReplyState, xn as listEmails, xt as AUTOMATED_FLAG_DESCRIPTION, y as formatAwaitingCell, yn as listDefaultNetworkMembers, yt as withFlagSuggestion, z as readPendingMail, zn as replyToEmail, zt as completeWebhookEvent } from "../api-command-BixHVNwQ.js";
|
|
3
3
|
import { S as resolveListenSubscription, _ as acquireListenLock, a as mailLockBusy, c as mailTime, d as readMailJson, f as removeMailFile, g as ListenStateError, h as writeMailJson, i as mailId, l as privateMailDirectory, m as withMailLock, o as mailObject, u as privateMailPermissions, x as normalizeListenOrigin, y as listenIdentity } from "../shared-mail-files-SPPcis9g.js";
|
|
4
|
-
import { $ as
|
|
5
|
-
import {
|
|
6
|
-
import { c as
|
|
7
|
-
import {
|
|
8
|
-
import { a as
|
|
9
|
-
import { a as
|
|
10
|
-
import { autoSignalEligible, dispatchAutoRead, dispatchAutoWorking, haltAutoWorking, restoreAutoWorking } from "./auto-signals.js";
|
|
4
|
+
import { $ as currentCliLocation, A as NETWORK_ADMISSION_PENDING_RETRY_MS, B as contactAgentAddress, C as invitationProfileName, D as externalReceivingState, E as RECEIVER_MODES, F as AddressNotesApiError, G as readAgentInvitation, H as agentConnectionStatus, I as addressNoteTarget, J as savedReceiver, K as receiverStatusCommand, L as runAddressNotesRequest, M as createNotificationContactPolicy, N as evaluateContactPolicy, O as verificationReplySubmitted, P as canonicalContactSelector, Q as claudeConfigDir, R as ContactsApiError, S as defaultAgentProfileName, T as runAgentConnect, U as agentInvitationHash, V as runContactRequest, W as connectAgent, X as recordHookMailCheck, Y as installClaudeWakeHook, Z as boundSessionProfiles, _ as disconnectAgent, _t as readHookLauncherWarning, a as endSession, at as hasMachineSessionHooks, b as identitySuggestions, c as pendingSessionDisconnects, ct as repairClaudeHooks, d as registerSession, dt as MachineFileError, et as describeSessionHookChange, f as retryPendingDisconnects, ft as inspectManagedBlock, g as AgentDisconnectError, gt as writeManagedFile, h as enrollmentResumes, ht as upsertManagedBlock, i as connectedProfilesForSession, it as findOnPath, j as NetworkAdmissionPendingError, k as ContactPolicyReadRetryError, l as psProcessInfo, lt as samePath, m as enrollAgent, mt as readManagedFile, n as OMP_MAIN, nt as ensureHookLauncher, o as headlessClaudeRun, ot as inspectClaudeHooks, p as runDetached, pt as jsonIndentation, q as refusalAfterReplacement, r as agentConnectionState, rt as ephemeralCliReason, st as readClaudeSettings, t as MACHINE_RUNTIMES, tt as describeSessionHookItem, u as readClaudeHookInput, ut as writeClaudeSettings, v as cliInvocation, vt as refreshOwnerMemberAddressPeriodically, w as pollCheckCommand, x as connectWarnings, y as generatedAgentName, yt as withOwnerMemberAddress, z as contactAddress } from "../machine-session-BEkDi4_N.js";
|
|
5
|
+
import { a as scopedChatSenderTrust, i as readBeforeDeadline, n as isPlainChatReply, o as presenceDisposition, r as isScopedChatReply, s as readPresenceProjection, t as isConnectedChatCredential } from "../scoped-chat-DSLrmgWQ.js";
|
|
6
|
+
import { _ as NativeSessionDisconnectedError, a as readBundledConnectSkill, b as NotificationOutcomeUnknownError, c as openSessionNotifications, d as isRoutineNotificationContent, f as notificationPartReader, g as defaultSessionSocket, i as installedVersion, l as notificationReceiptPage, m as SESSION_UUID$1, o as notificationScope, p as readConversationStatusContent, r as installConnectSkill, s as notificationSenders, t as connectSkillTarget, u as NotificationRetryError, v as NativeSessionError, y as NativeSessionNotLoadedError } from "../connect-skill-DBkhFAkO.js";
|
|
7
|
+
import { c as startBackgroundListen, i as backgroundListenToken, l as stopBackgroundListen, o as runBackgroundListen, r as backgroundListenStatus, u as verifyBackgroundListenTarget } from "../listen-background-CMfxkeVP.js";
|
|
8
|
+
import { a as REPEAT_IDLE_MAX_MINUTES, d as parseRepeatTick, f as preparePresenceAliveEmail, g as isEmailReceivedEvent, i as REPEAT_EVERY_MAX_MINUTES, l as parseInteractionEnvelope$1, m as repeatStopCommand, o as REPEAT_MAX_SENDS_MAX, p as prepareSignalEmail, s as buildRepeatStopBody, u as parsePresenceEnvelope, v as parseWebhookEvent, y as parseFromHeader } from "../repeats-D2xtLium-B8Wq41vG.js";
|
|
9
|
+
import { a as ensureSharedMailSubscription, c as reserveSharedMailSubscription, d as otherParticipants, f as EventConnection, h as pushFile, i as sharedMailScope, l as followEmailConversation, m as pullFile, n as reconcileChatSend, o as createSharedMailWaiter, p as EventReceiverError, r as openSharedMailReceiver, s as openSharedMailStore, t as sendSignal, u as readConversationFollow } from "../signal-command-D0Rig6eA.js";
|
|
10
|
+
import { autoSignalEligible, dispatchAutoRead, dispatchAutoWorking, haltAutoWorking, isSentSignal, restoreAutoWorking } from "./auto-signals.js";
|
|
11
11
|
import { t as guardJsonOutputCommands } from "../json-output-Cf-GFeff.js";
|
|
12
12
|
import { Args, Command, Errors, Flags, ux } from "@oclif/core";
|
|
13
13
|
import { chmodSync, closeSync, constants, cpSync, existsSync, fstatSync, fsyncSync, linkSync, lstatSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
@@ -272,7 +272,7 @@ const openapiDocument = {
|
|
|
272
272
|
"/cli/signup/start": { "post": {
|
|
273
273
|
"operationId": "startCliSignup",
|
|
274
274
|
"summary": "Start CLI account signup",
|
|
275
|
-
"description": "Starts a terminal-native CLI signup.
|
|
275
|
+
"description": "Starts a terminal-native CLI signup. The API creates a pending\nsignup session, sends an email verification code, and returns an opaque\nsignup token used by the resend and verify steps. This endpoint\ndoes not require an API key.\n",
|
|
276
276
|
"tags": ["CLI"],
|
|
277
277
|
"security": [],
|
|
278
278
|
"requestBody": {
|
|
@@ -334,7 +334,7 @@ const openapiDocument = {
|
|
|
334
334
|
"/cli/signup/verify": { "post": {
|
|
335
335
|
"operationId": "verifyCliSignup",
|
|
336
336
|
"summary": "Verify CLI signup and create OAuth session",
|
|
337
|
-
"description": "Verifies the email code for a CLI signup session and creates the\naccount.
|
|
337
|
+
"description": "Verifies the email code for a CLI signup session and creates the\naccount. An org-scoped OAuth CLI session is created and the\ntoken set is returned exactly once. This endpoint does not\nrequire an API key.\n",
|
|
338
338
|
"tags": ["CLI"],
|
|
339
339
|
"security": [],
|
|
340
340
|
"requestBody": {
|
|
@@ -354,7 +354,7 @@ const openapiDocument = {
|
|
|
354
354
|
}] } } }
|
|
355
355
|
},
|
|
356
356
|
"400": {
|
|
357
|
-
"description": "Invalid request, invalid verification code, expired token,
|
|
357
|
+
"description": "Invalid request, invalid verification code, expired token, rejected password, or account creation failure",
|
|
358
358
|
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
|
|
359
359
|
},
|
|
360
360
|
"429": { "$ref": "#/components/responses/RateLimited" }
|
|
@@ -363,7 +363,7 @@ const openapiDocument = {
|
|
|
363
363
|
"/agent/signup/start": { "post": {
|
|
364
364
|
"operationId": "startAgentSignup",
|
|
365
365
|
"summary": "Start agent account signup",
|
|
366
|
-
"description": "Starts an agent-native signup session.
|
|
366
|
+
"description": "Starts an agent-native signup session. The API creates a pending\nsignup session, sends an email verification code, and returns an opaque\nsignup token used by the resend and verify steps. This endpoint\ndoes not require an API key.\n",
|
|
367
367
|
"tags": ["Agent"],
|
|
368
368
|
"security": [],
|
|
369
369
|
"requestBody": {
|
|
@@ -425,7 +425,7 @@ const openapiDocument = {
|
|
|
425
425
|
"/agent/signup/verify": { "post": {
|
|
426
426
|
"operationId": "verifyAgentSignup",
|
|
427
427
|
"summary": "Verify agent signup and create OAuth tokens",
|
|
428
|
-
"description": "Verifies the email code for an agent signup session and creates\nthe account when needed.
|
|
428
|
+
"description": "Verifies the email code for an agent signup session and creates\nthe account when needed. An org-scoped OAuth session for CLI\nauthentication is minted and the raw tokens are returned exactly\nonce. For existing users, the optional `org_id` selects which\naccessible workspace should receive the new session.\n",
|
|
429
429
|
"tags": ["Agent"],
|
|
430
430
|
"security": [],
|
|
431
431
|
"requestBody": {
|
|
@@ -445,7 +445,7 @@ const openapiDocument = {
|
|
|
445
445
|
}] } } }
|
|
446
446
|
},
|
|
447
447
|
"400": {
|
|
448
|
-
"description": "Invalid request, invalid verification code, expired token,
|
|
448
|
+
"description": "Invalid request, invalid verification code, expired token, or account creation failure",
|
|
449
449
|
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
|
|
450
450
|
},
|
|
451
451
|
"403": { "$ref": "#/components/responses/Forbidden" },
|
|
@@ -9765,7 +9765,6 @@ const openapiDocument = {
|
|
|
9765
9765
|
"access_denied",
|
|
9766
9766
|
"expired_token",
|
|
9767
9767
|
"invalid_device_code",
|
|
9768
|
-
"invalid_signup_code",
|
|
9769
9768
|
"invalid_signup_token",
|
|
9770
9769
|
"invalid_verification_code",
|
|
9771
9770
|
"email_delivery_failed",
|
|
@@ -10070,12 +10069,6 @@ const openapiDocument = {
|
|
|
10070
10069
|
"format": "email",
|
|
10071
10070
|
"maxLength": 254
|
|
10072
10071
|
},
|
|
10073
|
-
"signup_code": {
|
|
10074
|
-
"type": "string",
|
|
10075
|
-
"minLength": 1,
|
|
10076
|
-
"maxLength": 128,
|
|
10077
|
-
"description": "Optional signup code. Omit if you do not have one."
|
|
10078
|
-
},
|
|
10079
10072
|
"terms_accepted": {
|
|
10080
10073
|
"type": "boolean",
|
|
10081
10074
|
"const": true,
|
|
@@ -10255,12 +10248,6 @@ const openapiDocument = {
|
|
|
10255
10248
|
"format": "email",
|
|
10256
10249
|
"maxLength": 254
|
|
10257
10250
|
},
|
|
10258
|
-
"signup_code": {
|
|
10259
|
-
"type": "string",
|
|
10260
|
-
"minLength": 1,
|
|
10261
|
-
"maxLength": 128,
|
|
10262
|
-
"description": "Optional signup code. Omit if you do not have one."
|
|
10263
|
-
},
|
|
10264
10251
|
"terms_accepted": {
|
|
10265
10252
|
"type": "boolean",
|
|
10266
10253
|
"const": true,
|
|
@@ -17470,7 +17457,7 @@ const operationManifest = [
|
|
|
17470
17457
|
"binaryResponse": false,
|
|
17471
17458
|
"bodyRequired": true,
|
|
17472
17459
|
"command": "start-agent-signup",
|
|
17473
|
-
"description": "Starts an agent-native signup session.
|
|
17460
|
+
"description": "Starts an agent-native signup session. The API creates a pending\nsignup session, sends an email verification code, and returns an opaque\nsignup token used by the resend and verify steps. This endpoint\ndoes not require an API key.\n",
|
|
17474
17461
|
"hasJsonBody": true,
|
|
17475
17462
|
"method": "POST",
|
|
17476
17463
|
"operationId": "startAgentSignup",
|
|
@@ -17486,12 +17473,6 @@ const operationManifest = [
|
|
|
17486
17473
|
"format": "email",
|
|
17487
17474
|
"maxLength": 254
|
|
17488
17475
|
},
|
|
17489
|
-
"signup_code": {
|
|
17490
|
-
"type": "string",
|
|
17491
|
-
"minLength": 1,
|
|
17492
|
-
"maxLength": 128,
|
|
17493
|
-
"description": "Optional signup code. Omit if you do not have one."
|
|
17494
|
-
},
|
|
17495
17476
|
"terms_accepted": {
|
|
17496
17477
|
"type": "boolean",
|
|
17497
17478
|
"const": true,
|
|
@@ -17626,7 +17607,7 @@ const operationManifest = [
|
|
|
17626
17607
|
"binaryResponse": false,
|
|
17627
17608
|
"bodyRequired": true,
|
|
17628
17609
|
"command": "verify-agent-signup",
|
|
17629
|
-
"description": "Verifies the email code for an agent signup session and creates\nthe account when needed.
|
|
17610
|
+
"description": "Verifies the email code for an agent signup session and creates\nthe account when needed. An org-scoped OAuth session for CLI\nauthentication is minted and the raw tokens are returned exactly\nonce. For existing users, the optional `org_id` selects which\naccessible workspace should receive the new session.\n",
|
|
17630
17611
|
"hasJsonBody": true,
|
|
17631
17612
|
"method": "POST",
|
|
17632
17613
|
"operationId": "verifyAgentSignup",
|
|
@@ -19817,7 +19798,7 @@ const operationManifest = [
|
|
|
19817
19798
|
"binaryResponse": false,
|
|
19818
19799
|
"bodyRequired": true,
|
|
19819
19800
|
"command": "start-cli-signup",
|
|
19820
|
-
"description": "Starts a terminal-native CLI signup.
|
|
19801
|
+
"description": "Starts a terminal-native CLI signup. The API creates a pending\nsignup session, sends an email verification code, and returns an opaque\nsignup token used by the resend and verify steps. This endpoint\ndoes not require an API key.\n",
|
|
19821
19802
|
"hasJsonBody": true,
|
|
19822
19803
|
"method": "POST",
|
|
19823
19804
|
"operationId": "startCliSignup",
|
|
@@ -19833,12 +19814,6 @@ const operationManifest = [
|
|
|
19833
19814
|
"format": "email",
|
|
19834
19815
|
"maxLength": 254
|
|
19835
19816
|
},
|
|
19836
|
-
"signup_code": {
|
|
19837
|
-
"type": "string",
|
|
19838
|
-
"minLength": 1,
|
|
19839
|
-
"maxLength": 128,
|
|
19840
|
-
"description": "Optional signup code. Omit if you do not have one."
|
|
19841
|
-
},
|
|
19842
19817
|
"terms_accepted": {
|
|
19843
19818
|
"type": "boolean",
|
|
19844
19819
|
"const": true,
|
|
@@ -19899,7 +19874,7 @@ const operationManifest = [
|
|
|
19899
19874
|
"binaryResponse": false,
|
|
19900
19875
|
"bodyRequired": true,
|
|
19901
19876
|
"command": "verify-cli-signup",
|
|
19902
|
-
"description": "Verifies the email code for a CLI signup session and creates the\naccount.
|
|
19877
|
+
"description": "Verifies the email code for a CLI signup session and creates the\naccount. An org-scoped OAuth CLI session is created and the\ntoken set is returned exactly once. This endpoint does not\nrequire an API key.\n",
|
|
19903
19878
|
"hasJsonBody": true,
|
|
19904
19879
|
"method": "POST",
|
|
19905
19880
|
"operationId": "verifyCliSignup",
|
|
@@ -35277,9 +35252,25 @@ function readCursor(path) {
|
|
|
35277
35252
|
} catch {}
|
|
35278
35253
|
return null;
|
|
35279
35254
|
}
|
|
35280
|
-
/**
|
|
35281
|
-
|
|
35282
|
-
|
|
35255
|
+
/**
|
|
35256
|
+
* Mail the CLI handles itself: a presence probe whose authenticated
|
|
35257
|
+
* projection marks it as control mail (verified, or pending while its proof
|
|
35258
|
+
* settles; a rejected one is ordinary mail), and the exact setup challenge
|
|
35259
|
+
* this profile's setup recorded. Nothing is judged by sender or subject: the
|
|
35260
|
+
* owner can write from the control address, and that email is listed like
|
|
35261
|
+
* any other.
|
|
35262
|
+
*/
|
|
35263
|
+
function isControlMail(email, setupChallengeId) {
|
|
35264
|
+
return presenceDisposition(email) !== "ordinary" || setupChallengeId !== null && email.id === setupChallengeId;
|
|
35265
|
+
}
|
|
35266
|
+
/** The setup challenge's email ID saved by this profile's setup, if any. */
|
|
35267
|
+
function savedSetupChallengeId(directory) {
|
|
35268
|
+
try {
|
|
35269
|
+
const id = readMailJson(join(directory, "setup.json"))?.challenge?.id;
|
|
35270
|
+
return typeof id === "string" && id.length > 0 ? id : null;
|
|
35271
|
+
} catch {
|
|
35272
|
+
return null;
|
|
35273
|
+
}
|
|
35283
35274
|
}
|
|
35284
35275
|
async function checkAgentMail(options) {
|
|
35285
35276
|
const { identity } = options;
|
|
@@ -35288,9 +35279,14 @@ async function checkAgentMail(options) {
|
|
|
35288
35279
|
const release = acquireListenLock(directory, "mail-check");
|
|
35289
35280
|
const readCommand = (id) => `PRIMITIVE_AGENT_PROFILE=${identity.profileName} ${options.invocation ?? "primitive"} emails get --id ${id} --brief`;
|
|
35290
35281
|
const to = identity.agentAddress.toLowerCase();
|
|
35282
|
+
const ownerMember = (options.ownerMemberAddress ?? (() => refreshOwnerMemberAddressPeriodically({
|
|
35283
|
+
configDir: options.configDir,
|
|
35284
|
+
profileName: identity.profileName
|
|
35285
|
+
})))().catch(() => identity.ownerMemberAddress ?? null);
|
|
35291
35286
|
try {
|
|
35292
35287
|
const path = join(directory, CURSOR_FILE);
|
|
35293
35288
|
const saved = readCursor(path);
|
|
35289
|
+
const setupChallenge = savedSetupChallengeId(directory);
|
|
35294
35290
|
let cursor = saved;
|
|
35295
35291
|
const emails = [];
|
|
35296
35292
|
let controlSkipped = 0;
|
|
@@ -35310,7 +35306,7 @@ async function checkAgentMail(options) {
|
|
|
35310
35306
|
});
|
|
35311
35307
|
if (result.error || !result.data) throw new MailCheckApiError(result.error);
|
|
35312
35308
|
const rows = result.data.data ?? [];
|
|
35313
|
-
for (const row of rows) if (isControlMail(row,
|
|
35309
|
+
for (const row of rows) if (isControlMail(row, setupChallenge)) controlSkipped++;
|
|
35314
35310
|
else emails.push({
|
|
35315
35311
|
id: row.id,
|
|
35316
35312
|
received_at: row.received_at,
|
|
@@ -35329,6 +35325,7 @@ async function checkAgentMail(options) {
|
|
|
35329
35325
|
emails,
|
|
35330
35326
|
more,
|
|
35331
35327
|
control_skipped: controlSkipped,
|
|
35328
|
+
owner_member_address: await ownerMember,
|
|
35332
35329
|
profile: identity.profileName,
|
|
35333
35330
|
to,
|
|
35334
35331
|
read_command: readCommand("<id>")
|
|
@@ -35353,9 +35350,9 @@ var AgentCheckMailCommand = class AgentCheckMailCommand extends Command {
|
|
|
35353
35350
|
static summary = "Check a connected agent's mail since its last check";
|
|
35354
35351
|
static description = `Print the mail that reached the selected connected agent profile since its previous check, oldest first, once, without waiting. This is how an agent connected with poll receiving (no local session ID or hooks, so nothing can wake it) receives mail: run it at the start of each turn and after sending, then read each email with its \`read_command\`, which selects this profile: an email is readable only under the profile that received it.
|
|
35355
35352
|
|
|
35356
|
-
Acknowledgements marked fyi and mail in muted threads are left out.
|
|
35353
|
+
Acknowledgements marked fyi and mail in muted threads are left out. Presence probes and this profile's setup challenge are handled by the CLI and only counted in \`control_skipped\`; any other email from the connection's control address, such as one the owner wrote from it, is listed like any other email. The position is saved privately with the profile and moves forward only after mail was read, so mail is reported again rather than lost when a check fails or is interrupted; deduplicate by email ID. The first check starts before the address's first email. \`more: true\` means more new mail remains: handle these and check again.
|
|
35357
35354
|
|
|
35358
|
-
Requires a connected agent profile selected with ${AGENT_PROFILE_ENV}. Output is one JSON document: \`outcome\` ("mail" | "empty"), \`emails\` (id, received_at, sender, thread_id, to, and the read_command that reads that email under this profile; never subject or body), \`more\`, \`control_skipped\`, \`profile\`, \`to\` (the address this profile receives for) and \`read_command\` (the template with <id>).`;
|
|
35355
|
+
Requires a connected agent profile selected with ${AGENT_PROFILE_ENV}. Output is one JSON document: \`outcome\` ("mail" | "empty"), \`emails\` (id, received_at, sender, thread_id, to, and the read_command that reads that email under this profile; never subject or body), \`more\`, \`control_skipped\`, \`owner_member_address\` (the owner's personal address, where reports and questions go, or null when none is known; refreshed from the server every few minutes), \`profile\`, \`to\` (the address this profile receives for) and \`read_command\` (the template with <id>).`;
|
|
35359
35356
|
static examples = [`${AGENT_PROFILE_ENV}=connection-0123456789ab <%= config.bin %> agent check-mail --json`];
|
|
35360
35357
|
static flags = { json: Flags.boolean({ description: "Print JSON (already the default)" }) };
|
|
35361
35358
|
async run() {
|
|
@@ -35514,7 +35511,7 @@ function invocation$1(entry) {
|
|
|
35514
35511
|
return entry && /[\\/]_npx[\\/]/.test(entry) ? "npx -y primitive@latest" : "primitive";
|
|
35515
35512
|
}
|
|
35516
35513
|
var AgentConnectCommand = class AgentConnectCommand extends Command {
|
|
35517
|
-
static description = `Connect this coding session to Primitive in one call. With --session, the command checks this CLI's capabilities, installs or refreshes the matching primitive-connect skill for the detected runtime (Claude Code or Codex) from files bundled in this CLI, claims the owner's private setup invitation from piped stdin, answers one authenticated setup challenge, enables owner notifications, starts receiving, seeds a private AGENT_INFO note from --name and --info when absent, and prints one JSON result. The receiver defaults to external hooks in Claude Code and the native background listener elsewhere. Without a session (no --session, or an empty one) the receiver is poll: for runtimes with no local session ID or hooks, such as a cloud-hosted conversation whose commands run in a separate sandbox, the invitation is claimed and verified the same way, nothing is installed, and the result's receiving.checkCommand is the command the agent runs to check for new mail at the start of each turn and after it sends. Native receiving starts or reuses a supervised background listener and waits briefly for its first successful mail check; external receiving installs the exact Claude session's fail-open Stop hook and resume SessionStart hook after the verification reply; a real idle mail event must still verify wake. The profile defaults to session-<session>, or to connection-<invitation hash prefix> without a session. --resume continues saved progress without reading stdin or replaying a claim or uncertain verification send. After the reply is submitted it waits up to a minute for the server to confirm the connection and reports verification.state verified, or reply_submitted while confirmation is still pending. Verification is separate from receiver health. Both official production (https://api.primitive.dev/v1) and staging (https://api.primitive-staging-1.com/v1) invitations pin their API origin. Never pass an invitation as a command argument. One address per session: if this session already has a connected Primitive address, including one saved in the profile being connected, the command claims nothing, leaves stdin unread, and exits 3 with status already_connected. Its detail names how to continue that profile's own connection when that is the only one: --resume for a setup with saved progress, or --keep-existing to refresh a claim-only profile from the same invitation. Otherwise ask the user whether to keep the existing address or disconnect it first, then rerun with --keep-existing or --replace-existing. Never choose for the user. Select the saved identity with PRIMITIVE_AGENT_PROFILE. Use --status --json with --profile, or with PRIMITIVE_AGENT_PROFILE set, to inspect saved identity and local receiver health offline; it exits 1 when the profile is not configured.`;
|
|
35514
|
+
static description = `Connect this coding session to Primitive in one call. With --session, the command checks this CLI's capabilities, installs or refreshes the matching primitive-connect skill for the detected runtime (Claude Code or Codex) from files bundled in this CLI, claims the owner's private setup invitation from piped stdin, answers one authenticated setup challenge, enables owner notifications, starts receiving, seeds a private AGENT_INFO note from --name and --info when absent, and prints one JSON result. The receiver defaults to external hooks in Claude Code and the native background listener elsewhere. When the native default cannot work because this machine has no local session socket (for example Codex older than 0.158.0), the command connects with poll receiving instead and reports receiving.fallbackReason and receiving.fallbackDetail. Without a session (no --session, or an empty one) the receiver is poll: for runtimes with no local session ID or hooks, such as a cloud-hosted conversation whose commands run in a separate sandbox, the invitation is claimed and verified the same way, nothing is installed, and the result's receiving.checkCommand is the command the agent runs to check for new mail at the start of each turn and after it sends. Native receiving starts or reuses a supervised background listener and waits briefly for its first successful mail check; external receiving installs the exact Claude session's fail-open Stop hook and resume SessionStart hook after the verification reply; a real idle mail event must still verify wake. The profile defaults to session-<session>, or to connection-<invitation hash prefix> without a session. --resume continues saved progress without reading stdin or replaying a claim or uncertain verification send. After the reply is submitted it waits up to a minute for the server to confirm the connection and reports verification.state verified, or reply_submitted while confirmation is still pending. Verification is separate from receiver health. Both official production (https://api.primitive.dev/v1) and staging (https://api.primitive-staging-1.com/v1) invitations pin their API origin. Never pass an invitation as a command argument. One address per session: if this session already has a connected Primitive address, including one saved in the profile being connected, the command claims nothing, leaves stdin unread, and exits 3 with status already_connected. Its detail names how to continue that profile's own connection when that is the only one: --resume for a setup with saved progress, or --keep-existing to refresh a claim-only profile from the same invitation. Otherwise ask the user whether to keep the existing address or disconnect it first, then rerun with --keep-existing or --replace-existing. Never choose for the user. Select the saved identity with PRIMITIVE_AGENT_PROFILE. Use --status --json with --profile, or with PRIMITIVE_AGENT_PROFILE set, to inspect saved identity and local receiver health offline; it exits 1 when the profile is not configured.`;
|
|
35518
35515
|
static summary = "Connect and verify an agent address";
|
|
35519
35516
|
static examples = [
|
|
35520
35517
|
"<%= config.bin %> agent connect --session \"$CODEX_THREAD_ID\" --name Research --info \"Reviews pull requests\" --json < private-invitation.txt",
|
|
@@ -35577,6 +35574,7 @@ var AgentConnectCommand = class AgentConnectCommand extends Command {
|
|
|
35577
35574
|
async run() {
|
|
35578
35575
|
const { flags } = await this.parse(AgentConnectCommand);
|
|
35579
35576
|
let pollProfile;
|
|
35577
|
+
let replaced = [];
|
|
35580
35578
|
try {
|
|
35581
35579
|
if (flags.status) {
|
|
35582
35580
|
const profileName = flags.profile ?? (process.env["PRIMITIVE_AGENT_PROFILE"]?.trim() || void 0);
|
|
@@ -35608,7 +35606,6 @@ var AgentConnectCommand = class AgentConnectCommand extends Command {
|
|
|
35608
35606
|
invitationText ??= await readAgentInvitation(process.stdin, process.stdin.isTTY);
|
|
35609
35607
|
return invitationText;
|
|
35610
35608
|
};
|
|
35611
|
-
let replaced = [];
|
|
35612
35609
|
let replaceExisting;
|
|
35613
35610
|
const guardSession = flags.resume ? null : flags.session !== void 0 ? session?.toLowerCase() ?? null : guardedSession(void 0);
|
|
35614
35611
|
if (guardSession && !flags["keep-existing"]) {
|
|
@@ -35684,8 +35681,10 @@ var AgentConnectCommand = class AgentConnectCommand extends Command {
|
|
|
35684
35681
|
else {
|
|
35685
35682
|
this.log(`Agent ${output.address}: verification ${output.verification.state}; receiving ${output.receiving.state}; skill ${output.skill.state}.`);
|
|
35686
35683
|
this.log(`Select it with ${output.selectProfile}.`);
|
|
35684
|
+
for (const warning of output.warnings) this.log(warning.message);
|
|
35687
35685
|
if (output.ownerNotifications === "silenced") this.log("Owner notifications remain silenced by the existing preference or policy.");
|
|
35688
35686
|
if (external && verificationReplySubmitted(output.verification.state)) this.log(output.externalHook === "installed_unverified" ? "External receive hook installed. Idle wake still needs a live mail check." : "External receive hook is unavailable. Pairing may complete, but this session will not wake automatically.");
|
|
35687
|
+
if (poll && "fallbackDetail" in output.receiving) this.log(String(output.receiving.fallbackDetail));
|
|
35689
35688
|
if (poll && "checkCommand" in output.receiving) this.log(`Nothing wakes this session for new mail. Check it at the start of each turn and after sending with: ${output.receiving.checkCommand}`);
|
|
35690
35689
|
if (output.status !== "connected") this.log(`Resume: ${output.resumeCommand}`);
|
|
35691
35690
|
}
|
|
@@ -35705,16 +35704,23 @@ var AgentConnectCommand = class AgentConnectCommand extends Command {
|
|
|
35705
35704
|
configDir: this.config.configDir,
|
|
35706
35705
|
onlyIfUnknown: claimed.status === "claimed"
|
|
35707
35706
|
});
|
|
35707
|
+
const warnings = connectWarnings(this.config.configDir, result.identity.profileName);
|
|
35708
35708
|
if (flags.json) this.log(JSON.stringify(replaced.length ? {
|
|
35709
35709
|
...result,
|
|
35710
|
+
warnings,
|
|
35710
35711
|
replacedExisting: replaced
|
|
35711
|
-
} :
|
|
35712
|
+
} : {
|
|
35713
|
+
...result,
|
|
35714
|
+
warnings
|
|
35715
|
+
}));
|
|
35712
35716
|
else {
|
|
35713
35717
|
this.log(result.status === "claimed" ? "Agent profile saved. Email readiness is not yet verified." : "Agent profile already configured; no claim was sent.");
|
|
35714
35718
|
this.log(`Select it with PRIMITIVE_AGENT_PROFILE=${result.identity.profileName}.`);
|
|
35715
35719
|
this.log(result.ownerReportGuidance);
|
|
35720
|
+
for (const warning of warnings) this.log(warning.message);
|
|
35716
35721
|
}
|
|
35717
|
-
} catch (
|
|
35722
|
+
} catch (caught) {
|
|
35723
|
+
const error = refusalAfterReplacement(caught, replaced);
|
|
35718
35724
|
throw new Errors.CLIError(error instanceof AgentConnectionSetupError ? error.message : flags.session?.trim() ? `Setup paused. Preserve the private profile and run ${invocation$1(process.argv[1])} agent connect --profile ${flags.profile ?? defaultAgentProfileName(flags.session.trim())} --session ${flags.session.trim()}${flags.receiver ? ` --receiver ${flags.receiver}` : ""} --resume --json. Do not manually resend verification or reclaim the invitation.` : pollProfile ? `Setup paused. Preserve the private profile and run ${invocation$1(process.argv[1])} agent connect --profile ${pollProfile} --receiver poll --resume --json. Do not manually resend verification or reclaim the invitation.` : "Agent setup did not complete. Preserve the private profile and request a fresh owner invitation if a claim may have been submitted.", { exit: 1 });
|
|
35719
35725
|
}
|
|
35720
35726
|
}
|
|
@@ -36000,6 +36006,7 @@ var AgentEnrollCommand = class AgentEnrollCommand extends Command {
|
|
|
36000
36006
|
agentAddress: result.identity.agentAddress,
|
|
36001
36007
|
sessionId: flags.session
|
|
36002
36008
|
}) : null;
|
|
36009
|
+
const warnings = connectWarnings(this.config.configDir, result.identity.profileName);
|
|
36003
36010
|
const output = result.receiving.state === "poll" ? {
|
|
36004
36011
|
...result,
|
|
36005
36012
|
receiving: {
|
|
@@ -36007,10 +36014,20 @@ var AgentEnrollCommand = class AgentEnrollCommand extends Command {
|
|
|
36007
36014
|
mode: "poll",
|
|
36008
36015
|
checkCommand: pollCheckCommand(invocation(process.argv[1]), result.identity.profileName)
|
|
36009
36016
|
},
|
|
36010
|
-
externalHook
|
|
36017
|
+
externalHook,
|
|
36018
|
+
warnings
|
|
36019
|
+
} : flags.receiver === "external" && result.connection.status !== "owner_inactive" ? {
|
|
36020
|
+
...result,
|
|
36021
|
+
receiving: {
|
|
36022
|
+
...result.receiving,
|
|
36023
|
+
state: externalReceivingState(externalHook)
|
|
36024
|
+
},
|
|
36025
|
+
externalHook,
|
|
36026
|
+
warnings
|
|
36011
36027
|
} : {
|
|
36012
36028
|
...result,
|
|
36013
|
-
externalHook
|
|
36029
|
+
externalHook,
|
|
36030
|
+
warnings
|
|
36014
36031
|
};
|
|
36015
36032
|
const identity = identitySuggestions({
|
|
36016
36033
|
invocation: invocation(process.argv[1]),
|
|
@@ -36028,8 +36045,9 @@ var AgentEnrollCommand = class AgentEnrollCommand extends Command {
|
|
|
36028
36045
|
};
|
|
36029
36046
|
if (flags.json) this.log(JSON.stringify(printed));
|
|
36030
36047
|
else {
|
|
36031
|
-
this.log(`Agent ${result.identity.agentAddress}: pairing ${result.connection.status}; verification ${result.verification.state}; receiving ${
|
|
36048
|
+
this.log(`Agent ${result.identity.agentAddress}: pairing ${result.connection.status}; verification ${result.verification.state}; receiving ${output.receiving.state}.`);
|
|
36032
36049
|
this.log(`Select it with PRIMITIVE_AGENT_PROFILE=${result.identity.profileName}.`);
|
|
36050
|
+
for (const warning of warnings) this.log(warning.message);
|
|
36033
36051
|
if (flags["contact-requests"]) this.log(`Contact requests: ${result.contactRequestPolicy}.`);
|
|
36034
36052
|
if (result.contactRequestPolicy === "owner_disabled") this.log("The owner disabled contact requests for this address. Review the policy in the app if you want them enabled.");
|
|
36035
36053
|
if (result.contactRequestPolicy === "unavailable") this.log("Contact-request policy could not be confirmed. Receiving can still be configured; rerun this exact enrollment after policy access is restored.");
|
|
@@ -36654,6 +36672,66 @@ var AgentSessionRegisterCommand = class AgentSessionRegisterCommand extends Comm
|
|
|
36654
36672
|
}
|
|
36655
36673
|
};
|
|
36656
36674
|
//#endregion
|
|
36675
|
+
//#region src/oclif/commands/agent-status.ts
|
|
36676
|
+
/**
|
|
36677
|
+
* Picks the profile `agent status` reads: an explicit --profile, then
|
|
36678
|
+
* PRIMITIVE_AGENT_PROFILE, then the one address connected for this runtime
|
|
36679
|
+
* session. Null when none applies or the session has several addresses.
|
|
36680
|
+
*/
|
|
36681
|
+
function statusProfile(params) {
|
|
36682
|
+
const env = params.env ?? process.env;
|
|
36683
|
+
const chosen = params.profile ?? (env["PRIMITIVE_AGENT_PROFILE"]?.trim() || void 0);
|
|
36684
|
+
if (chosen) return { profile: chosen };
|
|
36685
|
+
const session = guardedSession(void 0, env);
|
|
36686
|
+
if (!session) return {
|
|
36687
|
+
profile: null,
|
|
36688
|
+
bound: []
|
|
36689
|
+
};
|
|
36690
|
+
const { others } = inspectSessionAddresses({
|
|
36691
|
+
configDir: params.configDir,
|
|
36692
|
+
session
|
|
36693
|
+
});
|
|
36694
|
+
const only = others.length === 1 ? others[0] : void 0;
|
|
36695
|
+
return only ? { profile: only.profile } : {
|
|
36696
|
+
profile: null,
|
|
36697
|
+
bound: others.map((row) => row.profile)
|
|
36698
|
+
};
|
|
36699
|
+
}
|
|
36700
|
+
/** A hidden alias of `agent connect --status`, for the command agents guess. */
|
|
36701
|
+
var AgentStatusCommand = class AgentStatusCommand extends Command {
|
|
36702
|
+
static hidden = true;
|
|
36703
|
+
static summary = "Show this agent's saved connection (agent connect --status)";
|
|
36704
|
+
static description = `Same as \`agent connect --status\`: read the saved identity and local receiver health offline. The profile is --profile, else ${AGENT_PROFILE_ENV}, else the one address connected for this runtime session.`;
|
|
36705
|
+
static flags = {
|
|
36706
|
+
profile: Flags.string({ description: "Local agent profile name" }),
|
|
36707
|
+
json: Flags.boolean({ description: "Print the status as JSON" })
|
|
36708
|
+
};
|
|
36709
|
+
async run() {
|
|
36710
|
+
const { flags } = await this.parse(AgentStatusCommand);
|
|
36711
|
+
const picked = statusProfile({
|
|
36712
|
+
configDir: this.config.configDir,
|
|
36713
|
+
profile: flags.profile
|
|
36714
|
+
});
|
|
36715
|
+
if (picked.profile === null) {
|
|
36716
|
+
const detail = picked.bound.length > 1 ? `This session has several connected profiles (${picked.bound.join(", ")}). Pass --profile <name>.` : `No Primitive address is connected for this session. Pass --profile <name> or set ${AGENT_PROFILE_ENV} to inspect a saved profile.`;
|
|
36717
|
+
this.log(flags.json ? JSON.stringify({
|
|
36718
|
+
status: "not_configured",
|
|
36719
|
+
profileName: null,
|
|
36720
|
+
...picked.bound.length > 1 ? { profiles: picked.bound } : {},
|
|
36721
|
+
detail
|
|
36722
|
+
}) : detail);
|
|
36723
|
+
process.exitCode = 1;
|
|
36724
|
+
return;
|
|
36725
|
+
}
|
|
36726
|
+
await AgentConnectCommand.run([
|
|
36727
|
+
"--status",
|
|
36728
|
+
"--profile",
|
|
36729
|
+
picked.profile,
|
|
36730
|
+
...flags.json ? ["--json"] : []
|
|
36731
|
+
], this.config);
|
|
36732
|
+
}
|
|
36733
|
+
};
|
|
36734
|
+
//#endregion
|
|
36657
36735
|
//#region src/oclif/commands/agent-upgrade.ts
|
|
36658
36736
|
/**
|
|
36659
36737
|
* Interactive upgrade of an emailless agent account to a full developer
|
|
@@ -41530,7 +41608,7 @@ async function buildEmailBrief(input) {
|
|
|
41530
41608
|
connected_agent_verified: detail.sender_connected_agent_verified === true
|
|
41531
41609
|
},
|
|
41532
41610
|
thread_id: threadId,
|
|
41533
|
-
in_thread: sentInThread(thread, self) ?? null,
|
|
41611
|
+
in_thread: sentInThread(thread, self, input.isOwnSignal) ?? null,
|
|
41534
41612
|
...alsoAddressed(otherParticipants(detail, self)),
|
|
41535
41613
|
attachments: briefAttachments(detail, { hideInteractionPart: interaction?.hint === "card" || interaction?.hint === "status" }),
|
|
41536
41614
|
newer: thread?.newerInboundCount === void 0 ? null : {
|
|
@@ -41639,6 +41717,7 @@ async function runBrief(command, flags) {
|
|
|
41639
41717
|
client: apiClient.client,
|
|
41640
41718
|
detail,
|
|
41641
41719
|
connected,
|
|
41720
|
+
isOwnSignal: (sentId) => isSentSignal(command.config.configDir, sentId),
|
|
41642
41721
|
signal: AbortSignal.timeout(3e4)
|
|
41643
41722
|
});
|
|
41644
41723
|
command.log(flags.json ? JSON.stringify(brief, null, 2) : renderEmailBrief(brief));
|
|
@@ -43341,8 +43420,8 @@ const PRIMITIVE_TEAM_AUTHOR = {
|
|
|
43341
43420
|
name: "Primitive Team",
|
|
43342
43421
|
url: "https://primitive.dev"
|
|
43343
43422
|
};
|
|
43344
|
-
const SDK_VERSION_RANGE = "^1.
|
|
43345
|
-
const CLI_VERSION_RANGE = "^1.
|
|
43423
|
+
const SDK_VERSION_RANGE = "^1.35.0";
|
|
43424
|
+
const CLI_VERSION_RANGE = "^1.49.0";
|
|
43346
43425
|
const ESBUILD_VERSION_RANGE = "^0.27.0";
|
|
43347
43426
|
function renderHandler() {
|
|
43348
43427
|
return `// env.PRIMITIVE_API_KEY, env.PRIMITIVE_WEBHOOK_SECRET, and
|
|
@@ -46873,6 +46952,7 @@ async function runSharedNotificationListen(options) {
|
|
|
46873
46952
|
contact: !authorization?.contactRequest
|
|
46874
46953
|
}),
|
|
46875
46954
|
localInThread: false,
|
|
46955
|
+
isOwnSignal: (sentId) => isSentSignal(options.configDir, sentId),
|
|
46876
46956
|
signal: nextSignal
|
|
46877
46957
|
});
|
|
46878
46958
|
} catch {
|
|
@@ -47588,6 +47668,10 @@ async function createWakeMail(options) {
|
|
|
47588
47668
|
});
|
|
47589
47669
|
const identity = auth.connectedAgent;
|
|
47590
47670
|
const recipient = identity?.agentAddress;
|
|
47671
|
+
if (identity) refreshOwnerMemberAddressPeriodically({
|
|
47672
|
+
configDir: options.configDir,
|
|
47673
|
+
profileName: identity.profileName
|
|
47674
|
+
});
|
|
47591
47675
|
const policy = recipient ? apiContactPolicy(apiClient.client, recipient, options.contactRequests) : void 0;
|
|
47592
47676
|
const notices = identity && options.contactRequests ? openContactRequestNotices(options.configDir, identity) : void 0;
|
|
47593
47677
|
const activatedAt = notices ? Date.parse(notices.activate()) : 0;
|
|
@@ -47824,6 +47908,7 @@ async function createWakeMail(options) {
|
|
|
47824
47908
|
contact: admission.kind === "allowed"
|
|
47825
47909
|
}),
|
|
47826
47910
|
localInThread: Boolean(requested || followed),
|
|
47911
|
+
isOwnSignal: (sentId) => isSentSignal(options.configDir, sentId),
|
|
47827
47912
|
signal
|
|
47828
47913
|
});
|
|
47829
47914
|
if (!await recordNotice(detail, {
|
|
@@ -48969,8 +49054,7 @@ const DEFAULT_SIGNUP_COMMAND_COPY = {
|
|
|
48969
49054
|
actionGerund: "creating a new account",
|
|
48970
49055
|
confirmCommand: (email) => `signup confirm ${email} <code>`,
|
|
48971
49056
|
resendCommand: (email) => `signup resend ${email}`,
|
|
48972
|
-
startCommand: (email) => `signup ${email}
|
|
48973
|
-
codeRequired: false
|
|
49057
|
+
startCommand: (email) => `signup ${email}`
|
|
48974
49058
|
};
|
|
48975
49059
|
function cliError$2(message) {
|
|
48976
49060
|
return new Errors.CLIError(message, { exit: 1 });
|
|
@@ -49252,16 +49336,12 @@ async function startSignup(params) {
|
|
|
49252
49336
|
}
|
|
49253
49337
|
if (params.flags.force) deletePendingAgentSignup(params.configDir);
|
|
49254
49338
|
const confirmTermsFn = params.deps.confirmTerms ?? confirmTerms;
|
|
49255
|
-
const promptRequiredFn = params.deps.promptRequired ?? promptRequired;
|
|
49256
49339
|
const startFn = params.deps.startAgentSignup ?? startAgentSignup;
|
|
49257
|
-
const rawSignupCode = params.flags["signup-code"];
|
|
49258
|
-
const signupCode = (rawSignupCode && rawSignupCode.trim().length > 0 ? rawSignupCode : void 0) ?? (copy.codeRequired ? await promptRequiredFn("Signup code: ") : void 0);
|
|
49259
49340
|
if (!params.flags["accept-terms"]) await confirmTermsFn();
|
|
49260
49341
|
const started = await startFn({
|
|
49261
49342
|
body: {
|
|
49262
49343
|
device_name: params.flags["device-name"] ?? hostname(),
|
|
49263
49344
|
email: params.email,
|
|
49264
|
-
...signupCode ? { signup_code: signupCode } : {},
|
|
49265
49345
|
terms_accepted: true
|
|
49266
49346
|
},
|
|
49267
49347
|
client: params.apiClient.client,
|
|
@@ -49489,10 +49569,6 @@ function commonStartFlags() {
|
|
|
49489
49569
|
force: Flags.boolean({
|
|
49490
49570
|
char: "f",
|
|
49491
49571
|
description: "Replace saved credentials or pending signup state when needed"
|
|
49492
|
-
}),
|
|
49493
|
-
"signup-code": Flags.string({
|
|
49494
|
-
description: "Optional signup code. Omit if you do not have one.",
|
|
49495
|
-
env: "PRIMITIVE_SIGNUP_CODE"
|
|
49496
49572
|
})
|
|
49497
49573
|
};
|
|
49498
49574
|
}
|
|
@@ -49506,7 +49582,6 @@ var SignupCommand = class SignupCommand extends Command {
|
|
|
49506
49582
|
static examples = [
|
|
49507
49583
|
"<%= config.bin %> signup user@example.com",
|
|
49508
49584
|
"<%= config.bin %> signup user@example.com --accept-terms",
|
|
49509
|
-
"<%= config.bin %> signup user@example.com --signup-code invite-code --accept-terms",
|
|
49510
49585
|
"<%= config.bin %> signup confirm user@example.com 123456"
|
|
49511
49586
|
];
|
|
49512
49587
|
static flags = commonStartFlags();
|
|
@@ -49883,7 +49958,7 @@ function shellQuote(value) {
|
|
|
49883
49958
|
}
|
|
49884
49959
|
const MANAGED_SUFFIX = /\bagent session-register --runtime codex --hook\s*$/;
|
|
49885
49960
|
function codexHookCommand(cli) {
|
|
49886
|
-
return `${shellQuote(cli.
|
|
49961
|
+
return `${shellQuote(cli.runtimeNode)} ${shellQuote(cli.entry)} agent session-register --runtime codex --hook`;
|
|
49887
49962
|
}
|
|
49888
49963
|
/** A SessionStart hook this CLI installed, from any CLI path or version. */
|
|
49889
49964
|
function isManaged(hook) {
|
|
@@ -50109,6 +50184,10 @@ function repairCodexHook(settings, cli) {
|
|
|
50109
50184
|
changed
|
|
50110
50185
|
};
|
|
50111
50186
|
}
|
|
50187
|
+
/** Whether Codex hooks.json carries the SessionStart hook, from any CLI path. */
|
|
50188
|
+
function hasCodexSessionHook(settings) {
|
|
50189
|
+
return managedPositions(settings).length > 0;
|
|
50190
|
+
}
|
|
50112
50191
|
function writeCodexHooks(params) {
|
|
50113
50192
|
const original = params.read.state === "present" ? params.read.text : null;
|
|
50114
50193
|
const indent = original === null ? 2 : jsonIndentation(original);
|
|
@@ -50347,6 +50426,29 @@ async function ownerConnectionStatuses(credentials, fetchImpl) {
|
|
|
50347
50426
|
}
|
|
50348
50427
|
return partial();
|
|
50349
50428
|
}
|
|
50429
|
+
/** Whether any saved agent profile still holds a credential. */
|
|
50430
|
+
function connectedProfileSaved(configDir) {
|
|
50431
|
+
let names;
|
|
50432
|
+
try {
|
|
50433
|
+
names = readdirSync(join(agentProfilesDirectory(configDir), "profiles"));
|
|
50434
|
+
} catch {
|
|
50435
|
+
return false;
|
|
50436
|
+
}
|
|
50437
|
+
return names.some((name) => {
|
|
50438
|
+
try {
|
|
50439
|
+
agentProfileName(name);
|
|
50440
|
+
return loadConnectedAgentProfile(configDir, name) !== null;
|
|
50441
|
+
} catch {
|
|
50442
|
+
return false;
|
|
50443
|
+
}
|
|
50444
|
+
});
|
|
50445
|
+
}
|
|
50446
|
+
/**
|
|
50447
|
+
* Why a machine-wide check does not apply: agents on this machine were
|
|
50448
|
+
* connected one session at a time with `agent connect`, and no member login
|
|
50449
|
+
* (which machine-wide session registration needs) is saved.
|
|
50450
|
+
*/
|
|
50451
|
+
const PER_CONNECTION_SKIP = "Not set up: agents on this machine were connected one session at a time with `primitive agent connect`, which does not need it. To register every session on this machine automatically, sign in with `primitive login`, then run `primitive machine doctor --fix`.";
|
|
50350
50452
|
function check(id, status, detail, extra = {}) {
|
|
50351
50453
|
return {
|
|
50352
50454
|
id,
|
|
@@ -50371,9 +50473,21 @@ async function runMachineDoctor(options) {
|
|
|
50371
50473
|
const selected = (runtime) => !options.runtimes || options.runtimes.has(runtime);
|
|
50372
50474
|
const present = Object.fromEntries(MACHINE_RUNTIMES.map((runtime) => [runtime, runtimePresent(runtime, paths, env)]));
|
|
50373
50475
|
const skipRuntime = (runtime) => !selected(runtime) ? "Not selected with --runtime." : !present[runtime] ? `${runtime === "claude" ? "Claude Code" : runtime === "codex" ? "Codex" : "omp"} was not found on this machine.` : null;
|
|
50374
|
-
const cli = currentCliLocation(options.cliEntry, env, options.execPath
|
|
50476
|
+
const cli = currentCliLocation(options.cliEntry, env, options.execPath, {
|
|
50477
|
+
configDir: options.configDir,
|
|
50478
|
+
platform: options.platform
|
|
50479
|
+
});
|
|
50375
50480
|
const ephemeral = cli ? ephemeralCliReason(cli.entry) : null;
|
|
50376
|
-
const
|
|
50481
|
+
const ephemeralBlocked = ephemeral ? `This CLI runs from ${ephemeral}, which can be deleted; install it with \`npm install -g primitive\` before repairing hooks.` : null;
|
|
50482
|
+
const hookBlocked = !cli ? "This CLI's hook scripts were not found next to it." : cli.launcher ? null : ephemeralBlocked;
|
|
50483
|
+
const codexBlocked = !cli ? "This CLI's hook scripts were not found next to it." : ephemeralBlocked;
|
|
50484
|
+
const perConnection = !(() => {
|
|
50485
|
+
try {
|
|
50486
|
+
return loadCliCredentials(options.configDir) !== null;
|
|
50487
|
+
} catch {
|
|
50488
|
+
return true;
|
|
50489
|
+
}
|
|
50490
|
+
})() && connectedProfileSaved(options.configDir);
|
|
50377
50491
|
const skillEnv = {
|
|
50378
50492
|
...env,
|
|
50379
50493
|
CLAUDE_CONFIG_DIR: paths.claudeDir,
|
|
@@ -50400,6 +50514,7 @@ async function runMachineDoctor(options) {
|
|
|
50400
50514
|
path: target,
|
|
50401
50515
|
action: "edit_file"
|
|
50402
50516
|
});
|
|
50517
|
+
if (perConnection && (read.state === "absent" || inspectManagedBlock(read.text, body).state === "missing")) return check(id, "skip", PER_CONNECTION_SKIP, { path: target });
|
|
50403
50518
|
if (read.state === "absent") return check(id, "fail", `${target} does not exist yet.`, {
|
|
50404
50519
|
path: target,
|
|
50405
50520
|
fixable: true
|
|
@@ -50444,6 +50559,7 @@ async function runMachineDoctor(options) {
|
|
|
50444
50559
|
} catch {
|
|
50445
50560
|
info = null;
|
|
50446
50561
|
}
|
|
50562
|
+
if (!info && perConnection) return check(id, "skip", PER_CONNECTION_SKIP, { path: target });
|
|
50447
50563
|
if (!info) return check(id, "fail", `Not installed at ${target}.`, {
|
|
50448
50564
|
path: target,
|
|
50449
50565
|
fixable: true
|
|
@@ -50502,12 +50618,20 @@ async function runMachineDoctor(options) {
|
|
|
50502
50618
|
},
|
|
50503
50619
|
restoreProfiles: options.profiles
|
|
50504
50620
|
};
|
|
50621
|
+
const launcherMissing = () => !!cli?.launcher && settingsRead.ok && !existsSync(cli.launcher.path) && JSON.stringify(settingsRead.settings).includes(JSON.stringify(cli.launcher.path));
|
|
50505
50622
|
const hookCheck = (id) => ({
|
|
50506
50623
|
inspect: () => {
|
|
50507
50624
|
const skip = skipRuntime("claude");
|
|
50508
50625
|
if (skip) return check(id, "skip", skip);
|
|
50509
50626
|
if (!settingsRead.ok) return check(id, "fail", "Claude settings.json is invalid; repair it first.", { path: join(paths.claudeDir, "settings.json") });
|
|
50510
|
-
|
|
50627
|
+
if (perConnection && id !== "claude.hook.stop" && !hasMachineSessionHooks(settingsRead.settings)) return check(id, "skip", PER_CONNECTION_SKIP, { path: join(paths.claudeDir, "settings.json") });
|
|
50628
|
+
const inspected = inspectClaudeHooks(settingsRead.settings, hookContext)[id];
|
|
50629
|
+
const finding = inspected.status === "fail" && launcherMissing() ? {
|
|
50630
|
+
...inspected,
|
|
50631
|
+
detail: `${inspected.detail} The hook launcher ${cli?.launcher?.path} is missing; a repair writes it again.`
|
|
50632
|
+
} : inspected;
|
|
50633
|
+
const launcherWarning = id === "claude.hook.stop" && cli?.launcher ? readHookLauncherWarning(options.configDir) : null;
|
|
50634
|
+
if (launcherWarning && finding.status === "ok") return check(id, "warn", `${finding.detail} The last hook run reported: ${launcherWarning}`, { path: join(paths.claudeDir, "settings.json") });
|
|
50511
50635
|
return check(id, finding.status, finding.detail, {
|
|
50512
50636
|
fixable: finding.fixable,
|
|
50513
50637
|
path: join(paths.claudeDir, "settings.json"),
|
|
@@ -50522,9 +50646,17 @@ async function runMachineDoctor(options) {
|
|
|
50522
50646
|
repair: () => {
|
|
50523
50647
|
if (!settingsRead.ok) return false;
|
|
50524
50648
|
const findings = inspectClaudeHooks(settingsRead.settings, hookContext);
|
|
50525
|
-
const
|
|
50649
|
+
const machineHooksSkipped = perConnection && !hasMachineSessionHooks(settingsRead.settings);
|
|
50650
|
+
const ids = HOOK_CHECK_IDS.filter((hook) => (hook === "claude.hook.stop" || !machineHooksSkipped) && (hook === id || !options.only || options.only.has(hook)) && findings[hook].status === "fail" && findings[hook].fixable);
|
|
50526
50651
|
const repaired = repairClaudeHooks(settingsRead.settings, hookContext, new Set(ids), { profiles: options.profiles });
|
|
50527
|
-
|
|
50652
|
+
const restoreLauncher = launcherMissing();
|
|
50653
|
+
if (!repaired.changed.size && !restoreLauncher) return false;
|
|
50654
|
+
if (cli && hookBlocked === null) try {
|
|
50655
|
+
ensureHookLauncher(cli);
|
|
50656
|
+
} catch {
|
|
50657
|
+
throw new MachineFileError(`The hook launcher ${cli.launcher?.path ?? ""} could not be written.`);
|
|
50658
|
+
}
|
|
50659
|
+
if (!repaired.changed.size) return id === "claude.hook.stop";
|
|
50528
50660
|
writeClaudeSettings({
|
|
50529
50661
|
claudeDir: paths.claudeDir,
|
|
50530
50662
|
read: settingsRead.read,
|
|
@@ -50547,17 +50679,21 @@ async function runMachineDoctor(options) {
|
|
|
50547
50679
|
path: read.path,
|
|
50548
50680
|
action: "edit_file"
|
|
50549
50681
|
});
|
|
50682
|
+
if (perConnection && !hasCodexSessionHook(read.settings)) return check(id, "skip", PER_CONNECTION_SKIP, { path: read.path });
|
|
50550
50683
|
const configToml = readManagedFile(join(paths.codexHome, "config.toml"));
|
|
50551
|
-
const finding = inspectCodexHook(read,
|
|
50684
|
+
const finding = inspectCodexHook(read, {
|
|
50685
|
+
cli,
|
|
50686
|
+
blocked: codexBlocked
|
|
50687
|
+
}, configToml.state === "present" ? configToml.text : null);
|
|
50552
50688
|
return check(id, finding.status, finding.detail, {
|
|
50553
50689
|
fixable: finding.fixable,
|
|
50554
50690
|
path: read.path,
|
|
50555
|
-
...finding.status === "fail" && !finding.fixable &&
|
|
50691
|
+
...finding.status === "fail" && !finding.fixable && codexBlocked ? { action: "install_cli" } : {}
|
|
50556
50692
|
});
|
|
50557
50693
|
},
|
|
50558
50694
|
repair: () => {
|
|
50559
50695
|
const read = readCodexHooks(paths.codexHome);
|
|
50560
|
-
if (!read.ok || !cli ||
|
|
50696
|
+
if (!read.ok || !cli || codexBlocked) return false;
|
|
50561
50697
|
const repaired = repairCodexHook(read.settings, cli);
|
|
50562
50698
|
if (!repaired.changed) return false;
|
|
50563
50699
|
writeCodexHooks({
|
|
@@ -50670,10 +50806,18 @@ async function runMachineDoctor(options) {
|
|
|
50670
50806
|
} },
|
|
50671
50807
|
"cli.path_stable": { inspect: () => {
|
|
50672
50808
|
if (!cli) return check("cli.path_stable", "fail", "The running CLI's files could not be located.", { action: "install_cli" });
|
|
50673
|
-
if (ephemeral) return check("cli.path_stable", "fail", `This CLI runs from ${ephemeral}; hooks pointing at it would break. Install it globally with \`npm install -g primitive\`.`, {
|
|
50809
|
+
if (ephemeral && !cli.launcher) return check("cli.path_stable", "fail", `This CLI runs from ${ephemeral}; hooks pointing at it would break. Install it globally with \`npm install -g primitive\`.`, {
|
|
50674
50810
|
action: "install_cli",
|
|
50675
50811
|
path: cli.entry
|
|
50676
50812
|
});
|
|
50813
|
+
if (ephemeral) {
|
|
50814
|
+
const launcherNote = `This CLI runs from ${ephemeral}. Claude Code hooks run through ${cli.launcher?.path}, which uses the \`primitive\` on PATH or fetches this version again with npx if the cache is removed.`;
|
|
50815
|
+
const codexRead = readCodexHooks(paths.codexHome);
|
|
50816
|
+
return selected("codex") && present.codex && !(perConnection && codexRead.ok && !hasCodexSessionHook(codexRead.settings)) ? check("cli.path_stable", "warn", `${launcherNote} The Codex SessionStart hook names the CLI directly; install it globally with \`npm install -g primitive\` so that hook keeps working.`, {
|
|
50817
|
+
action: "install_cli",
|
|
50818
|
+
path: cli.entry
|
|
50819
|
+
}) : check("cli.path_stable", "ok", launcherNote, { path: cli.entry });
|
|
50820
|
+
}
|
|
50677
50821
|
const onPath = findOnPath("primitive", env);
|
|
50678
50822
|
if (onPath && !samePath(onPath, cli.entry)) return check("cli.path_stable", "warn", `\`primitive\` on PATH is ${onPath}, but this run is ${cli.entry}; hooks follow the copy that runs the doctor.`, { path: cli.entry });
|
|
50679
50823
|
return check("cli.path_stable", "ok", `Hooks use ${cli.node} and ${cli.entry}.`, { path: cli.entry });
|
|
@@ -50685,7 +50829,7 @@ async function runMachineDoctor(options) {
|
|
|
50685
50829
|
} catch {
|
|
50686
50830
|
return check("auth.member_login", "fail", "The saved login file is unreadable. Sign in again.", { action: "login" });
|
|
50687
50831
|
}
|
|
50688
|
-
if (!saved) return check("auth.member_login", "fail", "No saved member login on this machine.", { action: "login" });
|
|
50832
|
+
if (!saved) return perConnection ? check("auth.member_login", "skip", "No member login is saved. Agents on this machine were connected with `primitive agent connect` and use their own saved credentials; sign in with `primitive login` only to register every session on this machine automatically.") : check("auth.member_login", "fail", "No saved member login on this machine.", { action: "login" });
|
|
50689
50833
|
let credentials;
|
|
50690
50834
|
try {
|
|
50691
50835
|
credentials = await refreshStoredCliCredentials({
|
|
@@ -50839,7 +50983,7 @@ function renderCheck(check) {
|
|
|
50839
50983
|
}
|
|
50840
50984
|
var MachineDoctorCommand = class MachineDoctorCommand extends Command {
|
|
50841
50985
|
static summary = "Check, and optionally repair, this machine's Primitive setup for coding agents";
|
|
50842
|
-
static description = "Checks everything that lets Claude Code, Codex and omp sessions on this machine register with Primitive and answer mail: the CLI install and version, the saved member login, Claude settings and Primitive's SessionStart, SessionEnd and per-session receive hooks, the managed instruction block in each runtime's global instructions file, the bundled primitive-connect skill, and saved agent profiles disconnected in Primitive. Each check reports ok, warn, fail or skip, whether it can be repaired automatically, and an action (login, install_cli, update_cli, edit_file) when only a person can fix it. --fix repairs what it safely can: it only adds, rewrites or removes Primitive-owned hooks, blocks and skill copies, backs up any existing file beside it as <file>.primitive-bak-<timestamp> before changing it, writes atomically, and changes nothing when nothing drifted, so it is safe to run on a timer. Malformed or hand-edited files it cannot parse are reported and left unchanged. Exits 0 when every check is ok or skipped, 1 otherwise.";
|
|
50986
|
+
static description = "Checks everything that lets Claude Code, Codex and omp sessions on this machine register with Primitive and answer mail: the CLI install and version, the saved member login, Claude settings and Primitive's SessionStart, SessionEnd and per-session receive hooks, the managed instruction block in each runtime's global instructions file, the bundled primitive-connect skill, and saved agent profiles disconnected in Primitive. Each check reports ok, warn, fail or skip, whether it can be repaired automatically, and an action (login, install_cli, update_cli, edit_file) when only a person can fix it. --fix repairs what it safely can: it only adds, rewrites or removes Primitive-owned hooks, blocks and skill copies, backs up any existing file beside it as <file>.primitive-bak-<timestamp> before changing it, writes atomically, and changes nothing when nothing drifted, so it is safe to run on a timer. Malformed or hand-edited files it cannot parse are reported and left unchanged. On a machine whose agents were all connected with `agent connect` and that has no saved member login, machine-wide setup it does not use (the member login, SessionStart and SessionEnd hooks, instruction blocks, skills) is reported as skip, and --fix does not add it. Exits 0 when every check is ok or skipped, 1 otherwise.";
|
|
50843
50987
|
static examples = [
|
|
50844
50988
|
"<%= config.bin %> machine doctor",
|
|
50845
50989
|
"<%= config.bin %> machine doctor --json",
|
|
@@ -55823,40 +55967,35 @@ const SIGNIN_OTP_COPY = {
|
|
|
55823
55967
|
actionGerund: "signing in",
|
|
55824
55968
|
confirmCommand: (email) => `signin otp confirm ${email} <code>`,
|
|
55825
55969
|
resendCommand: (email) => `signin otp resend ${email}`,
|
|
55826
|
-
startCommand: (email) => `signin otp ${email}
|
|
55827
|
-
codeRequired: true
|
|
55970
|
+
startCommand: (email) => `signin otp ${email}`
|
|
55828
55971
|
};
|
|
55829
55972
|
const SIGNIN_EMAIL_COPY = {
|
|
55830
55973
|
actionNoun: "sign-in",
|
|
55831
55974
|
actionGerund: "signing in",
|
|
55832
55975
|
confirmCommand: (email) => `signin confirm ${email} <code>`,
|
|
55833
55976
|
resendCommand: (email) => `signin resend ${email}`,
|
|
55834
|
-
startCommand: (email) => `signin ${email}
|
|
55835
|
-
codeRequired: true
|
|
55977
|
+
startCommand: (email) => `signin ${email}`
|
|
55836
55978
|
};
|
|
55837
55979
|
const LOGIN_EMAIL_COPY = {
|
|
55838
55980
|
actionNoun: "login",
|
|
55839
55981
|
actionGerund: "logging in",
|
|
55840
55982
|
confirmCommand: (email) => `login confirm ${email} <code>`,
|
|
55841
55983
|
resendCommand: (email) => `login resend ${email}`,
|
|
55842
|
-
startCommand: (email) => `login ${email}
|
|
55843
|
-
codeRequired: true
|
|
55984
|
+
startCommand: (email) => `login ${email}`
|
|
55844
55985
|
};
|
|
55845
55986
|
const LOGIN_OTP_COPY = {
|
|
55846
55987
|
actionNoun: "login",
|
|
55847
55988
|
actionGerund: "logging in",
|
|
55848
55989
|
confirmCommand: (email) => `login otp confirm ${email} <code>`,
|
|
55849
55990
|
resendCommand: (email) => `login otp resend ${email}`,
|
|
55850
|
-
startCommand: (email) => `login otp ${email}
|
|
55851
|
-
codeRequired: true
|
|
55991
|
+
startCommand: (email) => `login otp ${email}`
|
|
55852
55992
|
};
|
|
55853
55993
|
const OTP_COPY = {
|
|
55854
55994
|
actionNoun: "email-code auth",
|
|
55855
55995
|
actionGerund: "authenticating",
|
|
55856
55996
|
confirmCommand: (email) => `otp confirm ${email} <code>`,
|
|
55857
55997
|
resendCommand: (email) => `otp resend ${email}`,
|
|
55858
|
-
startCommand: (email) => `otp ${email}
|
|
55859
|
-
codeRequired: true
|
|
55998
|
+
startCommand: (email) => `otp ${email}`
|
|
55860
55999
|
};
|
|
55861
56000
|
function acquireCredentialsLock(configDir) {
|
|
55862
56001
|
try {
|
|
@@ -55877,10 +56016,6 @@ function commonOtpStartFlags() {
|
|
|
55877
56016
|
force: Flags.boolean({
|
|
55878
56017
|
char: "f",
|
|
55879
56018
|
description: "Replace saved credentials or pending email-code auth state when needed"
|
|
55880
|
-
}),
|
|
55881
|
-
"signup-code": Flags.string({
|
|
55882
|
-
description: "Signup code required to start email-code sign-in",
|
|
55883
|
-
env: "PRIMITIVE_SIGNUP_CODE"
|
|
55884
56019
|
})
|
|
55885
56020
|
};
|
|
55886
56021
|
}
|
|
@@ -55891,15 +56026,15 @@ var SigninCommand = class extends LoginCommand$1 {
|
|
|
55891
56026
|
}) };
|
|
55892
56027
|
static description = `Sign in or log in to an existing Primitive account and save an org-scoped OAuth session locally.
|
|
55893
56028
|
|
|
55894
|
-
Run \`primitive signin <email> --
|
|
56029
|
+
Run \`primitive signin <email> --accept-terms\` for email-code sign-in, then \`primitive signin confirm <email> <code>\`. Run \`primitive signin\` with no email to use browser approval; \`primitive signin browser\` is the explicit browser form. \`primitive login\` supports the same flows with login-shaped commands. \`primitive otp <email>\` is the shortest email-code auth form. For new account creation, use \`primitive signup <email>\`.`;
|
|
55895
56030
|
static summary = "Sign in to an existing account";
|
|
55896
56031
|
static examples = [
|
|
55897
56032
|
"<%= config.bin %> signin",
|
|
55898
56033
|
"<%= config.bin %> signin browser",
|
|
55899
56034
|
"<%= config.bin %> signin --no-browser",
|
|
55900
|
-
"<%= config.bin %> signin user@example.com --
|
|
56035
|
+
"<%= config.bin %> signin user@example.com --accept-terms",
|
|
55901
56036
|
"<%= config.bin %> signin confirm user@example.com 123456",
|
|
55902
|
-
"<%= config.bin %> signin otp user@example.com --
|
|
56037
|
+
"<%= config.bin %> signin otp user@example.com --accept-terms",
|
|
55903
56038
|
"<%= config.bin %> signin otp confirm user@example.com 123456"
|
|
55904
56039
|
];
|
|
55905
56040
|
static flags = {
|
|
@@ -55914,7 +56049,7 @@ Run \`primitive signin <email> --signup-code <code> --accept-terms\` for email-c
|
|
|
55914
56049
|
const commandClass = this.constructor;
|
|
55915
56050
|
const { args, flags } = await this.parse(commandClass);
|
|
55916
56051
|
if (!args.email) {
|
|
55917
|
-
if (flags["
|
|
56052
|
+
if (flags["accept-terms"]) throw cliError(`Email-code auth needs an email address. Run \`primitive ${this.emailCodeCopy().startCommand("<email>")} --accept-terms\`.`);
|
|
55918
56053
|
await this.runBrowserLogin(flags, this.retryCommand());
|
|
55919
56054
|
return;
|
|
55920
56055
|
}
|
|
@@ -55941,15 +56076,15 @@ var LoginCommand = class extends SigninCommand {
|
|
|
55941
56076
|
static args = SigninCommand.args;
|
|
55942
56077
|
static description = `Log in or sign in to an existing Primitive account and save an org-scoped OAuth session locally.
|
|
55943
56078
|
|
|
55944
|
-
Run \`primitive login <email> --
|
|
56079
|
+
Run \`primitive login <email> --accept-terms\` for email-code login, then \`primitive login confirm <email> <code>\`. Run \`primitive login\` with no email to use browser approval; \`primitive login browser\` is the explicit browser form. \`primitive signin\` supports the same flows with signin-shaped commands. \`primitive otp <email>\` is the shortest email-code auth form. For new account creation, use \`primitive signup <email>\`.`;
|
|
55945
56080
|
static summary = "Log in to an existing account";
|
|
55946
56081
|
static examples = [
|
|
55947
56082
|
"<%= config.bin %> login",
|
|
55948
56083
|
"<%= config.bin %> login browser",
|
|
55949
56084
|
"<%= config.bin %> login --no-browser",
|
|
55950
|
-
"<%= config.bin %> login user@example.com --
|
|
56085
|
+
"<%= config.bin %> login user@example.com --accept-terms",
|
|
55951
56086
|
"<%= config.bin %> login confirm user@example.com 123456",
|
|
55952
|
-
"<%= config.bin %> login otp user@example.com --
|
|
56087
|
+
"<%= config.bin %> login otp user@example.com --accept-terms",
|
|
55953
56088
|
"<%= config.bin %> login otp confirm user@example.com 123456"
|
|
55954
56089
|
];
|
|
55955
56090
|
static flags = SigninCommand.flags;
|
|
@@ -55991,9 +56126,9 @@ var SigninOtpCommand = class extends Command {
|
|
|
55991
56126
|
description: "Email address to sign in with",
|
|
55992
56127
|
required: false
|
|
55993
56128
|
}) };
|
|
55994
|
-
static description = "Start email-code sign-in using Primitive's signup/auth OTP flow, send a verification code, and save the pending token locally.
|
|
56129
|
+
static description = "Start email-code sign-in using Primitive's signup/auth OTP flow, send a verification code, and save the pending token locally.";
|
|
55995
56130
|
static summary = "Start OTP sign-in";
|
|
55996
|
-
static examples = ["<%= config.bin %> signin otp user@example.com --
|
|
56131
|
+
static examples = ["<%= config.bin %> signin otp user@example.com --accept-terms", "<%= config.bin %> signin otp confirm user@example.com 123456"];
|
|
55997
56132
|
static flags = commonOtpStartFlags();
|
|
55998
56133
|
async run() {
|
|
55999
56134
|
const commandClass = this.constructor;
|
|
@@ -56016,9 +56151,9 @@ var SigninOtpCommand = class extends Command {
|
|
|
56016
56151
|
};
|
|
56017
56152
|
var LoginOtpCommand = class extends SigninOtpCommand {
|
|
56018
56153
|
static args = SigninOtpCommand.args;
|
|
56019
|
-
static description = "Start email-code login using Primitive's signup/auth OTP flow, send a verification code, and save the pending token locally.
|
|
56154
|
+
static description = "Start email-code login using Primitive's signup/auth OTP flow, send a verification code, and save the pending token locally.";
|
|
56020
56155
|
static summary = "Start OTP login";
|
|
56021
|
-
static examples = ["<%= config.bin %> login otp user@example.com --
|
|
56156
|
+
static examples = ["<%= config.bin %> login otp user@example.com --accept-terms", "<%= config.bin %> login otp confirm user@example.com 123456"];
|
|
56022
56157
|
static flags = SigninOtpCommand.flags;
|
|
56023
56158
|
emailCodeCopy() {
|
|
56024
56159
|
return LOGIN_OTP_COPY;
|
|
@@ -56026,9 +56161,9 @@ var LoginOtpCommand = class extends SigninOtpCommand {
|
|
|
56026
56161
|
};
|
|
56027
56162
|
var OtpCommand = class extends SigninOtpCommand {
|
|
56028
56163
|
static args = SigninOtpCommand.args;
|
|
56029
|
-
static description = "Start email-code authentication, send a verification code, and save the pending token locally.
|
|
56164
|
+
static description = "Start email-code authentication, send a verification code, and save the pending token locally.";
|
|
56030
56165
|
static summary = "Start email-code auth";
|
|
56031
|
-
static examples = ["<%= config.bin %> otp user@example.com --
|
|
56166
|
+
static examples = ["<%= config.bin %> otp user@example.com --accept-terms", "<%= config.bin %> otp confirm user@example.com 123456"];
|
|
56032
56167
|
static flags = SigninOtpCommand.flags;
|
|
56033
56168
|
emailCodeCopy() {
|
|
56034
56169
|
return OTP_COPY;
|
|
@@ -57478,6 +57613,7 @@ const COMMANDS = {
|
|
|
57478
57613
|
completion: CompletionCommand,
|
|
57479
57614
|
"agent:upgrade": AgentUpgradeCommand,
|
|
57480
57615
|
"agent:connect": AgentConnectCommand,
|
|
57616
|
+
"agent:status": AgentStatusCommand,
|
|
57481
57617
|
"agent:check-mail": AgentCheckMailCommand,
|
|
57482
57618
|
"agent:disconnect": AgentDisconnectCommand,
|
|
57483
57619
|
"agent:enroll": AgentEnrollCommand,
|