@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,335 @@
1
+ #!/usr/bin/env bun
2
+
3
+ /**
4
+ * Claude Code Hook: check-bugs
5
+ *
6
+ * Runs a headless Codex agent to check for potential bugs.
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 bug 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 CheckBugsConfig {
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 = "checkBugsConfig";
48
+ const STATE_DIR = join(homedir(), ".claude", "hook-state");
49
+ const EDIT_TOOLS = ["Edit", "Write", "NotebookEdit"];
50
+
51
+ /**
52
+ * Sanitize ID to prevent path traversal and injection attacks
53
+ */
54
+ function sanitizeId(id: string): string {
55
+ if (!id || typeof id !== 'string') return 'default';
56
+ // Only allow alphanumeric, dash, underscore
57
+ return id.replace(/[^a-zA-Z0-9_-]/g, '-').slice(0, 100) || 'default';
58
+ }
59
+
60
+ /**
61
+ * Sanitize file path for safe display in prompts
62
+ */
63
+ function sanitizePath(path: string): string {
64
+ if (!path || typeof path !== 'string') return '';
65
+ // Remove any shell special characters that could be used for injection
66
+ return path.replace(/[`$"'\\;&|<>(){}[\]!#*?~]/g, '_');
67
+ }
68
+
69
+ const BUGS_PROMPT = `You are a code reviewer focused on finding bugs. Review the following files that were recently edited and identify potential bugs:
70
+
71
+ FILES TO REVIEW:
72
+ {files}
73
+
74
+ For each bug found, create a task using the service-implementation CLI:
75
+ service-implementation task dispatch "{taskListId}" -s "BUG: [severity] - [brief description]" -d "[detailed description with file:line reference and suggested fix]"
76
+
77
+ Severity levels: CRITICAL, HIGH, MEDIUM, LOW
78
+
79
+ Focus on:
80
+ - Logic errors and off-by-one errors
81
+ - Null/undefined reference issues
82
+ - Race conditions and async bugs
83
+ - Memory leaks
84
+ - Unhandled edge cases
85
+ - Type mismatches
86
+ - Incorrect error handling
87
+ - Security vulnerabilities
88
+ - Performance issues
89
+ - Resource cleanup issues
90
+
91
+ If no bugs are found, do not create any tasks.
92
+ Only report meaningful bugs, not style issues or minor nitpicks.
93
+ Limit to max 5 most important bugs.`;
94
+
95
+ function isValidRepoPattern(cwd: string): boolean {
96
+ const dirName = cwd.split("/").filter(Boolean).pop() || "";
97
+ // Match: hook-checklint, skill-installhook, iapp-mail, etc.
98
+ return /^[a-z]+-[a-z0-9-]+$/i.test(dirName);
99
+ }
100
+
101
+ function readStdinJson(): HookInput | null {
102
+ try {
103
+ const stdin = readFileSync(0, "utf-8");
104
+ return JSON.parse(stdin);
105
+ } catch {
106
+ return null;
107
+ }
108
+ }
109
+
110
+ function readSettings(path: string): Record<string, unknown> {
111
+ if (!existsSync(path)) return {};
112
+ try {
113
+ return JSON.parse(readFileSync(path, "utf-8"));
114
+ } catch {
115
+ return {};
116
+ }
117
+ }
118
+
119
+ function getConfig(cwd: string): CheckBugsConfig {
120
+ // Try project settings first
121
+ const projectSettings = readSettings(join(cwd, ".claude", "settings.json"));
122
+ if (projectSettings[CONFIG_KEY]) {
123
+ return projectSettings[CONFIG_KEY] as CheckBugsConfig;
124
+ }
125
+
126
+ // Fall back to global settings
127
+ const globalSettings = readSettings(join(homedir(), ".claude", "settings.json"));
128
+ if (globalSettings[CONFIG_KEY]) {
129
+ return globalSettings[CONFIG_KEY] as CheckBugsConfig;
130
+ }
131
+
132
+ // Default config
133
+ return {
134
+ editThreshold: 3,
135
+ keywords: ["dev"],
136
+ enabled: true,
137
+ };
138
+ }
139
+
140
+ function getStateFile(sessionId: string): string {
141
+ mkdirSync(STATE_DIR, { recursive: true });
142
+ const safeSessionId = sanitizeId(sessionId);
143
+ return join(STATE_DIR, `checkbugs-${safeSessionId}.json`);
144
+ }
145
+
146
+ function getSessionState(sessionId: string): SessionState {
147
+ const stateFile = getStateFile(sessionId);
148
+ if (existsSync(stateFile)) {
149
+ try {
150
+ return JSON.parse(readFileSync(stateFile, "utf-8"));
151
+ } catch {
152
+ // Corrupted state, reset
153
+ }
154
+ }
155
+ return { editCount: 0, editedFiles: [], lastCheckRun: 0, checkInProgress: false };
156
+ }
157
+
158
+ function saveSessionState(sessionId: string, state: SessionState): void {
159
+ const stateFile = getStateFile(sessionId);
160
+ writeFileSync(stateFile, JSON.stringify(state, null, 2));
161
+ }
162
+
163
+ function getSessionName(transcriptPath: string): string | null {
164
+ if (!existsSync(transcriptPath)) return null;
165
+
166
+ try {
167
+ const content = readFileSync(transcriptPath, "utf-8");
168
+ let lastTitle: string | null = null;
169
+ let searchStart = 0;
170
+
171
+ while (true) {
172
+ const titleIndex = content.indexOf('"custom-title"', searchStart);
173
+ if (titleIndex === -1) break;
174
+
175
+ const lineStart = content.lastIndexOf("\n", titleIndex) + 1;
176
+ const lineEnd = content.indexOf("\n", titleIndex);
177
+ const line = content.slice(lineStart, lineEnd === -1 ? undefined : lineEnd);
178
+
179
+ try {
180
+ const entry = JSON.parse(line);
181
+ if (entry.type === "custom-title" && entry.customTitle) {
182
+ lastTitle = entry.customTitle;
183
+ }
184
+ } catch {
185
+ // Skip malformed lines
186
+ }
187
+
188
+ searchStart = titleIndex + 1;
189
+ }
190
+
191
+ return lastTitle;
192
+ } catch {
193
+ return null;
194
+ }
195
+ }
196
+
197
+ function getProjectTaskListId(cwd: string): string | null {
198
+ const dirName = cwd.split("/").filter(Boolean).pop() || "";
199
+ return `${dirName}-bugfixes`;
200
+ }
201
+
202
+ function runHeadlessBugsCheck(
203
+ cwd: string,
204
+ files: string[],
205
+ taskListId: string
206
+ ): void {
207
+ // Sanitize file paths to prevent prompt injection
208
+ const filesFormatted = files.map((f) => `- ${sanitizePath(f)}`).join("\n");
209
+ // Sanitize taskListId
210
+ const safeTaskListId = sanitizeId(taskListId);
211
+
212
+ const prompt = BUGS_PROMPT
213
+ .replace("{files}", filesFormatted)
214
+ .replace("{taskListId}", safeTaskListId);
215
+
216
+ // Spawn headless Codex agent in background
217
+ const child = spawn(
218
+ "codex",
219
+ [
220
+ "exec",
221
+ prompt,
222
+ ],
223
+ {
224
+ cwd,
225
+ detached: true,
226
+ stdio: "ignore",
227
+ }
228
+ );
229
+
230
+ // Detach from parent process
231
+ child.unref();
232
+
233
+ console.error(`[hook-checkbugs] Started bugs check for ${files.length} files`);
234
+ }
235
+
236
+ function approve() {
237
+ console.log(JSON.stringify({ decision: "approve" }));
238
+ process.exit(0);
239
+ }
240
+
241
+ export function run() {
242
+ const hookInput = readStdinJson();
243
+ if (!hookInput) {
244
+ approve();
245
+ return;
246
+ }
247
+
248
+ const { session_id, cwd, tool_name, tool_input, transcript_path } = hookInput;
249
+
250
+ // Only process edit tools
251
+ if (!EDIT_TOOLS.includes(tool_name)) {
252
+ approve();
253
+ return;
254
+ }
255
+
256
+ // Check repo pattern - only run for [prefix]-[name] folders
257
+ if (!isValidRepoPattern(cwd)) {
258
+ approve();
259
+ return;
260
+ }
261
+
262
+ const config = getConfig(cwd);
263
+
264
+ // Check if hook is disabled
265
+ if (config.enabled === false) {
266
+ approve();
267
+ return;
268
+ }
269
+
270
+ // Check keywords match
271
+ const sessionName = transcript_path ? getSessionName(transcript_path) : null;
272
+ const nameToCheck = sessionName || config.taskListId || "";
273
+ const keywords = config.keywords || ["dev"];
274
+
275
+ const matchesKeyword = keywords.some((keyword) =>
276
+ nameToCheck.toLowerCase().includes(keyword.toLowerCase())
277
+ );
278
+
279
+ // If keywords are configured and we have a session name, check for match
280
+ // Empty nameToCheck means we can't filter, so allow the check to proceed
281
+ if (keywords.length > 0 && nameToCheck && !matchesKeyword) {
282
+ approve();
283
+ return;
284
+ }
285
+
286
+ // Get edited file path
287
+ const filePath = (tool_input.file_path || tool_input.notebook_path) as string | undefined;
288
+ if (!filePath) {
289
+ approve();
290
+ return;
291
+ }
292
+
293
+ // Update session state
294
+ const state = getSessionState(session_id);
295
+
296
+ // Skip if check already in progress
297
+ if (state.checkInProgress) {
298
+ approve();
299
+ return;
300
+ }
301
+
302
+ state.editCount++;
303
+
304
+ if (!state.editedFiles.includes(filePath)) {
305
+ state.editedFiles.push(filePath);
306
+ }
307
+
308
+ const threshold = Math.min(7, Math.max(3, config.editThreshold || 3));
309
+
310
+ // Check if we should run bugs check
311
+ if (state.editCount >= threshold) {
312
+ const taskListId = config.taskListId || getProjectTaskListId(cwd) || "default-bugfixes";
313
+
314
+ // Mark check in progress
315
+ state.checkInProgress = true;
316
+ saveSessionState(session_id, state);
317
+
318
+ // Run headless bugs check (async, non-blocking)
319
+ runHeadlessBugsCheck(cwd, state.editedFiles, taskListId);
320
+
321
+ // Reset counter after starting check
322
+ state.editCount = 0;
323
+ state.editedFiles = [];
324
+ state.lastCheckRun = Date.now();
325
+ state.checkInProgress = false;
326
+ }
327
+
328
+ saveSessionState(session_id, state);
329
+ approve();
330
+ }
331
+
332
+ // Allow direct execution
333
+ if (import.meta.main) {
334
+ run();
335
+ }
@@ -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,137 @@
1
+ # @hasnaxyz/hook-checkdocs
2
+
3
+ Claude Code hook that checks for missing documentation and creates tasks via service-implementation.
4
+
5
+ ## Features
6
+
7
+ - **Async execution**: Runs in background, non-blocking
8
+ - **Headless Claude agent**: Spawns `claude -p` to check documentation
9
+ - **Task dispatch**: Creates tasks via `service-implementation task dispatch`
10
+ - **Configurable threshold**: Check after N file edits (3-7, default: 3)
11
+ - **Repo pattern check**: Only runs for repos matching `[prefix]-[name]` pattern
12
+ - **Session-aware**: Only runs for sessions matching configured keywords
13
+
14
+ ## Installation
15
+
16
+ ### Global CLI
17
+
18
+ ```bash
19
+ bun add -g @hasnaxyz/hook-checkdocs
20
+ hook-checkdocs install --global
21
+ ```
22
+
23
+ ### Project-specific
24
+
25
+ ```bash
26
+ cd /path/to/your/project
27
+ bunx @hasnaxyz/hook-checkdocs install
28
+ ```
29
+
30
+ ## Requirements
31
+
32
+ - `claude` CLI (for headless agent)
33
+ - `service-implementation` CLI (for task dispatch)
34
+
35
+ ## Usage
36
+
37
+ Once installed, the hook runs automatically after file edits (Edit, Write, NotebookEdit tools).
38
+
39
+ ### Commands
40
+
41
+ ```bash
42
+ hook-checkdocs install [path] # Install the hook
43
+ hook-checkdocs config [path] # Update configuration
44
+ hook-checkdocs uninstall [path] # Remove the hook
45
+ hook-checkdocs status # Show hook status
46
+ hook-checkdocs run # Execute hook (called by Claude Code)
47
+ ```
48
+
49
+ ### Options
50
+
51
+ - `--global`, `-g`: Apply to global settings (`~/.claude/settings.json`)
52
+ - `/path/to/repo`: Apply to specific project path
53
+
54
+ ## Configuration
55
+
56
+ Configuration is stored in `.claude/settings.json`:
57
+
58
+ ```json
59
+ {
60
+ "hooks": {
61
+ "PostToolUse": [{
62
+ "matcher": {
63
+ "tool_name": "^(Edit|Write|NotebookEdit)$"
64
+ },
65
+ "hooks": [{
66
+ "type": "command",
67
+ "command": "bunx @hasnaxyz/hook-checkdocs@latest run",
68
+ "timeout": 120,
69
+ "async": true
70
+ }]
71
+ }]
72
+ },
73
+ "checkDocsConfig": {
74
+ "editThreshold": 3,
75
+ "taskListId": "myproject-dev",
76
+ "keywords": ["dev"],
77
+ "enabled": true
78
+ }
79
+ }
80
+ ```
81
+
82
+ ### Options
83
+
84
+ | Option | Type | Default | Description |
85
+ |--------|------|---------|-------------|
86
+ | `editThreshold` | number | 3 | Run check after this many edits (3-7) |
87
+ | `taskListId` | string | auto | Task list for dispatching tasks |
88
+ | `keywords` | string[] | ["dev"] | Only run for matching sessions |
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. **Validates repo**: Only runs for repos matching `[prefix]-[name]` pattern
95
+ 3. **Counts edits**: Maintains per-session edit counter
96
+ 4. **Triggers check**: After N edits, spawns headless Claude agent
97
+ 5. **Agent reviews**: Claude analyzes files for missing documentation
98
+ 6. **Creates tasks**: Uses `service-implementation task dispatch` for each issue
99
+ 7. **Non-blocking**: Runs async, doesn't block main session
100
+
101
+ ## Documentation Issues Detected
102
+
103
+ The hook checks for:
104
+
105
+ - Missing function/method documentation
106
+ - Outdated README sections
107
+ - Missing API documentation
108
+ - Missing inline comments for complex logic
109
+ - Missing type definitions documentation
110
+ - Missing usage examples
111
+
112
+ ## Task Format
113
+
114
+ Tasks are dispatched with:
115
+
116
+ ```bash
117
+ service-implementation task dispatch "myproject-dev" \
118
+ -s "DOCS: [brief description]" \
119
+ -d "[detailed description of what docs need to be added/updated]"
120
+ ```
121
+
122
+ ## Session State
123
+
124
+ State is persisted in `~/.claude/hook-state/checkdocs-{session_id}.json`:
125
+
126
+ ```json
127
+ {
128
+ "editCount": 2,
129
+ "editedFiles": ["src/file.ts", "src/other.ts"],
130
+ "lastCheckRun": 1706500000000,
131
+ "checkInProgress": false
132
+ }
133
+ ```
134
+
135
+ ## License
136
+
137
+ MIT
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@hasnaxyz/hook-checkdocs",
3
+ "version": "0.1.6",
4
+ "description": "Claude Code hook that checks for missing documentation and creates tasks",
5
+ "type": "module",
6
+ "bin": {
7
+ "hook-checkdocs": "./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
+ "docs",
33
+ "documentation",
34
+ "headless",
35
+ "automation",
36
+ "cli"
37
+ ],
38
+ "author": "Hasna",
39
+ "license": "MIT",
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "https://github.com/hasnaxyz/hook-checkdocs.git"
43
+ },
44
+ "publishConfig": {
45
+ "access": "restricted",
46
+ "registry": "https://registry.npmjs.org/"
47
+ },
48
+ "engines": {
49
+ "node": ">=18",
50
+ "bun": ">=1.0"
51
+ },
52
+ "devDependencies": {
53
+ "@types/bun": "^1.3.8",
54
+ "@types/node": "^20",
55
+ "typescript": "^5.0.0"
56
+ }
57
+ }