Spike: a tool.call hook that holds a call on a promise of its own

<h1>nixie</h1>
A personal assistant platform that its owner runs and controls: every rule readable and editable, every decision recorded, and personal data kept on the owner's own hosts.
<a href="./docs/README.md">Documentation</a> • <a href="./docs/README.md#decisions">Decisions</a> • <a href="./AGENTS.md">Agent Guidelines</a>
nixie is in Phase 2, Research, and has no product code. The work runs in 4 phases: brainstorm, research, design, and decide. Decisions are recorded as research settles each question.
bun install
bun run check # format, lint, and the prose check
hooks/register.js 23 lines1// A hooks module imports only its own files, so the timer comes from setTimeout.
2function waitMs(ms) {
3 // oxlint-disable-next-line promise/avoid-new
4 return new Promise((resolve) => {
5 setTimeout(resolve, ms);
6 });
7}
8
9// Holds MARK_HOLD calls for 15 s on a timer of the hook's own, then denies them.
10async function handleToolCall($, e, next) {
11 if (!e.command.includes('MARK_HOLD')) {
12 return next(e);
13 }
14 await $.ui.log(`nixie hold start budget=${JSON.stringify(next.budget)}`, { to: 'debug' });
15 await waitMs(15_000);
16 await $.ui.log('nixie hold end', { to: 'debug' });
17 return { deny: 'nixie-hold-promise: the owner refused this command.' };
18}
19
20export function register(on) {
21 on('tool.call', { tool: 'Bash' }, handleToolCall);
22}
23