aiden-runtime 4.1.4 → 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 (169) hide show
  1. package/README.md +250 -847
  2. package/dist/api/server.js +32 -5
  3. package/dist/cli/v4/aidenCLI.js +379 -53
  4. package/dist/cli/v4/callbacks.js +248 -0
  5. package/dist/cli/v4/chatSession.js +292 -4
  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 +75 -3
  21. package/dist/cli/v4/display/capabilityCard.js +26 -0
  22. package/dist/cli/v4/display/progressBar.js +41 -8
  23. package/dist/cli/v4/display.js +258 -15
  24. package/dist/cli/v4/replyRenderer.js +31 -23
  25. package/dist/cli/v4/toolPreview.js +10 -0
  26. package/dist/cli/v4/updateBootPrompt.js +170 -0
  27. package/dist/core/playwrightBridge.js +129 -0
  28. package/dist/core/toolRegistry.js +7 -1
  29. package/dist/core/v4/aidenAgent.js +371 -4
  30. package/dist/core/v4/browserState.js +436 -0
  31. package/dist/core/v4/checkpoint.js +79 -0
  32. package/dist/core/v4/daemon/bootstrap.js +604 -0
  33. package/dist/core/v4/daemon/cleanShutdown.js +154 -0
  34. package/dist/core/v4/daemon/cron/cronBridge.js +126 -0
  35. package/dist/core/v4/daemon/cron/cronEmitter.js +173 -0
  36. package/dist/core/v4/daemon/cron/migration.js +199 -0
  37. package/dist/core/v4/daemon/cron/misfirePolicy.js +115 -0
  38. package/dist/core/v4/daemon/daemonConfig.js +90 -0
  39. package/dist/core/v4/daemon/db/connection.js +106 -0
  40. package/dist/core/v4/daemon/db/migrations.js +296 -0
  41. package/dist/core/v4/daemon/db/schema/v1.spec.js +18 -0
  42. package/dist/core/v4/daemon/dispatcher/agentRunner.js +98 -0
  43. package/dist/core/v4/daemon/dispatcher/budgetGate.js +127 -0
  44. package/dist/core/v4/daemon/dispatcher/daemonApproval.js +113 -0
  45. package/dist/core/v4/daemon/dispatcher/dailyBudgetTracker.js +120 -0
  46. package/dist/core/v4/daemon/dispatcher/dispatcher.js +389 -0
  47. package/dist/core/v4/daemon/dispatcher/fireRateLimiter.js +113 -0
  48. package/dist/core/v4/daemon/dispatcher/index.js +53 -0
  49. package/dist/core/v4/daemon/dispatcher/promptTemplate.js +95 -0
  50. package/dist/core/v4/daemon/dispatcher/realAgentRunner.js +356 -0
  51. package/dist/core/v4/daemon/dispatcher/resolveModel.js +93 -0
  52. package/dist/core/v4/daemon/dispatcher/sessionId.js +93 -0
  53. package/dist/core/v4/daemon/drain.js +156 -0
  54. package/dist/core/v4/daemon/eventLoopLag.js +73 -0
  55. package/dist/core/v4/daemon/health.js +159 -0
  56. package/dist/core/v4/daemon/idempotencyStore.js +204 -0
  57. package/dist/core/v4/daemon/index.js +179 -0
  58. package/dist/core/v4/daemon/instanceTracker.js +99 -0
  59. package/dist/core/v4/daemon/resourceRegistry.js +150 -0
  60. package/dist/core/v4/daemon/restartCode.js +32 -0
  61. package/dist/core/v4/daemon/restartFailureCounter.js +77 -0
  62. package/dist/core/v4/daemon/runStore.js +114 -0
  63. package/dist/core/v4/daemon/runtimeLock.js +167 -0
  64. package/dist/core/v4/daemon/signals.js +50 -0
  65. package/dist/core/v4/daemon/supervisor.js +272 -0
  66. package/dist/core/v4/daemon/triggerBus.js +279 -0
  67. package/dist/core/v4/daemon/triggers/email/allowlist.js +70 -0
  68. package/dist/core/v4/daemon/triggers/email/automatedSender.js +78 -0
  69. package/dist/core/v4/daemon/triggers/email/bodyExtractor.js +0 -0
  70. package/dist/core/v4/daemon/triggers/email/emailSeenStore.js +99 -0
  71. package/dist/core/v4/daemon/triggers/email/emailSpec.js +107 -0
  72. package/dist/core/v4/daemon/triggers/email/imapConnection.js +211 -0
  73. package/dist/core/v4/daemon/triggers/email/index.js +332 -0
  74. package/dist/core/v4/daemon/triggers/email/seenUids.js +60 -0
  75. package/dist/core/v4/daemon/triggers/fileObservationsStore.js +93 -0
  76. package/dist/core/v4/daemon/triggers/fileWatcher.js +253 -0
  77. package/dist/core/v4/daemon/triggers/fileWatcherSpec.js +88 -0
  78. package/dist/core/v4/daemon/triggers/fsIdentity.js +42 -0
  79. package/dist/core/v4/daemon/triggers/globMatcher.js +100 -0
  80. package/dist/core/v4/daemon/triggers/reconcile.js +206 -0
  81. package/dist/core/v4/daemon/triggers/settleStat.js +81 -0
  82. package/dist/core/v4/daemon/triggers/webhook.js +376 -0
  83. package/dist/core/v4/daemon/triggers/webhookDeliveriesStore.js +109 -0
  84. package/dist/core/v4/daemon/triggers/webhookIdempotency.js +72 -0
  85. package/dist/core/v4/daemon/triggers/webhookRateLimit.js +56 -0
  86. package/dist/core/v4/daemon/triggers/webhookSpec.js +76 -0
  87. package/dist/core/v4/daemon/triggers/webhookVerifier.js +128 -0
  88. package/dist/core/v4/daemon/types.js +15 -0
  89. package/dist/core/v4/dockerSession.js +461 -0
  90. package/dist/core/v4/dryRun.js +117 -0
  91. package/dist/core/v4/failureClassifier.js +779 -0
  92. package/dist/core/v4/loopTrace.js +257 -0
  93. package/dist/core/v4/recoveryReport.js +449 -0
  94. package/dist/core/v4/runtimeToggles.js +187 -0
  95. package/dist/core/v4/sandboxConfig.js +285 -0
  96. package/dist/core/v4/sandboxFs.js +316 -0
  97. package/dist/core/v4/suggestionCatalog.js +41 -0
  98. package/dist/core/v4/suggestionEngine.js +210 -0
  99. package/dist/core/v4/toolRegistry.js +18 -0
  100. package/dist/core/v4/turnState.js +587 -0
  101. package/dist/core/v4/update/checkUpdate.js +63 -3
  102. package/dist/core/v4/update/installMethodDetect.js +115 -0
  103. package/dist/core/v4/update/registryClient.js +121 -0
  104. package/dist/core/v4/update/skipState.js +75 -0
  105. package/dist/core/v4/verifier.js +448 -0
  106. package/dist/core/version.js +1 -1
  107. package/dist/core/webSearch.js +64 -24
  108. package/dist/tools/v4/browser/_observer.js +224 -0
  109. package/dist/tools/v4/browser/browserBlocker.js +396 -0
  110. package/dist/tools/v4/browser/browserClick.js +18 -1
  111. package/dist/tools/v4/browser/browserClose.js +18 -1
  112. package/dist/tools/v4/browser/browserExtract.js +5 -1
  113. package/dist/tools/v4/browser/browserFill.js +17 -1
  114. package/dist/tools/v4/browser/browserGetUrl.js +5 -1
  115. package/dist/tools/v4/browser/browserNavigate.js +16 -1
  116. package/dist/tools/v4/browser/browserScreenshot.js +5 -1
  117. package/dist/tools/v4/browser/browserScroll.js +18 -1
  118. package/dist/tools/v4/browser/browserType.js +17 -1
  119. package/dist/tools/v4/browser/captchaCheck.js +5 -1
  120. package/dist/tools/v4/executeCode.js +1 -0
  121. package/dist/tools/v4/files/fileCopy.js +56 -2
  122. package/dist/tools/v4/files/fileDelete.js +38 -1
  123. package/dist/tools/v4/files/fileList.js +12 -1
  124. package/dist/tools/v4/files/fileMove.js +59 -2
  125. package/dist/tools/v4/files/filePatch.js +43 -1
  126. package/dist/tools/v4/files/fileRead.js +12 -1
  127. package/dist/tools/v4/files/fileWrite.js +41 -1
  128. package/dist/tools/v4/index.js +71 -58
  129. package/dist/tools/v4/memory/memoryAdd.js +14 -0
  130. package/dist/tools/v4/memory/memoryRemove.js +14 -0
  131. package/dist/tools/v4/memory/memoryReplace.js +15 -0
  132. package/dist/tools/v4/memory/sessionSummary.js +12 -0
  133. package/dist/tools/v4/process/processKill.js +19 -0
  134. package/dist/tools/v4/process/processList.js +1 -0
  135. package/dist/tools/v4/process/processLogRead.js +1 -0
  136. package/dist/tools/v4/process/processSpawn.js +13 -0
  137. package/dist/tools/v4/process/processWait.js +1 -0
  138. package/dist/tools/v4/sessions/recallSession.js +1 -0
  139. package/dist/tools/v4/sessions/sessionList.js +1 -0
  140. package/dist/tools/v4/sessions/sessionSearch.js +1 -0
  141. package/dist/tools/v4/skills/lookupToolSchema.js +2 -0
  142. package/dist/tools/v4/skills/skillManage.js +13 -0
  143. package/dist/tools/v4/skills/skillView.js +1 -0
  144. package/dist/tools/v4/skills/skillsList.js +1 -0
  145. package/dist/tools/v4/subagent/subagentFanout.js +1 -0
  146. package/dist/tools/v4/system/aidenSelfUpdate.js +16 -0
  147. package/dist/tools/v4/system/appClose.js +13 -0
  148. package/dist/tools/v4/system/appInput.js +13 -0
  149. package/dist/tools/v4/system/appLaunch.js +13 -0
  150. package/dist/tools/v4/system/clipboardRead.js +1 -0
  151. package/dist/tools/v4/system/clipboardWrite.js +14 -0
  152. package/dist/tools/v4/system/mediaKey.js +12 -0
  153. package/dist/tools/v4/system/mediaSessions.js +1 -0
  154. package/dist/tools/v4/system/mediaTransport.js +13 -0
  155. package/dist/tools/v4/system/naturalEvents.js +1 -0
  156. package/dist/tools/v4/system/nowPlaying.js +1 -0
  157. package/dist/tools/v4/system/osProcessList.js +1 -0
  158. package/dist/tools/v4/system/screenshot.js +1 -0
  159. package/dist/tools/v4/system/systemInfo.js +1 -0
  160. package/dist/tools/v4/system/volumeSet.js +17 -0
  161. package/dist/tools/v4/terminal/shellExec.js +81 -9
  162. package/dist/tools/v4/web/deepResearch.js +1 -0
  163. package/dist/tools/v4/web/openUrl.js +1 -0
  164. package/dist/tools/v4/web/webFetch.js +1 -0
  165. package/dist/tools/v4/web/webPage.js +1 -0
  166. package/dist/tools/v4/web/webSearch.js +1 -0
  167. package/dist/tools/v4/web/youtubeSearch.js +1 -0
  168. package/package.json +7 -1
  169. package/plugins/aiden-plugin-cdp-browser/.granted-permissions.json +8 -0
