@hasna/hooks 0.0.1 → 0.0.3

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 (64) hide show
  1. package/.hooks/index.ts +6 -0
  2. package/bin/index.js +1 -1
  3. package/dist/index.js +366 -0
  4. package/hooks/hook-agentmessages/bin/cli.ts +125 -0
  5. package/package.json +2 -2
  6. package/hooks/hook-agentmessages/src/check-messages.ts +0 -151
  7. package/hooks/hook-agentmessages/src/install.ts +0 -126
  8. package/hooks/hook-agentmessages/src/session-start.ts +0 -255
  9. package/hooks/hook-agentmessages/src/uninstall.ts +0 -89
  10. package/hooks/hook-branchprotect/src/cli.ts +0 -126
  11. package/hooks/hook-branchprotect/src/hook.ts +0 -88
  12. package/hooks/hook-branchprotect/tsconfig.json +0 -25
  13. package/hooks/hook-checkbugs/src/cli.ts +0 -628
  14. package/hooks/hook-checkbugs/src/hook.ts +0 -335
  15. package/hooks/hook-checkbugs/tsconfig.json +0 -15
  16. package/hooks/hook-checkdocs/src/cli.ts +0 -628
  17. package/hooks/hook-checkdocs/src/hook.ts +0 -310
  18. package/hooks/hook-checkdocs/tsconfig.json +0 -15
  19. package/hooks/hook-checkfiles/src/cli.ts +0 -545
  20. package/hooks/hook-checkfiles/src/hook.ts +0 -321
  21. package/hooks/hook-checkfiles/tsconfig.json +0 -15
  22. package/hooks/hook-checklint/src/cli-patch.ts +0 -32
  23. package/hooks/hook-checklint/src/cli.ts +0 -667
  24. package/hooks/hook-checklint/src/hook.ts +0 -473
  25. package/hooks/hook-checklint/tsconfig.json +0 -15
  26. package/hooks/hook-checkpoint/src/cli.ts +0 -191
  27. package/hooks/hook-checkpoint/src/hook.ts +0 -207
  28. package/hooks/hook-checkpoint/tsconfig.json +0 -25
  29. package/hooks/hook-checksecurity/src/cli.ts +0 -601
  30. package/hooks/hook-checksecurity/src/hook.ts +0 -334
  31. package/hooks/hook-checksecurity/tsconfig.json +0 -15
  32. package/hooks/hook-checktasks/src/cli.ts +0 -578
  33. package/hooks/hook-checktasks/src/hook.ts +0 -308
  34. package/hooks/hook-checktasks/tsconfig.json +0 -20
  35. package/hooks/hook-checktests/src/cli.ts +0 -627
  36. package/hooks/hook-checktests/src/hook.ts +0 -334
  37. package/hooks/hook-checktests/tsconfig.json +0 -15
  38. package/hooks/hook-contextrefresh/src/cli.ts +0 -152
  39. package/hooks/hook-contextrefresh/src/hook.ts +0 -148
  40. package/hooks/hook-contextrefresh/tsconfig.json +0 -25
  41. package/hooks/hook-gitguard/src/cli.ts +0 -159
  42. package/hooks/hook-gitguard/src/hook.ts +0 -129
  43. package/hooks/hook-gitguard/tsconfig.json +0 -25
  44. package/hooks/hook-packageage/src/cli.ts +0 -165
  45. package/hooks/hook-packageage/src/hook.ts +0 -177
  46. package/hooks/hook-packageage/tsconfig.json +0 -25
  47. package/hooks/hook-phonenotify/src/cli.ts +0 -196
  48. package/hooks/hook-phonenotify/src/hook.ts +0 -139
  49. package/hooks/hook-phonenotify/tsconfig.json +0 -25
  50. package/hooks/hook-precompact/src/cli.ts +0 -168
  51. package/hooks/hook-precompact/src/hook.ts +0 -122
  52. package/hooks/hook-precompact/tsconfig.json +0 -25
  53. package/src/cli/components/App.tsx +0 -191
  54. package/src/cli/components/CategorySelect.tsx +0 -37
  55. package/src/cli/components/DataTable.tsx +0 -133
  56. package/src/cli/components/Header.tsx +0 -18
  57. package/src/cli/components/HookSelect.tsx +0 -29
  58. package/src/cli/components/InstallProgress.tsx +0 -105
  59. package/src/cli/components/SearchView.tsx +0 -86
  60. package/src/cli/index.tsx +0 -218
  61. package/src/index.ts +0 -31
  62. package/src/lib/installer.ts +0 -288
  63. package/src/lib/registry.ts +0 -205
  64. package/tsconfig.json +0 -17
