@aria-cli/tools 1.0.12 → 1.0.14

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 (233) hide show
  1. package/dist/index.js +378 -70
  2. package/dist/network-runtime/index.js +8 -12
  3. package/dist-cjs/index.js +400 -435
  4. package/dist-cjs/network-runtime/index.js +8 -172
  5. package/package.json +8 -6
  6. package/dist/.tsbuildinfo +0 -1
  7. package/dist/ask-user-interaction.js +0 -22
  8. package/dist/cache/web-cache.js +0 -66
  9. package/dist/definitions/arion.js +0 -104
  10. package/dist/definitions/browser/browser.js +0 -418
  11. package/dist/definitions/browser/index.js +0 -4
  12. package/dist/definitions/browser/pw-downloads.js +0 -114
  13. package/dist/definitions/browser/pw-interactions.js +0 -199
  14. package/dist/definitions/browser/pw-responses.js +0 -76
  15. package/dist/definitions/browser/pw-session.js +0 -310
  16. package/dist/definitions/browser/pw-shared.js +0 -66
  17. package/dist/definitions/browser/pw-snapshot.js +0 -301
  18. package/dist/definitions/browser/pw-state.js +0 -62
  19. package/dist/definitions/browser/types.js +0 -4
  20. package/dist/definitions/code-intelligence.js +0 -470
  21. package/dist/definitions/core.js +0 -109
  22. package/dist/definitions/delegation.js +0 -512
  23. package/dist/definitions/deploy.js +0 -65
  24. package/dist/definitions/filesystem.js +0 -196
  25. package/dist/definitions/frg.js +0 -63
  26. package/dist/definitions/index.js +0 -20
  27. package/dist/definitions/memory.js +0 -123
  28. package/dist/definitions/messaging.js +0 -625
  29. package/dist/definitions/meta.js +0 -349
  30. package/dist/definitions/network.js +0 -159
  31. package/dist/definitions/outlook.js +0 -277
  32. package/dist/definitions/patch/apply-patch.js +0 -184
  33. package/dist/definitions/patch/fuzzy-match.js +0 -166
  34. package/dist/definitions/patch/index.js +0 -1
  35. package/dist/definitions/patch/patch-parser.js +0 -207
  36. package/dist/definitions/patch/sandbox-paths.js +0 -105
  37. package/dist/definitions/process/index.js +0 -4
  38. package/dist/definitions/process/process-registry.js +0 -213
  39. package/dist/definitions/process/process.js +0 -386
  40. package/dist/definitions/process/pty-keys.js +0 -254
  41. package/dist/definitions/process/session-slug.js +0 -142
  42. package/dist/definitions/quip.js +0 -195
  43. package/dist/definitions/search.js +0 -60
  44. package/dist/definitions/session-history.js +0 -69
  45. package/dist/definitions/shell.js +0 -181
  46. package/dist/definitions/slack.js +0 -180
  47. package/dist/definitions/web.js +0 -109
  48. package/dist/executors/apply-patch.js +0 -901
  49. package/dist/executors/arion.js +0 -119
  50. package/dist/executors/code-intelligence.js +0 -882
  51. package/dist/executors/deploy.js +0 -848
  52. package/dist/executors/filesystem.js +0 -1122
  53. package/dist/executors/frg-freshness.js +0 -576
  54. package/dist/executors/frg.js +0 -298
  55. package/dist/executors/index.js +0 -46
  56. package/dist/executors/learning-meta.js +0 -1146
  57. package/dist/executors/lsp-client.js +0 -296
  58. package/dist/executors/memory.js +0 -750
  59. package/dist/executors/meta.js +0 -220
  60. package/dist/executors/process-registry.js +0 -465
  61. package/dist/executors/pty-session-store.js +0 -30
  62. package/dist/executors/pty.js +0 -271
  63. package/dist/executors/restart.js +0 -119
  64. package/dist/executors/search-freshness.js +0 -195
  65. package/dist/executors/search-types.js +0 -52
  66. package/dist/executors/search.js +0 -66
  67. package/dist/executors/self-diagnose.js +0 -398
  68. package/dist/executors/session-history.js +0 -283
  69. package/dist/executors/shell-safety.js +0 -473
  70. package/dist/executors/shell.js +0 -954
  71. package/dist/executors/utils.js +0 -33
  72. package/dist/executors/web.js +0 -542
  73. package/dist/extraction/content-extraction.js +0 -235
  74. package/dist/extraction/index.js +0 -4
  75. package/dist/headless-control-contract.js +0 -967
  76. package/dist/local-control-http-auth.js +0 -2
  77. package/dist/mcp/client.js +0 -181
  78. package/dist/mcp/connection.js +0 -480
  79. package/dist/mcp/index.js +0 -10
  80. package/dist/mcp/jsonrpc.js +0 -144
  81. package/dist/mcp/types.js +0 -7
  82. package/dist/network-control-adapter.js +0 -72
  83. package/dist/network-runtime/address-types.js +0 -165
  84. package/dist/network-runtime/db-owner-fencing.js +0 -69
  85. package/dist/network-runtime/delivery-receipts.js +0 -267
  86. package/dist/network-runtime/direct-endpoint-authority.js +0 -25
  87. package/dist/network-runtime/local-control-contract.js +0 -627
  88. package/dist/network-runtime/node-store-contract.js +0 -34
  89. package/dist/network-runtime/pair-route-contract.js +0 -77
  90. package/dist/network-runtime/peer-capabilities.js +0 -28
  91. package/dist/network-runtime/peer-principal-ref.js +0 -12
  92. package/dist/network-runtime/peer-state-machine.js +0 -121
  93. package/dist/network-runtime/protocol-schemas.js +0 -205
  94. package/dist/network-runtime/runtime-bootstrap-contract.js +0 -60
  95. package/dist/outlook/desktop-session.js +0 -279
  96. package/dist/policy.js +0 -149
  97. package/dist/providers/brave.js +0 -62
  98. package/dist/providers/duckduckgo.js +0 -176
  99. package/dist/providers/exa.js +0 -63
  100. package/dist/providers/firecrawl.js +0 -55
  101. package/dist/providers/index.js +0 -7
  102. package/dist/providers/jina.js +0 -49
  103. package/dist/providers/router.js +0 -96
  104. package/dist/providers/search-provider.js +0 -32
  105. package/dist/providers/tavily.js +0 -54
  106. package/dist/quip/desktop-session.js +0 -317
  107. package/dist/registry/index.js +0 -1
  108. package/dist/registry/registry.js +0 -756
  109. package/dist/runtime-socket-local-control-client.js +0 -330
  110. package/dist/security/dns-normalization.js +0 -19
  111. package/dist/security/dns-pinning.js +0 -123
  112. package/dist/security/external-content.js +0 -91
  113. package/dist/security/ssrf.js +0 -181
  114. package/dist/slack/desktop-session.js +0 -324
  115. package/dist/tool-factory.js +0 -47
  116. package/dist/types.js +0 -7
  117. package/dist/utils/retry.js +0 -132
  118. package/dist/utils/safe-parse-json.js +0 -160
  119. package/dist/utils/url.js +0 -19
  120. package/dist-cjs/.tsbuildinfo +0 -1
  121. package/dist-cjs/ask-user-interaction.js +0 -27
  122. package/dist-cjs/cache/web-cache.js +0 -70
  123. package/dist-cjs/definitions/arion.js +0 -107
  124. package/dist-cjs/definitions/browser/browser.js +0 -421
  125. package/dist-cjs/definitions/browser/index.js +0 -8
  126. package/dist-cjs/definitions/browser/pw-downloads.js +0 -117
  127. package/dist-cjs/definitions/browser/pw-interactions.js +0 -213
  128. package/dist-cjs/definitions/browser/pw-responses.js +0 -84
  129. package/dist-cjs/definitions/browser/pw-session.js +0 -326
  130. package/dist-cjs/definitions/browser/pw-shared.js +0 -72
  131. package/dist-cjs/definitions/browser/pw-snapshot.js +0 -307
  132. package/dist-cjs/definitions/browser/pw-state.js +0 -70
  133. package/dist-cjs/definitions/browser/types.js +0 -5
  134. package/dist-cjs/definitions/code-intelligence.js +0 -473
  135. package/dist-cjs/definitions/core.js +0 -133
  136. package/dist-cjs/definitions/delegation.js +0 -515
  137. package/dist-cjs/definitions/deploy.js +0 -68
  138. package/dist-cjs/definitions/filesystem.js +0 -199
  139. package/dist-cjs/definitions/frg.js +0 -66
  140. package/dist-cjs/definitions/index.js +0 -43
  141. package/dist-cjs/definitions/memory.js +0 -126
  142. package/dist-cjs/definitions/messaging.js +0 -631
  143. package/dist-cjs/definitions/meta.js +0 -352
  144. package/dist-cjs/definitions/network.js +0 -162
  145. package/dist-cjs/definitions/outlook.js +0 -280
  146. package/dist-cjs/definitions/patch/apply-patch.js +0 -191
  147. package/dist-cjs/definitions/patch/fuzzy-match.js +0 -172
  148. package/dist-cjs/definitions/patch/index.js +0 -5
  149. package/dist-cjs/definitions/patch/patch-parser.js +0 -215
  150. package/dist-cjs/definitions/patch/sandbox-paths.js +0 -113
  151. package/dist-cjs/definitions/process/index.js +0 -8
  152. package/dist-cjs/definitions/process/process-registry.js +0 -231
  153. package/dist-cjs/definitions/process/process.js +0 -389
  154. package/dist-cjs/definitions/process/pty-keys.js +0 -259
  155. package/dist-cjs/definitions/process/session-slug.js +0 -145
  156. package/dist-cjs/definitions/quip.js +0 -198
  157. package/dist-cjs/definitions/search.js +0 -63
  158. package/dist-cjs/definitions/session-history.js +0 -72
  159. package/dist-cjs/definitions/shell.js +0 -184
  160. package/dist-cjs/definitions/slack.js +0 -183
  161. package/dist-cjs/definitions/web.js +0 -112
  162. package/dist-cjs/executors/apply-patch.js +0 -938
  163. package/dist-cjs/executors/arion.js +0 -125
  164. package/dist-cjs/executors/code-intelligence.js +0 -925
  165. package/dist-cjs/executors/deploy.js +0 -869
  166. package/dist-cjs/executors/filesystem.js +0 -1167
  167. package/dist-cjs/executors/frg-freshness.js +0 -627
  168. package/dist-cjs/executors/frg.js +0 -334
  169. package/dist-cjs/executors/index.js +0 -143
  170. package/dist-cjs/executors/learning-meta.js +0 -1165
  171. package/dist-cjs/executors/lsp-client.js +0 -310
  172. package/dist-cjs/executors/memory.js +0 -796
  173. package/dist-cjs/executors/meta.js +0 -226
  174. package/dist-cjs/executors/process-registry.js +0 -469
  175. package/dist-cjs/executors/pty-session-store.js +0 -34
  176. package/dist-cjs/executors/pty.js +0 -312
  177. package/dist-cjs/executors/restart.js +0 -155
  178. package/dist-cjs/executors/search-freshness.js +0 -234
  179. package/dist-cjs/executors/search-types.js +0 -56
  180. package/dist-cjs/executors/search.js +0 -102
  181. package/dist-cjs/executors/self-diagnose.js +0 -434
  182. package/dist-cjs/executors/session-history.js +0 -320
  183. package/dist-cjs/executors/shell-safety.js +0 -478
  184. package/dist-cjs/executors/shell.js +0 -1001
  185. package/dist-cjs/executors/utils.js +0 -73
  186. package/dist-cjs/executors/web.js +0 -547
  187. package/dist-cjs/extraction/content-extraction.js +0 -243
  188. package/dist-cjs/extraction/index.js +0 -8
  189. package/dist-cjs/headless-control-contract.js +0 -972
  190. package/dist-cjs/local-control-http-auth.js +0 -5
  191. package/dist-cjs/mcp/client.js +0 -185
  192. package/dist-cjs/mcp/connection.js +0 -484
  193. package/dist-cjs/mcp/index.js +0 -30
  194. package/dist-cjs/mcp/jsonrpc.js +0 -148
  195. package/dist-cjs/mcp/types.js +0 -8
  196. package/dist-cjs/network-control-adapter.js +0 -77
  197. package/dist-cjs/network-runtime/address-types.js +0 -168
  198. package/dist-cjs/network-runtime/db-owner-fencing.js +0 -76
  199. package/dist-cjs/network-runtime/delivery-receipts.js +0 -276
  200. package/dist-cjs/network-runtime/direct-endpoint-authority.js +0 -29
  201. package/dist-cjs/network-runtime/local-control-contract.js +0 -633
  202. package/dist-cjs/network-runtime/node-store-contract.js +0 -38
  203. package/dist-cjs/network-runtime/pair-route-contract.js +0 -80
  204. package/dist-cjs/network-runtime/peer-capabilities.js +0 -37
  205. package/dist-cjs/network-runtime/peer-principal-ref.js +0 -15
  206. package/dist-cjs/network-runtime/peer-state-machine.js +0 -129
  207. package/dist-cjs/network-runtime/protocol-schemas.js +0 -212
  208. package/dist-cjs/network-runtime/runtime-bootstrap-contract.js +0 -63
  209. package/dist-cjs/outlook/desktop-session.js +0 -318
  210. package/dist-cjs/policy.js +0 -155
  211. package/dist-cjs/providers/brave.js +0 -66
  212. package/dist-cjs/providers/duckduckgo.js +0 -180
  213. package/dist-cjs/providers/exa.js +0 -67
  214. package/dist-cjs/providers/firecrawl.js +0 -59
  215. package/dist-cjs/providers/index.js +0 -17
  216. package/dist-cjs/providers/jina.js +0 -53
  217. package/dist-cjs/providers/router.js +0 -100
  218. package/dist-cjs/providers/search-provider.js +0 -36
  219. package/dist-cjs/providers/tavily.js +0 -58
  220. package/dist-cjs/quip/desktop-session.js +0 -353
  221. package/dist-cjs/registry/index.js +0 -6
  222. package/dist-cjs/registry/registry.js +0 -761
  223. package/dist-cjs/runtime-socket-local-control-client.js +0 -367
  224. package/dist-cjs/security/dns-normalization.js +0 -22
  225. package/dist-cjs/security/dns-pinning.js +0 -160
  226. package/dist-cjs/security/external-content.js +0 -95
  227. package/dist-cjs/security/ssrf.js +0 -221
  228. package/dist-cjs/slack/desktop-session.js +0 -366
  229. package/dist-cjs/tool-factory.js +0 -50
  230. package/dist-cjs/types.js +0 -8
  231. package/dist-cjs/utils/retry.js +0 -169
  232. package/dist-cjs/utils/safe-parse-json.js +0 -164
  233. package/dist-cjs/utils/url.js +0 -23
