@agimon-ai/doompi-hook 0.0.1-alpha.5 → 0.0.1-alpha.52

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.
package/README.md CHANGED
@@ -1,11 +1,21 @@
1
1
  # @agimon-ai/doompi-hook
2
2
 
3
- Claude-Code-compatible repository and plugin hooks for
3
+ Claude Code-compatible repository and plugin hooks for
4
4
  [DoomPi](https://www.npmjs.com/package/@agimon-ai/doompi) sessions.
5
5
 
6
6
  A **hook** is a shell command the repository runs at a point in the session: before a tool call,
7
7
  after one, at session start, when the agent settles, and at session end. Commands are declared in
8
- `.doom/hooks.yaml`, grouped so a mode can turn a whole family of them on or off:
8
+ `.doom/hooks.yaml`, grouped so a mode can turn a whole family of them on or off.
9
+
10
+ > **Alpha:** hook configuration and runtime contracts may change between releases.
11
+
12
+ ## Requirements
13
+
14
+ - Node.js 22.19.0 or newer
15
+ - Pi 0.85.0
16
+ - `/bin/bash`
17
+
18
+ Configure hooks in `.doom/hooks.yaml`:
9
19
 
10
20
  ```yaml
11
21
  # .doom/hooks.yaml
@@ -25,14 +35,15 @@ groups:
25
35
  skipInSubagent: true
26
36
  ```
27
37
 
28
- A group marked `core: true` always loads. Every other group loads only when the active mode selected
29
- it. The same document is read from the global `.doom` directory and from the repository, and a
30
- repository group replaces the global group of the same id outright.
38
+ A group marked `core: true` always loads. Every other group loads only when the active mode selects
39
+ it. The same document is read from the global `.doom` directory and from the repository. A
40
+ repository group replaces the global group of the same ID outright.
31
41
 
32
42
  ## Activation
33
43
 
34
- The DoomPi distribution activates this package by default. Layers only declare the `hookGroups`
35
- that should run in a major mode:
44
+ The distribution activates this package by default through the `default.packages` list written by
45
+ `doompi init` and `dpi init` in `.doom/modes.yaml`. Keep it there, or declare it in a selected layer,
46
+ for hooks to run. Layers only declare the `hookGroups` to select; they do not define the hook commands:
36
47
 
37
48
  ```yaml
38
49
  # .doom/modes.yaml
@@ -41,14 +52,16 @@ layers:
41
52
  hookGroups: [safety, workflow]
42
53
  ```
43
54
 
44
- A session with no selected `hookGroups` still runs groups marked `core: true`; other groups remain inactive.
55
+ A session with no selected `hookGroups` still runs groups marked `core: true`; other groups remain
56
+ inactive.
45
57
 
46
58
  ## What a hook sees and can say
47
59
 
48
60
  Each command is run through `/bin/bash -c` in the repository root, with the Claude Code payload for
49
- the event on stdin and `CLAUDE_PROJECT_DIR`, `CODEX_REPO_ROOT`, `ORIGINAL_REPO_PATH` and — for a
50
- hook declared by a plugin or a global config — `CLAUDE_PLUGIN_ROOT` in the environment. Tool names
51
- in the payload and in `matcher` are Claude names (`Bash`, `Write`), not Pi's.
61
+ the event on stdin. The environment includes `CLAUDE_PROJECT_DIR`, `CODEX_REPO_ROOT`, and
62
+ `ORIGINAL_REPO_PATH`. Every resolved hook also receives `CLAUDE_PLUGIN_ROOT`, set to the root that
63
+ declared its repository, personal, or plugin configuration. Tool names in the payload and in
64
+ `matcher` are Claude names (`Bash`, `Write`), not Pi's.
52
65
 
53
66
  The last stdout line that starts with `{` is read as the hook's decision:
54
67
 
@@ -70,14 +83,44 @@ indistinguishable from one that passed.
70
83
  expires, is sent `SIGTERM` and then `SIGKILL` two seconds later, so a stalled hook does not leave
71
84
  the processes it started behind.
72
85
 
73
- ## Installation
86
+ ## Help guidance
87
+
88
+ While the Help minor mode is active, this package contributes `doompi-author-hook`. The prompt
89
+ covers `.doom/hooks.yaml`, group activation, commands, payloads, decisions, and verification, and
90
+ is withdrawn when the package or Help provider unloads.
74
91
 
75
- DoomPi already includes this package. For standalone Pi installation:
92
+ ## Install
93
+
94
+ For standalone Pi installation:
76
95
 
77
96
  ```bash
78
97
  pi install npm:@agimon-ai/doompi-hook
79
98
  ```
80
99
 
100
+ ## Public API
101
+
102
+ ```ts
103
+ import { createBashHookRunner, hookExtension } from '@agimon-ai/doompi-hook';
104
+ import type { HookDecision, HookEventName } from '@agimon-ai/doompi-hook';
105
+ ```
106
+
107
+ ## Development
108
+
109
+ ```bash
110
+ pnpm build
111
+ pnpm typecheck
112
+ pnpm test
113
+ pnpm lint
114
+ ```
115
+
116
+ Maintained by [Agimon](https://agimon.ai/about).
117
+
81
118
  ## License
82
119
 
83
120
  MIT
121
+
122
+ ## Extension lifecycle and source layout
123
+
124
+ `extensions/pi.ts` declares Config-dependent service bindings, typed controller events, and Help resources. The readiness gate in `services/hookRuntime/` keeps session-start hooks ahead of dependent events and rejects stale generations. Session-end hooks finish during `session_shutdown` before the shared helper disposes the service binding.
125
+
126
+ `extensions/server.ts` declares the server hooks from `controllers/serverHooks.ts`. Controllers dispatch through `services/<name>/`; constants and shared types have their own roots. Flat `exports/` publishes reusable capabilities, and extension entry points are built directly.
package/llms.txt CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  Claude-Code-compatible repository and plugin hooks for Doom Pi sessions.
4
4
 
5
- ## Resources
5
+ ## How to author
6
6
 
7
- - [Package README](./README.md): the `.doom/hooks.yaml` document, group selection, the event mapping, and what a hook decision can do.
7
+ - [Author DoomPi hooks](./src/prompts/doompi-author-hook/SKILL.md): Create `.doom/hooks.yaml` groups and Claude-compatible hook commands.
8
+
9
+ ## Package reference
10
+
11
+ - [Package README](./README.md): The hook registry, group selection, event mapping, decisions, and failure handling.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agimon-ai/doompi-hook",
3
- "version": "0.0.1-alpha.5",
3
+ "version": "0.0.1-alpha.52",
4
4
  "description": "Claude-Code-compatible repository and plugin hook runner for DoomPi sessions.",
5
5
  "keywords": [
6
6
  "ai",
@@ -16,18 +16,28 @@
16
16
  "repository-hooks"
17
17
  ],
18
18
  "homepage": "https://agimon.ai",
19
+ "bugs": {
20
+ "url": "https://github.com/AgiFlow/doompi/issues"
21
+ },
19
22
  "license": "MIT",
20
23
  "author": "Vuong Ngo",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/AgiFlow/doompi.git",
27
+ "directory": "packages/default/doompi-hook"
28
+ },
21
29
  "files": [
22
30
  "dist",
23
31
  "llms.txt",
24
32
  "README.md",
33
+ "src/prompts",
25
34
  "LICENSE",
26
35
  "package.json"
27
36
  ],
28
37
  "type": "module",
29
38
  "main": "./dist/index.cjs",
30
- "types": "./dist/index.d.mts",
39
+ "module": "./dist/index.mjs",
40
+ "types": "./dist/index.d.cts",
31
41
  "jsnext:main": "./dist/index.mjs",
32
42
  "exports": {
33
43
  ".": {
@@ -35,34 +45,45 @@
35
45
  "import": "./dist/index.mjs",
36
46
  "require": "./dist/index.cjs"
37
47
  },
48
+ "./api-contracts": {
49
+ "types": "./dist/api-contracts.d.mts",
50
+ "import": "./dist/api-contracts.mjs",
51
+ "require": "./dist/api-contracts.cjs"
52
+ },
38
53
  "./extensions/pi": {
39
54
  "types": "./dist/extensions/pi.d.mts",
40
55
  "import": "./dist/extensions/pi.mjs",
41
56
  "require": "./dist/extensions/pi.cjs"
42
57
  },
58
+ "./extensions/server": {
59
+ "types": "./dist/extensions/server.d.mts",
60
+ "import": "./dist/extensions/server.mjs",
61
+ "require": "./dist/extensions/server.cjs"
62
+ },
43
63
  "./package.json": "./package.json"
44
64
  },
45
65
  "publishConfig": {
46
66
  "access": "public"
47
67
  },
48
68
  "dependencies": {
49
- "@deepseek-ai/cordis": "4.0.1",
50
- "yaml": "2.9.0",
51
- "@agimon-ai/doompi-config": "0.0.1-alpha.27",
52
- "@agimon-ai/doompi-telemetry": "0.0.1-alpha.27",
53
- "@agimon-ai/doompi-extension-contracts": "0.0.1-alpha.27"
69
+ "@agimon-ai/doompi-config": "0.0.1-alpha.74",
70
+ "@agimon-ai/doompi-core": "0.0.1-alpha.75",
71
+ "@agimon-ai/doompi-telemetry": "0.0.1-alpha.72",
72
+ "@deepseek-ai/cordis": "4.0.2",
73
+ "yaml": "2.9.0"
54
74
  },
55
75
  "devDependencies": {
56
- "@agimon-ai/vibe-lint-plugin-doom-extension": "0.0.1-alpha.26",
57
- "@earendil-works/pi-coding-agent": "0.84.2",
58
- "@types/node": "26.1.1",
59
- "@vitest/coverage-v8": "4.1.10",
60
- "tsdown": "0.22.14",
61
- "typescript": "6.0.3",
62
- "vitest": "4.1.10"
76
+ "@agimon-ai/doompi-build": "0.0.1-alpha.4",
77
+ "@agimon-ai/vibe-lint-plugin-doom-extension": "0.0.1-alpha.70",
78
+ "@earendil-works/pi-coding-agent": "0.85.1",
79
+ "@types/node": "26.5.1",
80
+ "@vitest/coverage-v8": "5.0.0",
81
+ "tsdown": "0.23.0",
82
+ "typescript": "7.0.2",
83
+ "vitest": "5.0.0"
63
84
  },
64
85
  "peerDependencies": {
65
- "@earendil-works/pi-coding-agent": "0.84.2"
86
+ "@earendil-works/pi-coding-agent": "0.85.1"
66
87
  },
67
88
  "peerDependenciesMeta": {
68
89
  "@earendil-works/pi-coding-agent": {
@@ -72,6 +93,17 @@
72
93
  "engines": {
73
94
  "node": ">=22.19.0"
74
95
  },
96
+ "doompiServer": {
97
+ "entry": "./generated/server.ts",
98
+ "dist": "./dist/extensions/server.mjs",
99
+ "scopes": [
100
+ "session"
101
+ ],
102
+ "contracts": {
103
+ "entry": "./src/exports/apiContracts.ts",
104
+ "dist": "./dist/api-contracts.mjs"
105
+ }
106
+ },
75
107
  "pi": {
76
108
  "extensions": [
77
109
  "./dist/extensions/pi.mjs"
@@ -0,0 +1,51 @@
1
+ ---
2
+ name: doompi-author-hook
3
+ description: Author DoomPi repository or plugin hooks. Use when creating or changing .doom/hooks.yaml, selecting hook groups from modes.yaml, writing hook commands, or adapting Claude Code hook payloads and decisions to DoomPi.
4
+ ---
5
+
6
+ # Author DoomPi hooks
7
+
8
+ Write the smallest hook that enforces the requested policy, and treat every hook command as executable repository code.
9
+
10
+ ## Repository registry
11
+
12
+ Define repository and personal hooks in `.doom/hooks.yaml`:
13
+
14
+ ```yaml
15
+ groups:
16
+ safety:
17
+ core: true
18
+ hooks:
19
+ - event: PreToolUse
20
+ pi:
21
+ matcher: Bash
22
+ command: .doom/hooks/guard-destructive-commands.sh
23
+ timeout: 10
24
+ skipInSubagent: true
25
+ order: 0
26
+ ```
27
+
28
+ - Personal configuration comes from `~/.pi/.doom/hooks.yaml`; repository configuration comes from `<repo>/.doom/hooks.yaml`.
29
+ - A repository group replaces a personal group with the same ID as one complete value.
30
+ - `core: true` runs regardless of the selected groups. Otherwise, add the group ID to a layer's `hookGroups` in `modes.yaml`.
31
+ - `matcher` is a regular expression over Claude tool names such as `Bash` and `Write`, even though Pi uses lowercase tool names internally.
32
+ - Use `skipInSubagent: true` when running the hook in a child could duplicate or close parent-owned work. Lower `order` values run first, with declaration order as the tiebreaker.
33
+
34
+ Supported repository events are `SessionStart`, `PreToolUse`, `PostToolUse`, and `Stop`. `SessionEnd` is resolved only from plugin `hooks.json` documents.
35
+
36
+ ## Command contract
37
+
38
+ DoomPi runs each command through `/bin/bash -c` from the repository root and writes the Claude-compatible event payload to stdin. The environment includes `CLAUDE_PROJECT_DIR`, `CODEX_REPO_ROOT`, `ORIGINAL_REPO_PATH`, and `CLAUDE_PLUGIN_ROOT`. For `.doom/hooks.yaml`, `CLAUDE_PLUGIN_ROOT` is the root that declared the personal or repository document.
39
+
40
+ The final stdout line beginning with `{` is parsed as the hook decision. Use Claude Code decision fields only when the event supports them. `PreToolUse` may deny a tool or add context, `PostToolUse` may append context or mark a result as denied, and `SessionStart` may add context. `Stop` and `SessionEnd` run for side effects.
41
+
42
+ Hook failures are advisory: nonzero exits, invalid JSON, spawn failures, and timeouts are reported to the agent instead of crashing the turn. Set `timeout` in seconds only when the 10-second default is unsuitable. A timeout terminates the command's process group.
43
+
44
+ ## Verification
45
+
46
+ Before enabling a new hook broadly:
47
+
48
+ 1. Run the command directly with a representative JSON payload on stdin.
49
+ 2. Start DoomPi with the intended major mode and confirm the group appears in `doompi --explain` output.
50
+ 3. Exercise the exact lifecycle event in a disposable session, including a child session when `skipInSubagent` matters.
51
+ 4. Confirm failure output reaches the agent and that repeated shutdown does not repeat external side effects unexpectedly.