diff options
| author | Ellie Huxtable <ellie@atuin.sh> | 2026-04-13 21:48:05 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-04-13 21:48:05 +0100 |
| commit | ce148460d41a54993bb33ef17ec59ab33e2a34f5 (patch) | |
| tree | feba0521a926a79d9bab85092b725fedf520baae /contrib/pi/atuin.ts | |
| parent | feat: autoinstall ai shell history hooks (#3399) (diff) | |
| download | atuin-ce148460d41a54993bb33ef17ec59ab33e2a34f5.zip | |
refactor: rename examples -> contrib (#3400)
<!-- Thank you for making a PR! Bug fixes are always welcome, but if
you're adding a new feature or changing an existing one, we'd really
appreciate if you open an issue, post on the forum, or drop in on
Discord -->
## Checks
- [ ] I am happy for maintainers to push small adjustments to this PR,
to speed up the review cycle
- [ ] I have checked that there are no existing pull requests for the
same thing
Diffstat (limited to 'contrib/pi/atuin.ts')
| -rw-r--r-- | contrib/pi/atuin.ts | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/contrib/pi/atuin.ts b/contrib/pi/atuin.ts new file mode 100644 index 00000000..55c17cb8 --- /dev/null +++ b/contrib/pi/atuin.ts @@ -0,0 +1,87 @@ +/** + * Atuin extension for pi. + * + * Tracks bash commands executed by pi in Atuin history with author `pi`. + * + * Install with: + * atuin hook install pi + * + * Then restart pi or run /reload. + */ + +import type { BashOperations, ExtensionAPI } from "@mariozechner/pi-coding-agent"; +import { createBashTool, createLocalBashOperations } from "@mariozechner/pi-coding-agent"; + +const ATUIN_AUTHOR = "pi"; +const ATUIN_TIMEOUT_MS = 10_000; + +async function startHistory( + pi: ExtensionAPI, + cwd: string, + command: string, +): Promise<string | undefined> { + try { + const result = await pi.exec( + "atuin", + ["history", "start", "--author", ATUIN_AUTHOR, "--", command], + { cwd, timeout: ATUIN_TIMEOUT_MS }, + ); + + if (result.code !== 0) return undefined; + + const id = result.stdout.trim(); + return id.length > 0 ? id : undefined; + } catch { + return undefined; + } +} + +async function endHistory( + pi: ExtensionAPI, + cwd: string, + historyId: string, + exitCode: number, +): Promise<void> { + try { + await pi.exec( + "atuin", + ["history", "end", historyId, "--exit", String(exitCode)], + { cwd, timeout: ATUIN_TIMEOUT_MS }, + ); + } catch { + // Ignore Atuin failures so command execution is never blocked. + } +} + +export default function atuinPiExtension(pi: ExtensionAPI) { + const cwd = process.cwd(); + const local = createLocalBashOperations(); + + const trackedOperations: BashOperations = { + async exec(command, commandCwd, options) { + const historyId = await startHistory(pi, commandCwd, command); + let exitCode: number | null = null; + + try { + const result = await local.exec(command, commandCwd, options); + exitCode = result.exitCode; + return result; + } finally { + if (historyId) { + await endHistory( + pi, + commandCwd, + historyId, + exitCode ?? (options.signal?.aborted ? 130 : 1), + ); + } + } + }, + }; + + pi.registerTool( + createBashTool(cwd, { + operations: trackedOperations, + }), + ); +} |
