|
@@ -158,7 +158,11 @@ async function completeStdout(toolName: string, result: BashRunResult, rawOutput
|
|
|
* success with zero results (`noMatches`), anything else throws a
|
|
* success with zero results (`noMatches`), anything else throws a
|
|
|
* {@link SearchError} (abort/timeout → `SEARCH_ABORTED`, invalid pattern →
|
|
* {@link SearchError} (abort/timeout → `SEARCH_ABORTED`, invalid pattern →
|
|
|
* `SEARCH_INVALID_PATTERN`, the rest → `SEARCH_FAILED` /
|
|
* `SEARCH_INVALID_PATTERN`, the rest → `SEARCH_FAILED` /
|
|
|
- * `SEARCH_RAW_OUTPUT_OVERFLOW`).
|
|
|
|
|
|
|
+ * `SEARCH_RAW_OUTPUT_OVERFLOW`). A `run()` REJECTION — the seam's
|
|
|
|
|
+ * infrastructure failures (pre-aborted signal, unusable workdir, missing
|
|
|
|
|
+ * shell) — is translated into the same taxonomy: a pre-aborted signal becomes
|
|
|
|
|
+ * `SEARCH_ABORTED`, everything else `SEARCH_FAILED`, with the original as
|
|
|
|
|
+ * `cause`.
|
|
|
*
|
|
*
|
|
|
* @param ctx - the plugin context; execution uses its `bash` service.
|
|
* @param ctx - the plugin context; execution uses its `bash` service.
|
|
|
* @param exec - the tool-execution context; supplies the session cwd and the abort signal.
|
|
* @param exec - the tool-execution context; supplies the session cwd and the abort signal.
|
|
@@ -180,7 +184,18 @@ export async function runRipgrep(
|
|
|
...cwd !== undefined ? { workdir: cwd } : {},
|
|
...cwd !== undefined ? { workdir: cwd } : {},
|
|
|
...exec.signal ? { signal: exec.signal } : {},
|
|
...exec.signal ? { signal: exec.signal } : {},
|
|
|
})
|
|
})
|
|
|
- const result = await ctx.bash.run(spec)
|
|
|
|
|
|
|
+ let result: BashRunResult
|
|
|
|
|
+ try {
|
|
|
|
|
+ result = await ctx.bash.run(spec)
|
|
|
|
|
+ } catch (error: unknown) {
|
|
|
|
|
+ // The seam contract: run() REJECTS only for infrastructure failures — a
|
|
|
|
|
+ // pre-aborted signal, an unusable workdir, a missing shell. Translate them
|
|
|
|
|
+ // so these failures stay machine-routable under the SEARCH_* taxonomy.
|
|
|
|
|
+ if (spec.signal?.aborted === true) {
|
|
|
|
|
+ throw new SearchError(`${toolName} was aborted before completion (tool timeout or caller cancellation)`, 'SEARCH_ABORTED', { cause: error })
|
|
|
|
|
+ }
|
|
|
|
|
+ throw new SearchError(`${toolName} could not start its search command (unusable working directory or missing shell)`, 'SEARCH_FAILED', { cause: error })
|
|
|
|
|
+ }
|
|
|
if (result.aborted) {
|
|
if (result.aborted) {
|
|
|
throw new SearchError(`${toolName} was aborted before completion (tool timeout or caller cancellation)`, 'SEARCH_ABORTED')
|
|
throw new SearchError(`${toolName} was aborted before completion (tool timeout or caller cancellation)`, 'SEARCH_ABORTED')
|
|
|
}
|
|
}
|