@hasna/hooks 0.0.1

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.
Files changed (110) hide show
  1. package/.npmrc.example +2 -0
  2. package/AGENTS.md +54 -0
  3. package/CLAUDE.md +70 -0
  4. package/CONTRIBUTING.md +45 -0
  5. package/README.md +232 -0
  6. package/bin/index.js +5171 -0
  7. package/hooks/hook-agentmessages/CLAUDE.md +79 -0
  8. package/hooks/hook-agentmessages/LICENSE +21 -0
  9. package/hooks/hook-agentmessages/README.md +107 -0
  10. package/hooks/hook-agentmessages/package.json +31 -0
  11. package/hooks/hook-agentmessages/src/check-messages.ts +151 -0
  12. package/hooks/hook-agentmessages/src/install.ts +126 -0
  13. package/hooks/hook-agentmessages/src/session-start.ts +255 -0
  14. package/hooks/hook-agentmessages/src/uninstall.ts +89 -0
  15. package/hooks/hook-branchprotect/CLAUDE.md +23 -0
  16. package/hooks/hook-branchprotect/README.md +25 -0
  17. package/hooks/hook-branchprotect/package.json +42 -0
  18. package/hooks/hook-branchprotect/src/cli.ts +126 -0
  19. package/hooks/hook-branchprotect/src/hook.ts +88 -0
  20. package/hooks/hook-branchprotect/tsconfig.json +25 -0
  21. package/hooks/hook-checkbugs/LICENSE +21 -0
  22. package/hooks/hook-checkbugs/README.md +140 -0
  23. package/hooks/hook-checkbugs/package.json +58 -0
  24. package/hooks/hook-checkbugs/src/cli.ts +628 -0
  25. package/hooks/hook-checkbugs/src/hook.ts +335 -0
  26. package/hooks/hook-checkbugs/tsconfig.json +15 -0
  27. package/hooks/hook-checkdocs/README.md +137 -0
  28. package/hooks/hook-checkdocs/package.json +57 -0
  29. package/hooks/hook-checkdocs/src/cli.ts +628 -0
  30. package/hooks/hook-checkdocs/src/hook.ts +310 -0
  31. package/hooks/hook-checkdocs/tsconfig.json +15 -0
  32. package/hooks/hook-checkfiles/LICENSE +21 -0
  33. package/hooks/hook-checkfiles/README.md +141 -0
  34. package/hooks/hook-checkfiles/package.json +56 -0
  35. package/hooks/hook-checkfiles/src/cli.ts +545 -0
  36. package/hooks/hook-checkfiles/src/hook.ts +321 -0
  37. package/hooks/hook-checkfiles/tsconfig.json +15 -0
  38. package/hooks/hook-checklint/LICENSE +21 -0
  39. package/hooks/hook-checklint/README.md +147 -0
  40. package/hooks/hook-checklint/package.json +57 -0
  41. package/hooks/hook-checklint/src/cli-patch.ts +32 -0
  42. package/hooks/hook-checklint/src/cli.ts +667 -0
  43. package/hooks/hook-checklint/src/hook.ts +473 -0
  44. package/hooks/hook-checklint/tsconfig.json +15 -0
  45. package/hooks/hook-checkpoint/CLAUDE.md +23 -0
  46. package/hooks/hook-checkpoint/README.md +37 -0
  47. package/hooks/hook-checkpoint/package.json +58 -0
  48. package/hooks/hook-checkpoint/src/cli.ts +191 -0
  49. package/hooks/hook-checkpoint/src/hook.ts +207 -0
  50. package/hooks/hook-checkpoint/tsconfig.json +25 -0
  51. package/hooks/hook-checksecurity/LICENSE +21 -0
  52. package/hooks/hook-checksecurity/README.md +158 -0
  53. package/hooks/hook-checksecurity/package.json +57 -0
  54. package/hooks/hook-checksecurity/src/cli.ts +601 -0
  55. package/hooks/hook-checksecurity/src/hook.ts +334 -0
  56. package/hooks/hook-checksecurity/tsconfig.json +15 -0
  57. package/hooks/hook-checktasks/README.md +144 -0
  58. package/hooks/hook-checktasks/package.json +55 -0
  59. package/hooks/hook-checktasks/src/cli.ts +578 -0
  60. package/hooks/hook-checktasks/src/hook.ts +308 -0
  61. package/hooks/hook-checktasks/tsconfig.json +20 -0
  62. package/hooks/hook-checktests/LICENSE +21 -0
  63. package/hooks/hook-checktests/README.md +137 -0
  64. package/hooks/hook-checktests/package.json +57 -0
  65. package/hooks/hook-checktests/src/cli.ts +627 -0
  66. package/hooks/hook-checktests/src/hook.ts +334 -0
  67. package/hooks/hook-checktests/tsconfig.json +15 -0
  68. package/hooks/hook-contextrefresh/CLAUDE.md +23 -0
  69. package/hooks/hook-contextrefresh/README.md +42 -0
  70. package/hooks/hook-contextrefresh/package.json +42 -0
  71. package/hooks/hook-contextrefresh/src/cli.ts +152 -0
  72. package/hooks/hook-contextrefresh/src/hook.ts +148 -0
  73. package/hooks/hook-contextrefresh/tsconfig.json +25 -0
  74. package/hooks/hook-gitguard/CLAUDE.md +22 -0
  75. package/hooks/hook-gitguard/README.md +30 -0
  76. package/hooks/hook-gitguard/package.json +57 -0
  77. package/hooks/hook-gitguard/src/cli.ts +159 -0
  78. package/hooks/hook-gitguard/src/hook.ts +129 -0
  79. package/hooks/hook-gitguard/tsconfig.json +25 -0
  80. package/hooks/hook-packageage/CLAUDE.md +23 -0
  81. package/hooks/hook-packageage/README.md +33 -0
  82. package/hooks/hook-packageage/package.json +42 -0
  83. package/hooks/hook-packageage/src/cli.ts +165 -0
  84. package/hooks/hook-packageage/src/hook.ts +177 -0
  85. package/hooks/hook-packageage/tsconfig.json +25 -0
  86. package/hooks/hook-phonenotify/CLAUDE.md +25 -0
  87. package/hooks/hook-phonenotify/README.md +44 -0
  88. package/hooks/hook-phonenotify/package.json +42 -0
  89. package/hooks/hook-phonenotify/src/cli.ts +196 -0
  90. package/hooks/hook-phonenotify/src/hook.ts +139 -0
  91. package/hooks/hook-phonenotify/tsconfig.json +25 -0
  92. package/hooks/hook-precompact/CLAUDE.md +23 -0
  93. package/hooks/hook-precompact/README.md +36 -0
  94. package/hooks/hook-precompact/package.json +42 -0
  95. package/hooks/hook-precompact/src/cli.ts +168 -0
  96. package/hooks/hook-precompact/src/hook.ts +122 -0
  97. package/hooks/hook-precompact/tsconfig.json +25 -0
  98. package/package.json +61 -0
  99. package/src/cli/components/App.tsx +191 -0
  100. package/src/cli/components/CategorySelect.tsx +37 -0
  101. package/src/cli/components/DataTable.tsx +133 -0
  102. package/src/cli/components/Header.tsx +18 -0
  103. package/src/cli/components/HookSelect.tsx +29 -0
  104. package/src/cli/components/InstallProgress.tsx +105 -0
  105. package/src/cli/components/SearchView.tsx +86 -0
  106. package/src/cli/index.tsx +218 -0
  107. package/src/index.ts +31 -0
  108. package/src/lib/installer.ts +288 -0
  109. package/src/lib/registry.ts +205 -0
  110. package/tsconfig.json +17 -0