@@ -1,271 +0,0 @@
1
- /**
2
- * @aria/tools - PTY executor for interactive terminal programs
3
- *
4
- * Provides PTY (pseudo-terminal) support for running interactive programs
5
- * that require a terminal environment (like vim, less, etc.)
6
- */
7
- import * as nodePty from "node-pty";
8
- import { sanitizeEnv } from "./shell.js";
9
- /**
10
- * Error thrown when a PTY operation times out.
11
- */
12
- export class PTYTimeoutError extends Error {
13
- output;
14
- constructor(message, output) {
15
- super(message);
16
- this.output = output;
17
- this.name = "PTYTimeoutError";
18
- }
19
- }
20
- /**
21
- * Error thrown when a PTY operation fails.
22
- */
23
- export class PTYError extends Error {
24
- output;
25
- constructor(message, output) {
26
- super(message);
27
- this.output = output;
28
- this.name = "PTYError";
29
- }
30
- }
31
- /**
32
- * A session wrapping a PTY process.
33
- * Provides methods for interacting with the process and collecting output.
34
- */
35
- export class PTYSession {
36
- static MAX_OUTPUT = 10 * 1024 * 1024; // 10MB
37
- _output = "";
38
- _isRunning = true;
39
- _exitCode;
40
- _exitPromise;
41
- _exitResolve;
42
- _pty;
43
- _dataDisposable;
44
- _exitDisposable;
45
- constructor(pty) {
46
- this._pty = pty;
47
- // Set up exit promise
48
- this._exitPromise = new Promise((resolve) => {
49
- this._exitResolve = resolve;
50
- });
51
- // Collect output with buffer cap
52
- this._dataDisposable = pty.onData((data) => {
53
- this._output += data;
54
- if (this._output.length > PTYSession.MAX_OUTPUT) {
55
- this._output = this._output.slice(-PTYSession.MAX_OUTPUT);
56
- }
57
- });
58
- // Handle exit
59
- this._exitDisposable = pty.onExit(({ exitCode }) => {
60
- this._isRunning = false;
61
- this._exitCode = exitCode;
62
- this._exitResolve(exitCode);
63
- });
64
- }
65
- /**
66
- * Write data to the terminal input.
67
- */
68
- write(data) {
69
- if (!this._isRunning) {
70
- throw new PTYError("Cannot write to a closed PTY session");
71
- }
72
- this._pty.write(data);
73
- }
74
- /**
75
- * Resize the terminal.
76
- */
77
- resize(cols, rows) {
78
- if (!this._isRunning) {
79
- throw new PTYError("Cannot resize a closed PTY session");
80
- }
81
- this._pty.resize(cols, rows);
82
- }
83
- /**
84
- * Wait for a pattern to appear in the output.
85
- * @param pattern String or RegExp to match
86
- * @param timeoutMs Timeout in milliseconds (default: 5000)
87
- * @returns The output accumulated up to and including the match
88
- */
89
- async waitFor(pattern, timeoutMs = 5000) {
90
- const startTime = Date.now();
91
- const regex = typeof pattern === "string" ? new RegExp(escapeRegExp(pattern)) : pattern;
92
- // Check if pattern already matches
93
- if (regex.test(this._output)) {
94
- return this._output;
95
- }
96
- return new Promise((resolve, reject) => {
97
- let checkInterval;
98
- let timeoutHandle;
99
- const cleanup = () => {
100
- if (checkInterval)
101
- clearInterval(checkInterval);
102
- if (timeoutHandle)
103
- clearTimeout(timeoutHandle);
104
- };
105
- const check = () => {
106
- if (regex.test(this._output)) {
107
- cleanup();
108
- resolve(this._output);
109
- return true;
110
- }
111
- if (!this._isRunning) {
112
- cleanup();
113
- reject(new PTYError(`Process exited before pattern was found: ${pattern}`, this._output));
114
- return true;
115
- }
116
- return false;
117
- };
118
- // Initial check
119
- if (check())
120
- return;
121
- // Set up polling
122
- checkInterval = setInterval(() => {
123
- check();
124
- }, 10);
125
- // Set up timeout
126
- timeoutHandle = setTimeout(() => {
127
- cleanup();
128
- const elapsed = Date.now() - startTime;
129
- reject(new PTYTimeoutError(`Timeout (${elapsed}ms) waiting for pattern: ${pattern}`, this._output));
130
- }, timeoutMs);
131
- });
132
- }
133
- /**
134
- * Wait for the process to exit.
135
- * @param timeoutMs Timeout in milliseconds (default: 30000)
136
- * @returns The complete output
137
- */
138
- async waitForExit(timeoutMs = 30000) {
139
- if (!this._isRunning) {
140
- return this._output;
141
- }
142
- return new Promise((resolve, reject) => {
143
- let timeoutHandle;
144
- timeoutHandle = setTimeout(() => {
145
- reject(new PTYTimeoutError(`Timeout (${timeoutMs}ms) waiting for process to exit`, this._output));
146
- }, timeoutMs);
147
- this._exitPromise
148
- .then(() => {
149
- if (timeoutHandle)
150
- clearTimeout(timeoutHandle);
151
- resolve(this._output);
152
- })
153
- .catch(reject);
154
- });
155
- }
156
- /**
157
- * Kill the process.
158
- * @param signal Signal to send (default: SIGHUP on Unix)
159
- */
160
- kill(signal) {
161
- if (!this._isRunning) {
162
- return;
163
- }
164
- try {
165
- this._pty.kill(signal);
166
- }
167
- catch {
168
- // Process may already be dead
169
- }
170
- }
171
- /**
172
- * Close the session and clean up resources.
173
- */
174
- close() {
175
- // Kill the process first before disposing handlers
176
- if (this._isRunning) {
177
- this.kill("SIGKILL");
178
- // Mark as not running since we won't receive the exit event
179
- // after disposing the handlers
180
- this._isRunning = false;
181
- // Resolve the exit promise to unblock any waiters
182
- // Use -1 to indicate forced termination
183
- this._exitResolve(-1);
184
- }
185
- this._dataDisposable.dispose();
186
- this._exitDisposable.dispose();
187
- }
188
- /**
189
- * Get the current output buffer.
190
- */
191
- get output() {
192
- return this._output;
193
- }
194
- /**
195
- * Check if the process is still running.
196
- */
197
- get isRunning() {
198
- return this._isRunning;
199
- }
200
- /**
201
- * Get the process ID.
202
- */
203
- get pid() {
204
- return this._pty.pid;
205
- }
206
- /**
207
- * Get the exit code (undefined if still running).
208
- */
209
- get exitCode() {
210
- return this._exitCode;
211
- }
212
- /**
213
- * Get the current terminal columns.
214
- */
215
- get cols() {
216
- return this._pty.cols;
217
- }
218
- /**
219
- * Get the current terminal rows.
220
- */
221
- get rows() {
222
- return this._pty.rows;
223
- }
224
- }
225
- /**
226
- * Create a new PTY session.
227
- * @param options Options for the PTY
228
- * @returns A PTYSession wrapping the process
229
- */
230
- export async function createPTYSession(options) {
231
- const defaultCols = 80;
232
- const defaultRows = 24;
233
- const pty = nodePty.spawn(options.command, options.args ?? [], {
234
- name: "xterm-256color",
235
- cols: options.cols ?? defaultCols,
236
- rows: options.rows ?? defaultRows,
237
- cwd: options.cwd ?? process.cwd(),
238
- env: {
239
- ...sanitizeEnv(options.env),
240
- TERM: "xterm-256color",
241
- },
242
- });
243
- return new PTYSession(pty);
244
- }
245
- /**
246
- * Run a command in a PTY and wait for it to complete.
247
- * This is a convenience function for commands that don't require interaction.
248
- *
249
- * @param options Options for the PTY, with optional timeout
250
- * @returns The output and exit code
251
- */
252
- export async function runInPTY(options) {
253
- const { timeoutMs = 30000, ...ptyOptions } = options;
254
- const session = await createPTYSession(ptyOptions);
255
- try {
256
- const output = await session.waitForExit(timeoutMs);
257
- return {
258
- output,
259
- exitCode: session.exitCode ?? 0,
260
- };
261
- }
262
- finally {
263
- session.close();
264
- }
265
- }
266
- /**
267
- * Escape special regex characters in a string.
268
- */
269
- function escapeRegExp(string) {
270
- return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
271
- }
@@ -1,119 +0,0 @@
1
- /**
2
- * @aria/tools - Restart executor
3
- *
4
- * Single restart path for both TUI and daemon:
5
- * Register an 'exit' handler to spawn a replacement process, then SIGINT
6
- * the current process for graceful shutdown. The replacement starts fresh
7
- * and goes through normal startup (heap check, createCliContext, REPL/daemon).
8
- */
9
- import { success, fail } from "./utils.js";
10
- import { spawn } from "node:child_process";
11
- import { existsSync, readdirSync, readFileSync } from "node:fs";
12
- import { dirname, join, resolve } from "node:path";
13
- import * as os from "node:os";
14
- import { RESUME_ARION_ENV, RESUME_SESSION_ENV, writeRelaunchMarker } from "@aria-cli/types";
15
- function findPnpmWorkspaceRoot(startDir) {
16
- let dir = resolve(startDir);
17
- while (true) {
18
- if (existsSync(join(dir, "pnpm-workspace.yaml")))
19
- return dir;
20
- const parent = dirname(dir);
21
- if (parent === dir)
22
- return null;
23
- dir = parent;
24
- }
25
- }
26
- function getPnpmCommand() {
27
- return process.platform === "win32" ? "pnpm.cmd" : "pnpm";
28
- }
29
- async function rebuildWorkspaceIfPresent(startDir) {
30
- const root = findPnpmWorkspaceRoot(startDir);
31
- if (!root)
32
- return { attempted: false };
33
- const pnpm = getPnpmCommand();
34
- await new Promise((resolvePromise, rejectPromise) => {
35
- const child = spawn(pnpm, ["build"], {
36
- cwd: root,
37
- env: process.env,
38
- stdio: "inherit",
39
- });
40
- child.on("error", rejectPromise);
41
- child.on("close", (code) => {
42
- if (code === 0)
43
- resolvePromise();
44
- else
45
- rejectPromise(new Error(`pnpm build failed with exit code ${code ?? "unknown"}`));
46
- });
47
- });
48
- return { attempted: true };
49
- }
50
- /**
51
- * Find the daemon PID for the current ARIA_HOME by scanning owner records.
52
- * Owner records live at $RUNTIME_ROOT/owners/*.json where RUNTIME_ROOT is
53
- * XDG_RUNTIME_DIR/aria or ~/.aria/run.
54
- */
55
- function findDaemonPid() {
56
- const ariaHome = process.env.ARIA_HOME?.trim() || join(os.homedir(), ".aria");
57
- const runtimeDir = process.env.XDG_RUNTIME_DIR?.trim();
58
- const runtimeRoot = runtimeDir ? join(runtimeDir, "aria") : join(ariaHome, "run");
59
- const ownersDir = join(runtimeRoot, "owners");
60
- if (!existsSync(ownersDir))
61
- return null;
62
- const canonicalHome = resolve(ariaHome);
63
- for (const file of readdirSync(ownersDir).filter((f) => f.endsWith(".json"))) {
64
- try {
65
- const record = JSON.parse(readFileSync(join(ownersDir, file), "utf8"));
66
- if (record.ariaHome && resolve(record.ariaHome) === canonicalHome) {
67
- return typeof record.runtimePid === "number" ? record.runtimePid : null;
68
- }
69
- }
70
- catch {
71
- // Skip malformed records
72
- }
73
- }
74
- return null;
75
- }
76
- export async function executeRestart(input, ctx) {
77
- if (ctx.abortSignal?.aborted)
78
- return fail("Operation cancelled");
79
- const reason = (input.reason ?? "").trim() || "Restart requested";
80
- // Note: tool definition has requiresConfirmation: true, so the framework
81
- // already prompts the user before execute() is called. No need to confirm again.
82
- process.stderr.write(`[aria] Rebuilding workspace before restart...\n`);
83
- try {
84
- const rebuilt = await rebuildWorkspaceIfPresent(ctx.workingDir || process.cwd());
85
- if (!rebuilt.attempted) {
86
- process.stderr.write(`[aria] No pnpm workspace detected; skipping build\n`);
87
- }
88
- }
89
- catch (error) {
90
- process.stderr.write(`[aria] Build failed; continuing restart: ${error.message}\n`);
91
- }
92
- process.stderr.write(`[aria] Restarting: ${reason}\n`);
93
- const sessionId = process.env[RESUME_SESSION_ENV] ?? null;
94
- const arionName = process.env[RESUME_ARION_ENV] || "ARIA";
95
- // Write disk-backed marker so the replacement process can resume the session.
96
- writeRelaunchMarker({
97
- sessionId,
98
- arionName,
99
- pid: process.ppid || process.pid,
100
- timestamp: new Date().toISOString(),
101
- });
102
- // Spawn replacement on exit, then SIGINT for graceful shutdown.
103
- // Works for both TUI and daemon — no supervisor needed.
104
- const targetPid = findDaemonPid() ?? process.pid;
105
- process.once("exit", () => {
106
- spawn(process.execPath, [...process.execArgv, ...process.argv.slice(1)], {
107
- detached: true,
108
- stdio: "ignore",
109
- }).unref();
110
- });
111
- process.stderr.write(`[aria] Sending SIGINT to pid ${targetPid} for graceful restart\n`);
112
- try {
113
- process.kill(targetPid, "SIGINT");
114
- }
115
- catch {
116
- process.kill(process.pid, "SIGINT");
117
- }
118
- return success("Restarting...");
119
- }
@@ -1,195 +0,0 @@
1
- /**
2
- * Freshness tracker for aria-search (code_search tool).
3
- *
4
- * Mirrors frg-freshness.ts patterns to close the freshness gaps:
5
- * 1. Tracks file mutations from ARIA tool writes (session overlay)
6
- * 2. Reconciles git-dirty files on each search
7
- * 3. Generates session overlay for the napi search() call
8
- *
9
- * The session overlay gives 0ms visibility for pending mutations —
10
- * files written by agents/users appear in search results immediately
11
- * without waiting for an index rebuild or hot.log sync.
12
- */
13
- import * as fsSync from "node:fs";
14
- import * as nodePath from "node:path";
15
- import { execFileSync } from "node:child_process";
16
- const repoStates = new Map();
17
- /** Minimum interval between git-dirty reconciliations (avoid hammering git). */
18
- const GIT_RECONCILE_INTERVAL_MS = 2_000;
19
- /** Max content size to cache in memory per file. */
20
- const MAX_CACHED_CONTENT_BYTES = 256 * 1024;
21
- function norm(p) {
22
- return nodePath.resolve(p);
23
- }
24
- function getState(root) {
25
- const key = norm(root);
26
- let state = repoStates.get(key);
27
- if (!state) {
28
- state = { sequence: 0, pending: new Map(), lastGitReconcileMs: 0 };
29
- repoStates.set(key, state);
30
- }
31
- return state;
32
- }
33
- // ---------------------------------------------------------------------------
34
- // Public API — called from filesystem/patch executors
35
- // ---------------------------------------------------------------------------
36
- /**
37
- * Record a file mutation from an ARIA tool write/edit/delete.
38
- * Called alongside recordFrgMutation in filesystem.ts and apply-patch.ts.
39
- */
40
- export function recordSearchMutation(filePath, operation, content) {
41
- // Find the git repo root to scope mutations correctly
42
- const repoRoot = findGitRepoRoot(filePath);
43
- if (!repoRoot)
44
- return;
45
- const state = getState(repoRoot);
46
- state.sequence += 1;
47
- const normalizedPath = norm(filePath);
48
- state.pending.set(normalizedPath, {
49
- path: normalizedPath,
50
- operation,
51
- content: typeof content === "string" && Buffer.byteLength(content, "utf8") <= MAX_CACHED_CONTENT_BYTES
52
- ? content
53
- : undefined,
54
- sequence: state.sequence,
55
- });
56
- }
57
- // ---------------------------------------------------------------------------
58
- // Public API — called from search executor
59
- // ---------------------------------------------------------------------------
60
- /**
61
- * Reconcile git-dirty files into the pending mutations map.
62
- * Runs `git diff --name-status -z HEAD` and `git ls-files -o --exclude-standard -z`
63
- * to detect files modified/created/deleted by external agents or the user.
64
- *
65
- * Throttled to at most once per GIT_RECONCILE_INTERVAL_MS to avoid
66
- * hammering git on rapid sequential searches.
67
- */
68
- export function reconcileSearchGitDirty(root) {
69
- const state = getState(root);
70
- const now = Date.now();
71
- if (now - state.lastGitReconcileMs < GIT_RECONCILE_INTERVAL_MS) {
72
- return; // Throttled — recent reconciliation is still fresh enough
73
- }
74
- state.lastGitReconcileMs = now;
75
- const normalizedRoot = norm(root);
76
- // Tracked modified/deleted files
77
- const trackedOutput = runGit(normalizedRoot, ["diff", "--name-status", "-z", "HEAD", "--"]);
78
- if (trackedOutput) {
79
- const tokens = trackedOutput.split("\0").filter(Boolean);
80
- for (let i = 0; i < tokens.length; i++) {
81
- const status = tokens[i] ?? "";
82
- if (status.startsWith("R")) {
83
- // Rename: old path deleted, new path written
84
- const oldPath = tokens[++i];
85
- const newPath = tokens[++i];
86
- if (oldPath)
87
- addGitDirtyMutation(state, normalizedRoot, oldPath, "delete");
88
- if (newPath)
89
- addGitDirtyMutation(state, normalizedRoot, newPath, "write");
90
- continue;
91
- }
92
- const filePath = tokens[++i];
93
- if (!filePath)
94
- continue;
95
- addGitDirtyMutation(state, normalizedRoot, filePath, status.startsWith("D") ? "delete" : "write");
96
- }
97
- }
98
- // Untracked new files
99
- const untrackedOutput = runGit(normalizedRoot, ["ls-files", "-o", "--exclude-standard", "-z"]);
100
- if (untrackedOutput) {
101
- for (const token of untrackedOutput.split("\0").filter(Boolean)) {
102
- addGitDirtyMutation(state, normalizedRoot, token, "write");
103
- }
104
- }
105
- }
106
- function addGitDirtyMutation(state, root, relativePath, operation) {
107
- const absPath = norm(nodePath.join(root, relativePath));
108
- const existing = state.pending.get(absPath);
109
- // Don't overwrite ARIA-sourced mutations (which have cached content)
110
- if (existing?.content)
111
- return;
112
- if (existing?.operation === operation)
113
- return;
114
- state.sequence += 1;
115
- state.pending.set(absPath, {
116
- path: absPath,
117
- operation,
118
- content: undefined, // Will be read from disk in getSearchSessionOverlay
119
- sequence: state.sequence,
120
- });
121
- }
122
- /**
123
- * Generate the session overlay for the napi search() call.
124
- * Reads content from disk for mutations without cached content.
125
- */
126
- export function getSearchSessionOverlay(root) {
127
- const state = getState(root);
128
- const sessionWrites = [];
129
- const sessionDeletes = [];
130
- for (const mutation of state.pending.values()) {
131
- if (mutation.operation === "delete") {
132
- sessionDeletes.push(mutation.path);
133
- continue;
134
- }
135
- let content = mutation.content;
136
- if (typeof content !== "string") {
137
- // Read from disk — closes the gap where git-dirty files have no cached content
138
- try {
139
- const buf = fsSync.readFileSync(mutation.path);
140
- if (!buf.subarray(0, Math.min(buf.length, 8192)).includes(0)) {
141
- content = buf.toString("utf8");
142
- }
143
- }
144
- catch {
145
- continue; // Unreadable — skip
146
- }
147
- }
148
- if (typeof content === "string") {
149
- sessionWrites.push({ path: mutation.path, content });
150
- }
151
- }
152
- return { sessionWrites, sessionDeletes };
153
- }
154
- /**
155
- * Clear all pending mutations for a repo root.
156
- * Called after a full index rebuild (all mutations are now in the base index).
157
- */
158
- export function clearSearchMutations(root) {
159
- const key = norm(root);
160
- repoStates.delete(key);
161
- }
162
- // ---------------------------------------------------------------------------
163
- // Helpers
164
- // ---------------------------------------------------------------------------
165
- function findGitRepoRoot(startPath) {
166
- let current = norm(startPath);
167
- try {
168
- if (!fsSync.statSync(current).isDirectory()) {
169
- current = nodePath.dirname(current);
170
- }
171
- }
172
- catch {
173
- current = nodePath.dirname(current);
174
- }
175
- while (true) {
176
- if (fsSync.existsSync(nodePath.join(current, ".git")))
177
- return current;
178
- const parent = nodePath.dirname(current);
179
- if (parent === current)
180
- return null;
181
- current = parent;
182
- }
183
- }
184
- function runGit(cwd, args) {
185
- try {
186
- return execFileSync("git", args, {
187
- cwd,
188
- encoding: "utf8",
189
- stdio: ["ignore", "pipe", "ignore"],
190
- }).trim();
191
- }
192
- catch {
193
- return null;
194
- }
195
- }
@@ -1,52 +0,0 @@
1
- /**
2
- * Shared types and utilities for the unified search tool.
3
- *
4
- * Used by:
5
- * - Base executor in @aria/tools (learning-meta.ts)
6
- * - Runner wrapper in @aria/aria (search-wrapper.ts)
7
- * - Tests
8
- */
9
- // ---------------------------------------------------------------------------
10
- // Shared dedup logic — single source of truth for both base executor and wrapper
11
- // ---------------------------------------------------------------------------
12
- /** Source priority for dedup (lower = higher priority). */
13
- export const SOURCE_PRIORITY = {
14
- builtin: 0,
15
- local_cli: 1,
16
- memoria: 2,
17
- local: 3,
18
- "skills.sh": 4,
19
- clawhub: 5,
20
- npm: 6,
21
- brew: 7,
22
- web: 8,
23
- };
24
- /**
25
- * Dedup search results by name with source priority.
26
- * When the same name appears from multiple sources, keep the higher-priority one.
27
- */
28
- export function dedupSearchResults(results, limit) {
29
- const deduped = new Map();
30
- for (const item of results) {
31
- const normalizedName = item.name.trim().toLowerCase();
32
- const existing = deduped.get(normalizedName);
33
- if (!existing) {
34
- deduped.set(normalizedName, item);
35
- }
36
- else {
37
- const existingPriority = SOURCE_PRIORITY[existing.source] ?? 99;
38
- const newPriority = SOURCE_PRIORITY[item.source] ?? 99;
39
- if (newPriority < existingPriority) {
40
- deduped.set(normalizedName, item);
41
- }
42
- }
43
- }
44
- const sorted = [...deduped.values()].sort((a, b) => {
45
- const aPriority = SOURCE_PRIORITY[a.source] ?? 99;
46
- const bPriority = SOURCE_PRIORITY[b.source] ?? 99;
47
- if (aPriority !== bPriority)
48
- return aPriority - bPriority;
49
- return a.name.localeCompare(b.name);
50
- });
51
- return sorted.slice(0, limit);
52
- }
@@ -1,66 +0,0 @@
1
- /**
2
- * Executor for the native indexed regex search tool.
3
- *
4
- * Freshness architecture (frg parity):
5
- * 1. ARIA tool writes → recordSearchMutation → session overlay (0ms visibility)
6
- * 2. External edits → reconcileSearchGitDirty → session overlay (0ms visibility)
7
- * 3. Commit/version change → syncIndex or buildIndex (incremental/full)
8
- * 4. Session overlay passed to napi search() — no index rebuild needed
9
- */
10
- import * as nodePath from "node:path";
11
- import { buildIndex, syncIndex, indexStatus, search } from "@aria-cli/search";
12
- import { success, fail } from "./utils.js";
13
- import { reconcileSearchGitDirty, getSearchSessionOverlay, clearSearchMutations, } from "./search-freshness.js";
14
- export async function executeSearch(input, ctx) {
15
- const opts = input;
16
- const dir = nodePath.resolve(ctx.workingDir, opts.directory || ".");
17
- try {
18
- // Step 1: Index management — build or sync base index if needed.
19
- const status = indexStatus(dir);
20
- if (status.state === "none") {
21
- buildIndex(dir);
22
- clearSearchMutations(dir); // fresh index includes everything
23
- }
24
- else if (status.state === "stale") {
25
- // Commit or binary version changed — incremental sync is sufficient
26
- // (syncIndex rebuilds hot.log from git diff, much cheaper than full build).
27
- // Only fall back to full build if sync fails.
28
- try {
29
- syncIndex(dir);
30
- }
31
- catch {
32
- buildIndex(dir);
33
- }
34
- clearSearchMutations(dir);
35
- }
36
- // "ready" — base index is fresh, session overlay handles uncommitted changes
37
- // Step 2: Reconcile git-dirty files into pending mutations.
38
- // Detects files modified/created/deleted by external agents or the user.
39
- // Throttled to avoid hammering git on rapid sequential searches.
40
- reconcileSearchGitDirty(dir);
41
- // Step 3: Generate session overlay from pending mutations.
42
- // This gives 0ms visibility for ARIA tool writes and external edits —
43
- // no index rebuild needed. The overlay is applied in-memory by the
44
- // Rust search engine on top of the base index + hot.log.
45
- const overlay = getSearchSessionOverlay(dir);
46
- // Step 4: Search with overlay.
47
- const results = search({
48
- pattern: opts.pattern,
49
- directory: dir,
50
- maxResults: opts.maxResults ?? 1000,
51
- fileGlob: opts.fileGlob,
52
- fileType: opts.fileType,
53
- caseSensitive: opts.caseSensitive ?? true,
54
- literal: opts.literal ?? false,
55
- context: opts.context ?? 0,
56
- sessionWrites: overlay.sessionWrites,
57
- sessionDeletes: overlay.sessionDeletes,
58
- });
59
- const truncated = results.length >= (opts.maxResults ?? 1000);
60
- return success(`Found ${results.length} matches for "${opts.pattern}"${truncated ? " (truncated)" : ""}`, { matches: results, truncated });
61
- }
62
- catch (err) {
63
- const reason = err instanceof Error ? err.message : String(err);
64
- return fail(`Search failed: ${reason}`);
65
- }
66
- }