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,210 @@
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/suggestionEngine.ts — v4.5 Phase 8b.
10
+ *
11
+ * Contextual one-time suggestions for the v4.4/v4.5 subsystems the
12
+ * user hasn't enabled yet. Fires when their CURRENT task would
13
+ * genuinely benefit:
14
+ *
15
+ * - sandbox → destructive shell pattern + sandbox is OFF
16
+ * - browser_depth → browser_* tool call + browser_depth is OFF
17
+ * - daemon_scheduling → user said "every day", "watch this folder",
18
+ * "when an email arrives", etc.
19
+ * - tce_recovery → recovery situation reached + TCE is OFF
20
+ * (lower priority; most users keep TCE on)
21
+ *
22
+ * Budget Q-P8b-1(a): 2 suggestions per session global. Each slot
23
+ * fires AT MOST ONCE per session. Resets on REPL restart.
24
+ *
25
+ * Dismissal Q-P8b-4(c) + Q-P8b-6(a):
26
+ * - Per-session: `dismissAll()` silences for the rest of the session.
27
+ * - Permanent: `runtime_toggles.suggestions = false` in config.yaml
28
+ * (slash command persists). Engine reads via runtimeToggles
29
+ * singleton — when the toggle reports OFF the engine treats every
30
+ * classification as "no tip".
31
+ *
32
+ * Pure module — no I/O. Display happens at the call site
33
+ * (`display.dim()` per audit Q-P8b-3). Engine only classifies +
34
+ * tracks state.
35
+ */
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.buildSuggestionEngine = buildSuggestionEngine;
38
+ exports.getSuggestionEngine = getSuggestionEngine;
39
+ exports._resetSuggestionEngineForTests = _resetSuggestionEngineForTests;
40
+ const dangerousPatterns_1 = require("../../moat/dangerousPatterns");
41
+ const runtimeToggles_1 = require("./runtimeToggles");
42
+ const suggestionCatalog_1 = require("./suggestionCatalog");
43
+ // ── Daemon-scheduling regex (Q-P8b-2a — simple keyword) ────────────────────
44
+ const SCHEDULING_PATTERNS = [
45
+ /\b(every|each)\s+(day|hour|minute|week|morning|evening|monday|tuesday|wednesday|thursday|friday|saturday|sunday)\b/i,
46
+ /\b(daily|hourly|weekly|nightly)\b/i,
47
+ /\bat\s+\d{1,2}(:\d{2})?\s*(am|pm)?\s+(every|each)\b/i,
48
+ /\bwatch\s+(this|the)?\s*(folder|directory|path)\b/i,
49
+ /\bmonitor\s+(changes|files?|directory|folder)\b/i,
50
+ /\bwhen\s+(an?\s+)?(email|webhook|file|message)\s+(arrives|comes|is\s+received|drops)\b/i,
51
+ /\b(remind|alert|notify)\s+me\s+(when|to|every)\b/i,
52
+ /\bset\s+up\s+(a\s+)?(cron|schedule|trigger|watcher|webhook)\b/i,
53
+ ];
54
+ // ── System-path heuristic for file_* tool sandbox tips ─────────────────────
55
+ const SYSTEM_PATH_PATTERNS = [
56
+ /^\/etc\b/i,
57
+ /^\/System\b/i,
58
+ /^\/Library\/System\b/i,
59
+ /^\/usr\/(s)?bin\b/i,
60
+ /^[A-Z]:\\Windows\b/i,
61
+ /^[A-Z]:\\Program\s+Files\b/i,
62
+ /\\System32\\/i,
63
+ ];
64
+ function isSystemPath(p) {
65
+ if (typeof p !== 'string' || p.length === 0)
66
+ return false;
67
+ return SYSTEM_PATH_PATTERNS.some((r) => r.test(p));
68
+ }
69
+ // ── Classifiers (pure) ─────────────────────────────────────────────────────
70
+ /** sandbox slot — destructive shell or system-path write. */
71
+ function classifySandbox(call) {
72
+ const args = (call.arguments ?? {});
73
+ if (call.name === 'shell_exec') {
74
+ const cmd = typeof args.command === 'string' ? args.command : '';
75
+ if (cmd.length === 0)
76
+ return false;
77
+ const cls = (0, dangerousPatterns_1.classifyCommand)(cmd);
78
+ return cls.tier === 'caution' || cls.tier === 'dangerous';
79
+ }
80
+ if (call.name === 'file_write' || call.name === 'file_delete'
81
+ || call.name === 'file_move' || call.name === 'file_patch') {
82
+ const target = typeof args.path === 'string' ? args.path
83
+ : typeof args.target === 'string' ? args.target
84
+ : '';
85
+ return isSystemPath(target);
86
+ }
87
+ return false;
88
+ }
89
+ /** browser_depth slot — any browser_* tool fires the suggestion when off. */
90
+ function classifyBrowserDepth(call) {
91
+ return call.name.startsWith('browser_');
92
+ }
93
+ /** daemon_scheduling slot — keyword regex on initial message. */
94
+ function classifySchedulingIntent(message) {
95
+ if (typeof message !== 'string' || message.length < 6)
96
+ return false;
97
+ return SCHEDULING_PATTERNS.some((r) => r.test(message));
98
+ }
99
+ // ── Singleton ──────────────────────────────────────────────────────────────
100
+ const DEFAULT_BUDGET_PER_SESSION = 2;
101
+ function buildSuggestionEngine(opts = {}) {
102
+ const budget = opts.budgetPerSession ?? DEFAULT_BUDGET_PER_SESSION;
103
+ const getRT = opts.runtimeTogglesGetter ?? (() => (0, runtimeToggles_1.getRuntimeToggles)());
104
+ const firedSlots = new Set();
105
+ let dismissedSession = false;
106
+ function permanentlyOff() {
107
+ try {
108
+ // 'suggestions' is wired as a runtime toggle key via Phase 8b
109
+ // schema extension. When the user has typed `/suggestions off`
110
+ // (persisted to config.yaml runtime_toggles.suggestions=false),
111
+ // the toggle reports off and we skip every classification.
112
+ return !getRT().isEnabled('suggestions');
113
+ }
114
+ catch {
115
+ // Defensive — if the toggle key isn't registered yet we treat
116
+ // suggestions as on (the default).
117
+ return false;
118
+ }
119
+ }
120
+ function canFire(slot) {
121
+ if (dismissedSession)
122
+ return false;
123
+ if (permanentlyOff())
124
+ return false;
125
+ if (firedSlots.has(slot))
126
+ return false;
127
+ if (firedSlots.size >= budget)
128
+ return false;
129
+ // Only suggest when the relevant subsystem is OFF — otherwise the
130
+ // tip is noise. Mapping: slot → underlying runtimeToggles key.
131
+ try {
132
+ switch (slot) {
133
+ case 'sandbox':
134
+ if (getRT().isEnabled('sandbox'))
135
+ return false;
136
+ break;
137
+ case 'browser_depth':
138
+ if (getRT().isEnabled('browser_depth'))
139
+ return false;
140
+ break;
141
+ case 'tce_recovery':
142
+ if (getRT().isEnabled('tce'))
143
+ return false;
144
+ break;
145
+ case 'daemon_scheduling':
146
+ // No matching toggle — daemon mode is a process-level
147
+ // boolean (AIDEN_DAEMON). Suggest only when daemon is off,
148
+ // which we detect by reading the env var (the daemon
149
+ // toggle isn't part of runtime_toggles by design).
150
+ if (process.env.AIDEN_DAEMON === '1')
151
+ return false;
152
+ break;
153
+ }
154
+ }
155
+ catch { /* defensive */ }
156
+ return true;
157
+ }
158
+ function build(slot) {
159
+ return { slot, message: (0, suggestionCatalog_1.suggestionMessageFor)(slot) };
160
+ }
161
+ return {
162
+ checkToolCall(call) {
163
+ if (!call || typeof call.name !== 'string')
164
+ return null;
165
+ if (classifyBrowserDepth(call) && canFire('browser_depth')) {
166
+ return build('browser_depth');
167
+ }
168
+ if (classifySandbox(call) && canFire('sandbox')) {
169
+ return build('sandbox');
170
+ }
171
+ return null;
172
+ },
173
+ checkInitialMessage(message) {
174
+ if (classifySchedulingIntent(message) && canFire('daemon_scheduling')) {
175
+ return build('daemon_scheduling');
176
+ }
177
+ return null;
178
+ },
179
+ recordFired(slot) {
180
+ firedSlots.add(slot);
181
+ },
182
+ dismissAll() {
183
+ dismissedSession = true;
184
+ },
185
+ snapshot() {
186
+ return {
187
+ firedSlots: [...firedSlots],
188
+ dismissedSession,
189
+ permanentlyOff: permanentlyOff(),
190
+ budgetRemaining: Math.max(0, budget - firedSlots.size),
191
+ };
192
+ },
193
+ _resetForTests() {
194
+ firedSlots.clear();
195
+ dismissedSession = false;
196
+ },
197
+ };
198
+ }
199
+ // ── Process-wide singleton ─────────────────────────────────────────────────
200
+ let _singleton = null;
201
+ function getSuggestionEngine() {
202
+ if (!_singleton)
203
+ _singleton = buildSuggestionEngine();
204
+ return _singleton;
205
+ }
206
+ function _resetSuggestionEngineForTests() {
207
+ if (_singleton)
208
+ _singleton._resetForTests();
209
+ _singleton = null;
210
+ }
@@ -136,12 +136,30 @@ class ToolRegistry {
136
136
  riskTier = c.tier;
137
137
  reason = c.reason;
138
138
  }
139
+ // v4.4 Phase 4 — dangerous-tier auto-preview. Surface
140
+ // "what would happen if you say yes" to the approval prompt.
141
+ // Effective tier is the handler annotation (Phase 1 floor)
142
+ // OR the classifier escalation above (whichever is higher).
143
+ let preview;
144
+ const effectiveTier = (riskTier === 'dangerous' || handler.riskTier === 'dangerous')
145
+ ? 'dangerous' : (riskTier ?? handler.riskTier);
146
+ if (effectiveTier === 'dangerous' && typeof handler.buildPreview === 'function') {
147
+ try {
148
+ preview = await handler.buildPreview(args, context);
149
+ }
150
+ catch {
151
+ // Preview is best-effort. A bad preview never blocks
152
+ // the underlying approval decision.
153
+ preview = undefined;
154
+ }
155
+ }
139
156
  const allowed = await context.approvalEngine.checkApproval({
140
157
  toolName: call.name,
141
158
  category: handler.category,
142
159
  args,
143
160
  riskTier,
144
161
  reason,
162
+ preview,
145
163
  });
146
164
  if (!allowed) {
147
165
  return {