aiden-runtime 4.1.5 → 4.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.
Files changed (163) hide show
  1. package/README.md +250 -847
  2. package/dist/api/server.js +32 -5
  3. package/dist/cli/v4/aidenCLI.js +351 -53
  4. package/dist/cli/v4/callbacks.js +170 -0
  5. package/dist/cli/v4/chatSession.js +138 -3
  6. package/dist/cli/v4/commands/_runtimeToggleHelpers.js +92 -0
  7. package/dist/cli/v4/commands/browserDepth.js +45 -0
  8. package/dist/cli/v4/commands/cron.js +264 -0
  9. package/dist/cli/v4/commands/daemon.js +541 -0
  10. package/dist/cli/v4/commands/daemonStatus.js +253 -0
  11. package/dist/cli/v4/commands/help.js +7 -0
  12. package/dist/cli/v4/commands/index.js +20 -1
  13. package/dist/cli/v4/commands/runs.js +203 -0
  14. package/dist/cli/v4/commands/sandbox.js +48 -0
  15. package/dist/cli/v4/commands/suggestions.js +68 -0
  16. package/dist/cli/v4/commands/tce.js +41 -0
  17. package/dist/cli/v4/commands/trigger.js +378 -0
  18. package/dist/cli/v4/commands/update.js +95 -3
  19. package/dist/cli/v4/daemonAgentBuilder.js +142 -0
  20. package/dist/cli/v4/defaultSoul.js +1 -1
  21. package/dist/cli/v4/display/capabilityCard.js +26 -0
  22. package/dist/cli/v4/display.js +18 -8
  23. package/dist/cli/v4/replyRenderer.js +31 -23
  24. package/dist/cli/v4/updateBootPrompt.js +170 -0
  25. package/dist/core/playwrightBridge.js +129 -0
  26. package/dist/core/v4/aidenAgent.js +308 -4
  27. package/dist/core/v4/browserState.js +436 -0
  28. package/dist/core/v4/checkpoint.js +79 -0
  29. package/dist/core/v4/daemon/bootstrap.js +604 -0
  30. package/dist/core/v4/daemon/cleanShutdown.js +154 -0
  31. package/dist/core/v4/daemon/cron/cronBridge.js +126 -0
  32. package/dist/core/v4/daemon/cron/cronEmitter.js +173 -0
  33. package/dist/core/v4/daemon/cron/migration.js +199 -0
  34. package/dist/core/v4/daemon/cron/misfirePolicy.js +115 -0
  35. package/dist/core/v4/daemon/daemonConfig.js +90 -0
  36. package/dist/core/v4/daemon/db/connection.js +106 -0
  37. package/dist/core/v4/daemon/db/migrations.js +296 -0
  38. package/dist/core/v4/daemon/db/schema/v1.spec.js +18 -0
  39. package/dist/core/v4/daemon/dispatcher/agentRunner.js +98 -0
  40. package/dist/core/v4/daemon/dispatcher/budgetGate.js +127 -0
  41. package/dist/core/v4/daemon/dispatcher/daemonApproval.js +113 -0
  42. package/dist/core/v4/daemon/dispatcher/dailyBudgetTracker.js +120 -0
  43. package/dist/core/v4/daemon/dispatcher/dispatcher.js +389 -0
  44. package/dist/core/v4/daemon/dispatcher/fireRateLimiter.js +113 -0
  45. package/dist/core/v4/daemon/dispatcher/index.js +53 -0
  46. package/dist/core/v4/daemon/dispatcher/promptTemplate.js +95 -0
  47. package/dist/core/v4/daemon/dispatcher/realAgentRunner.js +356 -0
  48. package/dist/core/v4/daemon/dispatcher/resolveModel.js +93 -0
  49. package/dist/core/v4/daemon/dispatcher/sessionId.js +93 -0
  50. package/dist/core/v4/daemon/drain.js +156 -0
  51. package/dist/core/v4/daemon/eventLoopLag.js +73 -0
  52. package/dist/core/v4/daemon/health.js +159 -0
  53. package/dist/core/v4/daemon/idempotencyStore.js +204 -0
  54. package/dist/core/v4/daemon/index.js +179 -0
  55. package/dist/core/v4/daemon/instanceTracker.js +99 -0
  56. package/dist/core/v4/daemon/resourceRegistry.js +150 -0
  57. package/dist/core/v4/daemon/restartCode.js +32 -0
  58. package/dist/core/v4/daemon/restartFailureCounter.js +77 -0
  59. package/dist/core/v4/daemon/runStore.js +114 -0
  60. package/dist/core/v4/daemon/runtimeLock.js +167 -0
  61. package/dist/core/v4/daemon/signals.js +50 -0
  62. package/dist/core/v4/daemon/supervisor.js +272 -0
  63. package/dist/core/v4/daemon/triggerBus.js +279 -0
  64. package/dist/core/v4/daemon/triggers/email/allowlist.js +70 -0
  65. package/dist/core/v4/daemon/triggers/email/automatedSender.js +78 -0
  66. package/dist/core/v4/daemon/triggers/email/bodyExtractor.js +0 -0
  67. package/dist/core/v4/daemon/triggers/email/emailSeenStore.js +99 -0
  68. package/dist/core/v4/daemon/triggers/email/emailSpec.js +107 -0
  69. package/dist/core/v4/daemon/triggers/email/imapConnection.js +211 -0
  70. package/dist/core/v4/daemon/triggers/email/index.js +332 -0
  71. package/dist/core/v4/daemon/triggers/email/seenUids.js +60 -0
  72. package/dist/core/v4/daemon/triggers/fileObservationsStore.js +93 -0
  73. package/dist/core/v4/daemon/triggers/fileWatcher.js +253 -0
  74. package/dist/core/v4/daemon/triggers/fileWatcherSpec.js +88 -0
  75. package/dist/core/v4/daemon/triggers/fsIdentity.js +42 -0
  76. package/dist/core/v4/daemon/triggers/globMatcher.js +100 -0
  77. package/dist/core/v4/daemon/triggers/reconcile.js +206 -0
  78. package/dist/core/v4/daemon/triggers/settleStat.js +81 -0
  79. package/dist/core/v4/daemon/triggers/webhook.js +376 -0
  80. package/dist/core/v4/daemon/triggers/webhookDeliveriesStore.js +109 -0
  81. package/dist/core/v4/daemon/triggers/webhookIdempotency.js +72 -0
  82. package/dist/core/v4/daemon/triggers/webhookRateLimit.js +56 -0
  83. package/dist/core/v4/daemon/triggers/webhookSpec.js +76 -0
  84. package/dist/core/v4/daemon/triggers/webhookVerifier.js +128 -0
  85. package/dist/core/v4/daemon/types.js +15 -0
  86. package/dist/core/v4/dockerSession.js +461 -0
  87. package/dist/core/v4/dryRun.js +117 -0
  88. package/dist/core/v4/failureClassifier.js +779 -0
  89. package/dist/core/v4/recoveryReport.js +449 -0
  90. package/dist/core/v4/runtimeToggles.js +187 -0
  91. package/dist/core/v4/sandboxConfig.js +285 -0
  92. package/dist/core/v4/sandboxFs.js +316 -0
  93. package/dist/core/v4/suggestionCatalog.js +41 -0
  94. package/dist/core/v4/suggestionEngine.js +210 -0
  95. package/dist/core/v4/toolRegistry.js +18 -0
  96. package/dist/core/v4/turnState.js +587 -0
  97. package/dist/core/v4/update/checkUpdate.js +63 -3
  98. package/dist/core/v4/update/installMethodDetect.js +115 -0
  99. package/dist/core/v4/update/registryClient.js +121 -0
  100. package/dist/core/v4/update/skipState.js +75 -0
  101. package/dist/core/v4/verifier.js +448 -0
  102. package/dist/core/version.js +1 -1
  103. package/dist/tools/v4/browser/_observer.js +224 -0
  104. package/dist/tools/v4/browser/browserBlocker.js +396 -0
  105. package/dist/tools/v4/browser/browserClick.js +18 -1
  106. package/dist/tools/v4/browser/browserClose.js +18 -1
  107. package/dist/tools/v4/browser/browserExtract.js +5 -1
  108. package/dist/tools/v4/browser/browserFill.js +17 -1
  109. package/dist/tools/v4/browser/browserGetUrl.js +5 -1
  110. package/dist/tools/v4/browser/browserNavigate.js +16 -1
  111. package/dist/tools/v4/browser/browserScreenshot.js +5 -1
  112. package/dist/tools/v4/browser/browserScroll.js +18 -1
  113. package/dist/tools/v4/browser/browserType.js +17 -1
  114. package/dist/tools/v4/browser/captchaCheck.js +5 -1
  115. package/dist/tools/v4/executeCode.js +1 -0
  116. package/dist/tools/v4/files/fileCopy.js +56 -2
  117. package/dist/tools/v4/files/fileDelete.js +38 -1
  118. package/dist/tools/v4/files/fileList.js +12 -1
  119. package/dist/tools/v4/files/fileMove.js +59 -2
  120. package/dist/tools/v4/files/filePatch.js +43 -1
  121. package/dist/tools/v4/files/fileRead.js +12 -1
  122. package/dist/tools/v4/files/fileWrite.js +41 -1
  123. package/dist/tools/v4/index.js +71 -58
  124. package/dist/tools/v4/memory/memoryAdd.js +14 -0
  125. package/dist/tools/v4/memory/memoryRemove.js +14 -0
  126. package/dist/tools/v4/memory/memoryReplace.js +15 -0
  127. package/dist/tools/v4/memory/sessionSummary.js +12 -0
  128. package/dist/tools/v4/process/processKill.js +19 -0
  129. package/dist/tools/v4/process/processList.js +1 -0
  130. package/dist/tools/v4/process/processLogRead.js +1 -0
  131. package/dist/tools/v4/process/processSpawn.js +13 -0
  132. package/dist/tools/v4/process/processWait.js +1 -0
  133. package/dist/tools/v4/sessions/recallSession.js +1 -0
  134. package/dist/tools/v4/sessions/sessionList.js +1 -0
  135. package/dist/tools/v4/sessions/sessionSearch.js +1 -0
  136. package/dist/tools/v4/skills/lookupToolSchema.js +2 -0
  137. package/dist/tools/v4/skills/skillManage.js +13 -0
  138. package/dist/tools/v4/skills/skillView.js +1 -0
  139. package/dist/tools/v4/skills/skillsList.js +1 -0
  140. package/dist/tools/v4/subagent/subagentFanout.js +1 -0
  141. package/dist/tools/v4/system/aidenSelfUpdate.js +16 -0
  142. package/dist/tools/v4/system/appClose.js +13 -0
  143. package/dist/tools/v4/system/appInput.js +13 -0
  144. package/dist/tools/v4/system/appLaunch.js +13 -0
  145. package/dist/tools/v4/system/clipboardRead.js +1 -0
  146. package/dist/tools/v4/system/clipboardWrite.js +14 -0
  147. package/dist/tools/v4/system/mediaKey.js +12 -0
  148. package/dist/tools/v4/system/mediaSessions.js +1 -0
  149. package/dist/tools/v4/system/mediaTransport.js +13 -0
  150. package/dist/tools/v4/system/naturalEvents.js +1 -0
  151. package/dist/tools/v4/system/nowPlaying.js +1 -0
  152. package/dist/tools/v4/system/osProcessList.js +1 -0
  153. package/dist/tools/v4/system/screenshot.js +1 -0
  154. package/dist/tools/v4/system/systemInfo.js +1 -0
  155. package/dist/tools/v4/system/volumeSet.js +17 -0
  156. package/dist/tools/v4/terminal/shellExec.js +81 -9
  157. package/dist/tools/v4/web/deepResearch.js +1 -0
  158. package/dist/tools/v4/web/openUrl.js +1 -0
  159. package/dist/tools/v4/web/webFetch.js +1 -0
  160. package/dist/tools/v4/web/webPage.js +1 -0
  161. package/dist/tools/v4/web/webSearch.js +1 -0
  162. package/dist/tools/v4/web/youtubeSearch.js +1 -0
  163. package/package.json +7 -1
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 Shiva Deore (Taracod).
4
+ * Licensed under AGPL-3.0. See LICENSE for details.
5
+ *
6
+ * Aiden — local-first agent.
7
+ */
8
+ /**
9
+ * core/v4/daemon/index.ts — v4.5 Phase 1: barrel exports for the
10
+ * daemon foundation.
11
+ *
12
+ * Phase 1 ships the foundation; Phases 2-6 add file watcher,
13
+ * webhook, email, scheduler-migration, integration, default-on.
14
+ *
15
+ * Public surface (re-exported here so callers do
16
+ * `import { ... } from '@/core/v4/daemon'` instead of subpath
17
+ * imports for the common operations):
18
+ *
19
+ * - configuration + paths
20
+ * - SQLite handle + migrations
21
+ * - runtime lock + instance tracker
22
+ * - clean-shutdown marker + restart-failure counter
23
+ * - trigger bus + idempotency store + run store
24
+ * - resource registry
25
+ * - supervisor + service template generators
26
+ * - drain + signal handlers
27
+ * - health + metrics endpoint mounter
28
+ * - event loop lag sampler
29
+ *
30
+ * Side-effect imports (modules that install global state) are NOT
31
+ * re-exported here — those must be invoked explicitly during
32
+ * daemon boot.
33
+ */
34
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
35
+ if (k2 === undefined) k2 = k;
36
+ var desc = Object.getOwnPropertyDescriptor(m, k);
37
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
38
+ desc = { enumerable: true, get: function() { return m[k]; } };
39
+ }
40
+ Object.defineProperty(o, k2, desc);
41
+ }) : (function(o, m, k, k2) {
42
+ if (k2 === undefined) k2 = k;
43
+ o[k2] = m[k];
44
+ }));
45
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
46
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
47
+ };
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ exports.reconcileFileWatcher = exports.createFileObservationsStore = exports.DEFAULT_FILE_WATCHER_SPEC = exports.parseFileWatcherSpec = exports.createFileWatcher = exports._resetDaemonBootstrapForTests = exports.getDaemonHandle = exports.bootstrapDaemon = exports._resetDaemonSignalHandlersForTests = exports.installDaemonSignalHandlers = exports._resetDrainStateForTests = exports.isDraining = exports.signalToReason = exports.performDrain = exports.windowsServiceGuidance = exports.generateLaunchdPlist = exports.generateSystemdUnit = exports.startSupervisor = exports._resetResourceRegistryForTests = exports.createResourceRegistry = exports.getResourceRegistry = exports.createRunStore = exports.IDEMPOTENCY_DEFAULT_TTL_MS = exports.createIdempotencyStore = exports.DEFAULT_MAX_ATTEMPTS = exports.DEFAULT_CLAIM_LEASE_MS = exports.createTriggerBus = exports.DEFAULT_STUCK_LOOP_THRESHOLD = exports.createRestartFailureCounter = exports.evaluateBootState = exports.consumeCleanShutdownMarker = exports.isCleanShutdown = exports.touchCleanShutdownMarker = exports.createInstanceTracker = exports.DaemonAlreadyRunningError = exports.acquireRuntimeLock = exports.LATEST_SCHEMA_VERSION = exports.runMigrations = exports._closeAllDaemonDbsForTests = exports.closeDaemonDb = exports.openDaemonDb = exports._resetDaemonConfigForTests = exports.getHostname = exports.daemonCleanShutdownMarkerPath = exports.daemonRuntimeLockPath = exports.daemonDbPath = exports.daemonDir = exports.readDaemonConfig = exports.getDaemonConfig = exports.DAEMON_RESTART_EXIT_CODE = void 0;
50
+ exports.evaluateDegraded = exports.mountHealthEndpoints = exports.isEventLoopResponsive = exports.getLastTickAt = exports.getEventLoopLagMs = exports.stopEventLoopLagSampler = exports.startEventLoopLagSampler = exports.BACKOFF_CONSTANTS = exports.nextBackoffMs = exports.createImapConnection = exports.extractEmailBody = exports.createEmailSeenStore = exports.DEFAULT_MAX_SEEN_UIDS = exports.createSeenUids = exports.compileSenderAllowlist = exports.AUTOMATED_HEADERS = exports.NOREPLY_PATTERNS = exports.isAutomatedSender = exports.DEFAULT_IMAP = exports.DEFAULT_EMAIL_SPEC = exports.parseEmailSpec = exports.createEmailTrigger = exports.createWebhookDeliveriesStore = exports.deriveIdempotencyKey = exports.createRateLimiter = exports.deriveEventName = exports.verifyWebhookSignature = exports.INSECURE_NO_AUTH = exports.DEFAULT_WEBHOOK_SPEC = exports.parseWebhookSpec = exports.assertSafeBind = exports.mountWebhookRoutes = exports.computeFileKey = exports.settleStat = exports.DEFAULT_IGNORE_PATTERNS = exports.compileGlobMatcher = void 0;
51
+ var restartCode_1 = require("./restartCode");
52
+ Object.defineProperty(exports, "DAEMON_RESTART_EXIT_CODE", { enumerable: true, get: function () { return restartCode_1.DAEMON_RESTART_EXIT_CODE; } });
53
+ var daemonConfig_1 = require("./daemonConfig");
54
+ Object.defineProperty(exports, "getDaemonConfig", { enumerable: true, get: function () { return daemonConfig_1.getDaemonConfig; } });
55
+ Object.defineProperty(exports, "readDaemonConfig", { enumerable: true, get: function () { return daemonConfig_1.readDaemonConfig; } });
56
+ Object.defineProperty(exports, "daemonDir", { enumerable: true, get: function () { return daemonConfig_1.daemonDir; } });
57
+ Object.defineProperty(exports, "daemonDbPath", { enumerable: true, get: function () { return daemonConfig_1.daemonDbPath; } });
58
+ Object.defineProperty(exports, "daemonRuntimeLockPath", { enumerable: true, get: function () { return daemonConfig_1.daemonRuntimeLockPath; } });
59
+ Object.defineProperty(exports, "daemonCleanShutdownMarkerPath", { enumerable: true, get: function () { return daemonConfig_1.daemonCleanShutdownMarkerPath; } });
60
+ Object.defineProperty(exports, "getHostname", { enumerable: true, get: function () { return daemonConfig_1.getHostname; } });
61
+ Object.defineProperty(exports, "_resetDaemonConfigForTests", { enumerable: true, get: function () { return daemonConfig_1._resetDaemonConfigForTests; } });
62
+ __exportStar(require("./types"), exports);
63
+ var connection_1 = require("./db/connection");
64
+ Object.defineProperty(exports, "openDaemonDb", { enumerable: true, get: function () { return connection_1.openDaemonDb; } });
65
+ Object.defineProperty(exports, "closeDaemonDb", { enumerable: true, get: function () { return connection_1.closeDaemonDb; } });
66
+ Object.defineProperty(exports, "_closeAllDaemonDbsForTests", { enumerable: true, get: function () { return connection_1._closeAllDaemonDbsForTests; } });
67
+ var migrations_1 = require("./db/migrations");
68
+ Object.defineProperty(exports, "runMigrations", { enumerable: true, get: function () { return migrations_1.runMigrations; } });
69
+ Object.defineProperty(exports, "LATEST_SCHEMA_VERSION", { enumerable: true, get: function () { return migrations_1.LATEST_SCHEMA_VERSION; } });
70
+ var runtimeLock_1 = require("./runtimeLock");
71
+ Object.defineProperty(exports, "acquireRuntimeLock", { enumerable: true, get: function () { return runtimeLock_1.acquireRuntimeLock; } });
72
+ Object.defineProperty(exports, "DaemonAlreadyRunningError", { enumerable: true, get: function () { return runtimeLock_1.DaemonAlreadyRunningError; } });
73
+ var instanceTracker_1 = require("./instanceTracker");
74
+ Object.defineProperty(exports, "createInstanceTracker", { enumerable: true, get: function () { return instanceTracker_1.createInstanceTracker; } });
75
+ var cleanShutdown_1 = require("./cleanShutdown");
76
+ Object.defineProperty(exports, "touchCleanShutdownMarker", { enumerable: true, get: function () { return cleanShutdown_1.touchCleanShutdownMarker; } });
77
+ Object.defineProperty(exports, "isCleanShutdown", { enumerable: true, get: function () { return cleanShutdown_1.isCleanShutdown; } });
78
+ Object.defineProperty(exports, "consumeCleanShutdownMarker", { enumerable: true, get: function () { return cleanShutdown_1.consumeCleanShutdownMarker; } });
79
+ Object.defineProperty(exports, "evaluateBootState", { enumerable: true, get: function () { return cleanShutdown_1.evaluateBootState; } });
80
+ var restartFailureCounter_1 = require("./restartFailureCounter");
81
+ Object.defineProperty(exports, "createRestartFailureCounter", { enumerable: true, get: function () { return restartFailureCounter_1.createRestartFailureCounter; } });
82
+ Object.defineProperty(exports, "DEFAULT_STUCK_LOOP_THRESHOLD", { enumerable: true, get: function () { return restartFailureCounter_1.DEFAULT_STUCK_LOOP_THRESHOLD; } });
83
+ var triggerBus_1 = require("./triggerBus");
84
+ Object.defineProperty(exports, "createTriggerBus", { enumerable: true, get: function () { return triggerBus_1.createTriggerBus; } });
85
+ Object.defineProperty(exports, "DEFAULT_CLAIM_LEASE_MS", { enumerable: true, get: function () { return triggerBus_1.DEFAULT_CLAIM_LEASE_MS; } });
86
+ Object.defineProperty(exports, "DEFAULT_MAX_ATTEMPTS", { enumerable: true, get: function () { return triggerBus_1.DEFAULT_MAX_ATTEMPTS; } });
87
+ var idempotencyStore_1 = require("./idempotencyStore");
88
+ Object.defineProperty(exports, "createIdempotencyStore", { enumerable: true, get: function () { return idempotencyStore_1.createIdempotencyStore; } });
89
+ Object.defineProperty(exports, "IDEMPOTENCY_DEFAULT_TTL_MS", { enumerable: true, get: function () { return idempotencyStore_1.DEFAULT_TTL_MS; } });
90
+ var runStore_1 = require("./runStore");
91
+ Object.defineProperty(exports, "createRunStore", { enumerable: true, get: function () { return runStore_1.createRunStore; } });
92
+ var resourceRegistry_1 = require("./resourceRegistry");
93
+ Object.defineProperty(exports, "getResourceRegistry", { enumerable: true, get: function () { return resourceRegistry_1.getResourceRegistry; } });
94
+ Object.defineProperty(exports, "createResourceRegistry", { enumerable: true, get: function () { return resourceRegistry_1.createResourceRegistry; } });
95
+ Object.defineProperty(exports, "_resetResourceRegistryForTests", { enumerable: true, get: function () { return resourceRegistry_1._resetResourceRegistryForTests; } });
96
+ var supervisor_1 = require("./supervisor");
97
+ Object.defineProperty(exports, "startSupervisor", { enumerable: true, get: function () { return supervisor_1.startSupervisor; } });
98
+ Object.defineProperty(exports, "generateSystemdUnit", { enumerable: true, get: function () { return supervisor_1.generateSystemdUnit; } });
99
+ Object.defineProperty(exports, "generateLaunchdPlist", { enumerable: true, get: function () { return supervisor_1.generateLaunchdPlist; } });
100
+ Object.defineProperty(exports, "windowsServiceGuidance", { enumerable: true, get: function () { return supervisor_1.windowsServiceGuidance; } });
101
+ var drain_1 = require("./drain");
102
+ Object.defineProperty(exports, "performDrain", { enumerable: true, get: function () { return drain_1.performDrain; } });
103
+ Object.defineProperty(exports, "signalToReason", { enumerable: true, get: function () { return drain_1.signalToReason; } });
104
+ Object.defineProperty(exports, "isDraining", { enumerable: true, get: function () { return drain_1.isDraining; } });
105
+ Object.defineProperty(exports, "_resetDrainStateForTests", { enumerable: true, get: function () { return drain_1._resetDrainStateForTests; } });
106
+ var signals_1 = require("./signals");
107
+ Object.defineProperty(exports, "installDaemonSignalHandlers", { enumerable: true, get: function () { return signals_1.installDaemonSignalHandlers; } });
108
+ Object.defineProperty(exports, "_resetDaemonSignalHandlersForTests", { enumerable: true, get: function () { return signals_1._resetDaemonSignalHandlersForTests; } });
109
+ var bootstrap_1 = require("./bootstrap");
110
+ Object.defineProperty(exports, "bootstrapDaemon", { enumerable: true, get: function () { return bootstrap_1.bootstrapDaemon; } });
111
+ Object.defineProperty(exports, "getDaemonHandle", { enumerable: true, get: function () { return bootstrap_1.getDaemonHandle; } });
112
+ Object.defineProperty(exports, "_resetDaemonBootstrapForTests", { enumerable: true, get: function () { return bootstrap_1._resetDaemonBootstrapForTests; } });
113
+ // ── v4.5 Phase 2 — file-watcher trigger ──────────────────────────────────
114
+ var fileWatcher_1 = require("./triggers/fileWatcher");
115
+ Object.defineProperty(exports, "createFileWatcher", { enumerable: true, get: function () { return fileWatcher_1.createFileWatcher; } });
116
+ var fileWatcherSpec_1 = require("./triggers/fileWatcherSpec");
117
+ Object.defineProperty(exports, "parseFileWatcherSpec", { enumerable: true, get: function () { return fileWatcherSpec_1.parseFileWatcherSpec; } });
118
+ Object.defineProperty(exports, "DEFAULT_FILE_WATCHER_SPEC", { enumerable: true, get: function () { return fileWatcherSpec_1.DEFAULT_FILE_WATCHER_SPEC; } });
119
+ var fileObservationsStore_1 = require("./triggers/fileObservationsStore");
120
+ Object.defineProperty(exports, "createFileObservationsStore", { enumerable: true, get: function () { return fileObservationsStore_1.createFileObservationsStore; } });
121
+ var reconcile_1 = require("./triggers/reconcile");
122
+ Object.defineProperty(exports, "reconcileFileWatcher", { enumerable: true, get: function () { return reconcile_1.reconcileFileWatcher; } });
123
+ var globMatcher_1 = require("./triggers/globMatcher");
124
+ Object.defineProperty(exports, "compileGlobMatcher", { enumerable: true, get: function () { return globMatcher_1.compileGlobMatcher; } });
125
+ Object.defineProperty(exports, "DEFAULT_IGNORE_PATTERNS", { enumerable: true, get: function () { return globMatcher_1.DEFAULT_IGNORE_PATTERNS; } });
126
+ var settleStat_1 = require("./triggers/settleStat");
127
+ Object.defineProperty(exports, "settleStat", { enumerable: true, get: function () { return settleStat_1.settleStat; } });
128
+ var fsIdentity_1 = require("./triggers/fsIdentity");
129
+ Object.defineProperty(exports, "computeFileKey", { enumerable: true, get: function () { return fsIdentity_1.computeFileKey; } });
130
+ // ── v4.5 Phase 3 — webhook trigger ───────────────────────────────────────
131
+ var webhook_1 = require("./triggers/webhook");
132
+ Object.defineProperty(exports, "mountWebhookRoutes", { enumerable: true, get: function () { return webhook_1.mountWebhookRoutes; } });
133
+ Object.defineProperty(exports, "assertSafeBind", { enumerable: true, get: function () { return webhook_1.assertSafeBind; } });
134
+ var webhookSpec_1 = require("./triggers/webhookSpec");
135
+ Object.defineProperty(exports, "parseWebhookSpec", { enumerable: true, get: function () { return webhookSpec_1.parseWebhookSpec; } });
136
+ Object.defineProperty(exports, "DEFAULT_WEBHOOK_SPEC", { enumerable: true, get: function () { return webhookSpec_1.DEFAULT_WEBHOOK_SPEC; } });
137
+ Object.defineProperty(exports, "INSECURE_NO_AUTH", { enumerable: true, get: function () { return webhookSpec_1.INSECURE_NO_AUTH; } });
138
+ var webhookVerifier_1 = require("./triggers/webhookVerifier");
139
+ Object.defineProperty(exports, "verifyWebhookSignature", { enumerable: true, get: function () { return webhookVerifier_1.verifyWebhookSignature; } });
140
+ Object.defineProperty(exports, "deriveEventName", { enumerable: true, get: function () { return webhookVerifier_1.deriveEventName; } });
141
+ var webhookRateLimit_1 = require("./triggers/webhookRateLimit");
142
+ Object.defineProperty(exports, "createRateLimiter", { enumerable: true, get: function () { return webhookRateLimit_1.createRateLimiter; } });
143
+ var webhookIdempotency_1 = require("./triggers/webhookIdempotency");
144
+ Object.defineProperty(exports, "deriveIdempotencyKey", { enumerable: true, get: function () { return webhookIdempotency_1.deriveIdempotencyKey; } });
145
+ var webhookDeliveriesStore_1 = require("./triggers/webhookDeliveriesStore");
146
+ Object.defineProperty(exports, "createWebhookDeliveriesStore", { enumerable: true, get: function () { return webhookDeliveriesStore_1.createWebhookDeliveriesStore; } });
147
+ // ── v4.5 Phase 4a — email IMAP trigger ───────────────────────────────────
148
+ var email_1 = require("./triggers/email");
149
+ Object.defineProperty(exports, "createEmailTrigger", { enumerable: true, get: function () { return email_1.createEmailTrigger; } });
150
+ var emailSpec_1 = require("./triggers/email/emailSpec");
151
+ Object.defineProperty(exports, "parseEmailSpec", { enumerable: true, get: function () { return emailSpec_1.parseEmailSpec; } });
152
+ Object.defineProperty(exports, "DEFAULT_EMAIL_SPEC", { enumerable: true, get: function () { return emailSpec_1.DEFAULT_EMAIL_SPEC; } });
153
+ Object.defineProperty(exports, "DEFAULT_IMAP", { enumerable: true, get: function () { return emailSpec_1.DEFAULT_IMAP; } });
154
+ var automatedSender_1 = require("./triggers/email/automatedSender");
155
+ Object.defineProperty(exports, "isAutomatedSender", { enumerable: true, get: function () { return automatedSender_1.isAutomatedSender; } });
156
+ Object.defineProperty(exports, "NOREPLY_PATTERNS", { enumerable: true, get: function () { return automatedSender_1.NOREPLY_PATTERNS; } });
157
+ Object.defineProperty(exports, "AUTOMATED_HEADERS", { enumerable: true, get: function () { return automatedSender_1.AUTOMATED_HEADERS; } });
158
+ var allowlist_1 = require("./triggers/email/allowlist");
159
+ Object.defineProperty(exports, "compileSenderAllowlist", { enumerable: true, get: function () { return allowlist_1.compileSenderAllowlist; } });
160
+ var seenUids_1 = require("./triggers/email/seenUids");
161
+ Object.defineProperty(exports, "createSeenUids", { enumerable: true, get: function () { return seenUids_1.createSeenUids; } });
162
+ Object.defineProperty(exports, "DEFAULT_MAX_SEEN_UIDS", { enumerable: true, get: function () { return seenUids_1.DEFAULT_MAX_SEEN_UIDS; } });
163
+ var emailSeenStore_1 = require("./triggers/email/emailSeenStore");
164
+ Object.defineProperty(exports, "createEmailSeenStore", { enumerable: true, get: function () { return emailSeenStore_1.createEmailSeenStore; } });
165
+ var bodyExtractor_1 = require("./triggers/email/bodyExtractor");
166
+ Object.defineProperty(exports, "extractEmailBody", { enumerable: true, get: function () { return bodyExtractor_1.extractEmailBody; } });
167
+ var imapConnection_1 = require("./triggers/email/imapConnection");
168
+ Object.defineProperty(exports, "createImapConnection", { enumerable: true, get: function () { return imapConnection_1.createImapConnection; } });
169
+ Object.defineProperty(exports, "nextBackoffMs", { enumerable: true, get: function () { return imapConnection_1.nextBackoffMs; } });
170
+ Object.defineProperty(exports, "BACKOFF_CONSTANTS", { enumerable: true, get: function () { return imapConnection_1.BACKOFF_CONSTANTS; } });
171
+ var eventLoopLag_1 = require("./eventLoopLag");
172
+ Object.defineProperty(exports, "startEventLoopLagSampler", { enumerable: true, get: function () { return eventLoopLag_1.startEventLoopLagSampler; } });
173
+ Object.defineProperty(exports, "stopEventLoopLagSampler", { enumerable: true, get: function () { return eventLoopLag_1.stopEventLoopLagSampler; } });
174
+ Object.defineProperty(exports, "getEventLoopLagMs", { enumerable: true, get: function () { return eventLoopLag_1.getEventLoopLagMs; } });
175
+ Object.defineProperty(exports, "getLastTickAt", { enumerable: true, get: function () { return eventLoopLag_1.getLastTickAt; } });
176
+ Object.defineProperty(exports, "isEventLoopResponsive", { enumerable: true, get: function () { return eventLoopLag_1.isEventLoopResponsive; } });
177
+ var health_1 = require("./health");
178
+ Object.defineProperty(exports, "mountHealthEndpoints", { enumerable: true, get: function () { return health_1.mountHealthEndpoints; } });
179
+ Object.defineProperty(exports, "evaluateDegraded", { enumerable: true, get: function () { return health_1.evaluateDegraded; } });
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 Shiva Deore (Taracod).
4
+ * Licensed under AGPL-3.0. See LICENSE for details.
5
+ *
6
+ * Aiden — local-first agent.
7
+ */
8
+ /**
9
+ * core/v4/daemon/instanceTracker.ts — v4.5 Phase 1: daemon_instances writer.
10
+ *
11
+ * Writes the current process's identity into the `daemon_instances`
12
+ * table, updates `last_heartbeat` every 5s, and marks `shutdown_at`
13
+ * + `shutdown_reason` + `exit_code` on graceful exit.
14
+ *
15
+ * Crash detection — a row whose `shutdown_at IS NULL` and whose
16
+ * `last_heartbeat` is older than 30s on the NEXT daemon's boot is a
17
+ * crash candidate. `cleanShutdown.ts` evaluates this on boot.
18
+ */
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.createInstanceTracker = createInstanceTracker;
21
+ const node_crypto_1 = require("node:crypto");
22
+ const daemonConfig_1 = require("./daemonConfig");
23
+ const HEARTBEAT_INTERVAL_MS = 5000;
24
+ function rowToTs(r) {
25
+ return {
26
+ instanceId: r.instance_id,
27
+ pid: r.pid,
28
+ hostname: r.hostname,
29
+ startedAt: r.started_at,
30
+ lastHeartbeat: r.last_heartbeat,
31
+ shutdownAt: r.shutdown_at,
32
+ shutdownReason: r.shutdown_reason,
33
+ exitCode: r.exit_code,
34
+ version: r.version,
35
+ };
36
+ }
37
+ function createInstanceTracker(opts) {
38
+ const instanceId = opts.instanceId ?? (0, node_crypto_1.randomUUID)();
39
+ const pid = opts.pid ?? process.pid;
40
+ const hostname = (0, daemonConfig_1.getHostname)();
41
+ const startedAt = Date.now();
42
+ const heartbeatIntervalMs = opts.heartbeatIntervalMs ?? HEARTBEAT_INTERVAL_MS;
43
+ opts.db
44
+ .prepare(`INSERT INTO daemon_instances
45
+ (instance_id, pid, hostname, started_at, last_heartbeat, version)
46
+ VALUES (?, ?, ?, ?, ?, ?)`)
47
+ .run(instanceId, pid, hostname, startedAt, startedAt, opts.version);
48
+ let timer = null;
49
+ const beat = () => {
50
+ try {
51
+ opts.db
52
+ .prepare('UPDATE daemon_instances SET last_heartbeat = ? WHERE instance_id = ?')
53
+ .run(Date.now(), instanceId);
54
+ }
55
+ catch { /* never crash the daemon on a heartbeat write failure */ }
56
+ };
57
+ return {
58
+ instanceId,
59
+ start() {
60
+ if (timer)
61
+ return;
62
+ timer = setInterval(beat, heartbeatIntervalMs);
63
+ if (typeof timer.unref === 'function')
64
+ timer.unref();
65
+ },
66
+ stop() {
67
+ if (!timer)
68
+ return;
69
+ clearInterval(timer);
70
+ timer = null;
71
+ },
72
+ markShuttingDown(reason) {
73
+ try {
74
+ opts.db
75
+ .prepare('UPDATE daemon_instances SET shutdown_reason = ? WHERE instance_id = ?')
76
+ .run(reason, instanceId);
77
+ }
78
+ catch { /* best-effort */ }
79
+ },
80
+ markShutdown(reason, exitCode) {
81
+ try {
82
+ opts.db
83
+ .prepare(`UPDATE daemon_instances
84
+ SET shutdown_at = ?,
85
+ shutdown_reason = ?,
86
+ exit_code = ?
87
+ WHERE instance_id = ?`)
88
+ .run(Date.now(), reason, exitCode, instanceId);
89
+ }
90
+ catch { /* best-effort */ }
91
+ },
92
+ current() {
93
+ const r = opts.db
94
+ .prepare('SELECT * FROM daemon_instances WHERE instance_id = ?')
95
+ .get(instanceId);
96
+ return r ? rowToTs(r) : null;
97
+ },
98
+ };
99
+ }
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 Shiva Deore (Taracod).
4
+ * Licensed under AGPL-3.0. See LICENSE for details.
5
+ *
6
+ * Aiden — local-first agent.
7
+ */
8
+ /**
9
+ * core/v4/daemon/resourceRegistry.ts — v4.5 Phase 1: unified resource ledger.
10
+ *
11
+ * Single registry for every long-lived resource the daemon owns:
12
+ * - Playwright browser contexts (v4.3)
13
+ * - Docker session containers (v4.4)
14
+ * - HTTP keepalive agents
15
+ * - chokidar file watchers (Phase 2)
16
+ * - Subprocesses spawned by tools
17
+ * - IMAP connections (Phase 4)
18
+ * - SQLite handles
19
+ * - Webhook subrouters (Phase 3)
20
+ *
21
+ * Each resource carries:
22
+ * - kind (typed enum)
23
+ * - owner (sessionId | instanceId | 'global')
24
+ * - lifecycle timestamps
25
+ * - optional ttlMs for soft-reaping idle resources
26
+ * - optional budgetUnits for budget-based eviction
27
+ * - close(): an idempotent disposer
28
+ *
29
+ * The shutdown drain (`drain.ts` step 4) calls `reapAll()` to close
30
+ * everything with a per-item timeout. A periodic 60s sweep calls
31
+ * `sweep()` to close TTL-exceeded resources during normal operation.
32
+ *
33
+ * Diagnostic surface: `GET /api/daemon/resources` returns `list()` +
34
+ * `budgetByKind()` as JSON.
35
+ */
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.createResourceRegistry = createResourceRegistry;
38
+ exports.getResourceRegistry = getResourceRegistry;
39
+ exports._resetResourceRegistryForTests = _resetResourceRegistryForTests;
40
+ const node_crypto_1 = require("node:crypto");
41
+ const _resources = new Map();
42
+ function withTimeout(p, ms) {
43
+ return new Promise((resolve, reject) => {
44
+ const t = setTimeout(() => reject(new Error(`resource close timed out after ${ms}ms`)), ms);
45
+ p.then((v) => { clearTimeout(t); resolve(v); }, (e) => { clearTimeout(t); reject(e); });
46
+ });
47
+ }
48
+ async function safeClose(r, perItemTimeoutMs) {
49
+ try {
50
+ const result = r.close();
51
+ if (result && typeof result.then === 'function') {
52
+ await withTimeout(result, perItemTimeoutMs);
53
+ }
54
+ return true;
55
+ }
56
+ catch {
57
+ return false;
58
+ }
59
+ }
60
+ function createResourceRegistry() {
61
+ return {
62
+ register(r) {
63
+ const id = r.id ?? (0, node_crypto_1.randomUUID)();
64
+ const now = Date.now();
65
+ _resources.set(id, {
66
+ id,
67
+ kind: r.kind,
68
+ owner: r.owner,
69
+ createdAt: now,
70
+ lastUsedAt: now,
71
+ ttlMs: r.ttlMs,
72
+ budgetUnits: r.budgetUnits,
73
+ metadata: r.metadata,
74
+ close: r.close,
75
+ });
76
+ return id;
77
+ },
78
+ touch(id) {
79
+ const r = _resources.get(id);
80
+ if (r)
81
+ r.lastUsedAt = Date.now();
82
+ },
83
+ async release(id) {
84
+ const r = _resources.get(id);
85
+ if (!r)
86
+ return;
87
+ _resources.delete(id);
88
+ await safeClose(r, 5000);
89
+ },
90
+ list(filter) {
91
+ const out = [];
92
+ for (const r of _resources.values()) {
93
+ if (filter?.kind && r.kind !== filter.kind)
94
+ continue;
95
+ if (filter?.owner && r.owner !== filter.owner)
96
+ continue;
97
+ out.push(r);
98
+ }
99
+ return out;
100
+ },
101
+ async sweep(now) {
102
+ const cutoff = now ?? Date.now();
103
+ const candidates = [];
104
+ for (const r of _resources.values()) {
105
+ if (r.ttlMs && cutoff - r.lastUsedAt > r.ttlMs)
106
+ candidates.push(r);
107
+ }
108
+ // Pull them out of the registry first so concurrent touches
109
+ // don't extend their lifetime mid-close.
110
+ for (const c of candidates)
111
+ _resources.delete(c.id);
112
+ const settled = await Promise.allSettled(candidates.map((c) => safeClose(c, 3000)));
113
+ return { reaped: settled.filter((s) => s.status === 'fulfilled' && s.value === true).length };
114
+ },
115
+ async reapAll(perItemTimeoutMs = 3000) {
116
+ const all = [..._resources.values()];
117
+ _resources.clear();
118
+ const settled = await Promise.allSettled(all.map((r) => safeClose(r, perItemTimeoutMs)));
119
+ let reaped = 0;
120
+ let failed = 0;
121
+ for (const s of settled) {
122
+ if (s.status === 'fulfilled' && s.value === true)
123
+ reaped++;
124
+ else
125
+ failed++;
126
+ }
127
+ return { reaped, failed };
128
+ },
129
+ budgetByKind() {
130
+ const out = {};
131
+ for (const r of _resources.values()) {
132
+ const slot = out[r.kind] ?? (out[r.kind] = { count: 0, budgetUnits: 0 });
133
+ slot.count += 1;
134
+ slot.budgetUnits += r.budgetUnits ?? 0;
135
+ }
136
+ return out;
137
+ },
138
+ };
139
+ }
140
+ // ── Process-scope singleton ────────────────────────────────────────────────
141
+ let _singleton = null;
142
+ function getResourceRegistry() {
143
+ if (!_singleton)
144
+ _singleton = createResourceRegistry();
145
+ return _singleton;
146
+ }
147
+ function _resetResourceRegistryForTests() {
148
+ _singleton = null;
149
+ _resources.clear();
150
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 Shiva Deore (Taracod).
4
+ * Licensed under AGPL-3.0. See LICENSE for details.
5
+ *
6
+ * Aiden — local-first agent.
7
+ */
8
+ /**
9
+ * core/v4/daemon/restartCode.ts — v4.5 Phase 1: graceful-restart exit code.
10
+ *
11
+ * Single source of truth. THREE consumers must use the same value:
12
+ * 1. The in-process drain handler (`drain.ts`) — passes this to
13
+ * `process.exit()` when the daemon is reloading via SIGUSR1.
14
+ * 2. The systemd unit (`templates/systemd.service.template`) —
15
+ * `RestartForceExitStatus=75` triggers an immediate respawn
16
+ * regardless of `Restart=` mode.
17
+ * 3. The launchd plist (`templates/launchd.plist.template`) —
18
+ * uses `KeepAlive.SuccessfulExit=false` which is launchd's
19
+ * analog (any non-zero exit triggers respawn; exit 0 does not).
20
+ *
21
+ * Value 75 == sysexits.h `EX_TEMPFAIL` — semantically "service
22
+ * unavailable, retry later", matching what a service supervisor
23
+ * should do.
24
+ */
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.DAEMON_RESTART_EXIT_CODE = void 0;
27
+ /**
28
+ * Exit code used by `aiden daemon restart` and the SIGUSR1 handler
29
+ * to signal "respawn me, graceful restart" to systemd / launchd /
30
+ * the internal supervisor.
31
+ */
32
+ exports.DAEMON_RESTART_EXIT_CODE = 75;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 Shiva Deore (Taracod).
4
+ * Licensed under AGPL-3.0. See LICENSE for details.
5
+ *
6
+ * Aiden — local-first agent.
7
+ */
8
+ /**
9
+ * core/v4/daemon/restartFailureCounter.ts — v4.5 Phase 1.
10
+ *
11
+ * Per-session stuck-loop guard. Each time a daemon crashes mid-turn
12
+ * for a given session, `incrementForSession(sessionId)` bumps the
13
+ * counter. When the counter reaches the configured threshold (default
14
+ * 3, configurable via AIDEN_DAEMON_RESTART_FAILURE_THRESHOLD), the
15
+ * session is auto-suspended: future restarts will refuse to resume it
16
+ * until the user explicitly sends a new message (which calls
17
+ * `resetForSession`).
18
+ *
19
+ * Counter resets to 0 when a turn completes successfully or when the
20
+ * user sends a new message.
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.DEFAULT_STUCK_LOOP_THRESHOLD = void 0;
24
+ exports.createRestartFailureCounter = createRestartFailureCounter;
25
+ exports.DEFAULT_STUCK_LOOP_THRESHOLD = 3;
26
+ function createRestartFailureCounter(opts) {
27
+ const threshold = opts.threshold ?? exports.DEFAULT_STUCK_LOOP_THRESHOLD;
28
+ const db = opts.db;
29
+ return {
30
+ incrementForSession(sessionId) {
31
+ const now = Date.now();
32
+ const tx = db.transaction(() => {
33
+ const row = db
34
+ .prepare('SELECT count, auto_suspended FROM restart_failure_counts WHERE session_id = ?')
35
+ .get(sessionId);
36
+ const newCount = (row?.count ?? 0) + 1;
37
+ const autoSuspended = newCount >= threshold;
38
+ if (row) {
39
+ db.prepare(`UPDATE restart_failure_counts
40
+ SET count = ?,
41
+ last_failure = ?,
42
+ auto_suspended = ?
43
+ WHERE session_id = ?`).run(newCount, now, autoSuspended ? 1 : 0, sessionId);
44
+ }
45
+ else {
46
+ db.prepare(`INSERT INTO restart_failure_counts
47
+ (session_id, count, last_failure, auto_suspended)
48
+ VALUES (?, ?, ?, ?)`).run(sessionId, newCount, now, autoSuspended ? 1 : 0);
49
+ }
50
+ return { newCount, autoSuspended };
51
+ });
52
+ return tx();
53
+ },
54
+ resetForSession(sessionId) {
55
+ db.prepare('DELETE FROM restart_failure_counts WHERE session_id = ?').run(sessionId);
56
+ },
57
+ isAutoSuspended(sessionId) {
58
+ const row = db
59
+ .prepare('SELECT auto_suspended FROM restart_failure_counts WHERE session_id = ?')
60
+ .get(sessionId);
61
+ return row?.auto_suspended === 1;
62
+ },
63
+ listSuspended() {
64
+ const rows = db
65
+ .prepare(`SELECT session_id, count, last_failure
66
+ FROM restart_failure_counts
67
+ WHERE auto_suspended = 1
68
+ ORDER BY last_failure DESC`)
69
+ .all();
70
+ return rows.map((r) => ({
71
+ sessionId: r.session_id,
72
+ count: r.count,
73
+ lastFailure: r.last_failure,
74
+ }));
75
+ },
76
+ };
77
+ }
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 Shiva Deore (Taracod).
4
+ * Licensed under AGPL-3.0. See LICENSE for details.
5
+ *
6
+ * Aiden — local-first agent.
7
+ */
8
+ /**
9
+ * core/v4/daemon/runStore.ts — v4.5 Phase 1: runs + run_events writers.
10
+ *
11
+ * Daemon-fired runs are persisted in `runs` (one row per turn) with
12
+ * a stream of `run_events` rows for per-event detail (tool calls,
13
+ * verifications, classifications, recovery actions, log lines).
14
+ *
15
+ * CLI-fired turns continue using in-memory trace structures — zero
16
+ * overhead for interactive use. The daemon path opts in by creating
17
+ * a run row + emitting events.
18
+ */
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.createRunStore = createRunStore;
21
+ function rowToTs(r) {
22
+ return {
23
+ id: r.id,
24
+ triggerEventId: r.trigger_event_id,
25
+ sessionId: r.session_id,
26
+ instanceId: r.instance_id,
27
+ status: r.status,
28
+ finishReason: r.finish_reason,
29
+ startedAt: r.started_at,
30
+ completedAt: r.completed_at,
31
+ resumePending: r.resume_pending === 1,
32
+ resumeReason: r.resume_reason,
33
+ };
34
+ }
35
+ function createRunStore(opts) {
36
+ const db = opts.db;
37
+ return {
38
+ create({ sessionId, instanceId, triggerEventId, status, startedAt }) {
39
+ const now = startedAt ?? Date.now();
40
+ const r = db.prepare(`INSERT INTO runs
41
+ (trigger_event_id, session_id, instance_id, status, started_at,
42
+ resume_pending)
43
+ VALUES (?, ?, ?, ?, ?, 0)`).run(triggerEventId ?? null, sessionId, instanceId, status ?? 'queued', now);
44
+ return Number(r.lastInsertRowid);
45
+ },
46
+ setStatus(runId, status, opts2 = {}) {
47
+ const completedAt = opts2.completedAt
48
+ ?? (status === 'completed' || status === 'failed' || status === 'cancelled' || status === 'interrupted'
49
+ ? Date.now()
50
+ : null);
51
+ db.prepare(`UPDATE runs
52
+ SET status = ?,
53
+ finish_reason = COALESCE(?, finish_reason),
54
+ completed_at = COALESCE(?, completed_at)
55
+ WHERE id = ?`).run(status, opts2.finishReason ?? null, completedAt, runId);
56
+ },
57
+ markResumePending(runId, reason) {
58
+ db.prepare(`UPDATE runs SET resume_pending = 1, resume_reason = ? WHERE id = ?`).run(reason, runId);
59
+ },
60
+ emitEvent(runId, kind, payload) {
61
+ const json = JSON.stringify(payload).slice(0, 4096);
62
+ db.prepare(`INSERT INTO run_events (run_id, ts, kind, payload) VALUES (?, ?, ?, ?)`).run(runId, Date.now(), kind, json);
63
+ },
64
+ listActive() {
65
+ const rows = db
66
+ .prepare(`SELECT * FROM runs WHERE status IN ('queued','running')`)
67
+ .all();
68
+ return rows.map(rowToTs);
69
+ },
70
+ get(runId) {
71
+ const r = db
72
+ .prepare('SELECT * FROM runs WHERE id = ?')
73
+ .get(runId);
74
+ return r ? rowToTs(r) : null;
75
+ },
76
+ countEvents(runId) {
77
+ const r = db
78
+ .prepare('SELECT COUNT(*) AS c FROM run_events WHERE run_id = ?')
79
+ .get(runId);
80
+ return r.c;
81
+ },
82
+ listRecent(opts2 = {}) {
83
+ const limit = Math.max(1, Math.min(opts2.limit ?? 50, 1000));
84
+ const whereParts = [];
85
+ const params = [];
86
+ if (opts2.status) {
87
+ whereParts.push('r.status = ?');
88
+ params.push(opts2.status);
89
+ }
90
+ if (opts2.source) {
91
+ whereParts.push('te.source = ?');
92
+ params.push(opts2.source);
93
+ }
94
+ if (opts2.sessionIdPrefix) {
95
+ whereParts.push('r.session_id LIKE ?');
96
+ params.push(`${opts2.sessionIdPrefix}%`);
97
+ }
98
+ const where = whereParts.length > 0 ? `WHERE ${whereParts.join(' AND ')}` : '';
99
+ const sql = `
100
+ SELECT r.* FROM runs r
101
+ LEFT JOIN trigger_events te ON r.trigger_event_id = te.id
102
+ ${where}
103
+ ORDER BY r.started_at DESC
104
+ LIMIT ?`;
105
+ params.push(limit);
106
+ const rows = db.prepare(sql).all(...params);
107
+ return rows.map(rowToTs);
108
+ },
109
+ listEvents(runId, limit = 200) {
110
+ const rows = db.prepare(`SELECT ts, kind, payload FROM run_events WHERE run_id = ? ORDER BY ts ASC LIMIT ?`).all(runId, Math.max(1, Math.min(limit, 5000)));
111
+ return rows;
112
+ },
113
+ };
114
+ }