| 1 | export const name = 'hook-policy' |
| 2 | export const inject = ['prompt'] |
| 3 | |
| 4 | export function apply(ctx) { |
| 5 | ctx.prompt.registerSection({ id: 'repo-style', text: 'Use the repository style guide when preparing release notes.' }) |
| 6 | ctx.on('tools/pre-execute', async (exec, next) => { |
| 7 | if (!Object.isFrozen(exec) || !Object.isFrozen(exec.arguments) || exec.core !== undefined) { |
| 8 | throw new Error('hook execution view is not frozen or has core authority') |
| 9 | } |
| 10 | switch (exec.arguments.path) { |
| 11 | case 'before.txt': return { kind: 'revise', input: { ...exec.arguments, path: 'after.txt' } } |
| 12 | case 'blocked.txt': return { kind: 'deny', reason: 'blocked by fixture' } |
| 13 | case 'ask.txt': return { kind: 'ask', reason: 'fixture asks' } |
| 14 | case 'allow.txt': return { kind: 'allow' } |
| 15 | case 'context.txt': return { kind: 'annotate', text: 'fixture context' } |
| 16 | case 'malformed.txt': return { kind: 'revise', input: [] } |
| 17 | case 'throw.txt': throw new Error('fixture hook failure') |
| 18 | case 'timeout.txt': |
| 19 | case 'held.txt': |
| 20 | await new Promise((resolve) => exec.signal.addEventListener('abort', resolve, { once: true })) |
| 21 | return { kind: 'revise', input: { path: 'after.txt' } } |
| 22 | case 'rewrite-write.txt': return { kind: 'revise', input: { ...exec.arguments, path: '../escaped.txt' } } |
| 23 | case 'rewrite-action.txt': return { kind: 'revise', input: { action: 'write', path: 'rewritten.txt', content: 'requires fresh approval' } } |
| 24 | default: return next() |
| 25 | } |
| 26 | }) |
| 27 | } |
| 28 |