@@ -26,6 +26,7 @@ exports.sessionSummaryTool = exports.memoryRemoveTool = void 0;
26
26
  exports.registerReadOnlyTools = registerReadOnlyTools;
27
27
  exports.registerWriteTools = registerWriteTools;
28
28
  exports.registerAllTools = registerAllTools;
29
+ const dryRun_1 = require("../../core/v4/dryRun");
29
30
  const webSearch_1 = require("./web/webSearch");
30
31
  const webFetch_1 = require("./web/webFetch");
31
32
  const webPage_1 = require("./web/webPage");
@@ -96,54 +97,61 @@ const subagentFanout_1 = require("./subagent/subagentFanout");
96
97
  * the full set).
97
98
  */
98
99
  function registerReadOnlyTools(registry) {
99
- registry.register(webSearch_1.webSearchTool);
100
- registry.register(webFetch_1.webFetchTool);
101
- registry.register(webPage_1.webPageTool);
102
- registry.register(deepResearch_1.deepResearchTool);
100
+ // v4.4 Phase 4 — every handler is funneled through withDryRun so
101
+ // AIDEN_DRYRUN=1 short-circuits `execute` to a preview. Read-only
102
+ // tools pass through unchanged (the HOC returns the handler as-is
103
+ // when `mutates: false`); the wrapper is cheap (`if (!mutates)
104
+ // return handler`) and keeps the registration call sites uniform
105
+ // across read/write tool sets.
106
+ const register = (h) => registry.register((0, dryRun_1.withDryRun)(h));
107
+ register(webSearch_1.webSearchTool);
108
+ register(webFetch_1.webFetchTool);
109
+ register(webPage_1.webPageTool);
110
+ register(deepResearch_1.deepResearchTool);
103
111
  // Phase 16f: open_url uses shell launch (start chrome / open / xdg-open)
104
112
  // for "open X in browser" requests — bypasses Playwright detection.
105
- registry.register(openUrl_1.openUrlTool);
113
+ register(openUrl_1.openUrlTool);
106
114
  // Phase 23.4a: youtube_search returns real /watch?v= URLs scraped
107
115
  // from youtube.com/results. media-search uses it before open_url so
108
116
  // the URL provenance gate has a candidate set to validate against —
109
117
  // closes the URL-hallucination failure mode where the model invented
110
118
  // 11-char IDs.
111
- registry.register(youtubeSearch_1.youtubeSearchTool);
112
- registry.register(fileRead_1.fileReadTool);
113
- registry.register(fileList_1.fileListTool);
114
- registry.register(browserScreenshot_1.browserScreenshotTool);
115
- registry.register(browserExtract_1.browserExtractTool);
116
- registry.register(browserGetUrl_1.browserGetUrlTool);
117
- registry.register(sessionSearch_1.sessionSearchTool);
118
- registry.register(sessionList_1.sessionListTool);
119
+ register(youtubeSearch_1.youtubeSearchTool);
120
+ register(fileRead_1.fileReadTool);
121
+ register(fileList_1.fileListTool);
122
+ register(browserScreenshot_1.browserScreenshotTool);
123
+ register(browserExtract_1.browserExtractTool);
124
+ register(browserGetUrl_1.browserGetUrlTool);
125
+ register(sessionSearch_1.sessionSearchTool);
126
+ register(sessionList_1.sessionListTool);
119
127
  // Phase v4.1.2-memory-C: recall_session reads SessionDistillation
120
128
  // files written by Phase A+B. Sits alongside session_search — the
121
129
  // two have distinct purposes (FTS5-over-messages vs ranked
122
130
  // distillation summaries); descriptions force the right model
123
131
  // choice.
124
- registry.register(recallSession_1.recallSessionTool);
125
- registry.register(skillsList_1.skillsListTool);
126
- registry.register(skillView_1.skillViewTool);
127
- registry.register(systemInfo_1.systemInfoTool);
128
- registry.register(nowPlaying_1.nowPlayingTool);
129
- registry.register(naturalEvents_1.naturalEventsTool);
132
+ register(recallSession_1.recallSessionTool);
133
+ register(skillsList_1.skillsListTool);
134
+ register(skillView_1.skillViewTool);
135
+ register(systemInfo_1.systemInfoTool);
136
+ register(nowPlaying_1.nowPlayingTool);
137
+ register(naturalEvents_1.naturalEventsTool);
130
138
  // Phase v4.1.2-followup-3 — computer-control read-only tools.
131
- registry.register(screenshot_1.screenshotTool);
132
- registry.register(osProcessList_1.osProcessListTool);
133
- registry.register(clipboardRead_1.clipboardReadTool);
139
+ register(screenshot_1.screenshotTool);
140
+ register(osProcessList_1.osProcessListTool);
141
+ register(clipboardRead_1.clipboardReadTool);
134
142
  // v4.1.4-media — GSMTC session enumeration (read). Pair with
135
143
  // mediaTransport (write) in the write-tools registration below.
136
- registry.register(mediaSessions_1.mediaSessionsTool);
137
- registry.register((0, lookupToolSchema_1.makeLookupToolSchema)(registry));
144
+ register(mediaSessions_1.mediaSessionsTool);
145
+ register((0, lookupToolSchema_1.makeLookupToolSchema)(registry));
138
146
  // Phase v4.1-subagent — register a stub for subagent_fanout so its
139
147
  // schema is visible to the agent loop, the MCP server, and the
140
148
  // /tools slash command BEFORE the runtime resolves provider /
141
149
  // adapter / agent dependencies. The full runtime calls
142
- // `registry.register(makeSubagentFanoutTool({...real opts}))` to
150
+ // `register(makeSubagentFanoutTool({...real opts}))` to
143
151
  // replace this stub once `buildAgentRuntime` has those handles.
144
152
  // Until then, calling the stub returns a clear "not wired" error
145
153
  // rather than crashing.
146
- registry.register(makeSubagentFanoutStub());
154
+ register(makeSubagentFanoutStub());
147
155
  }