@@ -0,0 +1,310 @@
1
+ #!/usr/bin/env bun
2
+
3
+ /**
4
+ * Claude Code Hook: check-docs
5
+ *
6
+ * Runs a headless Claude Code agent to check for missing documentation.
7
+ * Uses service-implementation CLI to dispatch tasks.
8
+ *
9
+ * This hook runs ASYNC (non-blocking) on PostToolUse.
10
+ * Only runs for repos matching [prefix]-[name] pattern.
11
+ *
12
+ * Configuration:
13
+ * - taskListId: task list for dispatching doc tasks
14
+ * - editThreshold: run check after this many edits (default: 3, range: 3-7)
15
+ * - keywords: keywords that trigger the check (default: ["dev"])
16
+ * - enabled: enable/disable the hook
17
+ */
18
+
19
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
20
+ import { join } from "path";
21
+ import { homedir } from "os";
22
+ import { spawn } from "child_process";
23
+
24
+ interface CheckDocsConfig {
25
+ taskListId?: string;
26
+ editThreshold?: number;
27
+ keywords?: string[];
28
+ enabled?: boolean;
29
+ }
30
+
31
+ interface HookInput {
32
+ session_id: string;
33
+ transcript_path: string;
34
+ cwd: string;
35
+ tool_name: string;
36
+ tool_input: Record<string, unknown>;
37
+ tool_output?: string;
38
+ }
39
+
40
+ interface SessionState {
41
+ editCount: number;
42
+ editedFiles: string[];
43
+ lastCheckRun: number;
44
+ checkInProgress: boolean;
45
+ }
46
+
47
+ const CONFIG_KEY = "checkDocsConfig";
48
+ const STATE_DIR = join(homedir(), ".claude", "hook-state");
49
+ const EDIT_TOOLS = ["Edit", "Write", "NotebookEdit"];
50
+
51
+ const DOCS_PROMPT = `You are a documentation reviewer. Review the following files that were recently edited and identify missing or outdated documentation:
52
+
53
+ FILES TO REVIEW:
54
+ {files}
55
+
56
+ For each documentation issue found, create a task using the service-implementation CLI:
57
+ service-implementation task dispatch "{taskListId}" -s "DOCS: [brief description]" -d "[detailed description of what docs need to be added/updated]"
58
+
59
+ Focus on:
60
+ - Missing function/method documentation
61
+ - Outdated README sections
62
+ - Missing API documentation
63
+ - Missing inline comments for complex logic
64
+ - Missing type definitions documentation
65
+ - Missing usage examples
66
+
67
+ If no documentation issues are found, do not create any tasks.
68
+ Only create tasks for meaningful documentation gaps, not trivial ones.
69
+ Limit to max 5 most important documentation tasks.`;
70
+
71
+ function isValidRepoPattern(cwd: string): boolean {
72
+ const dirName = cwd.split("/").filter(Boolean).pop() || "";
73
+ // Match: hook-checklint, skill-installhook, iapp-mail, etc.
74
+ return /^[a-z]+-[a-z0-9-]+$/i.test(dirName);
75
+ }
76
+
77
+ function readStdinJson(): HookInput | null {
78
+ try {
79
+ const stdin = readFileSync(0, "utf-8");
80
+ return JSON.parse(stdin);
81
+ } catch {
82
+ return null;
83
+ }
84
+ }
85
+
86
+ function readSettings(path: string): Record<string, unknown> {
87
+ if (!existsSync(path)) return {};
88
+ try {
89
+ return JSON.parse(readFileSync(path, "utf-8"));
90
+ } catch {
91
+ return {};
92
+ }
93
+ }
94
+
95
+ function getConfig(cwd: string): CheckDocsConfig {
96
+ // Try project settings first
97
+ const projectSettings = readSettings(join(cwd, ".claude", "settings.json"));
98
+ if (projectSettings[CONFIG_KEY]) {
99
+ return projectSettings[CONFIG_KEY] as CheckDocsConfig;
100
+ }
101
+
102
+ // Fall back to global settings
103
+ const globalSettings = readSettings(join(homedir(), ".claude", "settings.json"));
104
+ if (globalSettings[CONFIG_KEY]) {
105
+ return globalSettings[CONFIG_KEY] as CheckDocsConfig;
106
+ }
107
+
108
+ // Default config
109
+ return {
110
+ editThreshold: 3,
111
+ keywords: ["dev"],
112
+ enabled: true,
113
+ };
114
+ }
115
+
116
+ function getStateFile(sessionId: string): string {
117
+ mkdirSync(STATE_DIR, { recursive: true });
118
+ return join(STATE_DIR, `checkdocs-${sessionId}.json`);
119
+ }
120
+
121
+ function getSessionState(sessionId: string): SessionState {
122
+ const stateFile = getStateFile(sessionId);
123
+ if (existsSync(stateFile)) {
124
+ try {
125
+ return JSON.parse(readFileSync(stateFile, "utf-8"));
126
+ } catch {
127
+ // Corrupted state, reset
128
+ }
129
+ }
130
+ return { editCount: 0, editedFiles: [], lastCheckRun: 0, checkInProgress: false };
131
+ }
132
+
133
+ function saveSessionState(sessionId: string, state: SessionState): void {
134
+ const stateFile = getStateFile(sessionId);
135
+ writeFileSync(stateFile, JSON.stringify(state, null, 2));
136
+ }
137
+
138
+ function getSessionName(transcriptPath: string): string | null {
139
+ if (!existsSync(transcriptPath)) return null;
140
+
141
+ try {
142
+ const content = readFileSync(transcriptPath, "utf-8");
143
+ let lastTitle: string | null = null;
144
+ let searchStart = 0;
145
+
146
+ while (true) {
147
+ const titleIndex = content.indexOf('"custom-title"', searchStart);
148
+ if (titleIndex === -1) break;
149
+
150
+ const lineStart = content.lastIndexOf("\n", titleIndex) + 1;
151
+ const lineEnd = content.indexOf("\n", titleIndex);
152
+ const line = content.slice(lineStart, lineEnd === -1 ? undefined : lineEnd);
153
+
154
+ try {
155
+ const entry = JSON.parse(line);
156
+ if (entry.type === "custom-title" && entry.customTitle) {
157
+ lastTitle = entry.customTitle;
158
+ }
159
+ } catch {
160
+ // Skip malformed lines
161
+ }
162
+
163
+ searchStart = titleIndex + 1;
164
+ }
165
+
166
+ return lastTitle;
167
+ } catch {
168
+ return null;
169
+ }
170
+ }
171
+
172
+ function getProjectTaskListId(cwd: string): string | null {
173
+ const dirName = cwd.split("/").filter(Boolean).pop() || "";
174
+ return `${dirName}-dev`;
175
+ }
176
+
177
+ function runHeadlessDocsCheck(
178
+ cwd: string,
179
+ files: string[],
180
+ taskListId: string
181
+ ): void {
182
+ const filesFormatted = files.map((f) => `- ${f}`).join("\n");
183
+
184
+ const prompt = DOCS_PROMPT
185
+ .replace("{files}", filesFormatted)
186
+ .replace("{taskListId}", taskListId);
187
+
188
+ // Spawn headless Claude Code agent in background
189
+ const child = spawn(
190
+ "claude",
191
+ [
192
+ "-p",
193
+ prompt,
194
+ "--permission-mode",
195
+ "acceptEdits",
196
+ "--allowedTools",
197
+ "Bash,Read",
198
+ "--no-session-persistence",
199
+ ],
200
+ {
201
+ cwd,
202
+ detached: true,
203
+ stdio: "ignore",
204
+ }
205
+ );
206
+
207
+ // Detach from parent process
208
+ child.unref();
209
+
210
+ console.error(`[hook-checkdocs] Started docs check for ${files.length} files`);
211
+ }
212
+
213
+ function approve() {
214
+ console.log(JSON.stringify({ decision: "approve" }));
215
+ process.exit(0);
216
+ }
217
+
218
+ export function run() {
219
+ const hookInput = readStdinJson();
220
+ if (!hookInput) {
221
+ approve();
222
+ return;
223
+ }
224
+
225
+ const { session_id, cwd, tool_name, tool_input, transcript_path } = hookInput;
226
+
227
+ // Only process edit tools
228
+ if (!EDIT_TOOLS.includes(tool_name)) {
229
+ approve();
230
+ return;
231
+ }
232
+
233
+ // Check repo pattern - only run for [prefix]-[name] folders
234
+ if (!isValidRepoPattern(cwd)) {
235
+ approve();
236
+ return;
237
+ }
238
+
239
+ const config = getConfig(cwd);
240
+
241
+ // Check if hook is disabled
242
+ if (config.enabled === false) {
243
+ approve();
244
+ return;
245
+ }
246
+
247
+ // Check keywords match
248
+ const sessionName = transcript_path ? getSessionName(transcript_path) : null;
249
+ const nameToCheck = sessionName || config.taskListId || "";
250
+ const keywords = config.keywords || ["dev"];
251
+
252
+ const matchesKeyword = keywords.some((keyword) =>
253
+ nameToCheck.toLowerCase().includes(keyword.toLowerCase())
254
+ );
255
+
256
+ if (!matchesKeyword && keywords.length > 0 && nameToCheck) {
257
+ approve();
258
+ return;
259
+ }
260
+
261
+ // Get edited file path
262
+ const filePath = (tool_input.file_path || tool_input.notebook_path) as string | undefined;
263
+ if (!filePath) {
264
+ approve();
265
+ return;
266
+ }
267
+
268
+ // Update session state
269
+ const state = getSessionState(session_id);
270
+
271
+ // Skip if check already in progress
272
+ if (state.checkInProgress) {
273
+ approve();
274
+ return;
275
+ }
276
+
277
+ state.editCount++;
278
+
279
+ if (!state.editedFiles.includes(filePath)) {
280
+ state.editedFiles.push(filePath);
281
+ }
282
+
283
+ const threshold = Math.min(7, Math.max(3, config.editThreshold || 3));
284
+
285
+ // Check if we should run docs check
286
+ if (state.editCount >= threshold) {
287
+ const taskListId = config.taskListId || getProjectTaskListId(cwd) || "default-dev";
288
+
289
+ // Mark check in progress
290
+ state.checkInProgress = true;
291
+ saveSessionState(session_id, state);
292
+
293
+ // Run headless docs check (async, non-blocking)
294
+ runHeadlessDocsCheck(cwd, state.editedFiles, taskListId);
295
+
296
+ // Reset counter after starting check
297
+ state.editCount = 0;
298
+ state.editedFiles = [];
299
+ state.lastCheckRun = Date.now();
300
+ state.checkInProgress = false;
301
+ }
302
+
303
+ saveSessionState(session_id, state);
304
+ approve();
305
+ }
306
+
307
+ // Allow direct execution
308
+ if (import.meta.main) {
309
+ run();
310
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "outDir": "./dist",
10
+ "declaration": true,
11
+ "declarationMap": true
12
+ },
13
+ "include": ["src/**/*"],
14
+ "exclude": ["node_modules", "dist"]
15
+ }
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Hasna
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,141 @@
1
+ # @hasnaxyz/hook-checkfiles
2
+
3
+ Claude Code hook that runs a headless agent to review files and create tasks via service-implementation.
4
+
5
+ ## Features
6
+
7
+ - **Async execution**: Runs in background, non-blocking
8
+ - **Headless Claude agent**: Spawns `claude -p` to review files
9
+ - **Task dispatch**: Creates tasks via `service-implementation task dispatch`
10
+ - **Configurable threshold**: Review after N file edits (3-7, default: 3)
11
+ - **Session-aware**: Only runs for sessions matching configured keywords
12
+
13
+ ## Installation
14
+
15
+ ### Global CLI
16
+
17
+ ```bash
18
+ bun add -g @hasnaxyz/hook-checkfiles
19
+ hook-checkfiles install --global
20
+ ```
21
+
22
+ ### Project-specific
23
+
24
+ ```bash
25
+ cd /path/to/your/project
26
+ bunx @hasnaxyz/hook-checkfiles install
27
+ ```
28
+
29
+ ## Requirements
30
+
31
+ - `claude` CLI (for headless agent)
32
+ - `service-implementation` CLI (for task dispatch)
33
+
34
+ ## Usage
35
+
36
+ Once installed, the hook runs automatically after file edits (Edit, Write, NotebookEdit tools).
37
+
38
+ ### Commands
39
+
40
+ ```bash
41
+ hook-checkfiles install [path] # Install the hook
42
+ hook-checkfiles config [path] # Update configuration
43
+ hook-checkfiles uninstall [path] # Remove the hook
44
+ hook-checkfiles status # Show hook status
45
+ hook-checkfiles run # Execute hook (called by Claude Code)
46
+ ```
47
+
48
+ ### Options
49
+
50
+ - `--global`, `-g`: Apply to global settings (`~/.claude/settings.json`)
51
+ - `/path/to/repo`: Apply to specific project path
52
+
53
+ ## Configuration
54
+
55
+ Configuration is stored in `.claude/settings.json`:
56
+
57
+ ```json
58
+ {
59
+ "hooks": {
60
+ "PostToolUse": [{
61
+ "matcher": {
62
+ "tool_name": "^(Edit|Write|NotebookEdit)$"
63
+ },
64
+ "hooks": [{
65
+ "type": "command",
66
+ "command": "bunx @hasnaxyz/hook-checkfiles@latest run",
67
+ "timeout": 120,
68
+ "async": true
69
+ }]
70
+ }]
71
+ },
72
+ "checkFilesConfig": {
73
+ "editThreshold": 3,
74
+ "taskListId": "myproject-bugfixes",
75
+ "keywords": ["dev"],
76
+ "enabled": true
77
+ }
78
+ }
79
+ ```
80
+
81
+ ### Options
82
+
83
+ | Option | Type | Default | Description |
84
+ |--------|------|---------|-------------|
85
+ | `editThreshold` | number | 3 | Run review after this many edits (3-7) |
86
+ | `taskListId` | string | auto | Task list for dispatching tasks |
87
+ | `keywords` | string[] | ["dev"] | Only run for matching sessions |
88
+ | `reviewPrompt` | string | default | Custom prompt for headless agent |
89
+ | `enabled` | boolean | true | Enable/disable the hook |
90
+
91
+ ## How It Works
92
+
93
+ 1. **Tracks file edits**: Monitors Edit, Write, NotebookEdit tool calls
94
+ 2. **Counts edits**: Maintains per-session edit counter
95
+ 3. **Triggers review**: After N edits, spawns headless Claude agent
96
+ 4. **Agent reviews**: Claude analyzes files for issues
97
+ 5. **Creates tasks**: Uses `service-implementation task dispatch` for each issue
98
+ 6. **Non-blocking**: Runs async, doesn't block main session
99
+
100
+ ## Headless Agent
101
+
102
+ The hook spawns:
103
+
104
+ ```bash
105
+ claude -p "<review prompt>" \
106
+ --permission-mode acceptEdits \
107
+ --allowedTools "Bash,Read" \
108
+ --no-session-persistence
109
+ ```
110
+
111
+ The agent:
112
+ - Reads the edited files
113
+ - Identifies bugs, security issues, performance problems
114
+ - Creates tasks via `service-implementation task dispatch`
115
+
116
+ ## Task Format
117
+
118
+ Tasks are dispatched with:
119
+
120
+ ```bash
121
+ service-implementation task dispatch "myproject-bugfixes" \
122
+ -s "REVIEW: [brief issue description]" \
123
+ -d "[detailed description with file:line reference]"
124
+ ```
125
+
126
+ ## Session State
127
+
128
+ State is persisted in `~/.claude/hook-state/checkfiles-{session_id}.json`:
129
+
130
+ ```json
131
+ {
132
+ "editCount": 2,
133
+ "editedFiles": ["src/file.ts", "src/other.ts"],
134
+ "lastReviewRun": 1706500000000,
135
+ "reviewInProgress": false
136
+ }
137
+ ```
138
+
139
+ ## License
140
+
141
+ MIT
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@hasnaxyz/hook-checkfiles",
3
+ "version": "0.1.1",
4
+ "description": "Claude Code hook that runs headless agent to review files and create tasks",
5
+ "type": "module",
6
+ "bin": {
7
+ "hook-checkfiles": "./dist/cli.js"
8
+ },
9
+ "main": "./dist/hook.js",
10
+ "exports": {
11
+ ".": {
12
+ "import": "./dist/hook.js",
13
+ "types": "./dist/hook.d.ts"
14
+ },
15
+ "./cli": {
16
+ "import": "./dist/cli.js"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "README.md"
22
+ ],
23
+ "scripts": {
24
+ "build": "bun build ./src/cli.ts ./src/hook.ts --outdir ./dist --target node",
25
+ "prepublishOnly": "bun run build",
26
+ "typecheck": "tsc --noEmit"
27
+ },
28
+ "keywords": [
29
+ "claude-code",
30
+ "claude",
31
+ "hook",
32
+ "review",
33
+ "headless",
34
+ "automation",
35
+ "cli"
36
+ ],
37
+ "author": "Hasna",
38
+ "license": "MIT",
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "https://github.com/hasnaxyz/hook-checkfiles.git"
42
+ },
43
+ "publishConfig": {
44
+ "access": "restricted",
45
+ "registry": "https://registry.npmjs.org/"
46
+ },
47
+ "engines": {
48
+ "node": ">=18",
49
+ "bun": ">=1.0"
50
+ },
51
+ "devDependencies": {
52
+ "@types/bun": "^1.3.8",
53
+ "@types/node": "^20",
54
+ "typescript": "^5.0.0"
55
+ }
56
+ }