aiblueprint-cli 1.4.46 → 1.4.48
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.
- package/{claude-code-config → ai-config}/.claude-plugin/plugin.json +2 -2
- package/ai-config/scripts/CLAUDE.md +31 -0
- package/{claude-code-config → ai-config}/scripts/package.json +1 -8
- package/ai-config/skills/codex-environment/SKILL.md +182 -0
- package/dist/cli.js +932 -768
- package/package.json +2 -2
- package/claude-code-config/hooks/hooks.json +0 -15
- package/claude-code-config/scripts/CLAUDE.md +0 -50
- package/claude-code-config/scripts/command-validator/CLAUDE.md +0 -112
- package/claude-code-config/scripts/command-validator/README.md +0 -147
- package/claude-code-config/scripts/command-validator/src/__tests__/validator.test.ts +0 -99
- package/claude-code-config/scripts/command-validator/src/cli.ts +0 -120
- package/claude-code-config/scripts/command-validator/src/lib/security-rules.ts +0 -174
- package/claude-code-config/scripts/command-validator/src/lib/types.ts +0 -34
- package/claude-code-config/scripts/command-validator/src/lib/validator.ts +0 -90
- package/claude-code-config/song/finish.mp3 +0 -0
- package/claude-code-config/song/need-human.mp3 +0 -0
- /package/{claude-code-config → ai-config}/agents/action.md +0 -0
- /package/{claude-code-config → ai-config}/agents/explore-codebase.md +0 -0
- /package/{claude-code-config → ai-config}/agents/explore-docs.md +0 -0
- /package/{claude-code-config → ai-config}/agents/websearch.md +0 -0
- /package/{claude-code-config → ai-config}/scripts/.claude/commands/fix-on-my-computer.md +0 -0
- /package/{claude-code-config → ai-config}/scripts/biome.json +0 -0
- /package/{claude-code-config → ai-config}/scripts/bun.lockb +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/CLAUDE.md +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/README.md +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/__tests__/context.test.ts +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/__tests__/formatters.test.ts +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/__tests__/statusline.test.ts +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/data/.gitignore +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/data/.gitkeep +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/defaults.json +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/docs/ARCHITECTURE.md +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/fixtures/mock-transcript.jsonl +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/fixtures/test-input.json +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/src/index.ts +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/src/lib/config-types.ts +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/src/lib/config.ts +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/src/lib/context.ts +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/src/lib/formatters.ts +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/src/lib/git.ts +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/src/lib/menu-factories.ts +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/src/lib/presets.ts +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/src/lib/render-pure.ts +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/src/lib/types.ts +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/src/lib/utils.ts +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/src/tests/spend-v2.test.ts +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/statusline.config.json +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/test-with-fixtures.ts +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/test.ts +0 -0
- /package/{claude-code-config → ai-config}/scripts/statusline/tsconfig.json +0 -0
- /package/{claude-code-config → ai-config}/scripts/tsconfig.json +0 -0
- /package/{claude-code-config → ai-config}/skills/apex/SKILL.md +0 -0
- /package/{claude-code-config → ai-config}/skills/apex/scripts/setup-templates.sh +0 -0
- /package/{claude-code-config → ai-config}/skills/apex/scripts/update-progress.sh +0 -0
- /package/{claude-code-config → ai-config}/skills/apex/steps/step-00-init.md +0 -0
- /package/{claude-code-config → ai-config}/skills/apex/steps/step-00b-branch.md +0 -0
- /package/{claude-code-config → ai-config}/skills/apex/steps/step-00b-economy.md +0 -0
- /package/{claude-code-config → ai-config}/skills/apex/steps/step-00b-interactive.md +0 -0
- /package/{claude-code-config → ai-config}/skills/apex/steps/step-01-analyze.md +0 -0
- /package/{claude-code-config → ai-config}/skills/apex/steps/step-02-plan.md +0 -0
- /package/{claude-code-config → ai-config}/skills/apex/steps/step-03-execute.md +0 -0
- /package/{claude-code-config → ai-config}/skills/apex/steps/step-04-validate.md +0 -0
- /package/{claude-code-config → ai-config}/skills/apex/templates/00-context.md +0 -0
- /package/{claude-code-config → ai-config}/skills/apex/templates/01-analyze.md +0 -0
- /package/{claude-code-config → ai-config}/skills/apex/templates/02-plan.md +0 -0
- /package/{claude-code-config → ai-config}/skills/apex/templates/03-execute.md +0 -0
- /package/{claude-code-config → ai-config}/skills/apex/templates/04-validate.md +0 -0
- /package/{claude-code-config → ai-config}/skills/apex/templates/README.md +0 -0
- /package/{claude-code-config → ai-config}/skills/apex/templates/step-complete.md +0 -0
- /package/{claude-code-config → ai-config}/skills/claude-memory/SKILL.md +0 -0
- /package/{claude-code-config → ai-config}/skills/claude-memory/references/comprehensive-example.md +0 -0
- /package/{claude-code-config → ai-config}/skills/claude-memory/references/optimize-guide.md +0 -0
- /package/{claude-code-config → ai-config}/skills/claude-memory/references/project-patterns.md +0 -0
- /package/{claude-code-config → ai-config}/skills/claude-memory/references/prompting-techniques.md +0 -0
- /package/{claude-code-config → ai-config}/skills/claude-memory/references/rules-directory-guide.md +0 -0
- /package/{claude-code-config → ai-config}/skills/claude-memory/references/section-templates.md +0 -0
- /package/{claude-code-config → ai-config}/skills/commit/SKILL.md +0 -0
- /package/{claude-code-config → ai-config}/skills/create-pr/SKILL.md +0 -0
- /package/{claude-code-config → ai-config}/skills/fix-errors/SKILL.md +0 -0
- /package/{claude-code-config → ai-config}/skills/fix-grammar/SKILL.md +0 -0
- /package/{claude-code-config → ai-config}/skills/fix-pr-comments/SKILL.md +0 -0
- /package/{claude-code-config → ai-config}/skills/merge/SKILL.md +0 -0
- /package/{claude-code-config → ai-config}/skills/oneshot/SKILL.md +0 -0
- /package/{claude-code-config → ai-config}/skills/prompt-creator/SKILL.md +0 -0
- /package/{claude-code-config → ai-config}/skills/prompt-creator/references/anthropic-best-practices.md +0 -0
- /package/{claude-code-config → ai-config}/skills/prompt-creator/references/anti-patterns.md +0 -0
- /package/{claude-code-config → ai-config}/skills/prompt-creator/references/clarity-principles.md +0 -0
- /package/{claude-code-config → ai-config}/skills/prompt-creator/references/context-management.md +0 -0
- /package/{claude-code-config → ai-config}/skills/prompt-creator/references/few-shot-patterns.md +0 -0
- /package/{claude-code-config → ai-config}/skills/prompt-creator/references/openai-best-practices.md +0 -0
- /package/{claude-code-config → ai-config}/skills/prompt-creator/references/prompt-templates.md +0 -0
- /package/{claude-code-config → ai-config}/skills/prompt-creator/references/reasoning-techniques.md +0 -0
- /package/{claude-code-config → ai-config}/skills/prompt-creator/references/system-prompt-patterns.md +0 -0
- /package/{claude-code-config → ai-config}/skills/prompt-creator/references/xml-structure.md +0 -0
- /package/{claude-code-config → ai-config}/skills/ralph-loop/SKILL.md +0 -0
- /package/{claude-code-config → ai-config}/skills/ralph-loop/scripts/setup.sh +0 -0
- /package/{claude-code-config → ai-config}/skills/ralph-loop/steps/step-00-init.md +0 -0
- /package/{claude-code-config → ai-config}/skills/ralph-loop/steps/step-01-interactive-prd.md +0 -0
- /package/{claude-code-config → ai-config}/skills/ralph-loop/steps/step-02-create-stories.md +0 -0
- /package/{claude-code-config → ai-config}/skills/ralph-loop/steps/step-03-finish.md +0 -0
- /package/{claude-code-config → ai-config}/skills/skill-creator/LICENSE.txt +0 -0
- /package/{claude-code-config → ai-config}/skills/skill-creator/SKILL.md +0 -0
- /package/{claude-code-config → ai-config}/skills/skill-creator/package.json +0 -0
- /package/{claude-code-config → ai-config}/skills/skill-creator/references/output-patterns.md +0 -0
- /package/{claude-code-config → ai-config}/skills/skill-creator/references/progressive-disclosure-patterns.md +0 -0
- /package/{claude-code-config → ai-config}/skills/skill-creator/references/prompting-integration.md +0 -0
- /package/{claude-code-config → ai-config}/skills/skill-creator/references/real-world-examples.md +0 -0
- /package/{claude-code-config → ai-config}/skills/skill-creator/references/script-patterns.md +0 -0
- /package/{claude-code-config → ai-config}/skills/skill-creator/references/workflows.md +0 -0
- /package/{claude-code-config → ai-config}/skills/skill-creator/references/xml-tag-guide.md +0 -0
- /package/{claude-code-config → ai-config}/skills/skill-creator/scripts/init-skill.ts +0 -0
- /package/{claude-code-config → ai-config}/skills/skill-creator/scripts/package-skill.ts +0 -0
- /package/{claude-code-config → ai-config}/skills/skill-creator/scripts/validate.ts +0 -0
- /package/{claude-code-config → ai-config}/skills/subagent-creator/SKILL.md +0 -0
- /package/{claude-code-config → ai-config}/skills/subagent-creator/references/context-management.md +0 -0
- /package/{claude-code-config → ai-config}/skills/subagent-creator/references/debugging-agents.md +0 -0
- /package/{claude-code-config → ai-config}/skills/subagent-creator/references/error-handling-and-recovery.md +0 -0
- /package/{claude-code-config → ai-config}/skills/subagent-creator/references/evaluation-and-testing.md +0 -0
- /package/{claude-code-config → ai-config}/skills/subagent-creator/references/orchestration-patterns.md +0 -0
- /package/{claude-code-config → ai-config}/skills/subagent-creator/references/subagents.md +0 -0
- /package/{claude-code-config → ai-config}/skills/subagent-creator/references/writing-subagent-prompts.md +0 -0
- /package/{claude-code-config → ai-config}/skills/ultrathink/SKILL.md +0 -0
- /package/{claude-code-config → ai-config}/skills/workflow-apex-free/SKILL.md +0 -0
- /package/{claude-code-config → ai-config}/skills/workflow-apex-free/scripts/setup-templates.sh +0 -0
- /package/{claude-code-config → ai-config}/skills/workflow-apex-free/scripts/update-progress.sh +0 -0
- /package/{claude-code-config → ai-config}/skills/workflow-apex-free/steps/step-00-init.md +0 -0
- /package/{claude-code-config → ai-config}/skills/workflow-apex-free/steps/step-00b-branch.md +0 -0
- /package/{claude-code-config → ai-config}/skills/workflow-apex-free/steps/step-00b-economy.md +0 -0
- /package/{claude-code-config → ai-config}/skills/workflow-apex-free/steps/step-00b-interactive.md +0 -0
- /package/{claude-code-config → ai-config}/skills/workflow-apex-free/steps/step-01-analyze.md +0 -0
- /package/{claude-code-config → ai-config}/skills/workflow-apex-free/steps/step-02-plan.md +0 -0
- /package/{claude-code-config → ai-config}/skills/workflow-apex-free/steps/step-03-execute.md +0 -0
- /package/{claude-code-config → ai-config}/skills/workflow-apex-free/steps/step-04-validate.md +0 -0
- /package/{claude-code-config → ai-config}/skills/workflow-apex-free/templates/00-context.md +0 -0
- /package/{claude-code-config → ai-config}/skills/workflow-apex-free/templates/01-analyze.md +0 -0
- /package/{claude-code-config → ai-config}/skills/workflow-apex-free/templates/02-plan.md +0 -0
- /package/{claude-code-config → ai-config}/skills/workflow-apex-free/templates/03-execute.md +0 -0
- /package/{claude-code-config → ai-config}/skills/workflow-apex-free/templates/04-validate.md +0 -0
- /package/{claude-code-config → ai-config}/skills/workflow-apex-free/templates/README.md +0 -0
- /package/{claude-code-config → ai-config}/skills/workflow-apex-free/templates/step-complete.md +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aiblueprint-cli",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.48",
|
|
4
4
|
"description": "AIBlueprint CLI for setting up Claude Code configurations",
|
|
5
5
|
"author": "AIBlueprint",
|
|
6
6
|
"license": "MIT",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
},
|
|
48
48
|
"files": [
|
|
49
49
|
"dist",
|
|
50
|
-
"
|
|
50
|
+
"ai-config"
|
|
51
51
|
],
|
|
52
52
|
"keywords": [
|
|
53
53
|
"claude",
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# Scripts - Project Memory
|
|
2
|
-
|
|
3
|
-
Monorepo containing Claude Code utilities and extensions.
|
|
4
|
-
|
|
5
|
-
## Structure
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
scripts/
|
|
9
|
-
├── auto-rename-session/ # Auto-generates session titles via AI
|
|
10
|
-
├── claude-code-ai/ # Shared Claude API helpers
|
|
11
|
-
├── command-validator/ # Security validation for bash commands
|
|
12
|
-
├── statusline/ # Custom statusline for Claude Code
|
|
13
|
-
└── package.json # Root package with all scripts
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
## Commands
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
bun run test # Run ALL tests (186 tests)
|
|
20
|
-
bun run lint # Lint all packages
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### Per-Package Commands
|
|
24
|
-
|
|
25
|
-
| Package | Test | Start |
|
|
26
|
-
|---------|------|-------|
|
|
27
|
-
| auto-rename-session | `bun run auto-rename:test` | `bun run auto-rename:start` |
|
|
28
|
-
| claude-code-ai | `bun run ai:test` | - |
|
|
29
|
-
| command-validator | `bun run validator:test` | `bun run validator:cli` |
|
|
30
|
-
| statusline | `bun run statusline:test` | `bun run statusline:start` |
|
|
31
|
-
|
|
32
|
-
## Cross-Platform Support
|
|
33
|
-
|
|
34
|
-
All packages support macOS, Linux, and Windows (via WSL):
|
|
35
|
-
- Use `path.join()` instead of string concatenation
|
|
36
|
-
- Use `os.homedir()` instead of `process.env.HOME`
|
|
37
|
-
- Use `path.sep` or regex `[/\\]` for path splitting
|
|
38
|
-
|
|
39
|
-
## Shared Dependencies
|
|
40
|
-
|
|
41
|
-
- `@ai-sdk/anthropic` + `ai` - Claude API access
|
|
42
|
-
- `picocolors` - Terminal colors
|
|
43
|
-
- `@biomejs/biome` - Linting/formatting
|
|
44
|
-
- `bun:test` - Testing
|
|
45
|
-
|
|
46
|
-
## Credentials
|
|
47
|
-
|
|
48
|
-
Claude Code OAuth tokens are retrieved via `claude-code-ai/helper/credentials.ts`:
|
|
49
|
-
- macOS: Keychain (`security find-generic-password`)
|
|
50
|
-
- Linux/Windows: `~/.claude/.credentials.json`
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
# Command Validator - CLAUDE.md
|
|
2
|
-
|
|
3
|
-
This file provides guidance to Claude Code when working with the command-validator security package.
|
|
4
|
-
|
|
5
|
-
## Project Purpose
|
|
6
|
-
|
|
7
|
-
**Command Validator** is a security validation package for Claude Code's PreToolUse hook. It validates bash commands before execution to prevent dangerous operations like:
|
|
8
|
-
- System destruction (rm -rf /, dd, mkfs)
|
|
9
|
-
- Privilege escalation (sudo, chmod, passwd)
|
|
10
|
-
- Network attacks (nc, nmap, telnet)
|
|
11
|
-
- Malicious patterns (fork bombs, backdoors)
|
|
12
|
-
- Sensitive file access (/etc/passwd, /etc/shadow)
|
|
13
|
-
|
|
14
|
-
The validator is integrated as a hook in Claude Code settings and blocks dangerous commands while allowing safe operations.
|
|
15
|
-
|
|
16
|
-
## CRITICAL: This Project Uses BUN
|
|
17
|
-
|
|
18
|
-
**NEVER use npm or node commands. This project exclusively uses BUN.**
|
|
19
|
-
|
|
20
|
-
## Development Commands
|
|
21
|
-
|
|
22
|
-
**CRITICAL**: Only use these BUN commands:
|
|
23
|
-
|
|
24
|
-
### Testing (Primary Workflow)
|
|
25
|
-
- `bun test` - Run all tests with Vitest
|
|
26
|
-
- `bun test:ui` - Run tests with UI interface
|
|
27
|
-
- `bun run test` - Alternative test command
|
|
28
|
-
|
|
29
|
-
### Code Quality
|
|
30
|
-
- `bun run lint` - Run Biome linter and auto-fix
|
|
31
|
-
- `bun run format` - Format code with Biome
|
|
32
|
-
- `bunx tsc --noEmit` - TypeScript type checking (no build)
|
|
33
|
-
|
|
34
|
-
### Execution
|
|
35
|
-
- `bun src/cli.ts` - Run CLI validator directly
|
|
36
|
-
- `bun install` - Install dependencies
|
|
37
|
-
|
|
38
|
-
## Development Workflow
|
|
39
|
-
|
|
40
|
-
**CRITICAL**: The majority of work on this project follows this simple cycle:
|
|
41
|
-
|
|
42
|
-
### Test-Driven Development Cycle
|
|
43
|
-
1. **Run tests**: `bun test`
|
|
44
|
-
2. **Read errors**: Analyze test failures carefully
|
|
45
|
-
3. **Fix the problem**: Make minimal changes to pass tests
|
|
46
|
-
4. **Re-run tests**: `bun test` until ALL tests pass
|
|
47
|
-
5. **Repeat**: Continue cycle until all tests are green
|
|
48
|
-
|
|
49
|
-
**ALWAYS follow this workflow:**
|
|
50
|
-
```bash
|
|
51
|
-
bun test # See what's broken
|
|
52
|
-
# Fix the code
|
|
53
|
-
bun test # Verify fix works
|
|
54
|
-
# Repeat until green
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
## Architecture Overview
|
|
58
|
-
|
|
59
|
-
```
|
|
60
|
-
src/
|
|
61
|
-
├── cli.ts # CLI entry point (used by Claude Code hook)
|
|
62
|
-
├── lib/
|
|
63
|
-
│ ├── types.ts # TypeScript interfaces
|
|
64
|
-
│ ├── security-rules.ts # Security rules database
|
|
65
|
-
│ └── validator.ts # Core validation logic
|
|
66
|
-
└── __tests__/
|
|
67
|
-
└── validator.test.ts # Comprehensive test suite (82+ tests)
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### Key Files
|
|
71
|
-
- **@scripts/command-validator/src/lib/validator.ts** - Core CommandValidator class
|
|
72
|
-
- **@scripts/command-validator/src/lib/security-rules.ts** - Security rules database
|
|
73
|
-
- **@scripts/command-validator/src/__tests__/validator.test.ts** - All test cases
|
|
74
|
-
|
|
75
|
-
## Code Conventions
|
|
76
|
-
|
|
77
|
-
- **TypeScript**: Strict mode enabled
|
|
78
|
-
- **Testing**: Vitest with comprehensive coverage (82+ tests)
|
|
79
|
-
- **Linting**: Biome for formatting and linting
|
|
80
|
-
- **Imports**: ESM module format only
|
|
81
|
-
|
|
82
|
-
## Security Test Categories
|
|
83
|
-
|
|
84
|
-
The test suite validates:
|
|
85
|
-
1. **Safe Commands**: ls, git, npm, cat, cp, mv, mkdir (must allow)
|
|
86
|
-
2. **Dangerous Commands**: rm -rf /, dd, sudo, passwd (must block)
|
|
87
|
-
3. **Special Cases**: rm -rf safety rules, protected paths, command chains
|
|
88
|
-
4. **Malicious Patterns**: Fork bombs, backdoors, log manipulation
|
|
89
|
-
|
|
90
|
-
## IMPORTANT: Workflow Rules
|
|
91
|
-
|
|
92
|
-
- **BEFORE making changes**: Run `bun test` to see current state
|
|
93
|
-
- **AFTER any code change**: Run `bun test` to verify
|
|
94
|
-
- **NEVER assume tests pass**: Always verify with `bun test`
|
|
95
|
-
- **Fix one test at a time**: Make minimal changes, then re-test
|
|
96
|
-
- **Use Bun ONLY**: No npm, node, or yarn commands
|
|
97
|
-
|
|
98
|
-
## Common Modifications
|
|
99
|
-
|
|
100
|
-
Most changes involve:
|
|
101
|
-
1. **Adding new security rules** → Update @scripts/command-validator/src/lib/security-rules.ts
|
|
102
|
-
2. **Modifying validation logic** → Update @scripts/command-validator/src/lib/validator.ts
|
|
103
|
-
3. **Adding test cases** → Update @scripts/command-validator/src/__tests__/validator.test.ts
|
|
104
|
-
4. **Run tests after each change** → `bun test`
|
|
105
|
-
|
|
106
|
-
## Test Execution Priority
|
|
107
|
-
|
|
108
|
-
**ALWAYS use the test-driven approach:**
|
|
109
|
-
- Tests define the requirements
|
|
110
|
-
- Code changes must make tests pass
|
|
111
|
-
- All 82+ tests must be green before committing
|
|
112
|
-
- Use `bun test` continuously during development
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
# Command Validator
|
|
2
|
-
|
|
3
|
-
A secure command validation package for Claude Code's PreToolUse hook. This package validates bash commands before execution to prevent dangerous operations.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **Comprehensive Security Rules**: Blocks dangerous commands (rm -rf /, dd, mkfs, etc.)
|
|
8
|
-
- **Pattern Matching**: Detects malicious patterns like fork bombs, backdoors, and data exfiltration
|
|
9
|
-
- **Path Protection**: Prevents writes to system directories (/etc, /usr, /bin, etc.)
|
|
10
|
-
- **Command Chaining**: Validates chained commands (&&, ||, ;)
|
|
11
|
-
- **Fully Tested**: 82+ tests with Vitest ensuring reliable validation
|
|
12
|
-
|
|
13
|
-
## Installation
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
bun install
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Usage
|
|
20
|
-
|
|
21
|
-
### As a Claude Code Hook
|
|
22
|
-
|
|
23
|
-
The validator is configured as a PreToolUse hook in Claude Code settings:
|
|
24
|
-
|
|
25
|
-
```json
|
|
26
|
-
{
|
|
27
|
-
"hooks": {
|
|
28
|
-
"PreToolUse": [
|
|
29
|
-
{
|
|
30
|
-
"matcher": "Bash",
|
|
31
|
-
"hooks": [
|
|
32
|
-
{
|
|
33
|
-
"type": "command",
|
|
34
|
-
"command": "bun ~/.claude/scripts/command-validator/src/cli.ts"
|
|
35
|
-
}
|
|
36
|
-
]
|
|
37
|
-
}
|
|
38
|
-
]
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### Programmatic Usage
|
|
44
|
-
|
|
45
|
-
```typescript
|
|
46
|
-
import { CommandValidator } from "./src/lib/validator";
|
|
47
|
-
|
|
48
|
-
const validator = new CommandValidator();
|
|
49
|
-
const result = validator.validate("rm -rf /");
|
|
50
|
-
|
|
51
|
-
if (!result.isValid) {
|
|
52
|
-
console.log(`Blocked: ${result.violations.join(", ")}`);
|
|
53
|
-
console.log(`Severity: ${result.severity}`);
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
## Testing
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
# Run all tests
|
|
61
|
-
bun test
|
|
62
|
-
|
|
63
|
-
# Run tests with UI
|
|
64
|
-
bun test:ui
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
## Test Coverage
|
|
68
|
-
|
|
69
|
-
The test suite includes:
|
|
70
|
-
|
|
71
|
-
### Safe Commands (Must Allow)
|
|
72
|
-
- Standard utilities: ls, git, npm, pnpm, node, python
|
|
73
|
-
- File operations: cat, cp, mv, mkdir, touch
|
|
74
|
-
- Safe command chains with &&
|
|
75
|
-
|
|
76
|
-
### Dangerous Commands (Must Block)
|
|
77
|
-
- System destruction: rm -rf /, dd, mkfs, fdisk
|
|
78
|
-
- Privilege escalation: sudo, chmod, chown, passwd
|
|
79
|
-
- Network attacks: nc, nmap, telnet
|
|
80
|
-
- Malicious patterns: fork bombs, backdoors, log manipulation
|
|
81
|
-
- Sensitive file access: /etc/passwd, /etc/shadow, /etc/sudoers
|
|
82
|
-
|
|
83
|
-
### Special Cases
|
|
84
|
-
- rm -rf safety: Allows deletions in safe paths (~/Developer/, /tmp/)
|
|
85
|
-
- Protected paths: Blocks dangerous operations on /etc, /usr, /bin, etc.
|
|
86
|
-
- Binary content detection
|
|
87
|
-
- Command length limits
|
|
88
|
-
|
|
89
|
-
## Architecture
|
|
90
|
-
|
|
91
|
-
```
|
|
92
|
-
src/
|
|
93
|
-
├── cli.ts # CLI entry point (used by Claude Code hook)
|
|
94
|
-
├── lib/
|
|
95
|
-
│ ├── types.ts # TypeScript interfaces
|
|
96
|
-
│ ├── security-rules.ts # Security rules database
|
|
97
|
-
│ └── validator.ts # Core validation logic
|
|
98
|
-
└── __tests__/
|
|
99
|
-
└── validator.test.ts # Comprehensive test suite
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
## Security Rules
|
|
103
|
-
|
|
104
|
-
### Critical Commands
|
|
105
|
-
- `del`, `format`, `mkfs`, `shred`, `dd`, `fdisk`, `parted`
|
|
106
|
-
|
|
107
|
-
### Privilege Escalation
|
|
108
|
-
- `sudo`, `su`, `passwd`, `chpasswd`, `usermod`, `chmod`, `chown`
|
|
109
|
-
|
|
110
|
-
### Network Commands
|
|
111
|
-
- `nc`, `netcat`, `nmap`, `telnet`, `ssh-keygen`, `iptables`
|
|
112
|
-
|
|
113
|
-
### System Manipulation
|
|
114
|
-
- `systemctl`, `service`, `kill`, `killall`, `mount`, `umount`
|
|
115
|
-
|
|
116
|
-
### Protected Paths
|
|
117
|
-
- `/etc/`, `/usr/`, `/sbin/`, `/boot/`, `/sys/`, `/proc/`, `/dev/`, `/root/`
|
|
118
|
-
|
|
119
|
-
## Security Logs
|
|
120
|
-
|
|
121
|
-
Security events are logged to `data/security.log` inside the package directory. The log file contains:
|
|
122
|
-
- Timestamp
|
|
123
|
-
- Session ID
|
|
124
|
-
- Tool name
|
|
125
|
-
- Command (truncated to 500 chars)
|
|
126
|
-
- Blocked/allowed status
|
|
127
|
-
- Severity level
|
|
128
|
-
- Violations detected
|
|
129
|
-
|
|
130
|
-
The `data/` folder is gitignored to prevent committing sensitive log data.
|
|
131
|
-
|
|
132
|
-
## Development
|
|
133
|
-
|
|
134
|
-
```bash
|
|
135
|
-
# Run linter
|
|
136
|
-
bun run lint
|
|
137
|
-
|
|
138
|
-
# Format code
|
|
139
|
-
bun run format
|
|
140
|
-
|
|
141
|
-
# Type check
|
|
142
|
-
bunx tsc --noEmit
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
## License
|
|
146
|
-
|
|
147
|
-
MIT
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "bun:test";
|
|
2
|
-
import { CommandValidator } from "../lib/validator";
|
|
3
|
-
|
|
4
|
-
describe("CommandValidator", () => {
|
|
5
|
-
const validator = new CommandValidator();
|
|
6
|
-
|
|
7
|
-
describe("Commands that MUST be ALLOWED (action: allow)", () => {
|
|
8
|
-
const allowedCommands = [
|
|
9
|
-
"ls -la",
|
|
10
|
-
"pwd",
|
|
11
|
-
"git status",
|
|
12
|
-
"git add -A && git commit -m 'Clé API Google gérée côté client'",
|
|
13
|
-
"npm install",
|
|
14
|
-
"rm file.txt",
|
|
15
|
-
"rm -r folder",
|
|
16
|
-
"rm -f file.txt",
|
|
17
|
-
"echo 'éàù accents français'",
|
|
18
|
-
"git commit -m '🚀 emoji test'",
|
|
19
|
-
"cat /etc/passwd",
|
|
20
|
-
"curl http://example.com",
|
|
21
|
-
];
|
|
22
|
-
|
|
23
|
-
for (const command of allowedCommands) {
|
|
24
|
-
it(`should ALLOW: ${command}`, () => {
|
|
25
|
-
const result = validator.validate(command);
|
|
26
|
-
expect(result.isValid).toBe(true);
|
|
27
|
-
expect(result.action).toBe("allow");
|
|
28
|
-
expect(result.violations).toHaveLength(0);
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
describe("Commands that MUST be DENIED (action: deny) - rm -rf ONLY", () => {
|
|
34
|
-
const deniedCommands = [
|
|
35
|
-
"rm -rf /",
|
|
36
|
-
"rm -rf folder",
|
|
37
|
-
"rm -rf .",
|
|
38
|
-
"rm -rf /tmp/test",
|
|
39
|
-
"rm -fr folder",
|
|
40
|
-
"rm -r -f folder",
|
|
41
|
-
"rm -f -r folder",
|
|
42
|
-
"rm -rf /Users/test/.claude/skills",
|
|
43
|
-
"mkdir test && rm -rf test",
|
|
44
|
-
];
|
|
45
|
-
|
|
46
|
-
for (const command of deniedCommands) {
|
|
47
|
-
it(`should DENY: ${command}`, () => {
|
|
48
|
-
const result = validator.validate(command);
|
|
49
|
-
expect(result.isValid).toBe(false);
|
|
50
|
-
expect(result.action).toBe("deny");
|
|
51
|
-
expect(result.severity).toBe("CRITICAL");
|
|
52
|
-
expect(result.violations[0]).toContain("rm -rf is forbidden");
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
describe("Commands that MUST ASK permission (action: ask)", () => {
|
|
58
|
-
const askCommands = [
|
|
59
|
-
{ cmd: "sudo apt install", expected: "sudo" },
|
|
60
|
-
{ cmd: "sudo rm something", expected: "sudo" },
|
|
61
|
-
{ cmd: "chmod 777 file.txt", expected: "chmod" },
|
|
62
|
-
{ cmd: "chown root file.txt", expected: "chown" },
|
|
63
|
-
{ cmd: "dd if=/dev/zero of=test.img", expected: "dd" },
|
|
64
|
-
{ cmd: "kill -9 1234", expected: "kill" },
|
|
65
|
-
{ cmd: "killall node", expected: "killall" },
|
|
66
|
-
{ cmd: "su root", expected: "su" },
|
|
67
|
-
];
|
|
68
|
-
|
|
69
|
-
for (const { cmd, expected } of askCommands) {
|
|
70
|
-
it(`should ASK for: ${cmd}`, () => {
|
|
71
|
-
const result = validator.validate(cmd);
|
|
72
|
-
expect(result.isValid).toBe(false);
|
|
73
|
-
expect(result.action).toBe("ask");
|
|
74
|
-
expect(result.severity).toBe("HIGH");
|
|
75
|
-
expect(result.violations[0]).toContain(expected);
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
describe("Edge cases", () => {
|
|
81
|
-
it("should DENY empty commands", () => {
|
|
82
|
-
const result = validator.validate("");
|
|
83
|
-
expect(result.isValid).toBe(false);
|
|
84
|
-
expect(result.action).toBe("deny");
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it("should ALLOW commands with accented characters", () => {
|
|
88
|
-
const result = validator.validate("git commit -m 'éàùç accents'");
|
|
89
|
-
expect(result.isValid).toBe(true);
|
|
90
|
-
expect(result.action).toBe("allow");
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it("should ALLOW commands with emojis", () => {
|
|
94
|
-
const result = validator.validate("echo '🚀🎉'");
|
|
95
|
-
expect(result.isValid).toBe(true);
|
|
96
|
-
expect(result.action).toBe("allow");
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
});
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
|
|
3
|
-
import { join } from "node:path";
|
|
4
|
-
import type { HookInput, HookOutput } from "./lib/types";
|
|
5
|
-
import { CommandValidator } from "./lib/validator";
|
|
6
|
-
|
|
7
|
-
const LOG_FILE = join(import.meta.dir, "../data/security.log");
|
|
8
|
-
|
|
9
|
-
async function logSecurityEvent(
|
|
10
|
-
command: string,
|
|
11
|
-
toolName: string,
|
|
12
|
-
result: { isValid: boolean; severity: string; violations: string[] },
|
|
13
|
-
sessionId: string | null,
|
|
14
|
-
) {
|
|
15
|
-
const timestamp = new Date().toISOString();
|
|
16
|
-
const logEntry = {
|
|
17
|
-
timestamp,
|
|
18
|
-
sessionId,
|
|
19
|
-
toolName,
|
|
20
|
-
command: command.substring(0, 500),
|
|
21
|
-
blocked: !result.isValid,
|
|
22
|
-
severity: result.severity,
|
|
23
|
-
violations: result.violations,
|
|
24
|
-
source: "claude-code-hook",
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
const logLine = `${JSON.stringify(logEntry)}\n`;
|
|
29
|
-
const file = Bun.file(LOG_FILE);
|
|
30
|
-
const exists = await file.exists();
|
|
31
|
-
|
|
32
|
-
if (exists) {
|
|
33
|
-
const existingContent = await file.text();
|
|
34
|
-
await Bun.write(LOG_FILE, existingContent + logLine);
|
|
35
|
-
} else {
|
|
36
|
-
await Bun.write(LOG_FILE, logLine);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
console.error(
|
|
40
|
-
`[SECURITY] ${result.isValid ? "ALLOWED" : "BLOCKED"}: ${command.substring(0, 100)}`,
|
|
41
|
-
);
|
|
42
|
-
} catch (error) {
|
|
43
|
-
console.error("Failed to write security log:", error);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async function main() {
|
|
48
|
-
const validator = new CommandValidator();
|
|
49
|
-
|
|
50
|
-
try {
|
|
51
|
-
const stdin = process.stdin;
|
|
52
|
-
const chunks: Buffer[] = [];
|
|
53
|
-
|
|
54
|
-
for await (const chunk of stdin) {
|
|
55
|
-
chunks.push(chunk);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const input = Buffer.concat(chunks).toString();
|
|
59
|
-
|
|
60
|
-
if (!input.trim()) {
|
|
61
|
-
console.error("No input received from stdin");
|
|
62
|
-
process.exit(1);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
let hookData: HookInput;
|
|
66
|
-
try {
|
|
67
|
-
hookData = JSON.parse(input);
|
|
68
|
-
} catch (error) {
|
|
69
|
-
console.error("Invalid JSON input:", (error as Error).message);
|
|
70
|
-
process.exit(1);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const toolName = hookData.tool_name || "Unknown";
|
|
74
|
-
const toolInput = hookData.tool_input || {};
|
|
75
|
-
const sessionId = hookData.session_id || null;
|
|
76
|
-
|
|
77
|
-
if (toolName !== "Bash") {
|
|
78
|
-
console.log(`Skipping validation for tool: ${toolName}`);
|
|
79
|
-
process.exit(0);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const command = toolInput.command;
|
|
83
|
-
if (!command) {
|
|
84
|
-
console.error("No command found in tool input");
|
|
85
|
-
process.exit(1);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const result = validator.validate(command, toolName);
|
|
89
|
-
|
|
90
|
-
await logSecurityEvent(command, toolName, result, sessionId);
|
|
91
|
-
|
|
92
|
-
if (result.isValid) {
|
|
93
|
-
console.log("Command validation passed");
|
|
94
|
-
process.exit(0);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const message = result.action === "deny"
|
|
98
|
-
? `Command blocked!\n\nCommand: ${command}\nReason: ${result.violations.join(", ")}\nSeverity: ${result.severity}`
|
|
99
|
-
: `⚠️ Potentially dangerous command\n\nCommand: ${command}\nReason: ${result.violations.join(", ")}\nSeverity: ${result.severity}\n\nDo you want to proceed?`;
|
|
100
|
-
|
|
101
|
-
const hookOutput: HookOutput = {
|
|
102
|
-
hookSpecificOutput: {
|
|
103
|
-
hookEventName: "PreToolUse",
|
|
104
|
-
permissionDecision: result.action === "deny" ? "deny" : "ask",
|
|
105
|
-
permissionDecisionReason: message,
|
|
106
|
-
},
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
console.log(JSON.stringify(hookOutput));
|
|
110
|
-
process.exit(0);
|
|
111
|
-
} catch (error) {
|
|
112
|
-
console.error("Validation script error:", error);
|
|
113
|
-
process.exit(2);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
main().catch((error) => {
|
|
118
|
-
console.error("Fatal error:", error);
|
|
119
|
-
process.exit(2);
|
|
120
|
-
});
|