148
156
  /** Stub used until the runtime wires real provider / adapter / agent
149
157
  * dependencies. Returns the SAME schema as the real tool so MCP and
@@ -156,7 +164,7 @@ function makeSubagentFanoutStub() {
156
164
  apiMode: 'chat_completions',
157
165
  async call() {
158
166
  throw new Error('subagent_fanout: tool not wired — runtime did not replace the stub. ' +
159
- 'Call registry.register(makeSubagentFanoutTool({...})) after buildAgentRuntime.');
167
+ 'Call register(makeSubagentFanoutTool({...})) after buildAgentRuntime.');
160
168
  },
161
169
  },
162
170
  runChild: async () => {
@@ -170,50 +178,55 @@ function makeSubagentFanoutStub() {
170
178
  * engine — the registration order doesn't matter for that.
171
179
  */
172
180
  function registerWriteTools(registry) {
173
- registry.register(fileWrite_1.fileWriteTool);
174
- registry.register(filePatch_1.filePatchTool);
175
- registry.register(fileDelete_1.fileDeleteTool);
176
- registry.register(fileMove_1.fileMoveTool);
177
- registry.register(fileCopy_1.fileCopyTool);
178
- registry.register(shellExec_1.shellExecTool);
179
- registry.register(browserNavigate_1.browserNavigateTool);
180
- registry.register(browserClick_1.browserClickTool);
181
- registry.register(browserType_1.browserTypeTool);
182
- registry.register(browserFill_1.browserFillTool);
183
- registry.register(browserScroll_1.browserScrollTool);
184
- registry.register(browserClose_1.browserCloseTool);
185
- registry.register(executeCode_1.executeCodeTool);
186
- registry.register(processSpawn_1.processSpawnTool);
187
- registry.register(processList_1.processListTool);
188
- registry.register(processLogRead_1.processLogReadTool);
189
- registry.register(processKill_1.processKillTool);
190
- registry.register(processWait_1.processWaitTool);
181
+ // v4.4 Phase 4 — same withDryRun wrap as registerReadOnlyTools.
182
+ // Write tools are where the preview path is actually hot — when
183
+ // AIDEN_DRYRUN=1, each handler's `buildPreview` is called instead
184
+ // of `execute`.
185
+ const register = (h) => registry.register((0, dryRun_1.withDryRun)(h));
186
+ register(fileWrite_1.fileWriteTool);
187
+ register(filePatch_1.filePatchTool);
188
+ register(fileDelete_1.fileDeleteTool);
189
+ register(fileMove_1.fileMoveTool);
190
+ register(fileCopy_1.fileCopyTool);
191
+ register(shellExec_1.shellExecTool);
192
+ register(browserNavigate_1.browserNavigateTool);
193
+ register(browserClick_1.browserClickTool);
194
+ register(browserType_1.browserTypeTool);
195
+ register(browserFill_1.browserFillTool);
196
+ register(browserScroll_1.browserScrollTool);
197
+ register(browserClose_1.browserCloseTool);
198
+ register(executeCode_1.executeCodeTool);
199
+ register(processSpawn_1.processSpawnTool);
200
+ register(processList_1.processListTool);
201
+ register(processLogRead_1.processLogReadTool);
202
+ register(processKill_1.processKillTool);
203
+ register(processWait_1.processWaitTool);
191
204
  // Phase 9: memory write tools (gated by MemoryGuard for read-back
192
205
  // verification, then by the approval engine like every other write).
193
- registry.register(memoryAdd_1.memoryAddTool);
194
- registry.register(memoryReplace_1.memoryReplaceTool);
195
- registry.register(memoryRemove_1.memoryRemoveTool);
206
+ register(memoryAdd_1.memoryAddTool);
207
+ register(memoryReplace_1.memoryReplaceTool);
208
+ register(memoryRemove_1.memoryRemoveTool);
196
209
  // Phase v4.1.2 alive-core: cross-session continuity via /quit auto-summary.
197
- registry.register(sessionSummary_1.sessionSummaryTool);
210
+ register(sessionSummary_1.sessionSummaryTool);
198
211
  // Phase 10: skill_manage — mutating, also goes through the approval
199
212
  // engine. skills_list / skill_view stay in registerReadOnlyTools.
200
- registry.register(skillManage_1.skillManageTool);
213
+ register(skillManage_1.skillManageTool);
201
214
  // Phase v4.1.2-update: natural-language entry to the same install
202
215
  // executor that /update install uses. Two-step confirmation gate
203
216
  // (confirm:false → status; confirm:true → install).
204
- registry.register(aidenSelfUpdate_1.aidenSelfUpdateTool);
217
+ register(aidenSelfUpdate_1.aidenSelfUpdateTool);
205
218
  // Phase v4.1.2-followup-3 — computer-control mutating tools. All
206
219
  // route through the approval engine like every other write.
207
- registry.register(mediaKey_1.mediaKeyTool);
208
- registry.register(volumeSet_1.volumeSetTool);
209
- registry.register(appLaunch_1.appLaunchTool);
210
- registry.register(appClose_1.appCloseTool);
211
- registry.register(clipboardWrite_1.clipboardWriteTool);
220
+ register(mediaKey_1.mediaKeyTool);
221
+ register(volumeSet_1.volumeSetTool);
222
+ register(appLaunch_1.appLaunchTool);
223
+ register(appClose_1.appCloseTool);
224
+ register(clipboardWrite_1.clipboardWriteTool);
212
225
  // v4.1.4-media — verified GSMTC transport (replaces mediaKey for
213
226
  // the "name an app, play/pause it" case) + focused-window SendKeys
214
227
  // (escape hatch when GSMTC doesn't enumerate the surface).
215
- registry.register(mediaTransport_1.mediaTransportTool);
216
- registry.register(appInput_1.appInputTool);
228
+ register(mediaTransport_1.mediaTransportTool);
229
+ register(appInput_1.appInputTool);
217
230
  }
