deliberate 1.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.
- package/LICENSE +11 -0
- package/README.md +180 -0
- package/bin/cli.js +113 -0
- package/hooks/__pycache__/deliberate-commands.cpython-312.pyc +0 -0
- package/hooks/deliberate-changes.py +606 -0
- package/hooks/deliberate-commands-post.py +126 -0
- package/hooks/deliberate-commands.py +1742 -0
- package/hooks/hooks.json +29 -0
- package/hooks/setup-check.py +67 -0
- package/hooks/test_skip_commands.py +293 -0
- package/package.json +51 -0
- package/src/classifier/classify_command.py +346 -0
- package/src/classifier/embed_command.py +56 -0
- package/src/classifier/index.js +324 -0
- package/src/classifier/model-classifier.js +531 -0
- package/src/classifier/pattern-matcher.js +230 -0
- package/src/config.js +207 -0
- package/src/index.js +23 -0
- package/src/install.js +754 -0
- package/src/server.js +239 -0
- package/src/uninstall.js +198 -0
- package/training/build_classifier.py +325 -0
- package/training/expanded-command-safety.jsonl +712 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Copyright (c) 2025 TheRadarTech LLC. All Rights Reserved.
|
|
2
|
+
|
|
3
|
+
This software and associated documentation files (the "Software") are the
|
|
4
|
+
exclusive property of TheRadarTech LLC. No part of this Software may be reproduced,
|
|
5
|
+
distributed, modified, or transmitted in any form or by any means without
|
|
6
|
+
the prior written permission of TheRadarTech LLC.
|
|
7
|
+
|
|
8
|
+
Unauthorized copying, modification, distribution, or use of this Software,
|
|
9
|
+
via any medium, is strictly prohibited.
|
|
10
|
+
|
|
11
|
+
For licensing inquiries, contact: missioncontrol@the-radar.net
|
package/README.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Deliberate
|
|
2
|
+
|
|
3
|
+
A safety layer for AI coding agents.
|
|
4
|
+
|
|
5
|
+
## The Problem
|
|
6
|
+
|
|
7
|
+
AI agents have access to your shell. They can run any command. Delete files. Exfiltrate credentials. Open reverse shells. The only guardrail: a yes/no prompt you'll inevitably approve on autopilot.
|
|
8
|
+
|
|
9
|
+
## The Solution
|
|
10
|
+
|
|
11
|
+
Deliberate forces you to be deliberate. Every command gets classified and explained before execution:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
[Bash] rm -rf node_modules
|
|
15
|
+
π¨ [DANGEROUS] Recursively deletes the node_modules directory and all contents.
|
|
16
|
+
> Allow? [y/n]
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The analysis persists after executionβno more vanishing prompts:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
π¨ DELIBERATE [DANGEROUS]
|
|
23
|
+
Recursively deletes the node_modules directory and all contents.
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Three risk levels:
|
|
27
|
+
- β
**SAFE** β Read-only, no system changes
|
|
28
|
+
- β‘ **MODERATE** β Modifies files or services, reversible
|
|
29
|
+
- π¨ **DANGEROUS** β Destructive, credential access, network exfiltration
|
|
30
|
+
|
|
31
|
+
Every command shows its analysis. You decide with context, not blind trust.
|
|
32
|
+
|
|
33
|
+
## How It Works
|
|
34
|
+
|
|
35
|
+
Four layers, each serving a purpose:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
39
|
+
β Layer 1: Pattern Matcher β
|
|
40
|
+
β Regex rules. Deterministic. Can't be bypassed β
|
|
41
|
+
β by prompt injection. β
|
|
42
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
|
|
43
|
+
β Layer 2: ML Classifier β
|
|
44
|
+
β Semantic embeddings via CmdCaliper. Trained on β
|
|
45
|
+
β 712 labeled commands. Catches novel attacks. β
|
|
46
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
|
|
47
|
+
β Layer 3: LLM Explainer β
|
|
48
|
+
β Human-readable explanations. Uses your β
|
|
49
|
+
β configured provider (Claude, Ollama, etc). β
|
|
50
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
|
|
51
|
+
β Layer 4: Catch-All Backup β
|
|
52
|
+
β Automatic backup before ANY destructive command. β
|
|
53
|
+
β Files recoverable even if you approve by mistake. β
|
|
54
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The AI agent can't explain away its own commandsβthe classifier runs independently.
|
|
58
|
+
|
|
59
|
+
## Workflow Detection
|
|
60
|
+
|
|
61
|
+
Individual commands can look safe while the sequence is catastrophic. Deliberate tracks command history within sessions and detects dangerous patterns:
|
|
62
|
+
|
|
63
|
+
| Pattern | What It Detects |
|
|
64
|
+
|---------|-----------------|
|
|
65
|
+
| REPO_WIPE | rm + git rm + force push |
|
|
66
|
+
| MASS_DELETE | 3+ rm commands in sequence |
|
|
67
|
+
| HISTORY_REWRITE | git reset --hard + force push |
|
|
68
|
+
| TEMP_SWAP | copy to temp, delete original, copy back |
|
|
69
|
+
|
|
70
|
+
When a pattern is detected, you see the full contextβnot just the current command.
|
|
71
|
+
|
|
72
|
+
## Consequence Visualization
|
|
73
|
+
|
|
74
|
+
Before destructive commands run, you see exactly what will be affected:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
β οΈ WILL DELETE: 17 files, 2 directories (2,847 lines of code) [156.3 KB]
|
|
78
|
+
Files:
|
|
79
|
+
- src/ai/deliberate-ai.ts
|
|
80
|
+
- src/core/classification/classifier.ts
|
|
81
|
+
- src/cli/commands.ts
|
|
82
|
+
... and 14 more
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Supported commands:
|
|
86
|
+
- `rm` / `git rm` β shows files and line counts
|
|
87
|
+
- `git reset --hard` β shows uncommitted changes that will be discarded
|
|
88
|
+
- `git clean` β shows untracked files that will be deleted
|
|
89
|
+
- `git checkout --` β shows modified files that will revert
|
|
90
|
+
- `git stash drop` β shows stash contents that will be lost
|
|
91
|
+
|
|
92
|
+
## Automatic Backups
|
|
93
|
+
|
|
94
|
+
Every destructive command triggers an automatic backup before execution:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
~/.deliberate/backups/
|
|
98
|
+
βββ my-project/
|
|
99
|
+
βββ 20250114_120000/
|
|
100
|
+
βββ metadata.json # Command, paths, restore info
|
|
101
|
+
βββ files/ # Backed up files (original structure)
|
|
102
|
+
βββ git_state/ # Branch, commit, uncommitted diff
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Files are recoverable even if you approve a destructive command by mistake. The `metadata.json` includes file mappings for exact restore to original locations.
|
|
106
|
+
|
|
107
|
+
## Installation
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npm install -g deliberate
|
|
111
|
+
deliberate install
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The installer walks you through LLM provider setup (Claude, Anthropic API, or Ollama).
|
|
115
|
+
|
|
116
|
+
### Dependencies
|
|
117
|
+
|
|
118
|
+
**Python 3.9+** with ML libraries:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
pip install sentence-transformers scikit-learn numpy
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The CmdCaliper embedding model (~419MB) downloads on first use.
|
|
125
|
+
|
|
126
|
+
## CLI
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
deliberate install # Install hooks, configure LLM
|
|
130
|
+
deliberate status # Check installation
|
|
131
|
+
deliberate classify "rm -rf /" # Test classification β DANGEROUS
|
|
132
|
+
deliberate serve # Start classifier server (faster)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Training
|
|
136
|
+
|
|
137
|
+
The classifier ships with 481 labeled examples: reverse shells, credential theft, cloud operations, container escapes, privilege escalation, and safe workflows.
|
|
138
|
+
|
|
139
|
+
### Add Your Own
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Add to training/expanded-command-safety.jsonl
|
|
143
|
+
{"command": "...", "label": "DANGEROUS", "category": "..."}
|
|
144
|
+
|
|
145
|
+
# Retrain
|
|
146
|
+
python training/build_classifier.py --model base
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Active Learning
|
|
150
|
+
|
|
151
|
+
Uncertain classifications get logged. Review and approve them:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
python training/approve_cases.py # Review pending
|
|
155
|
+
python training/build_classifier.py --model base # Retrain
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Requirements
|
|
159
|
+
|
|
160
|
+
- Node.js 18+
|
|
161
|
+
- Python 3.9+
|
|
162
|
+
- Claude Code (or any tool supporting Claude Code hooks)
|
|
163
|
+
|
|
164
|
+
Works on macOS, Linux, and Windows.
|
|
165
|
+
|
|
166
|
+
## Uninstall
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
deliberate uninstall
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Acknowledgments
|
|
173
|
+
|
|
174
|
+
Command embeddings by [CmdCaliper](https://huggingface.co/CyCraftAI/CmdCaliper-base) from CyCraft AI.
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
Copyright Β© 2025 TheRadarTech LLC. All Rights Reserved.
|
|
179
|
+
|
|
180
|
+
This software is proprietary. See [LICENSE](LICENSE) for details.
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Deliberate CLI
|
|
4
|
+
* Safety layer for agentic coding tools
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
import { install } from '../src/install.js';
|
|
9
|
+
import { startServer } from '../src/server.js';
|
|
10
|
+
import { classify, getStatus } from '../src/classifier/index.js';
|
|
11
|
+
import { existsSync, readFileSync } from 'fs';
|
|
12
|
+
import { join } from 'path';
|
|
13
|
+
import { homedir } from 'os';
|
|
14
|
+
|
|
15
|
+
const program = new Command();
|
|
16
|
+
|
|
17
|
+
program
|
|
18
|
+
.name('deliberate')
|
|
19
|
+
.description('Safety layer for agentic coding tools')
|
|
20
|
+
.version('1.0.0');
|
|
21
|
+
|
|
22
|
+
program
|
|
23
|
+
.command('install')
|
|
24
|
+
.description('Install hooks and configure Claude Code integration')
|
|
25
|
+
.action(async () => {
|
|
26
|
+
await install();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
program
|
|
30
|
+
.command('serve')
|
|
31
|
+
.description('Start the classifier server')
|
|
32
|
+
.option('-p, --port <port>', 'Port to listen on', '8765')
|
|
33
|
+
.action(async (options) => {
|
|
34
|
+
await startServer(parseInt(options.port));
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
program
|
|
38
|
+
.command('classify <input>')
|
|
39
|
+
.description('Classify a command or file change')
|
|
40
|
+
.option('-t, --type <type>', 'Type of input: command, edit, write', 'command')
|
|
41
|
+
.action(async (input, options) => {
|
|
42
|
+
const result = await classify(input, options.type);
|
|
43
|
+
console.log(JSON.stringify(result, null, 2));
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
program
|
|
47
|
+
.command('status')
|
|
48
|
+
.description('Check if hooks are installed and classifier is ready')
|
|
49
|
+
.action(async () => {
|
|
50
|
+
console.log('Deliberate Status\n');
|
|
51
|
+
|
|
52
|
+
// Check hooks installation
|
|
53
|
+
const claudeSettingsPath = join(homedir(), '.claude', 'settings.json');
|
|
54
|
+
let hooksInstalled = false;
|
|
55
|
+
|
|
56
|
+
if (existsSync(claudeSettingsPath)) {
|
|
57
|
+
try {
|
|
58
|
+
const settings = JSON.parse(readFileSync(claudeSettingsPath, 'utf-8'));
|
|
59
|
+
const hooks = settings.hooks || {};
|
|
60
|
+
const preToolUse = hooks.PreToolUse || [];
|
|
61
|
+
const postToolUse = hooks.PostToolUse || [];
|
|
62
|
+
|
|
63
|
+
const hasCommandHook = preToolUse.some(h =>
|
|
64
|
+
h.command && h.command.includes('explain-command')
|
|
65
|
+
);
|
|
66
|
+
const hasChangesHook = postToolUse.some(h =>
|
|
67
|
+
h.command && h.command.includes('explain-changes')
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
if (hasCommandHook && hasChangesHook) {
|
|
71
|
+
console.log('Hooks: β
Installed (PreToolUse + PostToolUse)');
|
|
72
|
+
hooksInstalled = true;
|
|
73
|
+
} else if (hasCommandHook) {
|
|
74
|
+
console.log('Hooks: β οΈ Partial (PreToolUse only)');
|
|
75
|
+
hooksInstalled = true;
|
|
76
|
+
} else if (hasChangesHook) {
|
|
77
|
+
console.log('Hooks: β οΈ Partial (PostToolUse only)');
|
|
78
|
+
hooksInstalled = true;
|
|
79
|
+
} else {
|
|
80
|
+
console.log('Hooks: β Not installed');
|
|
81
|
+
}
|
|
82
|
+
} catch (e) {
|
|
83
|
+
console.log('Hooks: β Error reading settings');
|
|
84
|
+
}
|
|
85
|
+
} else {
|
|
86
|
+
console.log('Hooks: β Claude settings not found');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Check classifier status
|
|
90
|
+
const classifierStatus = getStatus();
|
|
91
|
+
|
|
92
|
+
if (classifierStatus.patternMatcher?.ready) {
|
|
93
|
+
console.log('Patterns: β
Ready');
|
|
94
|
+
} else {
|
|
95
|
+
console.log('Patterns: β Not loaded');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (classifierStatus.modelClassifier?.ready) {
|
|
99
|
+
console.log('Classifier: β
Ready');
|
|
100
|
+
} else {
|
|
101
|
+
console.log('Classifier: β οΈ Will load on first use');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Overall status
|
|
105
|
+
console.log('');
|
|
106
|
+
if (hooksInstalled) {
|
|
107
|
+
console.log('Status: Ready to protect your Claude Code sessions');
|
|
108
|
+
} else {
|
|
109
|
+
console.log('Status: Run "deliberate install" to set up hooks');
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
program.parse();
|
|
Binary file
|