hookstack-cli 0.1.5 → 0.1.7

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 (3) hide show
  1. package/README.md +95 -0
  2. package/bin/cli.mjs +4 -9
  3. package/package.json +3 -2
package/README.md ADDED
@@ -0,0 +1,95 @@
1
+ # hookstack-cli
2
+
3
+ **Install Claude Code hooks in one command.**
4
+
5
+ [hookstack.vercel.app](https://hookstack.vercel.app) — browse 66+ community-vetted lifecycle hooks for Claude Code & GitHub Copilot, then run this CLI to wire them into your project.
6
+
7
+ ---
8
+
9
+ ## Quick start
10
+
11
+ ```bash
12
+ npx hookstack-cli@latest install --hooks=secret-detection,destructive-command-guard
13
+ ```
14
+
15
+ That's it. The CLI fetches the hooks, shows you what will be installed, and patches your `.claude/settings.json`.
16
+
17
+ ---
18
+
19
+ ## Usage
20
+
21
+ ```
22
+ npx hookstack-cli@latest install --hooks=<slug1>,<slug2>,...
23
+
24
+ Options:
25
+ --hooks <slugs> Comma-separated hook slugs (required)
26
+ --global, -g Install into ~/.claude instead of ./.claude
27
+ --scope <s> "project" (default) or "global"
28
+ --yes, -y Skip prompts (non-interactive / CI)
29
+ --version, -v Print version
30
+ --help, -h Show help
31
+ ```
32
+
33
+ ### Interactive mode (default in a terminal)
34
+
35
+ When run in a terminal the CLI opens an interactive prompt:
36
+
37
+ 1. Fetches the requested hooks from the registry
38
+ 2. Shows an **installation summary** (path, category, events, blocking flag)
39
+ 3. Shows a **security panel** (shell access · network · filesystem writes · Snyk score)
40
+ 4. Asks for confirmation before writing anything
41
+
42
+ ### Non-interactive mode (`--yes` or piped)
43
+
44
+ Skips all prompts — useful in CI or dotfile bootstrap scripts.
45
+
46
+ ```bash
47
+ # CI bootstrap
48
+ npx hookstack-cli@latest install --hooks=secret-detection,git-push-guard --yes --scope=project
49
+ ```
50
+
51
+ ---
52
+
53
+ ## What gets installed
54
+
55
+ For each hook the CLI:
56
+
57
+ - Writes the `.mjs` script to `.claude/hooks/` (or `~/.claude/hooks/` for global scope)
58
+ - Patches `.claude/settings.json` to register the hook on the right lifecycle event
59
+
60
+ No new dependencies are added to your project. Hooks are plain Node.js scripts — no SDK, no agent modification.
61
+
62
+ ---
63
+
64
+ ## Finding hooks
65
+
66
+ Browse and filter the full catalogue at **[hookstack.vercel.app](https://hookstack.vercel.app)**:
67
+
68
+ - Filter by category (`security`, `workflow`, `context`, `validation`…)
69
+ - Select the hooks you want — your basket persists in the browser
70
+ - Copy the generated `npx hookstack-cli@latest install` command and run it
71
+
72
+ ### Popular hooks
73
+
74
+ | Slug | Event | What it does |
75
+ |---|---|---|
76
+ | `secret-detection` | `PreToolUse / Bash` | Blocks commands that would leak API keys |
77
+ | `destructive-command-guard` | `PreToolUse / Bash` | Stops `rm -rf /`, `DROP TABLE`, and similar |
78
+ | `sensitive-file-protection` | `PreToolUse / Write` | Keeps `.env` and key files untouched |
79
+ | `git-push-guard` | `PreToolUse / Bash` | No accidental push straight to `main` |
80
+ | `git-context-on-startup` | `SessionStart` | Every session opens with branch + status |
81
+ | `auto-format-on-save` | `PostToolUse / Write` | ESLint + Prettier run after every file write |
82
+ | `slack-notify-on-stop` | `Stop` | Pings you when the long task finishes |
83
+
84
+ ---
85
+
86
+ ## Requirements
87
+
88
+ - Node.js ≥ 18
89
+ - Claude Code installed (hooks are wired into its lifecycle)
90
+
91
+ ---
92
+
93
+ ## License
94
+
95
+ MIT — [github.com/steve-magne/hookstack](https://github.com/steve-magne/hookstack)
package/bin/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs'
3
3
  import { homedir } from 'os'
4
- import { join } from 'path'
4
+ import { join, dirname } from 'path'
5
5
  import { fileURLToPath } from 'url'
6
6
  import * as p from '@clack/prompts'
7
7
  import pc from 'picocolors'
@@ -17,7 +17,8 @@ import {
17
17
 
18
18
  const API_BASE = process.env.HOOKSTACK_API_BASE || 'https://hookstack.vercel.app'
19
19
  const REPO_URL = 'github.com/steve-magne/hookstack'
20
- const VERSION = '0.1.3'
20
+ const __dirname = dirname(fileURLToPath(import.meta.url))
21
+ const VERSION = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8')).version
21
22
 
22
23
  async function fetchHooks(slugs) {
23
24
  const url = `${API_BASE}/api/hooks?slugs=${slugs.map(encodeURIComponent).join(',')}`
@@ -222,7 +223,7 @@ async function main() {
222
223
  const args = parseArgs(process.argv)
223
224
 
224
225
  if (args.version) { console.log(VERSION); return }
225
- if (args.help || (!args.command && args.hooks.length === 0)) { console.log(HELP); return }
226
+ if (args.help || args.hooks.length === 0) { console.log(HELP); return }
226
227
 
227
228
  const command = args.command ?? 'install'
228
229
  if (command !== 'install') {
@@ -231,12 +232,6 @@ async function main() {
231
232
  process.exit(1)
232
233
  }
233
234
 
234
- if (args.hooks.length === 0) {
235
- console.error('✗ No hooks specified. Use --hooks=<slug1>,<slug2>')
236
- console.error(' Browse hooks at https://hookstack.vercel.app')
237
- process.exit(1)
238
- }
239
-
240
235
  const interactive = Boolean(process.stdout.isTTY) && !args.yes
241
236
  if (interactive) await interactiveInstall(args.hooks, args)
242
237
  else await directInstall(args.hooks, args)
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "hookstack-cli",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "CLI installer for the Hookstack catalogue of Claude Code hooks",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "hookstack-cli": "./bin/cli.mjs"
8
8
  },
9
9
  "files": [
10
- "bin/"
10
+ "bin/",
11
+ "README.md"
11
12
  ],
12
13
  "engines": {
13
14
  "node": ">=18"