@hasna/hooks 0.0.1 → 0.0.2

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 (62) hide show
  1. package/dist/index.js +366 -0
  2. package/hooks/hook-agentmessages/bin/cli.ts +125 -0
  3. package/package.json +2 -2
  4. package/hooks/hook-agentmessages/src/check-messages.ts +0 -151
  5. package/hooks/hook-agentmessages/src/install.ts +0 -126
  6. package/hooks/hook-agentmessages/src/session-start.ts +0 -255
  7. package/hooks/hook-agentmessages/src/uninstall.ts +0 -89
  8. package/hooks/hook-branchprotect/src/cli.ts +0 -126
  9. package/hooks/hook-branchprotect/src/hook.ts +0 -88
  10. package/hooks/hook-branchprotect/tsconfig.json +0 -25
  11. package/hooks/hook-checkbugs/src/cli.ts +0 -628
  12. package/hooks/hook-checkbugs/src/hook.ts +0 -335
  13. package/hooks/hook-checkbugs/tsconfig.json +0 -15
  14. package/hooks/hook-checkdocs/src/cli.ts +0 -628
  15. package/hooks/hook-checkdocs/src/hook.ts +0 -310
  16. package/hooks/hook-checkdocs/tsconfig.json +0 -15
  17. package/hooks/hook-checkfiles/src/cli.ts +0 -545
  18. package/hooks/hook-checkfiles/src/hook.ts +0 -321
  19. package/hooks/hook-checkfiles/tsconfig.json +0 -15
  20. package/hooks/hook-checklint/src/cli-patch.ts +0 -32
  21. package/hooks/hook-checklint/src/cli.ts +0 -667
  22. package/hooks/hook-checklint/src/hook.ts +0 -473
  23. package/hooks/hook-checklint/tsconfig.json +0 -15
  24. package/hooks/hook-checkpoint/src/cli.ts +0 -191
  25. package/hooks/hook-checkpoint/src/hook.ts +0 -207
  26. package/hooks/hook-checkpoint/tsconfig.json +0 -25
  27. package/hooks/hook-checksecurity/src/cli.ts +0 -601
  28. package/hooks/hook-checksecurity/src/hook.ts +0 -334
  29. package/hooks/hook-checksecurity/tsconfig.json +0 -15
  30. package/hooks/hook-checktasks/src/cli.ts +0 -578
  31. package/hooks/hook-checktasks/src/hook.ts +0 -308
  32. package/hooks/hook-checktasks/tsconfig.json +0 -20
  33. package/hooks/hook-checktests/src/cli.ts +0 -627
  34. package/hooks/hook-checktests/src/hook.ts +0 -334
  35. package/hooks/hook-checktests/tsconfig.json +0 -15
  36. package/hooks/hook-contextrefresh/src/cli.ts +0 -152
  37. package/hooks/hook-contextrefresh/src/hook.ts +0 -148
  38. package/hooks/hook-contextrefresh/tsconfig.json +0 -25
  39. package/hooks/hook-gitguard/src/cli.ts +0 -159
  40. package/hooks/hook-gitguard/src/hook.ts +0 -129
  41. package/hooks/hook-gitguard/tsconfig.json +0 -25
  42. package/hooks/hook-packageage/src/cli.ts +0 -165
  43. package/hooks/hook-packageage/src/hook.ts +0 -177
  44. package/hooks/hook-packageage/tsconfig.json +0 -25
  45. package/hooks/hook-phonenotify/src/cli.ts +0 -196
  46. package/hooks/hook-phonenotify/src/hook.ts +0 -139
  47. package/hooks/hook-phonenotify/tsconfig.json +0 -25
  48. package/hooks/hook-precompact/src/cli.ts +0 -168
  49. package/hooks/hook-precompact/src/hook.ts +0 -122
  50. package/hooks/hook-precompact/tsconfig.json +0 -25
  51. package/src/cli/components/App.tsx +0 -191
  52. package/src/cli/components/CategorySelect.tsx +0 -37
  53. package/src/cli/components/DataTable.tsx +0 -133
  54. package/src/cli/components/Header.tsx +0 -18
  55. package/src/cli/components/HookSelect.tsx +0 -29
  56. package/src/cli/components/InstallProgress.tsx +0 -105
  57. package/src/cli/components/SearchView.tsx +0 -86
  58. package/src/cli/index.tsx +0 -218
  59. package/src/index.ts +0 -31
  60. package/src/lib/installer.ts +0 -288
  61. package/src/lib/registry.ts +0 -205
  62. 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
- }