@@ -1,207 +0,0 @@
1
- #!/usr/bin/env bun
2
-
3
- /**
4
- * Claude Code Hook: checkpoint
5
- *
6
- * PreToolUse hook that creates shadow git snapshots before any file
7
- * Write/Edit operations. This provides a safety net with easy rollback
8
- * capability without cluttering the main project's git history.
9
- *
10
- * Shadow repo is stored in .claude-checkpoints/ (gitignored).
11
- */
12
-
13
- import { readFileSync, existsSync, mkdirSync, writeFileSync, appendFileSync } from "fs";
14
- import { execSync } from "child_process";
15
- import { join, resolve } from "path";
16
-
17
- interface HookInput {
18
- session_id: string;
19
- cwd: string;
20
- tool_name: string;
21
- tool_input: Record<string, unknown>;
22
- }
23
-
24
- interface HookOutput {
25
- decision?: "approve" | "block";
26
- reason?: string;
27
- }
28
-
29
- const CHECKPOINT_DIR = ".claude-checkpoints";
30
- const TOOLS_TO_CHECKPOINT = ["Write", "Edit", "NotebookEdit"];
31
-
32
- /**
33
- * Read JSON from stdin
34
- */
35
- function readStdinJson(): HookInput | null {
36
- try {
37
- const input = readFileSync(0, "utf-8").trim();
38
- if (!input) return null;
39
- return JSON.parse(input);
40
- } catch {
41
- return null;
42
- }
43
- }
44
-
45
- /**
46
- * Initialize shadow git repo for checkpoints
47
- */
48
- function initShadowRepo(cwd: string): string {
49
- const shadowPath = join(cwd, CHECKPOINT_DIR);
50
-
51
- if (!existsSync(shadowPath)) {
52
- mkdirSync(shadowPath, { recursive: true });
53
- }
54
-
55
- const gitDir = join(shadowPath, ".git");
56
- if (!existsSync(gitDir)) {
57
- execSync("git init", { cwd: shadowPath, stdio: "pipe" });
58
- execSync('git config user.email "hook-checkpoint@claude.local"', {
59
- cwd: shadowPath,
60
- stdio: "pipe",
61
- });
62
- execSync('git config user.name "hook-checkpoint"', {
63
- cwd: shadowPath,
64
- stdio: "pipe",
65
- });
66
-
67
- // Create initial commit
68
- writeFileSync(join(shadowPath, ".checkpoint-init"), new Date().toISOString());
69
- execSync("git add -A && git commit -m 'init: checkpoint repo'", {
70
- cwd: shadowPath,
71
- stdio: "pipe",
72
- });
73
- }
74
-
75
- // Ensure .claude-checkpoints is gitignored in main project
76
- const mainGitignore = join(cwd, ".gitignore");
77
- if (existsSync(mainGitignore)) {
78
- const content = readFileSync(mainGitignore, "utf-8");
79
- if (!content.includes(CHECKPOINT_DIR)) {
80
- appendFileSync(mainGitignore, `\n${CHECKPOINT_DIR}/\n`);
81
- }
82
- }
83
-
84
- return shadowPath;
85
- }
86
-
87
- /**
88
- * Copy the target file into the shadow repo and commit
89
- */
90
- function createCheckpoint(
91
- cwd: string,
92
- shadowPath: string,
93
- toolName: string,
94
- filePath: string,
95
- sessionId: string
96
- ): void {
97
- const absFilePath = resolve(cwd, filePath);
98
-
99
- if (!existsSync(absFilePath)) {
100
- // File doesn't exist yet (new file being created) — log but no snapshot needed
101
- const logEntry = `[${new Date().toISOString()}] ${toolName} creating new file: ${filePath}\n`;
102
- appendFileSync(join(shadowPath, "checkpoint.log"), logEntry);
103
- return;
104
- }
105
-
106
- // Copy file to shadow repo preserving relative path
107
- const relativePath = filePath.startsWith("/")
108
- ? filePath.replace(cwd, "").replace(/^\//, "")
109
- : filePath;
110
- const shadowFilePath = join(shadowPath, "files", relativePath);
111
- const shadowFileDir = join(shadowFilePath, "..");
112
-
113
- mkdirSync(shadowFileDir, { recursive: true });
114
-
115
- const content = readFileSync(absFilePath);
116
- writeFileSync(shadowFilePath, content);
117
-
118
- // Create metadata
119
- const metadata = {
120
- tool: toolName,
121
- file: filePath,
122
- session: sessionId,
123
- timestamp: new Date().toISOString(),
124
- };
125
- writeFileSync(
126
- join(shadowPath, "last-checkpoint.json"),
127
- JSON.stringify(metadata, null, 2)
128
- );
129
-
130
- // Commit to shadow repo
131
- try {
132
- execSync("git add -A", { cwd: shadowPath, stdio: "pipe" });
133
- const msg = `checkpoint: ${toolName} ${relativePath}`;
134
- execSync(`git commit -m "${msg}" --allow-empty`, {
135
- cwd: shadowPath,
136
- stdio: "pipe",
137
- });
138
- } catch {
139
- // Commit may fail if nothing changed — that's fine
140
- }
141
-
142
- // Log
143
- const logEntry = `[${new Date().toISOString()}] ${toolName} → ${relativePath} (session: ${sessionId})\n`;
144
- appendFileSync(join(shadowPath, "checkpoint.log"), logEntry);
145
- }
146
-
147
- /**
148
- * Extract file path from tool input
149
- */
150
- function getFilePath(toolName: string, toolInput: Record<string, unknown>): string | null {
151
- switch (toolName) {
152
- case "Write":
153
- case "Edit":
154
- return (toolInput.file_path as string) || null;
155
- case "NotebookEdit":
156
- return (toolInput.notebook_path as string) || null;
157
- default:
158
- return null;
159
- }
160
- }
161
-
162
- /**
163
- * Output hook response
164
- */
165
- function respond(output: HookOutput): void {
166
- console.log(JSON.stringify(output));
167
- }
168
-
169
- /**
170
- * Main hook execution
171
- */
172
- export function run(): void {
173
- const input = readStdinJson();
174
-
175
- if (!input) {
176
- respond({ decision: "approve" });
177
- return;
178
- }
179
-
180
- // Only checkpoint file-modifying tools
181
- if (!TOOLS_TO_CHECKPOINT.includes(input.tool_name)) {
182
- respond({ decision: "approve" });
183
- return;
184
- }
185
-
186
- const filePath = getFilePath(input.tool_name, input.tool_input);
187
- if (!filePath) {
188
- respond({ decision: "approve" });
189
- return;
190
- }
191
-
192
- try {
193
- const shadowPath = initShadowRepo(input.cwd);
194
- createCheckpoint(input.cwd, shadowPath, input.tool_name, filePath, input.session_id);
195
- } catch (error) {
196
- // Never block operations due to checkpoint failures
197
- const errMsg = error instanceof Error ? error.message : String(error);
198
- console.error(`[hook-checkpoint] Warning: checkpoint failed: ${errMsg}`);
199
- }
200
-
201
- // Always approve — checkpointing is non-blocking
202
- respond({ decision: "approve" });
203
- }
204
-
205
- if (import.meta.main) {
206
- run();
207
- }
@@ -1,25 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ESNext",
4
- "module": "ESNext",
5
- "lib": ["ESNext"],
6
- "moduleResolution": "bundler",
7
- "allowImportingTsExtensions": true,
8
- "strict": true,
9
- "esModuleInterop": true,
10
- "skipLibCheck": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "resolveJsonModule": true,
13
- "isolatedModules": true,
14
- "noEmit": true,
15
- "noUnusedLocals": true,
16
- "noUnusedParameters": true,
17
- "declaration": true,
18
- "declarationMap": true,
19
- "outDir": "./dist",
20
- "rootDir": "./src",
21
- "types": ["bun-types"]
22
- },
23
- "include": ["src/**/*"],
24
- "exclude": ["node_modules", "dist"]
25
- }