@agentproto/runtime 5.4.0 → 5.5.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/dist/index.d.ts CHANGED
@@ -695,6 +695,10 @@ interface RemoteStatus {
695
695
 
696
696
  /** `hosts.json` format. */
697
697
  declare const HOSTS_VERSION: 1;
698
+ /** One-line remediation logged once per failure streak once the threshold
699
+ * is crossed. Deliberately NOT a protocol change — the pairing itself is
700
+ * fine; a fresh host-scoped offer re-binds it. */
701
+ declare const HOST_HANDSHAKE_REMEDIATION_HINT: string;
698
702
  /** One persisted host — a daemon this daemon can drive. */
699
703
  interface HostRecord {
700
704
  /** The target daemon's identity fingerprint (32 hex). */
@@ -922,6 +926,13 @@ interface HostRegistry {
922
926
  start(): Promise<void>;
923
927
  }
924
928
  declare function createHostRegistry(deps: HostRegistryDeps): HostRegistry;
929
+ /** Read-only snapshot of `hosts.json` (the read-only twin of
930
+ * `readPairingsSnapshot`): for callers that just want the persisted
931
+ * records — e.g. `agentproto doctor`'s devices check flagging a host
932
+ * channel that persistently fails its handshake (BOOTSTRAP P3 item 4).
933
+ * No dial, no rendezvous, no `loadIdentity` deps. Never throws — a
934
+ * missing or malformed file yields `[]`. */
935
+ declare function readHostsSnapshot(path?: string): Promise<HostRecord[]>;
925
936
 
926
937
  /**
927
938
  * Daemon-side JOIN TOKEN registry (SANDBOX-VISIBILITY-JOIN, stacked on
@@ -7931,4 +7942,4 @@ interface GatewayHandle {
7931
7942
  */
7932
7943
  declare function createGateway(opts: CreateGatewayOptions): Promise<GatewayHandle>;
7933
7944
 
7934
- export { ActivityListFilter, type ActivityPolicyLister, type ActivityProjector, type ActivityProjectorRegistry, type ActivityProjectorSession, ActivityRecord, type ActivityWorkflowLister, AdapterAuthDescriptor, type AdapterCapabilitiesLister, type AdapterInstallResult, type AdapterListEntry, type AgentAdapterInstaller, type AgentAdapterLister, type AgentAdapterResolver, AgentSessionLike, AgentStreamEvent, type AttachSandboxOpts, type AttachSandboxResult, BUCKETS_ROOT, type BranchGcClass, type BranchGcCoverageView, type BranchGcHoldReason, type BranchGcKind, type BranchGcOutcomeView, type BranchGcPlanEntryView, type BranchGcPlanView, type BranchGcReclaimReason, type BranchGcResult, type BranchGcRunInput, type BranchGcRunner, type BranchGcStatus, type BranchGcSummaryView, type BranchGcTriageVerdict, type BranchGcVerdictInput, type BranchGcVerdictLookupInput, type BranchGcVerdictReader, type BranchGcVerdictRecordView, type BranchGcVerdictRecorder, type BrowserAdapterHandle, type BrowserAdapterInfo, type BrowserAdapterLister, type BrowserAdapterResolver, BuildHeartbeatAgent, CONTINUE_PROMPT_SOURCE, CanonicalPosture, type CapabilitiesInventory, type CapabilitiesInventoryMcp, type CapabilitiesInventorySkills, type CatalogModelsLister, CatalogModelsQuery, CatalogModelsResponse, type CatalogProviderModel, type CatalogProviderModelsQuery, type CatalogProviderModelsResponse, type CatalogProviderPricing, type ClaudeNativeRef, CompletionPolicySupervisor, type ComposeCandidate, ContextProfile, type ContinueInterruptedMode, type ContinueInterruptedOutcome, type ContinueInterruptedResult, type ContinueInterruptedSkipReason, type ContinueOnBootSummary, type ConversationIndexRecord, type ConversationNativeRef, type CostBudgetDecision, type CrashDetectSummary, type CrashReaperRegistry, type CreateGatewayOptions, type CreateJoinTokenInput, type CreateReviewRunnerOptions, type CreatedJoinToken, DEAD_SESSION_STATUSES, DEFAULT_ALWAYS_ON_TOOLS, DEFAULT_BUCKET, DEFAULT_CONTINUE_PROMPT, DEFAULT_HOST_LOAD_BUDGET_MS, DEFAULT_HOST_LOAD_THRESHOLDS, DEFAULT_ORCHESTRATOR_TOOLS, type DaemonReviewerHostDeps, DeclaredAdapterOption, type DeclaredAdapterPreset, DefaultsAdapterAuthConfig, type Device, type DeviceKind, type DeviceRegistry, type DeviceRole, type DiskLoad, type EagerResumeSummary, type EnableInput, type EnableResult, type FindComposeCandidateInput, type ForwardHttpRequest, type ForwardHttpResponse, GC_REAPABLE_STATES, type GatewayHandle, type GhRunner, HOSTS_VERSION, HOST_SCOPE_HEADER, type HarnessPreset, type HarnessPresetValidationDeps, HarnessPresetValidationError, type HarnessPresetsFile, type HermesNativeRef, type HostJoinMeta, type HostLoadCpu, type HostLoadDetail, type HostLoadMemory, type HostLoadReport, type HostLoadService, type HostLoadSwap, type HostLoadThresholds, type HostProbes, type HostProcess, type HostProcessOwner, type HostRecord, type HostRegistry, type HostRegistryDeps, type HostSessionRollup, type HostWarning, type HostWarningKind, INBOUND_PROVIDERS, type IdleReapSummary, type IdleReaperRegistry, type InboundEndpoint, type InboundEndpointStore, type InboundEndpointStoreOptions, type InboundEnqueuePrompt, type InboundIsSessionAlive, type InboundMessage, type InboundProvider, type InboundRestartSession, type InboundRouteMode, type InboundRouterDeps, type InboundRouterLog, type InboundSpawnForContact, type InboundWatcher, JOIN_TOKENS_VERSION, type JoinTokenRecord, type JoinTokenRegistry, type JoinTokenRegistryDeps, LEGACY_SESSIONS_FILE, type LedgerAnnotations, type LedgerEntry, type LedgerHostMeta, type LlmEndpointDescriptor, type LlmEndpointStatus, type LlmEndpointStatusReport, type LocatedConversation, type LocatedConversationByPath, MAX_AUTO_CONTINUE_ATTEMPTS, MCP_APP_BRIDGE_SCRIPT, type McpCredentialDeps, type MeasurableTool, type MeasuredToolEntry, MessageKind, MessageUrgency, type MigrationMarker, type ModelRolesInput, type ModelRolesOutput, type NormalizeInboundResult, type OpenPrResolver, type OrchestratorGatewayDeps, type OrchestratorInjection, type OrchestratorInjector, type OrchestratorInjectorDeps, type OrchestratorMcpServerFactory, type OrchestratorScope, type OrphanReaperRegistry, POSTURE_NATIVE_ALIASES, POSTURE_PREAMBLES, PolicyRunState, Posture, type PostureResolution, PrLookupError, type PrLookupErrorCode, PrResolvedState, type PrStateResolver, type PrStatusSnapshot, type PresetInfo, type ProjectBrowserToolsOptions, type ProjectedBrowserTool, type ProjectedBrowserTools, type ProjectedProvider, type ProjectedToolResult, ProvisionInFlight, QuotaReadableProfile, type RegisterBrainToolsOptions, type RegisterDeviceToolsOptions, type RegisterPairingToolsOptions, type RegisterReviewToolsOptions, type RegisterWebSearchToolsOptions, RemainingQuotaReader, type RemoteStatus, type ResolveNativeLinkInput, ResolvedAuthSpec, ResolvedModelRole, type ReuseResolution, type ReviewComposeContext, type ReviewLedger, type ReviewLedgerFilter, type ReviewRun, type ReviewRunInput, type ReviewRunStatus, type ReviewRunner, type ReviewSignature, type ReviewSigningKey, type ReviewerRunResult, type ReviewerSessionHost, type RouteAwareLaunchConfig, type RouteAwareLaunchConfigInput, RouteSpec, type RuntimeMeta, SIGN_NAMESPACE, type SandboxAdapterInfo, type SandboxConnectionDescriptor, type SandboxGcCandidate, type SandboxGcProviderHandle, type SandboxGcReapDeps, type SandboxGcReapResult, type SandboxLedgerEntry, type SandboxLedgerState, type SandboxProviderCapabilities, type SandboxProviderHandle, type SandboxProviderLister, type SandboxProviderResolver, type SandboxReconcileDeps, type SandboxReconcileProviderHandle, type SandboxReconcileResult, type SandboxReconcileRow, type SandboxReconcileVerdict, type ScopeTokenRegistry, type SentinelMatchClause, type SentinelSpec, type SentinelStatus, type SentinelTarget, type SentinelUntil, type SentinelView, SessionDescriptor, SessionEndReason, SessionMessage, type SessionMessageSentRecord, type SessionObserver, SessionUsage, type SessionUsageWithSubtree, type SessionWaitEvent, type SessionWaitResult, SessionsRegistry, type SkillPackInventoryEntry, type SkillsByHarnessEntry, SpawnDefaultsConfig, type StallWatchdogRegistry, type StallWatchdogSummary, type SubtreeChildUsage, type SubtreeUsageTotals, TaskLedger, type ToolListMeasurement, type TransmitterBinding, type TransmitterBindingStore, type TunnelDescriptor, type TunnelProvider, type TunnelStatus, UsageReadContext, UsageReadResult, UsageRollup, UsageSnapshotRecord, UserPreset, type VerifySignedAttestationResult, type WatcherDescriptor, type WatcherStartInput, type WebSearchInput, type WebSearchOutput, type WebSearchResult, type WorkspaceBrainSubscriber, type WorkspaceBrainSubscriberOptions, type WorkspaceBrains, WorkspaceFs, WorktreeAutoReclaimer, WorktreeField, type WorktreeGcClass, type WorktreeGcOutcomeView, type WorktreeGcPlanEntryView, type WorktreeGcReclaimReason, type WorktreeGcResult, type WorktreeGcRunInput, type WorktreeGcRunner, WorktreeIsolationMode, WorktreeProvisioner, type WorktreeStatusLister, type WorktreeStatusView, addHarnessPreset, allowedSignersLine, appendConversationRecord, attachSandbox, bucketDir, bucketSessionsFile, bucketTranscriptDir, buildCatalogProviderModels, buildHostLoadReport, buildMcpConfigSnippet, buildRouteAwareLaunchConfig, canonicalForModeId, claudeProjectSlug, collectGcCandidates, collectHostSample, composeSessionObservers, composedFromRangeSha, computeHostWarnings, continueInterruptedSessions, continueSkipReason, conversationIndexPath, createActivityProjector, createDaemonReviewerHost, createDefaultHostProbes, createDeviceRegistry, createFileStepCache, createGateway, createHostLoadService, createHostRegistry, createInboundEndpointStore, createJoinTokenRegistry, createOrchestratorInjector, createOrchestratorMcpServerFactory, createPrProvenanceReconciler, createReviewLaneExecutor, createReviewLedger, createReviewPackLoader, createReviewRunner, createScopeTokenRegistry, createWorkspaceBrainSubscriber, createWorkspaceBrains, daemonRegistryDir, declaredPresetToProviderPreset, defaultBrowserAdapterIds, defaultBrowserAdapterResolution, defaultReviewKeysDir, defaultReviewLedgerRoot, defaultReviewPackCacheDir, defineBraveSearchHttpDriver, defineSerperHttpDriver, describeOwner, enrichRollupWithProviderQuota, enrichWithRemainingQuota, ensureReviewSigningKey, evaluateCostBudget, execGh, extractHelpSection, fetchPrStatus, fileExists, findComposeCandidate, findConversationRecord, findNativeMode, findPrForCommit, formatToolCall, formatToolResult, getDefaultHarnessPreset, getHarnessPreset, getHostLoadService, getMcpCredentialDeps, getToolHelp, githubRepoOf, harnessPresetsPath, hostPlaceholders, injectMcpAppBridge, isAgentCliAuthConfigured, isSafeBucketSlug, listBuckets, listHarnessPresets, listPresets, listToolHelpTopics, loadHarnessPresets, loadWorkspaceModelRoles, locateConversationByNativePath, locateConversationBySessionId, makeBrowserAdapterLister, makeSandboxCredsStore, makeSandboxResolver, measureTool, measureToolList, migrateLegacySessionsFile, migrationMarkerPath, monitorPolicyWait, monitorSessionWait, narrowOrchestratorTools, normalizeInbound, normalizeModeId, normalizeRemote, parsePrUrl, prHeadSha, projectBrowserTools, readConversationIndex, readDaemonRegistry, readRegisteredSlugs, readRuntimeMeta, readSandboxLedger, readSessionForBrain, readUsageSnapshots, reapGcEntry, reapOrphanedDescendants, reconcileSandboxLedger, recordSandboxBoot, recordSandboxLiveness, recordSandboxOrigin, recordSandboxState, registerBrainTools, registerBuiltinRoutes, registerDeviceTools, registerPairingTools, registerReviewTools, registerSandboxAttachTool, registerWebSearchTools, removeHarnessPreset, removeSandboxLedgerEntry, repoSlug, resolveBucketSlug, resolveEffectiveLlmEndpointFlag, resolveNativeLink, resolvePosture, resolvePrincipal, resolveReuseFromLedger, resolveReviewerPreset, rollupSessionSubtree, runContinueOnBootPass, runCrashDetectPass, runEagerResumePass, runIdleReapPass, runShellLane, runStallWatchdogPass, sandboxLedgerPath, setDefaultPreset, setMcpCredentialDeps, signAttestation, sweepStaleDaemonRegistry, sweepStaleRuntimeMetas, toWorktreeStatusView, unlinkDaemonRegistryEntry, unlinkRuntimeMeta, updateHarnessPreset, upsertSandboxLedger, verifyInboundSignature, verifySignedAttestation, webSearchTool, withPr, withPrStatus, writeDaemonRegistryEntry };
7945
+ export { ActivityListFilter, type ActivityPolicyLister, type ActivityProjector, type ActivityProjectorRegistry, type ActivityProjectorSession, ActivityRecord, type ActivityWorkflowLister, AdapterAuthDescriptor, type AdapterCapabilitiesLister, type AdapterInstallResult, type AdapterListEntry, type AgentAdapterInstaller, type AgentAdapterLister, type AgentAdapterResolver, AgentSessionLike, AgentStreamEvent, type AttachSandboxOpts, type AttachSandboxResult, BUCKETS_ROOT, type BranchGcClass, type BranchGcCoverageView, type BranchGcHoldReason, type BranchGcKind, type BranchGcOutcomeView, type BranchGcPlanEntryView, type BranchGcPlanView, type BranchGcReclaimReason, type BranchGcResult, type BranchGcRunInput, type BranchGcRunner, type BranchGcStatus, type BranchGcSummaryView, type BranchGcTriageVerdict, type BranchGcVerdictInput, type BranchGcVerdictLookupInput, type BranchGcVerdictReader, type BranchGcVerdictRecordView, type BranchGcVerdictRecorder, type BrowserAdapterHandle, type BrowserAdapterInfo, type BrowserAdapterLister, type BrowserAdapterResolver, BuildHeartbeatAgent, CONTINUE_PROMPT_SOURCE, CanonicalPosture, type CapabilitiesInventory, type CapabilitiesInventoryMcp, type CapabilitiesInventorySkills, type CatalogModelsLister, CatalogModelsQuery, CatalogModelsResponse, type CatalogProviderModel, type CatalogProviderModelsQuery, type CatalogProviderModelsResponse, type CatalogProviderPricing, type ClaudeNativeRef, CompletionPolicySupervisor, type ComposeCandidate, ContextProfile, type ContinueInterruptedMode, type ContinueInterruptedOutcome, type ContinueInterruptedResult, type ContinueInterruptedSkipReason, type ContinueOnBootSummary, type ConversationIndexRecord, type ConversationNativeRef, type CostBudgetDecision, type CrashDetectSummary, type CrashReaperRegistry, type CreateGatewayOptions, type CreateJoinTokenInput, type CreateReviewRunnerOptions, type CreatedJoinToken, DEAD_SESSION_STATUSES, DEFAULT_ALWAYS_ON_TOOLS, DEFAULT_BUCKET, DEFAULT_CONTINUE_PROMPT, DEFAULT_HOST_LOAD_BUDGET_MS, DEFAULT_HOST_LOAD_THRESHOLDS, DEFAULT_ORCHESTRATOR_TOOLS, type DaemonReviewerHostDeps, DeclaredAdapterOption, type DeclaredAdapterPreset, DefaultsAdapterAuthConfig, type Device, type DeviceKind, type DeviceRegistry, type DeviceRole, type DiskLoad, type EagerResumeSummary, type EnableInput, type EnableResult, type FindComposeCandidateInput, type ForwardHttpRequest, type ForwardHttpResponse, GC_REAPABLE_STATES, type GatewayHandle, type GhRunner, HOSTS_VERSION, HOST_HANDSHAKE_REMEDIATION_HINT, HOST_SCOPE_HEADER, type HarnessPreset, type HarnessPresetValidationDeps, HarnessPresetValidationError, type HarnessPresetsFile, type HermesNativeRef, type HostJoinMeta, type HostLoadCpu, type HostLoadDetail, type HostLoadMemory, type HostLoadReport, type HostLoadService, type HostLoadSwap, type HostLoadThresholds, type HostProbes, type HostProcess, type HostProcessOwner, type HostRecord, type HostRegistry, type HostRegistryDeps, type HostSessionRollup, type HostWarning, type HostWarningKind, INBOUND_PROVIDERS, type IdleReapSummary, type IdleReaperRegistry, type InboundEndpoint, type InboundEndpointStore, type InboundEndpointStoreOptions, type InboundEnqueuePrompt, type InboundIsSessionAlive, type InboundMessage, type InboundProvider, type InboundRestartSession, type InboundRouteMode, type InboundRouterDeps, type InboundRouterLog, type InboundSpawnForContact, type InboundWatcher, JOIN_TOKENS_VERSION, type JoinTokenRecord, type JoinTokenRegistry, type JoinTokenRegistryDeps, LEGACY_SESSIONS_FILE, type LedgerAnnotations, type LedgerEntry, type LedgerHostMeta, type LlmEndpointDescriptor, type LlmEndpointStatus, type LlmEndpointStatusReport, type LocatedConversation, type LocatedConversationByPath, MAX_AUTO_CONTINUE_ATTEMPTS, MCP_APP_BRIDGE_SCRIPT, type McpCredentialDeps, type MeasurableTool, type MeasuredToolEntry, MessageKind, MessageUrgency, type MigrationMarker, type ModelRolesInput, type ModelRolesOutput, type NormalizeInboundResult, type OpenPrResolver, type OrchestratorGatewayDeps, type OrchestratorInjection, type OrchestratorInjector, type OrchestratorInjectorDeps, type OrchestratorMcpServerFactory, type OrchestratorScope, type OrphanReaperRegistry, POSTURE_NATIVE_ALIASES, POSTURE_PREAMBLES, PolicyRunState, Posture, type PostureResolution, PrLookupError, type PrLookupErrorCode, PrResolvedState, type PrStateResolver, type PrStatusSnapshot, type PresetInfo, type ProjectBrowserToolsOptions, type ProjectedBrowserTool, type ProjectedBrowserTools, type ProjectedProvider, type ProjectedToolResult, ProvisionInFlight, QuotaReadableProfile, type RegisterBrainToolsOptions, type RegisterDeviceToolsOptions, type RegisterPairingToolsOptions, type RegisterReviewToolsOptions, type RegisterWebSearchToolsOptions, RemainingQuotaReader, type RemoteStatus, type ResolveNativeLinkInput, ResolvedAuthSpec, ResolvedModelRole, type ReuseResolution, type ReviewComposeContext, type ReviewLedger, type ReviewLedgerFilter, type ReviewRun, type ReviewRunInput, type ReviewRunStatus, type ReviewRunner, type ReviewSignature, type ReviewSigningKey, type ReviewerRunResult, type ReviewerSessionHost, type RouteAwareLaunchConfig, type RouteAwareLaunchConfigInput, RouteSpec, type RuntimeMeta, SIGN_NAMESPACE, type SandboxAdapterInfo, type SandboxConnectionDescriptor, type SandboxGcCandidate, type SandboxGcProviderHandle, type SandboxGcReapDeps, type SandboxGcReapResult, type SandboxLedgerEntry, type SandboxLedgerState, type SandboxProviderCapabilities, type SandboxProviderHandle, type SandboxProviderLister, type SandboxProviderResolver, type SandboxReconcileDeps, type SandboxReconcileProviderHandle, type SandboxReconcileResult, type SandboxReconcileRow, type SandboxReconcileVerdict, type ScopeTokenRegistry, type SentinelMatchClause, type SentinelSpec, type SentinelStatus, type SentinelTarget, type SentinelUntil, type SentinelView, SessionDescriptor, SessionEndReason, SessionMessage, type SessionMessageSentRecord, type SessionObserver, SessionUsage, type SessionUsageWithSubtree, type SessionWaitEvent, type SessionWaitResult, SessionsRegistry, type SkillPackInventoryEntry, type SkillsByHarnessEntry, SpawnDefaultsConfig, type StallWatchdogRegistry, type StallWatchdogSummary, type SubtreeChildUsage, type SubtreeUsageTotals, TaskLedger, type ToolListMeasurement, type TransmitterBinding, type TransmitterBindingStore, type TunnelDescriptor, type TunnelProvider, type TunnelStatus, UsageReadContext, UsageReadResult, UsageRollup, UsageSnapshotRecord, UserPreset, type VerifySignedAttestationResult, type WatcherDescriptor, type WatcherStartInput, type WebSearchInput, type WebSearchOutput, type WebSearchResult, type WorkspaceBrainSubscriber, type WorkspaceBrainSubscriberOptions, type WorkspaceBrains, WorkspaceFs, WorktreeAutoReclaimer, WorktreeField, type WorktreeGcClass, type WorktreeGcOutcomeView, type WorktreeGcPlanEntryView, type WorktreeGcReclaimReason, type WorktreeGcResult, type WorktreeGcRunInput, type WorktreeGcRunner, WorktreeIsolationMode, WorktreeProvisioner, type WorktreeStatusLister, type WorktreeStatusView, addHarnessPreset, allowedSignersLine, appendConversationRecord, attachSandbox, bucketDir, bucketSessionsFile, bucketTranscriptDir, buildCatalogProviderModels, buildHostLoadReport, buildMcpConfigSnippet, buildRouteAwareLaunchConfig, canonicalForModeId, claudeProjectSlug, collectGcCandidates, collectHostSample, composeSessionObservers, composedFromRangeSha, computeHostWarnings, continueInterruptedSessions, continueSkipReason, conversationIndexPath, createActivityProjector, createDaemonReviewerHost, createDefaultHostProbes, createDeviceRegistry, createFileStepCache, createGateway, createHostLoadService, createHostRegistry, createInboundEndpointStore, createJoinTokenRegistry, createOrchestratorInjector, createOrchestratorMcpServerFactory, createPrProvenanceReconciler, createReviewLaneExecutor, createReviewLedger, createReviewPackLoader, createReviewRunner, createScopeTokenRegistry, createWorkspaceBrainSubscriber, createWorkspaceBrains, daemonRegistryDir, declaredPresetToProviderPreset, defaultBrowserAdapterIds, defaultBrowserAdapterResolution, defaultReviewKeysDir, defaultReviewLedgerRoot, defaultReviewPackCacheDir, defineBraveSearchHttpDriver, defineSerperHttpDriver, describeOwner, enrichRollupWithProviderQuota, enrichWithRemainingQuota, ensureReviewSigningKey, evaluateCostBudget, execGh, extractHelpSection, fetchPrStatus, fileExists, findComposeCandidate, findConversationRecord, findNativeMode, findPrForCommit, formatToolCall, formatToolResult, getDefaultHarnessPreset, getHarnessPreset, getHostLoadService, getMcpCredentialDeps, getToolHelp, githubRepoOf, harnessPresetsPath, hostPlaceholders, injectMcpAppBridge, isAgentCliAuthConfigured, isSafeBucketSlug, listBuckets, listHarnessPresets, listPresets, listToolHelpTopics, loadHarnessPresets, loadWorkspaceModelRoles, locateConversationByNativePath, locateConversationBySessionId, makeBrowserAdapterLister, makeSandboxCredsStore, makeSandboxResolver, measureTool, measureToolList, migrateLegacySessionsFile, migrationMarkerPath, monitorPolicyWait, monitorSessionWait, narrowOrchestratorTools, normalizeInbound, normalizeModeId, normalizeRemote, parsePrUrl, prHeadSha, projectBrowserTools, readConversationIndex, readDaemonRegistry, readHostsSnapshot, readRegisteredSlugs, readRuntimeMeta, readSandboxLedger, readSessionForBrain, readUsageSnapshots, reapGcEntry, reapOrphanedDescendants, reconcileSandboxLedger, recordSandboxBoot, recordSandboxLiveness, recordSandboxOrigin, recordSandboxState, registerBrainTools, registerBuiltinRoutes, registerDeviceTools, registerPairingTools, registerReviewTools, registerSandboxAttachTool, registerWebSearchTools, removeHarnessPreset, removeSandboxLedgerEntry, repoSlug, resolveBucketSlug, resolveEffectiveLlmEndpointFlag, resolveNativeLink, resolvePosture, resolvePrincipal, resolveReuseFromLedger, resolveReviewerPreset, rollupSessionSubtree, runContinueOnBootPass, runCrashDetectPass, runEagerResumePass, runIdleReapPass, runShellLane, runStallWatchdogPass, sandboxLedgerPath, setDefaultPreset, setMcpCredentialDeps, signAttestation, sweepStaleDaemonRegistry, sweepStaleRuntimeMetas, toWorktreeStatusView, unlinkDaemonRegistryEntry, unlinkRuntimeMeta, updateHarnessPreset, upsertSandboxLedger, verifyInboundSignature, verifySignedAttestation, webSearchTool, withPr, withPrStatus, writeDaemonRegistryEntry };
package/dist/index.mjs CHANGED
@@ -34907,6 +34907,9 @@ var DEFAULT_PROBE_BACKOFF_MAX_MS = 3e5;
34907
34907
  var DEFAULT_PROBE_CONCURRENCY = 4;
34908
34908
  var RESUME_STAGGER_MS = 500;
34909
34909
  var MAX_LAST_ERROR_CHARS = 300;
34910
+ var HOST_HANDSHAKE_FAILURE_HINT_THRESHOLD = 5;
34911
+ var HOST_HANDSHAKE_REMEDIATION_HINT = "host handshake failing \u2014 the controller should re-run `agentproto devices add` with a fresh `pair offer --host` (a reboot/reinstall on the host invalidates the old registration)";
34912
+ var handshakeFailures = /* @__PURE__ */ new Map();
34910
34913
  var DEFAULT_LAST_SEEN_PERSIST_MS = 3e4;
34911
34914
  var DEFAULT_SNAPSHOT_INTERVAL_MS = 15e3;
34912
34915
  var DEFAULT_SNAPSHOT_ACTIVE_INTERVAL_MS = 5e3;
@@ -35186,6 +35189,7 @@ function createHostRegistry(deps2) {
35186
35189
  async function markReached(record2) {
35187
35190
  const t = now();
35188
35191
  lastReachedAt.set(record2.fingerprint, t);
35192
+ handshakeFailures.delete(record2.fingerprint);
35189
35193
  record2.lastSeen = new Date(t).toISOString();
35190
35194
  record2.lastProbeAt = record2.lastSeen;
35191
35195
  const hadError = record2.lastError !== void 0;
@@ -35198,6 +35202,13 @@ function createHostRegistry(deps2) {
35198
35202
  async function markUnreachable(record2, message) {
35199
35203
  record2.lastProbeAt = new Date(now()).toISOString();
35200
35204
  const error = message.slice(0, MAX_LAST_ERROR_CHARS);
35205
+ const failures = (handshakeFailures.get(record2.fingerprint) ?? 0) + 1;
35206
+ handshakeFailures.set(record2.fingerprint, failures);
35207
+ if (failures === HOST_HANDSHAKE_FAILURE_HINT_THRESHOLD) {
35208
+ log(
35209
+ `[hosts] ${record2.fingerprint} (${record2.name}): failed to dial/handshake ${failures} times in a row \u2014 ` + HOST_HANDSHAKE_REMEDIATION_HINT
35210
+ );
35211
+ }
35201
35212
  if (record2.lastError === error) return;
35202
35213
  record2.lastError = error;
35203
35214
  await persist().catch((err) => log(`[hosts] lastError persist failed: ${errMsg3(err)}`));
@@ -35411,7 +35422,7 @@ function createHostRegistry(deps2) {
35411
35422
  async function forwardHttp(idOrName, req) {
35412
35423
  await ensureLoaded();
35413
35424
  const record2 = findHost(idOrName);
35414
- if (!record2) throw new Error(`no host matched "${idOrName}"`);
35425
+ if (!record2) throw hostLookupError(idOrName);
35415
35426
  onlineCounts.set(record2.fingerprint, (onlineCounts.get(record2.fingerprint) ?? 0) + 1);
35416
35427
  let client;
35417
35428
  try {
@@ -35431,7 +35442,7 @@ function createHostRegistry(deps2) {
35431
35442
  async function forwardHttpStream(idOrName, req) {
35432
35443
  await ensureLoaded();
35433
35444
  const record2 = findHost(idOrName);
35434
- if (!record2) throw new Error(`no host matched "${idOrName}"`);
35445
+ if (!record2) throw hostLookupError(idOrName);
35435
35446
  onlineCounts.set(record2.fingerprint, (onlineCounts.get(record2.fingerprint) ?? 0) + 1);
35436
35447
  let decremented = false;
35437
35448
  const decrement = () => {
@@ -35627,6 +35638,16 @@ function isHostsFile(v) {
35627
35638
  if (!Array.isArray(rec["hosts"])) return false;
35628
35639
  return rec["hosts"].every(isHostRecord);
35629
35640
  }
35641
+ async function readHostsSnapshot(path) {
35642
+ try {
35643
+ const raw = await readFile(path ?? defaultHostsPath(), "utf8");
35644
+ const parsed = JSON.parse(raw);
35645
+ if (!isHostsFile(parsed)) return [];
35646
+ return parsed.hosts.map((rec) => ({ ...rec }));
35647
+ } catch {
35648
+ return [];
35649
+ }
35650
+ }
35630
35651
  function isHostRecord(v) {
35631
35652
  if (typeof v !== "object" || v === null) return false;
35632
35653
  const r = v;
@@ -35638,6 +35659,11 @@ function isEnoent(err) {
35638
35659
  function errMsg3(err) {
35639
35660
  return err instanceof Error ? err.message : String(err);
35640
35661
  }
35662
+ function hostLookupError(idOrName) {
35663
+ return new Error(
35664
+ `no host matched "${idOrName}" \u2014 devices resolve role:host only: if you accepted an offer on the other machine, the roles may be inverted; see \`agentproto pair --help\``
35665
+ );
35666
+ }
35641
35667
 
35642
35668
  // src/device-registry.ts
35643
35669
  function inferKind2(name) {
@@ -38960,6 +38986,36 @@ async function assertCronAdapterResolvable(action, deps2) {
38960
38986
  }
38961
38987
  var DEFAULT_PERSIST_PATH3 = () => join(homedir(), ".agentproto", "cron-jobs.json");
38962
38988
  var TICK_INTERVAL_MS = 2e4;
38989
+ var MAX_RUNS_PER_JOB = 50;
38990
+ function ledgerPath(persistPath) {
38991
+ return `${persistPath}.runs.json`;
38992
+ }
38993
+ function loadRuns2(path) {
38994
+ try {
38995
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
38996
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return /* @__PURE__ */ new Map();
38997
+ const runs = /* @__PURE__ */ new Map();
38998
+ for (const [jobId, value] of Object.entries(parsed)) {
38999
+ if (Array.isArray(value)) {
39000
+ runs.set(jobId, value.filter(
39001
+ (run) => run && typeof run.runId === "string" && run.jobId === jobId && typeof run.startedAt === "string" && typeof run.endedAt === "string" && typeof run.ok === "boolean" && typeof run.result === "string"
39002
+ ).slice(-MAX_RUNS_PER_JOB));
39003
+ }
39004
+ }
39005
+ return runs;
39006
+ } catch {
39007
+ return /* @__PURE__ */ new Map();
39008
+ }
39009
+ }
39010
+ function saveRuns2(runs, path) {
39011
+ try {
39012
+ mkdirSync(dirname(path), { recursive: true });
39013
+ const tmp = `${path}.tmp.${process.pid}`;
39014
+ writeFileSync(tmp, JSON.stringify(Object.fromEntries(runs), null, 2) + "\n", "utf8");
39015
+ renameSync(tmp, path);
39016
+ } catch {
39017
+ }
39018
+ }
38963
39019
  function loadJobs(persistPath) {
38964
39020
  const result = /* @__PURE__ */ new Map();
38965
39021
  if (!existsSync(persistPath)) return result;
@@ -38982,6 +39038,9 @@ function loadJobs(persistPath) {
38982
39038
  const job = item;
38983
39039
  job.recurring = job.recurring ?? true;
38984
39040
  job.active = job.active ?? true;
39041
+ if (job.finished === void 0 && !job.recurring && !job.active && !!job.lastRunAt) {
39042
+ job.finished = true;
39043
+ }
38985
39044
  result.set(job.id, { job });
38986
39045
  }
38987
39046
  return result;
@@ -39019,6 +39078,14 @@ function createCronScheduler(opts) {
39019
39078
  const persistPath = opts.persistPath ?? DEFAULT_PERSIST_PATH3();
39020
39079
  const shouldPersist = opts.persist ?? opts.persistPath !== void 0;
39021
39080
  const jobs = shouldPersist ? loadJobs(persistPath) : /* @__PURE__ */ new Map();
39081
+ const runHistory = shouldPersist ? loadRuns2(ledgerPath(persistPath)) : /* @__PURE__ */ new Map();
39082
+ const appendRun = (run) => {
39083
+ const history = runHistory.get(run.jobId) ?? [];
39084
+ history.push(run);
39085
+ if (history.length > MAX_RUNS_PER_JOB) history.splice(0, history.length - MAX_RUNS_PER_JOB);
39086
+ runHistory.set(run.jobId, history);
39087
+ if (shouldPersist) saveRuns2(runHistory, ledgerPath(persistPath));
39088
+ };
39022
39089
  for (const state of jobs.values()) {
39023
39090
  if (!state.job.active) continue;
39024
39091
  try {
@@ -39141,7 +39208,15 @@ function createCronScheduler(opts) {
39141
39208
  if (!ok4) {
39142
39209
  throw new Error(`cron job '${job.id}': tool '${action.tool}' failed: ${summary2}`);
39143
39210
  }
39144
- return { ok: true, summary: `tool '${action.tool}': ${summary2}` };
39211
+ let sessionId2;
39212
+ if (action.tool === "agent_start") {
39213
+ try {
39214
+ const body = JSON.parse(summary2);
39215
+ if (typeof body.id === "string") sessionId2 = body.id;
39216
+ } catch {
39217
+ }
39218
+ }
39219
+ return { ok: true, summary: `tool '${action.tool}': ${summary2}`, sessionId: sessionId2 };
39145
39220
  }
39146
39221
  if (!dispatchTool) {
39147
39222
  throw new Error(
@@ -39164,6 +39239,7 @@ function createCronScheduler(opts) {
39164
39239
  }
39165
39240
  return {
39166
39241
  ok: true,
39242
+ sessionId,
39167
39243
  summary: sessionId ? `spawned session ${sessionId} (adapter=${action.adapter ?? action.harness ?? "preset"})` : `agent_start: ${summary}`
39168
39244
  };
39169
39245
  };
@@ -39172,45 +39248,37 @@ function createCronScheduler(opts) {
39172
39248
  state.running = true;
39173
39249
  try {
39174
39250
  const { job } = state;
39175
- const now = (/* @__PURE__ */ new Date()).toISOString();
39176
- job.lastRunAt = now;
39177
- sessionEvents.emit({ type: "cron:fired", jobId: job.id, label: job.label, ts: now });
39251
+ const startedAt = (/* @__PURE__ */ new Date()).toISOString();
39252
+ job.lastRunAt = startedAt;
39253
+ sessionEvents.emit({ type: "cron:fired", jobId: job.id, label: job.label, ts: startedAt });
39178
39254
  let result;
39255
+ let error;
39179
39256
  try {
39180
39257
  result = await executeAction(job);
39181
39258
  } catch (err) {
39182
- const error = err instanceof Error ? err.message : String(err);
39259
+ error = err instanceof Error ? err.message : String(err);
39183
39260
  result = { ok: false, summary: error };
39184
- sessionEvents.emit({
39185
- type: "cron:failed",
39186
- jobId: job.id,
39187
- label: job.label,
39188
- error,
39189
- ts: (/* @__PURE__ */ new Date()).toISOString()
39190
- });
39191
- job.lastResult = result;
39192
- if (!job.recurring) {
39193
- job.active = false;
39194
- job.nextRunAt = void 0;
39195
- state.cronInstance?.stop();
39196
- state.cronInstance = void 0;
39197
- } else if (state.cronInstance) {
39198
- const next = nextFireDate(state.cronInstance);
39199
- job.nextRunAt = next?.toISOString();
39200
- }
39201
- persistNow();
39202
- return;
39203
39261
  }
39204
- sessionEvents.emit({
39205
- type: "cron:succeeded",
39262
+ const endedAt = (/* @__PURE__ */ new Date()).toISOString();
39263
+ appendRun({
39264
+ runId: `run_${randomUUID()}`,
39206
39265
  jobId: job.id,
39207
- label: job.label,
39208
- summary: result.summary,
39209
- ts: (/* @__PURE__ */ new Date()).toISOString()
39266
+ startedAt,
39267
+ endedAt,
39268
+ ok: result.ok,
39269
+ ...result.sessionId ? { sessionId: result.sessionId } : {},
39270
+ result: result.summary,
39271
+ ...error ? { error } : {}
39210
39272
  });
39211
- job.lastResult = result;
39273
+ if (error) {
39274
+ sessionEvents.emit({ type: "cron:failed", jobId: job.id, label: job.label, error, ts: endedAt });
39275
+ } else {
39276
+ sessionEvents.emit({ type: "cron:succeeded", jobId: job.id, label: job.label, summary: result.summary, ts: endedAt });
39277
+ }
39278
+ job.lastResult = { ok: result.ok, summary: result.summary };
39212
39279
  if (!job.recurring) {
39213
39280
  job.active = false;
39281
+ job.finished = true;
39214
39282
  job.nextRunAt = void 0;
39215
39283
  state.cronInstance?.stop();
39216
39284
  state.cronInstance = void 0;
@@ -39257,6 +39325,7 @@ function createCronScheduler(opts) {
39257
39325
  action,
39258
39326
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
39259
39327
  active: true,
39328
+ finished: false,
39260
39329
  nextRunAt: next?.toISOString()
39261
39330
  };
39262
39331
  jobs.set(id, { job, cronInstance });
@@ -39269,11 +39338,55 @@ function createCronScheduler(opts) {
39269
39338
  get(id) {
39270
39339
  return jobs.get(id)?.job;
39271
39340
  },
39341
+ async update(id, patch) {
39342
+ const state = jobs.get(id);
39343
+ if (!state) throw new Error(`cron job not found: ${id}`);
39344
+ if (state.running) throw new Error(`cron job is running: ${id}`);
39345
+ const job = state.job;
39346
+ const schedule = patch.schedule ?? job.schedule;
39347
+ const timezone = patch.timezone === null ? void 0 : patch.timezone ?? job.timezone;
39348
+ const action = patch.action ?? job.action;
39349
+ if (!schedule) throw new Error("cron schedule must not be empty");
39350
+ assertCronActionAllowed(action);
39351
+ const cronInstance = parseCron(schedule, timezone);
39352
+ await assertCronAdapterResolvable(action, {
39353
+ resolveAgentAdapter,
39354
+ getAuthProfile: opts.getAuthProfile,
39355
+ listAgentAdapters: opts.listAgentAdapters
39356
+ });
39357
+ const active = patch.active ?? job.active;
39358
+ const next = active ? nextFireDate(cronInstance) : null;
39359
+ state.cronInstance?.stop();
39360
+ state.cronInstance = active ? cronInstance : void 0;
39361
+ job.schedule = schedule;
39362
+ job.timezone = timezone;
39363
+ job.action = action;
39364
+ job.recurring = patch.recurring ?? job.recurring;
39365
+ if (patch.label !== void 0) job.label = patch.label === null ? void 0 : patch.label;
39366
+ job.active = active;
39367
+ if (active) job.finished = false;
39368
+ job.nextRunAt = next?.toISOString();
39369
+ persistNow();
39370
+ return job;
39371
+ },
39372
+ runs({ jobId, limit = 20, cursor } = {}) {
39373
+ if (jobId && !jobs.has(jobId)) throw new Error(`cron job not found: ${jobId}`);
39374
+ if (!Number.isInteger(limit) || limit < 1 || limit > 200) {
39375
+ throw new Error("limit must be an integer from 1 to 200");
39376
+ }
39377
+ const all = (jobId ? runHistory.get(jobId) ?? [] : Array.from(runHistory.values()).flat()).slice().sort((a, b) => b.startedAt.localeCompare(a.startedAt) || b.runId.localeCompare(a.runId));
39378
+ const start = cursor ? all.findIndex((run) => run.runId === cursor) + 1 : 0;
39379
+ if (cursor && start === 0) throw new Error("invalid cron runs cursor");
39380
+ const runs = all.slice(start, start + limit);
39381
+ return { runs, ...start + limit < all.length ? { nextCursor: runs[runs.length - 1]?.runId } : {} };
39382
+ },
39272
39383
  delete(id) {
39273
39384
  const state = jobs.get(id);
39274
39385
  if (!state) throw new Error(`cron job not found: ${id}`);
39275
39386
  state.cronInstance?.stop();
39276
39387
  jobs.delete(id);
39388
+ runHistory.delete(id);
39389
+ if (shouldPersist) saveRuns2(runHistory, ledgerPath(persistPath));
39277
39390
  persistNow();
39278
39391
  },
39279
39392
  async run(id) {
@@ -42088,6 +42201,7 @@ function registerOrchestrationTools(rawServer, opts) {
42088
42201
  "When false, fires once then deactivates. Default true."
42089
42202
  ),
42090
42203
  label: z.string().optional().describe("Human-readable label for the job."),
42204
+ timezone: z.string().optional().describe("IANA timezone for interpreting the schedule. Defaults to host local time."),
42091
42205
  action: cronActionSchema.describe(
42092
42206
  "What to do when the job fires. 'command' runs an allowlisted shell command; 'agent' spawns a brand-new agent session and takes every agent_start field (access.profileRef, role, worktree, \u2026; not `wait`); 'prompt-session' re-prompts an existing, already-running session in place (for durable check-in jobs); 'tool' calls a registered daemon MCP tool in-process (cron_* refused)."
42093
42207
  )
@@ -42102,6 +42216,7 @@ function registerOrchestrationTools(rawServer, opts) {
42102
42216
  const job = await cronScheduler.create({
42103
42217
  label: input.label,
42104
42218
  schedule: input.schedule,
42219
+ timezone: input.timezone,
42105
42220
  recurring: input.recurring ?? true,
42106
42221
  action: input.action
42107
42222
  });
@@ -42139,6 +42254,7 @@ function registerOrchestrationTools(rawServer, opts) {
42139
42254
  schedule: j.schedule,
42140
42255
  recurring: j.recurring,
42141
42256
  active: j.active,
42257
+ finished: j.finished ?? false,
42142
42258
  nextRunAt: j.nextRunAt,
42143
42259
  lastRunAt: j.lastRunAt,
42144
42260
  // A failed last run must be visible without `full: true`.
@@ -42146,7 +42262,7 @@ function registerOrchestrationTools(rawServer, opts) {
42146
42262
  });
42147
42263
  registerBuiltinTool(server, {
42148
42264
  id: "cron_list",
42149
- description: "List all cron jobs (active and inactive) with their schedule, last result, and next fire time. COMPACT BY DEFAULT: each entry is a slim projection (id/label/schedule/recurring/active/nextRunAt/lastRunAt/lastOk); pass `full: true` (or `compact: false`) for the complete job record including action/createdAt/lastResult.",
42265
+ description: "List all cron jobs (active and inactive) with their schedule, last result, and next fire time. COMPACT BY DEFAULT: each entry is a slim projection (id/label/schedule/recurring/active/finished/nextRunAt/lastRunAt/lastOk); pass `full: true` (or `compact: false`) for the complete job record including action/createdAt/lastResult.",
42150
42266
  inputSchema: cronListSchema,
42151
42267
  handler: async () => cronScheduler.list(),
42152
42268
  transformers: [
@@ -42159,6 +42275,47 @@ function registerOrchestrationTools(rawServer, opts) {
42159
42275
  })
42160
42276
  ]
42161
42277
  });
42278
+ server.tool(
42279
+ "cron_update",
42280
+ "Edit a cron job's schedule, label, timezone, recurrence, action, or active state. Set active false to pause and true to resume.",
42281
+ {
42282
+ jobId: z.string().min(1),
42283
+ schedule: z.string().min(1).optional(),
42284
+ label: z.string().nullable().optional(),
42285
+ timezone: z.string().nullable().optional(),
42286
+ recurring: z.boolean().optional(),
42287
+ active: z.boolean().optional(),
42288
+ action: cronActionSchema.optional()
42289
+ },
42290
+ async (input) => {
42291
+ try {
42292
+ if (input.action?.kind === "tool" && opts.toolSubset && !opts.toolSubset.has(input.action.tool)) {
42293
+ throw new Error(`cron action kind "tool" cannot dispatch '${input.action.tool}': not in this server's tool subset`);
42294
+ }
42295
+ const { jobId, ...patch } = input;
42296
+ const job = await cronScheduler.update(jobId, patch);
42297
+ return { content: [{ type: "text", text: JSON.stringify(job) }] };
42298
+ } catch (err) {
42299
+ return { content: [{ type: "text", text: JSON.stringify({ error: err instanceof Error ? err.message : String(err) }) }], isError: true };
42300
+ }
42301
+ }
42302
+ );
42303
+ server.tool(
42304
+ "cron_runs",
42305
+ "Read cron fire history, newest first. Use nextCursor for the next page.",
42306
+ {
42307
+ jobId: z.string().min(1).optional(),
42308
+ limit: z.number().int().min(1).max(200).optional(),
42309
+ cursor: z.string().min(1).optional()
42310
+ },
42311
+ async (input) => {
42312
+ try {
42313
+ return { content: [{ type: "text", text: JSON.stringify(cronScheduler.runs(input)) }] };
42314
+ } catch (err) {
42315
+ return { content: [{ type: "text", text: JSON.stringify({ error: err instanceof Error ? err.message : String(err) }) }], isError: true };
42316
+ }
42317
+ }
42318
+ );
42162
42319
  server.tool(
42163
42320
  "cron_delete",
42164
42321
  "Permanently remove a cron job. Throws if the job is not found.",
@@ -45172,6 +45329,11 @@ async function startHttpServer(opts) {
45172
45329
  pid: process.pid,
45173
45330
  node: process.execPath,
45174
45331
  entry: process.argv[1] ?? null,
45332
+ // The PATH the daemon captured at start (recap B4): doctor compares
45333
+ // it against the login shell's to diagnose "installed in your shell
45334
+ // but not visible to the daemon". Additive — older CLI readers
45335
+ // ignore the field, and it is absent when a daemon predates it.
45336
+ path: process.env["PATH"] ?? null,
45175
45337
  resumeSessionsOnBoot: opts.meta.resumeSessionsOnBoot === true,
45176
45338
  continueInterruptedOnBoot: opts.meta.continueInterruptedOnBoot === true,
45177
45339
  idleReapAfterMs: opts.meta.idleReapAfterMs ?? 0,
@@ -50270,6 +50432,22 @@ async function handleCron(req, res, path, scheduler) {
50270
50432
  json3(200, { jobs: scheduler.list() });
50271
50433
  return true;
50272
50434
  }
50435
+ if (path === "/cron/runs" && req.method === "GET") {
50436
+ const params = new URL(req.url ?? "/", "http://localhost").searchParams;
50437
+ const rawLimit = params.get("limit");
50438
+ const limit = rawLimit === null ? void 0 : Number(rawLimit);
50439
+ try {
50440
+ json3(200, scheduler.runs({
50441
+ jobId: params.get("jobId") ?? void 0,
50442
+ limit,
50443
+ cursor: params.get("cursor") ?? void 0
50444
+ }));
50445
+ } catch (err) {
50446
+ const message = err instanceof Error ? err.message : String(err);
50447
+ json3(message.includes("not found") ? 404 : 400, { error: "runs_failed", message });
50448
+ }
50449
+ return true;
50450
+ }
50273
50451
  if (path === "/cron" && req.method === "POST") {
50274
50452
  const body = await readJsonBody2(req);
50275
50453
  if (!body || typeof body !== "object") {
@@ -50291,6 +50469,7 @@ async function handleCron(req, res, path, scheduler) {
50291
50469
  const job = await scheduler.create({
50292
50470
  label: typeof b.label === "string" ? b.label : void 0,
50293
50471
  schedule,
50472
+ timezone: typeof b.timezone === "string" ? b.timezone : void 0,
50294
50473
  recurring: typeof b.recurring === "boolean" ? b.recurring : true,
50295
50474
  action
50296
50475
  });
@@ -50338,6 +50517,27 @@ async function handleCron(req, res, path, scheduler) {
50338
50517
  }
50339
50518
  return true;
50340
50519
  }
50520
+ if (req.method === "PATCH") {
50521
+ const body = await readJsonBody2(req);
50522
+ if (!body || typeof body !== "object" || Array.isArray(body)) {
50523
+ json3(400, { error: "invalid_body" });
50524
+ return true;
50525
+ }
50526
+ const b = body;
50527
+ const allowed = /* @__PURE__ */ new Set(["schedule", "label", "timezone", "recurring", "active", "action"]);
50528
+ if (Object.keys(b).some((key) => !allowed.has(key)) || b.schedule !== void 0 && (typeof b.schedule !== "string" || !b.schedule) || b.label !== void 0 && b.label !== null && typeof b.label !== "string" || b.timezone !== void 0 && b.timezone !== null && typeof b.timezone !== "string" || b.recurring !== void 0 && typeof b.recurring !== "boolean" || b.active !== void 0 && typeof b.active !== "boolean" || b.action !== void 0 && (!b.action || typeof b.action !== "object" || Array.isArray(b.action))) {
50529
+ json3(400, { error: "invalid_body" });
50530
+ return true;
50531
+ }
50532
+ try {
50533
+ const job = await scheduler.update(jobId, b);
50534
+ json3(200, job);
50535
+ } catch (err) {
50536
+ const message = err instanceof Error ? err.message : String(err);
50537
+ json3(message.includes("not found") ? 404 : 400, { error: "update_failed", message });
50538
+ }
50539
+ return true;
50540
+ }
50341
50541
  return false;
50342
50542
  }
50343
50543
  async function handleRoutineDefs(req, res, path, registrar) {
@@ -61604,6 +61804,6 @@ var export_readPairingsSnapshot = pairing_registry_exports.readPairingsSnapshot;
61604
61804
  var export_removeProviderKey = providers_store_exports.removeProviderKey;
61605
61805
  var export_setProviderKey = providers_store_exports.setProviderKey;
61606
61806
 
61607
- export { AnthropicRemainingQuotaReader, AuthResolutionError, BUCKETS_ROOT, CLAUDE_CODE_OAUTH_SOURCE, CONTINUE_PROMPT_SOURCE, DEAD_SESSION_STATUSES, DEFAULT_ALWAYS_ON_TOOLS, DEFAULT_BUCKET, DEFAULT_CONTINUE_PROMPT, DEFAULT_HOST_LOAD_BUDGET_MS, DEFAULT_HOST_LOAD_THRESHOLDS, DEFAULT_MODEL_ROLES, DEFAULT_ORCHESTRATOR_TOOLS, DEFAULT_WORKTREE_ISOLATION, DEFAULT_WORKTREE_PROVISION_CONCURRENCY, GC_REAPABLE_STATES, HOSTS_VERSION, HOST_SCOPE_HEADER, HarnessPresetValidationError, INBOUND_PROVIDERS, JOIN_TOKENS_VERSION, LEGACY_SESSIONS_FILE, MAX_AUTO_CONTINUE_ATTEMPTS, MAX_MESSAGE_DATA_BYTES, MCP_APP_BRIDGE_SCRIPT, MESSAGE_KINDS, MESSAGE_PREAMBLE, MESSAGE_TAG, MESSAGE_URGENCIES, MODEL_ROLE_REF_PREFIX, export_PAIRINGS_VERSION as PAIRINGS_VERSION, POSTURE_NATIVE_ALIASES, POSTURE_PREAMBLES, export_PROVIDER_ENV_VARS as PROVIDER_ENV_VARS, PrLookupError, ResumeDisabledError, SESSION_END_REASONS, SESSION_ID_ENV, SIGN_NAMESPACE, SubscriptionSourceError, TASK_STATUSES, WORKSPACE_SLUG_ENV, WORKTREE_ISOLATION_ENV, WORKTREE_PROVISION_CONCURRENCY_ENV, activityCounts, addHarnessPreset, allowedSignersLine, appendConversationRecord, attachSandbox, bucketDir, bucketSessionsFile, bucketTranscriptDir, buildCatalogModels, buildCatalogProviderModels, buildHostLoadReport, buildMcpConfigSnippet, buildRouteAwareLaunchConfig, canonicalForModeId, claudeProjectSlug, collectGcCandidates, collectHostSample, compactOutcome, composeMode, composeSessionObservers, composedFromRangeSha, computeHostWarnings, continueInterruptedSessions, continueSkipReason, conversationIndexPath, createActivityProjector, createDaemonReviewerHost, createDefaultHostProbes, createDeviceRegistry, createFileStepCache, createGateway, createHostLoadService, createHostRegistry, createInboundEndpointStore, createJoinTokenRegistry, createOrchestratorInjector, createOrchestratorMcpServerFactory, export_createPairingRegistry as createPairingRegistry, createPrProvenanceReconciler, createProcessStatsService, createReviewLaneExecutor, createReviewLedger, createReviewPackLoader, createReviewRunner, createScopeTokenRegistry, createSessionMessage, createSupervisorTaskGateRunner, createTaskLedger, createWorkspaceBrainSubscriber, createWorkspaceBrains, createWorkspaceFs, credentialFingerprint, daemonRegistryDir, decideWorktreeIsolation, declaredPresetToProviderPreset, decomposeMode, defaultBrowserAdapterIds, defaultBrowserAdapterResolution, defaultReviewKeysDir, defaultReviewLedgerRoot, defaultReviewPackCacheDir, defineBraveSearchHttpDriver, defineSerperHttpDriver, deleteUserPreset, deriveSessionOutcome, deriveSessionUsage, describeOwner, enrichRollupWithProviderQuota, enrichWithRemainingQuota, ensureReviewSigningKey, escapeHumanPrompt, escapeMessageBody, evaluateCostBudget, execGh, extractHelpSection, fetchPrStatus, fileConversationStore, fileExists3 as fileExists, filterActivities, findComposeCandidate, findConversationRecord, findNativeMode, findPrForCommit, formatToolCall, formatToolResult, getDefaultHarnessPreset, getHarnessPreset, getHostLoadService, getMcpCredentialDeps, getProcessStatsService, export_getProviderKey as getProviderKey, getToolHelp, getUserPreset, githubRepoOf, harnessPresetsPath, hostPlaceholders, injectMcpAppBridge, export_injectProviderKeysIntoEnv as injectProviderKeysIntoEnv, isAgentCliAuthConfigured, isClosedTaskStatus, isKnownSessionEndReason, isMessageAllowed, isProviderLimitError, isSafeBucketSlug, isTerminalActivityState, listBuckets, listHarnessPresets, listModelRoles, listPresets, listToolHelpTopics, listUserPresets, loadHarnessPresets, export_loadProviders as loadProviders, loadQuotaStore, loadUserPresets, loadWorkspaceModelRoles, loadWorktreeIsolation, locateConversationByNativePath, locateConversationBySessionId, makeBrowserAdapterLister, makeSandboxCredsStore, makeSandboxResolver, matchesMessageFilter, measureTool, measureToolList, messageFrom, migrateLegacySessionsFile, migrationMarkerPath, mintMessageId, monitorPolicyWait, monitorSessionWait, narrowOrchestratorTools, normalizeCommand, normalizeInbound, normalizeModeId, normalizeRemote, normalizeSkillsOption, normalizeWorktreeField, parseAnthropicRateLimitHeaders, parseDuration, parseModelRoleRef, parsePrUrl, parseTaskStatus, parseWindow, parseWorktreeIsolationMode, pickUsageDetail, policyToActivities, policyWatchesSession, prHeadSha, prToActivities, projectBrowserTools, projectSessionUsage, export_providerEnvVar as providerEnvVar, export_providersPath as providersPath, readConversationIndex, readDaemonRegistry, export_readPairingsSnapshot as readPairingsSnapshot, readProfileQuota, readRegisteredSlugs, readRuntimeMeta, readSandboxLedger, readSessionForBrain, readUsageSnapshots, reapGcEntry, reapOrphanedDescendants, reconcileSandboxLedger, recordProfileQuota, recordSandboxBoot, recordSandboxLiveness, recordSandboxOrigin, recordSandboxState, registerBrainTools, registerBuiltinRoutes, registerDeviceTools, registerPairingTools, registerReviewTools, registerSandboxAttachTool, registerWebSearchTools, removeHarnessPreset, export_removeProviderKey as removeProviderKey, removeSandboxLedgerEntry, renderInboxDigest, renderSessionMessage, renderSessionMessages, repoSlug, resolveAuthSpec, resolveBucketSlug, resolveDeferredToolsGatewayOption, resolveEffectiveLlmEndpointFlag, resolveModelRole, resolveNativeLink, resolvePosture, resolvePrincipal, resolveRelation, resolveReuseFromLedger, resolveReviewerPreset, resolveSpawnDefaults, resolveSubscriptionCredential, rollupSessionSubtree, rollupUsage, runContinueOnBootPass, runCrashDetectPass, runEagerResumePass, runIdleReapPass, runShellLane, runStallWatchdogPass, sandboxLedgerPath, sanitizeLabel, saveUserPreset, setDefaultPreset, setMcpCredentialDeps, export_setProviderKey as setProviderKey, signAttestation, sweepStaleDaemonRegistry, sweepStaleRuntimeMetas, toWorktreeStatusView, trackWorktreeProvision, turnToActivities, unlinkDaemonRegistryEntry, unlinkRuntimeMeta, updateHarnessPreset, upsertSandboxLedger, userPresetsPath, verifyInboundSignature, verifySignedAttestation, webSearchTool, withPr, withPrStatus, workflowToActivities, writeDaemonRegistryEntry };
61807
+ export { AnthropicRemainingQuotaReader, AuthResolutionError, BUCKETS_ROOT, CLAUDE_CODE_OAUTH_SOURCE, CONTINUE_PROMPT_SOURCE, DEAD_SESSION_STATUSES, DEFAULT_ALWAYS_ON_TOOLS, DEFAULT_BUCKET, DEFAULT_CONTINUE_PROMPT, DEFAULT_HOST_LOAD_BUDGET_MS, DEFAULT_HOST_LOAD_THRESHOLDS, DEFAULT_MODEL_ROLES, DEFAULT_ORCHESTRATOR_TOOLS, DEFAULT_WORKTREE_ISOLATION, DEFAULT_WORKTREE_PROVISION_CONCURRENCY, GC_REAPABLE_STATES, HOSTS_VERSION, HOST_HANDSHAKE_REMEDIATION_HINT, HOST_SCOPE_HEADER, HarnessPresetValidationError, INBOUND_PROVIDERS, JOIN_TOKENS_VERSION, LEGACY_SESSIONS_FILE, MAX_AUTO_CONTINUE_ATTEMPTS, MAX_MESSAGE_DATA_BYTES, MCP_APP_BRIDGE_SCRIPT, MESSAGE_KINDS, MESSAGE_PREAMBLE, MESSAGE_TAG, MESSAGE_URGENCIES, MODEL_ROLE_REF_PREFIX, export_PAIRINGS_VERSION as PAIRINGS_VERSION, POSTURE_NATIVE_ALIASES, POSTURE_PREAMBLES, export_PROVIDER_ENV_VARS as PROVIDER_ENV_VARS, PrLookupError, ResumeDisabledError, SESSION_END_REASONS, SESSION_ID_ENV, SIGN_NAMESPACE, SubscriptionSourceError, TASK_STATUSES, WORKSPACE_SLUG_ENV, WORKTREE_ISOLATION_ENV, WORKTREE_PROVISION_CONCURRENCY_ENV, activityCounts, addHarnessPreset, allowedSignersLine, appendConversationRecord, attachSandbox, bucketDir, bucketSessionsFile, bucketTranscriptDir, buildCatalogModels, buildCatalogProviderModels, buildHostLoadReport, buildMcpConfigSnippet, buildRouteAwareLaunchConfig, canonicalForModeId, claudeProjectSlug, collectGcCandidates, collectHostSample, compactOutcome, composeMode, composeSessionObservers, composedFromRangeSha, computeHostWarnings, continueInterruptedSessions, continueSkipReason, conversationIndexPath, createActivityProjector, createDaemonReviewerHost, createDefaultHostProbes, createDeviceRegistry, createFileStepCache, createGateway, createHostLoadService, createHostRegistry, createInboundEndpointStore, createJoinTokenRegistry, createOrchestratorInjector, createOrchestratorMcpServerFactory, export_createPairingRegistry as createPairingRegistry, createPrProvenanceReconciler, createProcessStatsService, createReviewLaneExecutor, createReviewLedger, createReviewPackLoader, createReviewRunner, createScopeTokenRegistry, createSessionMessage, createSupervisorTaskGateRunner, createTaskLedger, createWorkspaceBrainSubscriber, createWorkspaceBrains, createWorkspaceFs, credentialFingerprint, daemonRegistryDir, decideWorktreeIsolation, declaredPresetToProviderPreset, decomposeMode, defaultBrowserAdapterIds, defaultBrowserAdapterResolution, defaultReviewKeysDir, defaultReviewLedgerRoot, defaultReviewPackCacheDir, defineBraveSearchHttpDriver, defineSerperHttpDriver, deleteUserPreset, deriveSessionOutcome, deriveSessionUsage, describeOwner, enrichRollupWithProviderQuota, enrichWithRemainingQuota, ensureReviewSigningKey, escapeHumanPrompt, escapeMessageBody, evaluateCostBudget, execGh, extractHelpSection, fetchPrStatus, fileConversationStore, fileExists3 as fileExists, filterActivities, findComposeCandidate, findConversationRecord, findNativeMode, findPrForCommit, formatToolCall, formatToolResult, getDefaultHarnessPreset, getHarnessPreset, getHostLoadService, getMcpCredentialDeps, getProcessStatsService, export_getProviderKey as getProviderKey, getToolHelp, getUserPreset, githubRepoOf, harnessPresetsPath, hostPlaceholders, injectMcpAppBridge, export_injectProviderKeysIntoEnv as injectProviderKeysIntoEnv, isAgentCliAuthConfigured, isClosedTaskStatus, isKnownSessionEndReason, isMessageAllowed, isProviderLimitError, isSafeBucketSlug, isTerminalActivityState, listBuckets, listHarnessPresets, listModelRoles, listPresets, listToolHelpTopics, listUserPresets, loadHarnessPresets, export_loadProviders as loadProviders, loadQuotaStore, loadUserPresets, loadWorkspaceModelRoles, loadWorktreeIsolation, locateConversationByNativePath, locateConversationBySessionId, makeBrowserAdapterLister, makeSandboxCredsStore, makeSandboxResolver, matchesMessageFilter, measureTool, measureToolList, messageFrom, migrateLegacySessionsFile, migrationMarkerPath, mintMessageId, monitorPolicyWait, monitorSessionWait, narrowOrchestratorTools, normalizeCommand, normalizeInbound, normalizeModeId, normalizeRemote, normalizeSkillsOption, normalizeWorktreeField, parseAnthropicRateLimitHeaders, parseDuration, parseModelRoleRef, parsePrUrl, parseTaskStatus, parseWindow, parseWorktreeIsolationMode, pickUsageDetail, policyToActivities, policyWatchesSession, prHeadSha, prToActivities, projectBrowserTools, projectSessionUsage, export_providerEnvVar as providerEnvVar, export_providersPath as providersPath, readConversationIndex, readDaemonRegistry, readHostsSnapshot, export_readPairingsSnapshot as readPairingsSnapshot, readProfileQuota, readRegisteredSlugs, readRuntimeMeta, readSandboxLedger, readSessionForBrain, readUsageSnapshots, reapGcEntry, reapOrphanedDescendants, reconcileSandboxLedger, recordProfileQuota, recordSandboxBoot, recordSandboxLiveness, recordSandboxOrigin, recordSandboxState, registerBrainTools, registerBuiltinRoutes, registerDeviceTools, registerPairingTools, registerReviewTools, registerSandboxAttachTool, registerWebSearchTools, removeHarnessPreset, export_removeProviderKey as removeProviderKey, removeSandboxLedgerEntry, renderInboxDigest, renderSessionMessage, renderSessionMessages, repoSlug, resolveAuthSpec, resolveBucketSlug, resolveDeferredToolsGatewayOption, resolveEffectiveLlmEndpointFlag, resolveModelRole, resolveNativeLink, resolvePosture, resolvePrincipal, resolveRelation, resolveReuseFromLedger, resolveReviewerPreset, resolveSpawnDefaults, resolveSubscriptionCredential, rollupSessionSubtree, rollupUsage, runContinueOnBootPass, runCrashDetectPass, runEagerResumePass, runIdleReapPass, runShellLane, runStallWatchdogPass, sandboxLedgerPath, sanitizeLabel, saveUserPreset, setDefaultPreset, setMcpCredentialDeps, export_setProviderKey as setProviderKey, signAttestation, sweepStaleDaemonRegistry, sweepStaleRuntimeMetas, toWorktreeStatusView, trackWorktreeProvision, turnToActivities, unlinkDaemonRegistryEntry, unlinkRuntimeMeta, updateHarnessPreset, upsertSandboxLedger, userPresetsPath, verifyInboundSignature, verifySignedAttestation, webSearchTool, withPr, withPrStatus, workflowToActivities, writeDaemonRegistryEntry };
61608
61808
  //# sourceMappingURL=index.mjs.map
61609
61809
  //# sourceMappingURL=index.mjs.map