218
231
  /** Register every v4 tool. Most callers want this. */
219
232
  function registerAllTools(registry) {
@@ -17,6 +17,7 @@
17
17
  */
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.memoryAddTool = void 0;
20
+ const dryRun_1 = require("../../../core/v4/dryRun");
20
21
  exports.memoryAddTool = {
21
22
  schema: {
22
23
  name: 'memory_add',
@@ -37,6 +38,19 @@ exports.memoryAddTool = {
37
38
  category: 'write',
38
39
  mutates: true,
39
40
  toolset: 'memory',
41
+ riskTier: 'caution', // v4.4 Phase 1
42
+ buildPreview(args) {
43
+ const file = args.file === 'user' ? 'user' : 'memory';
44
+ const content = String(args.content ?? '');
45
+ return {
46
+ tool: 'memory_add',
47
+ args,
48
+ riskTier: 'caution',
49
+ sideEffects: [{ type: 'memory_write', op: 'add', bullet: (0, dryRun_1.truncatePreview)(content) }],
50
+ detectedRisks: [],
51
+ summary: `Would append to ${file === 'user' ? 'USER.md' : 'MEMORY.md'}: "${(0, dryRun_1.truncatePreview)(content, 80)}"`,
52
+ };
53
+ },
40
54
  async execute(args, ctx) {
41
55
  if (!ctx.memoryGuard) {
42
56
  return { success: false, error: 'memory guard not configured' };
@@ -31,6 +31,7 @@
31
31
  Object.defineProperty(exports, "__esModule", { value: true });
32
32
  exports.memoryRemoveTool = void 0;
33
33
  const memoryGuard_1 = require("../../../moat/memoryGuard");
34
+ const dryRun_1 = require("../../../core/v4/dryRun");
34
35
  /** Section in MEMORY.md that Phase D promotion writes to. */
35
36
  const DURABLE_FACTS_HEADER = '## Durable facts';
36
37
  exports.memoryRemoveTool = {
@@ -59,6 +60,19 @@ exports.memoryRemoveTool = {
59
60
  category: 'write',
60
61
  mutates: true,
61
62
  toolset: 'memory',
63
+ riskTier: 'caution', // v4.4 Phase 1
64
+ buildPreview(args) {
65
+ const file = args.file === 'user' ? 'user' : 'memory';
66
+ const text = String(args.text ?? '');
67
+ return {
68
+ tool: 'memory_remove',
69
+ args,
70
+ riskTier: 'caution',
71
+ sideEffects: [{ type: 'memory_write', op: 'remove', pattern: (0, dryRun_1.truncatePreview)(text, 80) }],
72
+ detectedRisks: [],
73
+ summary: `Would remove from ${file === 'user' ? 'USER.md' : 'MEMORY.md'}: "${(0, dryRun_1.truncatePreview)(text, 80)}"`,
74
+ };
75
+ },
62
76
  async execute(args, ctx) {
63
77
  if (!ctx.memoryGuard) {
64
78
  return { success: false, error: 'memory guard not configured' };
@@ -16,6 +16,7 @@
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.memoryReplaceTool = void 0;
19
+ const dryRun_1 = require("../../../core/v4/dryRun");
19
20
  exports.memoryReplaceTool = {
20
21
  schema: {
21
22
  name: 'memory_replace',
@@ -37,6 +38,20 @@ exports.memoryReplaceTool = {
37
38
  category: 'write',
38
39
  mutates: true,
39
40
  toolset: 'memory',
41
+ riskTier: 'caution', // v4.4 Phase 1
42
+ buildPreview(args) {
43
+ const file = args.file === 'user' ? 'user' : 'memory';
44
+ const oldText = String(args.old_text ?? args.oldText ?? '');
45
+ const newText = String(args.new_text ?? args.newText ?? '');
46
+ return {
47
+ tool: 'memory_replace',
48
+ args,
49
+ riskTier: 'caution',
50
+ sideEffects: [{ type: 'memory_write', op: 'replace', pattern: (0, dryRun_1.truncatePreview)(oldText, 80), bullet: (0, dryRun_1.truncatePreview)(newText, 80) }],
51
+ detectedRisks: [],
52
+ summary: `Would replace in ${file === 'user' ? 'USER.md' : 'MEMORY.md'}: "${(0, dryRun_1.truncatePreview)(oldText, 40)}" → "${(0, dryRun_1.truncatePreview)(newText, 40)}"`,
53
+ };
54
+ },
40
55
  async execute(args, ctx) {
41
56
  if (!ctx.memoryGuard) {
42
57
  return { success: false, error: 'memory guard not configured' };
@@ -100,6 +100,18 @@ exports.sessionSummaryTool = {
100
100
  category: 'write',
101
101
  mutates: true,
102
102
  toolset: 'memory',
103
+ riskTier: 'caution', // v4.4 Phase 1
104
+ buildPreview(args, ctx) {
105
+ const sessionId = String(args.session_id ?? args.sessionId ?? ctx.sessionId ?? 'current');
106
+ return {
107
+ tool: 'session_summary',
108
+ args,
109
+ riskTier: 'caution',
110
+ sideEffects: [{ type: 'session_distill', session_id: sessionId }],
111
+ detectedRisks: [],
112
+ summary: `Would distill session ${sessionId} into Recent-sessions section of MEMORY.md`,
113
+ };
114
+ },
103
115
  async execute(args, ctx) {
104
116
  if (!ctx.memoryGuard) {
105
117
  return { success: false, error: 'memory guard not configured' };
@@ -31,6 +31,25 @@ exports.processKillTool = {
31
31
  category: 'write',
32
32
  mutates: true,
33
33
  toolset: 'process',
34
+ riskTier: 'dangerous', // v4.4 Phase 1
35
+ buildPreview(args, ctx) {
36
+ const id = String(args.id ?? '').trim();
37
+ const signal = args.signal || 'SIGTERM';
38
+ let pid = -1;
39
+ if (ctx.processes && id) {
40
+ const h = ctx.processes.get(id);
41
+ if (h && typeof h.pid === 'number')
42
+ pid = h.pid;
43
+ }
44
+ return {
45
+ tool: 'process_kill',
46
+ args,
47
+ riskTier: 'dangerous',
48
+ sideEffects: [{ type: 'process_kill', pid, signal }],
49
+ detectedRisks: signal === 'SIGKILL' ? ['SIGKILL'] : [],
50
+ summary: `Would send ${signal} to process ${id}${pid > 0 ? ` (pid ${pid})` : ''}`,
51
+ };
52
+ },
34
53
  async execute(args, ctx) {
35
54
  if (!ctx.processes) {
36
55
  return { success: false, error: 'process registry not configured' };
@@ -21,6 +21,7 @@ exports.processListTool = {
21
21
  category: 'read',
22
22
  mutates: false,
23
23
  toolset: 'process',
24
+ riskTier: 'safe', // v4.4 Phase 1
24
25
  async execute(_args, ctx) {
25
26
  if (!ctx.processes) {
26
27
  return { success: false, error: 'process registry not configured' };
@@ -31,6 +31,7 @@ exports.processLogReadTool = {
31
31
  category: 'read',
32
32
  mutates: false,
33
33
  toolset: 'process',
34
+ riskTier: 'safe', // v4.4 Phase 1
34
35
  async execute(args, ctx) {
35
36
  if (!ctx.processes) {
36
37
  return { success: false, error: 'process registry not configured' };
@@ -32,6 +32,19 @@ exports.processSpawnTool = {
32
32
  category: 'execute',
33
33
  mutates: true,
34
34
  toolset: 'process',
35
+ riskTier: 'dangerous', // v4.4 Phase 1
36
+ buildPreview(args, ctx) {
37
+ const command = String(args.command ?? '').trim();
38
+ const cwd = typeof args.cwd === 'string' ? args.cwd : ctx.cwd;
39
+ return {
40
+ tool: 'process_spawn',
41
+ args,
42
+ riskTier: 'dangerous',
43
+ sideEffects: [{ type: 'process_spawn', command, args: [] }],
44
+ detectedRisks: [],
45
+ summary: `Would spawn background process: \`${command.length > 80 ? command.slice(0, 80) + '…' : command}\` in ${cwd}`,
46
+ };
47
+ },
35
48
  async execute(args, ctx) {
36
49
  if (!ctx.processes) {
37
50
  return { success: false, error: 'process registry not configured' };
@@ -33,6 +33,7 @@ exports.processWaitTool = {
33
33
  category: 'read',
34
34
  mutates: false,
35
35
  toolset: 'process',
36
+ riskTier: 'safe', // v4.4 Phase 1
36
37
  async execute(args, ctx) {
37
38
  if (!ctx.processes) {
38
39
  return { success: false, error: 'process registry not configured' };
@@ -78,6 +78,7 @@ exports.recallSessionTool = {
78
78
  category: 'read',
79
79
  mutates: false,
80
80
  toolset: 'sessions',
81
+ riskTier: 'safe', // v4.4 Phase 1
81
82
  async execute(args, ctx) {
82
83
  if (!ctx.paths?.root) {
83
84
  return {
@@ -40,6 +40,7 @@ exports.sessionListTool = {
40
40
  category: 'read',
41
41
  mutates: false,
42
42
  toolset: 'sessions',
43
+ riskTier: 'safe', // v4.4 Phase 1
43
44
  async execute(args, ctx) {
44
45
  if (!ctx.sessions) {
45
46
  return {
@@ -45,6 +45,7 @@ exports.sessionSearchTool = {
45
45
  category: 'read',
46
46
  mutates: false,
47
47
  toolset: 'sessions',
48
+ riskTier: 'safe', // v4.4 Phase 1
48
49
  async execute(args, ctx) {
49
50
  const query = String(args.query ?? '').trim();
50
51
  if (!query)
@@ -45,6 +45,7 @@ function makeLookupToolSchema(registry) {
45
45
  category: 'read',
46
46
  mutates: false,
47
47
  toolset: 'skills',
48
+ riskTier: 'safe', // v4.4 Phase 1
48
49
  async execute(args) {
49
50
  const name = String(args.toolName ?? args.name ?? '').trim();
50
51
  if (!name)
@@ -63,6 +64,7 @@ function makeLookupToolSchema(registry) {
63
64
  category: handler.category,
64
65
  mutates: handler.mutates,
65
66
  toolset: handler.toolset,
67
+ riskTier: 'safe', // v4.4 Phase 1
66
68
  };
67
69
  },
68
70
  };
@@ -78,6 +78,19 @@ exports.skillManageTool = {
78
78
  category: 'write',
79
79
  mutates: true,
80
80
  toolset: 'skills',
81
+ riskTier: 'caution', // v4.4 Phase 1
82
+ buildPreview(args) {
83
+ const action = typeof args.action === 'string' ? args.action : '';
84
+ const name = typeof args.name === 'string' ? args.name : '';
85
+ return {
86
+ tool: 'skill_manage',
87
+ args,
88
+ riskTier: 'caution',
89
+ sideEffects: [{ type: 'skill_write', op: action, name }],
90
+ detectedRisks: action === 'delete' ? ['skill_delete'] : [],
91
+ summary: `Would ${action} skill: ${name}`,
92
+ };
93
+ },
81
94
  async execute(args, ctx) {
82
95
  if (!ctx.skillLoader || !ctx.paths) {
83
96
  return { success: false, error: 'No skill loader configured' };
@@ -38,6 +38,7 @@ exports.skillViewTool = {
38
38
  category: 'read',
39
39
  mutates: false,
40
40
  toolset: 'skills',
41
+ riskTier: 'safe', // v4.4 Phase 1
41
42
  async execute(args, ctx) {
42
43
  if (!ctx.skillLoader) {
43
44
  return { success: false, error: 'No skill loader configured' };
@@ -31,6 +31,7 @@ exports.skillsListTool = {
31
31
  category: 'read',
32
32
  mutates: false,
33
33
  toolset: 'skills',
34
+ riskTier: 'safe', // v4.4 Phase 1
34
35
  async execute(_args, ctx) {
35
36
  if (!ctx.skillLoader) {
36
37
  return {
@@ -122,6 +122,7 @@ function makeSubagentFanoutTool(factory) {
122
122
  category: 'network',
123
123
  mutates: false,
124
124
  toolset: 'subagent',
125
+ riskTier: 'caution', // v4.4 Phase 1
125
126
  async execute(args, _ctx) {
126
127
  const logger = factory.logger ?? (0, factory_1.noopLogger)();
127
128
  // ── Coerce args ────────────────────────────────────────────
@@ -68,6 +68,22 @@ exports.aidenSelfUpdateTool = {
68
68
  category: 'write',
69
69
  mutates: true,
70
70
  toolset: 'system',
71
+ riskTier: 'dangerous', // v4.4 Phase 1
72
+ // v4.4 Phase 4 — dry-run refuses; self-update bootstrapping is not
73
+ // safe to model with a no-op preview.
74
+ buildPreview(args) {
75
+ return {
76
+ tool: 'aiden_self_update',
77
+ args,
78
+ riskTier: 'dangerous',
79
+ sideEffects: [{
80
+ type: 'refuse',
81
+ reason: 'aiden_self_update is not safe to preview in dry-run mode. Set AIDEN_DRYRUN=0 to perform a real self-update (with the usual approval-engine confirmation).',
82
+ }],
83
+ detectedRisks: ['self_update'],
84
+ summary: 'Refused: aiden_self_update cannot be previewed in dry-run mode',
85
+ };
86
+ },
71
87
  async execute(args, ctx) {
72
88
  if (!ctx.paths) {
73
89
  return {
@@ -53,6 +53,19 @@ exports.appCloseTool = {
53
53
  category: 'execute',
54
54
  mutates: true,
55
55
  toolset: 'system',
56
+ riskTier: 'caution', // v4.4 Phase 1
57
+ buildPreview(args) {
58
+ const app = typeof args.app === 'string' ? args.app : '';
59
+ const force = args.force === true;
60
+ return {
61
+ tool: 'app_close',
62
+ args,
63
+ riskTier: 'caution',
64
+ sideEffects: [{ type: 'app_control', action: force ? 'force-close' : 'close', target: app }],
65
+ detectedRisks: force ? ['force_close'] : [],
66
+ summary: `Would ${force ? 'force-' : ''}close app: ${app}`,
67
+ };
68
+ },
56
69
  async execute(args, _ctx) {
57
70
  if (!(0, _psHelpers_1.isWindows)())
58
71
  return (0, _psHelpers_1.windowsOnlyError)('app_close');
@@ -89,6 +89,19 @@ exports.appInputTool = {
89
89
  category: 'execute',
90
90
  mutates: true,
91
91
  toolset: 'system',
92
+ riskTier: 'caution', // v4.4 Phase 1
93
+ buildPreview(args) {
94
+ const app = typeof args.app === 'string' ? args.app : '';
95
+ const keys = typeof args.keys === 'string' ? args.keys : '';
96
+ return {
97
+ tool: 'app_input',
98
+ args,
99
+ riskTier: 'caution',
100
+ sideEffects: [{ type: 'app_control', action: `send-keys:${keys}`, target: app }],
101
+ detectedRisks: [],
102
+ summary: `Would send keys "${keys}" to app: ${app}`,
103
+ };
104
+ },
92
105
  async execute(args, _ctx) {
93
106
  if (!(0, _psHelpers_1.isWindows)()) {
94
107
  return (0, _psHelpers_1.windowsOnlyError)('app_input', {
@@ -123,6 +123,19 @@ exports.appLaunchTool = {
123
123
  category: 'execute',
124
124
  mutates: true,
125
125
  toolset: 'system',
126
+ riskTier: 'caution', // v4.4 Phase 1
127
+ buildPreview(args) {
128
+ const app = typeof args.app === 'string' ? args.app : '';
129
+ const cliArgs = Array.isArray(args.args) ? args.args.map(String) : [];
130
+ return {
131
+ tool: 'app_launch',
132
+ args,
133
+ riskTier: 'caution',
134
+ sideEffects: [{ type: 'app_control', action: 'launch', target: app + (cliArgs.length ? ' ' + cliArgs.join(' ') : '') }],
135
+ detectedRisks: [],
136
+ summary: `Would launch app: ${app}${cliArgs.length ? ' with args ' + cliArgs.join(' ') : ''}`,
137
+ };
138
+ },
126
139
  async execute(args, _ctx) {
127
140
  if (!(0, _psHelpers_1.isWindows)())
128
141
  return (0, _psHelpers_1.windowsOnlyError)('app_launch');
@@ -32,6 +32,7 @@ exports.clipboardReadTool = {
32
32
  category: 'read',
33
33
  mutates: false,
34
34
  toolset: 'system',
35
+ riskTier: 'safe', // v4.4 Phase 1
35
36
  async execute(_args, _ctx) {
36
37
  if (!(0, _psHelpers_1.isWindows)())
37
38
  return (0, _psHelpers_1.windowsOnlyError)('clipboard_read');
@@ -19,6 +19,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.clipboardWriteTool = void 0;
20
20
  const node_child_process_1 = require("node:child_process");
21
21
  const _psHelpers_1 = require("./_psHelpers");
22
+ const dryRun_1 = require("../../../core/v4/dryRun");
22
23
  /**
23
24
  * Spawn `powershell.exe Set-Clipboard` with the text piped on stdin.
24
25
  * Wrapper Promise so the tool's `execute` can `await` it.
@@ -61,6 +62,19 @@ exports.clipboardWriteTool = {
61
62
  category: 'execute',
62
63
  mutates: true,
63
64
  toolset: 'system',
65
+ riskTier: 'caution', // v4.4 Phase 1
66
+ buildPreview(args) {
67
+ const text = typeof args.text === 'string' ? args.text : '';
68
+ const bytes = Buffer.byteLength(text, 'utf-8');
69
+ return {
70
+ tool: 'clipboard_write',
71
+ args,
72
+ riskTier: 'caution',
73
+ sideEffects: [{ type: 'clipboard_write', bytes, preview: (0, dryRun_1.truncatePreview)(text) }],
74
+ detectedRisks: [],
75
+ summary: `Would write ${bytes} bytes to clipboard`,
76
+ };
77
+ },
64
78
  async execute(args, _ctx) {
65
79
  if (!(0, _psHelpers_1.isWindows)())
66
80
  return (0, _psHelpers_1.windowsOnlyError)('clipboard_write');
@@ -53,6 +53,18 @@ exports.mediaKeyTool = {
53
53
  category: 'execute',
54
54
  mutates: true,
55
55
  toolset: 'system',
56
+ riskTier: 'caution', // v4.4 Phase 1
57
+ buildPreview(args) {
58
+ const action = typeof args.action === 'string' ? args.action : '';
59
+ return {
60
+ tool: 'media_key',
61
+ args,
62
+ riskTier: 'caution',
63
+ sideEffects: [{ type: 'media_control', action }],
64
+ detectedRisks: [],
65
+ summary: `Would send media key: ${action}`,
66
+ };
67
+ },
56
68
  async execute(args, _ctx) {
57
69
  if (!(0, _psHelpers_1.isWindows)()) {
58
70
  return (0, _psHelpers_1.windowsOnlyError)('media_key', {
@@ -113,6 +113,7 @@ exports.mediaSessionsTool = {
113
113
  category: 'read',
114
114
  mutates: false,
115
115
  toolset: 'system',
116
+ riskTier: 'safe', // v4.4 Phase 1
116
117
  async execute(_args, _ctx) {
117
118
  if (!(0, _psHelpers_1.isWindows)()) {
118
119
  return (0, _psHelpers_1.windowsOnlyError)('media_sessions', {
@@ -135,6 +135,19 @@ exports.mediaTransportTool = {
135
135
  category: 'execute',
136
136
  mutates: true,
137
137
  toolset: 'system',
138
+ riskTier: 'caution', // v4.4 Phase 1
139
+ buildPreview(args) {
140
+ const action = typeof args.action === 'string' ? args.action : '';
141
+ const target = typeof args.target === 'string' ? args.target : '';
142
+ return {
143
+ tool: 'media_transport',
144
+ args,
145
+ riskTier: 'caution',
146
+ sideEffects: [{ type: 'media_control', action: target ? `${action}:${target}` : action }],
147
+ detectedRisks: [],
148
+ summary: `Would invoke media transport: ${action}${target ? ` on ${target}` : ' (current session)'}`,
149
+ };
150
+ },
138
151
  async execute(args, _ctx) {
139
152
  if (!(0, _psHelpers_1.isWindows)()) {
140
153
  // v4.1.3-essentials: tailored capability card for non-Windows.