@brainfile/cli 0.3.0 → 0.4.0
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/settings.json +7 -0
- package/CHANGELOG.md +19 -0
- package/README.md +114 -1
- package/dist/cli.js +31 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/hooks.d.ts +34 -0
- package/dist/commands/hooks.d.ts.map +1 -0
- package/dist/commands/hooks.js +295 -0
- package/dist/commands/hooks.js.map +1 -0
- package/dist/utils/brainfile-finder.d.ts +12 -0
- package/dist/utils/brainfile-finder.d.ts.map +1 -0
- package/dist/utils/brainfile-finder.js +74 -0
- package/dist/utils/brainfile-finder.js.map +1 -0
- package/dist/utils/git-helper.d.ts +13 -0
- package/dist/utils/git-helper.d.ts.map +1 -0
- package/dist/utils/git-helper.js +59 -0
- package/dist/utils/git-helper.js.map +1 -0
- package/dist/utils/hook-parser.d.ts +15 -0
- package/dist/utils/hook-parser.d.ts.map +1 -0
- package/dist/utils/hook-parser.js +48 -0
- package/dist/utils/hook-parser.js.map +1 -0
- package/dist/utils/hook-settings.d.ts +27 -0
- package/dist/utils/hook-settings.d.ts.map +1 -0
- package/dist/utils/hook-settings.js +239 -0
- package/dist/utils/hook-settings.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -19,6 +19,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
19
19
|
|
|
20
20
|
### Security
|
|
21
21
|
|
|
22
|
+
## [0.4.0] - 2025-11-21
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
- **AI Agent Hooks Integration** - Native support for AI coding assistant hooks
|
|
26
|
+
- `brainfile hooks install <tool>` - Install hooks for Claude Code or Cursor
|
|
27
|
+
- `brainfile hooks uninstall <tool>` - Remove hooks with `--scope` option (user/project/all)
|
|
28
|
+
- `brainfile hooks list [tool]` - View installed hooks status
|
|
29
|
+
- `brainfile hooks after-edit` - Internal hook handler for post-edit events
|
|
30
|
+
- `brainfile hooks before-prompt` - Internal hook handler for pre-prompt events with staleness detection
|
|
31
|
+
- `brainfile hooks session-start` - Internal hook handler for session start
|
|
32
|
+
- Generic hook handlers work with multiple AI assistants (Claude Code and Cursor)
|
|
33
|
+
- Automatic task status reminders during AI-assisted development
|
|
34
|
+
- Smart staleness detection (warns if brainfile >5 minutes old with uncommitted changes)
|
|
35
|
+
- Git integration to detect uncommitted changes
|
|
36
|
+
- Gentle reminders (80%) + smart checkpoints (20%) approach
|
|
37
|
+
- Non-blocking hooks that fail gracefully
|
|
38
|
+
- Preserves existing hooks in settings files
|
|
39
|
+
- Works with both user and project scope installations
|
|
40
|
+
|
|
22
41
|
## [0.3.0] - 2025-11-20
|
|
23
42
|
|
|
24
43
|
### Added
|
package/README.md
CHANGED
|
@@ -251,6 +251,118 @@ brainfile template --use refactor \
|
|
|
251
251
|
--column in-progress
|
|
252
252
|
```
|
|
253
253
|
|
|
254
|
+
### AI Agent Hooks
|
|
255
|
+
|
|
256
|
+
Integrate Brainfile with AI coding assistants (Claude Code, Cursor) to get automatic reminders to update task status during development:
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
# Install hooks for Claude Code (user scope)
|
|
260
|
+
brainfile hooks install claude-code
|
|
261
|
+
|
|
262
|
+
# Install hooks for Cursor (project scope)
|
|
263
|
+
brainfile hooks install cursor --scope project
|
|
264
|
+
|
|
265
|
+
# List installed hooks
|
|
266
|
+
brainfile hooks list
|
|
267
|
+
|
|
268
|
+
# Uninstall hooks
|
|
269
|
+
brainfile hooks uninstall claude-code --scope all
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Supported AI Assistants:**
|
|
273
|
+
- **Claude Code** - Anthropic's official CLI
|
|
274
|
+
- **Cursor** - AI-powered code editor
|
|
275
|
+
|
|
276
|
+
**How it Works:**
|
|
277
|
+
|
|
278
|
+
The hooks integration provides intelligent reminders during your AI-assisted development workflow:
|
|
279
|
+
|
|
280
|
+
1. **Gentle Reminders (80% of interactions)**
|
|
281
|
+
- After editing files: "💡 Consider updating @brainfile.md"
|
|
282
|
+
- Non-blocking, shown once per edit
|
|
283
|
+
|
|
284
|
+
2. **Smart Checkpoints (20% of interactions)**
|
|
285
|
+
- Before new prompts: Checks if brainfile is stale (>5 minutes old)
|
|
286
|
+
- Only warns if you have uncommitted changes (excluding brainfile itself)
|
|
287
|
+
- Message: "⚠️ Files modified but @brainfile.md hasn't been updated."
|
|
288
|
+
|
|
289
|
+
3. **Session Start**
|
|
290
|
+
- Detects brainfile in project: "✅ Brainfile detected: @brainfile.md"
|
|
291
|
+
- Reminds you to track progress: "Remember to update task status as you work."
|
|
292
|
+
|
|
293
|
+
**Installation Options:**
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
# User scope (applies to all projects)
|
|
297
|
+
brainfile hooks install claude-code --scope user
|
|
298
|
+
|
|
299
|
+
# Project scope (applies to current project only)
|
|
300
|
+
brainfile hooks install cursor --scope project
|
|
301
|
+
|
|
302
|
+
# Install for both tools
|
|
303
|
+
brainfile hooks install claude-code
|
|
304
|
+
brainfile hooks install cursor
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
**Settings Locations:**
|
|
308
|
+
|
|
309
|
+
Claude Code:
|
|
310
|
+
- User: `~/.claude/settings.json`
|
|
311
|
+
- Project: `.claude/settings.json`
|
|
312
|
+
|
|
313
|
+
Cursor:
|
|
314
|
+
- User: `~/.cursor/hooks.json`
|
|
315
|
+
- Project: `.cursor/hooks.json`
|
|
316
|
+
|
|
317
|
+
**Hook Events:**
|
|
318
|
+
|
|
319
|
+
| Event | Trigger | Behavior |
|
|
320
|
+
|-------|---------|----------|
|
|
321
|
+
| PostToolUse / afterFileEdit | After editing files | Gentle reminder to update brainfile |
|
|
322
|
+
| UserPromptSubmit / beforeSubmitPrompt | Before processing new prompts | Smart staleness check |
|
|
323
|
+
| SessionStart / stop | When session starts/ends | Welcome message if brainfile detected |
|
|
324
|
+
|
|
325
|
+
**Managing Hooks:**
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
# List hooks for specific tool
|
|
329
|
+
brainfile hooks list claude-code
|
|
330
|
+
|
|
331
|
+
# List all hooks
|
|
332
|
+
brainfile hooks list
|
|
333
|
+
|
|
334
|
+
# Uninstall from user scope
|
|
335
|
+
brainfile hooks uninstall claude-code --scope user
|
|
336
|
+
|
|
337
|
+
# Uninstall from all scopes
|
|
338
|
+
brainfile hooks uninstall cursor --scope all
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
**Benefits:**
|
|
342
|
+
|
|
343
|
+
- Never forget to update task status during long coding sessions
|
|
344
|
+
- Automatic detection of stale brainfiles
|
|
345
|
+
- Git-aware (only warns about uncommitted changes)
|
|
346
|
+
- Non-intrusive design (fails silently if brainfile doesn't exist)
|
|
347
|
+
- Works alongside other hooks (preserves existing configuration)
|
|
348
|
+
- Compatible with multiple AI tools
|
|
349
|
+
|
|
350
|
+
**Example Workflow:**
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
# 1. Install hooks
|
|
354
|
+
brainfile hooks install claude-code
|
|
355
|
+
|
|
356
|
+
# 2. Start coding with Claude Code
|
|
357
|
+
# - Edit a file → "💡 Consider updating @brainfile.md"
|
|
358
|
+
# - Update brainfile → Edit another file → Continue working
|
|
359
|
+
# - 6+ minutes pass → New prompt → "⚠️ Files modified but @brainfile.md hasn't been updated"
|
|
360
|
+
# - Update brainfile → Continue working smoothly
|
|
361
|
+
|
|
362
|
+
# 3. Check installation
|
|
363
|
+
brainfile hooks list
|
|
364
|
+
```
|
|
365
|
+
|
|
254
366
|
## Features
|
|
255
367
|
|
|
256
368
|
### Colored Output
|
|
@@ -277,13 +389,14 @@ Task IDs are automatically generated with a timestamp and random string to ensur
|
|
|
277
389
|
- `brainfile move` - Move tasks between columns
|
|
278
390
|
- `brainfile template` - Template management
|
|
279
391
|
- `brainfile lint` - Validate and auto-fix syntax
|
|
392
|
+
- `brainfile hooks` - AI agent hooks integration (Claude Code, Cursor)
|
|
280
393
|
- Colored output and pretty-printing
|
|
281
394
|
- Binary compilation for distribution
|
|
282
395
|
|
|
283
396
|
### Future Enhancements
|
|
284
397
|
- `brainfile update` - Update existing tasks
|
|
285
398
|
- `brainfile delete` - Remove tasks
|
|
286
|
-
- Interactive mode for task creation
|
|
399
|
+
- Interactive mode for task creation (see `task-5` in brainfile.md)
|
|
287
400
|
- Advanced filtering and search
|
|
288
401
|
- Task completion tracking
|
|
289
402
|
- Subtask management
|
package/dist/cli.js
CHANGED
|
@@ -10,6 +10,7 @@ const move_1 = require("./commands/move");
|
|
|
10
10
|
const template_1 = require("./commands/template");
|
|
11
11
|
const lint_1 = require("./commands/lint");
|
|
12
12
|
const init_1 = require("./commands/init");
|
|
13
|
+
const hooks_1 = require("./commands/hooks");
|
|
13
14
|
// Read version from package.json
|
|
14
15
|
const packageJson = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, '..', 'package.json'), 'utf8'));
|
|
15
16
|
const program = new commander_1.Command();
|
|
@@ -65,5 +66,35 @@ program
|
|
|
65
66
|
.option('--fix', 'Automatically fix issues when possible')
|
|
66
67
|
.option('--check', 'Exit with error code if issues found (for CI/CD)')
|
|
67
68
|
.action(lint_1.lintCommand);
|
|
69
|
+
// Add hooks command group
|
|
70
|
+
const hooksCommand = program
|
|
71
|
+
.command('hooks')
|
|
72
|
+
.description('Manage AI agent hooks integration');
|
|
73
|
+
hooksCommand
|
|
74
|
+
.command('after-edit')
|
|
75
|
+
.description('Handle post-edit hook event (internal use by AI assistants)')
|
|
76
|
+
.action(hooks_1.afterEditCommand);
|
|
77
|
+
hooksCommand
|
|
78
|
+
.command('before-prompt')
|
|
79
|
+
.description('Handle pre-prompt hook event (internal use by AI assistants)')
|
|
80
|
+
.action(hooks_1.beforePromptCommand);
|
|
81
|
+
hooksCommand
|
|
82
|
+
.command('session-start')
|
|
83
|
+
.description('Handle session-start hook event (internal use by AI assistants)')
|
|
84
|
+
.action(hooks_1.sessionStartCommand);
|
|
85
|
+
hooksCommand
|
|
86
|
+
.command('install <tool>')
|
|
87
|
+
.description('Install brainfile hooks for an AI coding assistant')
|
|
88
|
+
.option('--scope <scope>', 'Installation scope: user or project', 'user')
|
|
89
|
+
.action((tool, options) => (0, hooks_1.installCommand)({ tool, scope: options.scope }));
|
|
90
|
+
hooksCommand
|
|
91
|
+
.command('uninstall <tool>')
|
|
92
|
+
.description('Uninstall brainfile hooks for an AI coding assistant')
|
|
93
|
+
.option('--scope <scope>', 'Scope to uninstall from: user, project, or all', 'user')
|
|
94
|
+
.action((tool, options) => (0, hooks_1.uninstallCommand)({ tool, scope: options.scope }));
|
|
95
|
+
hooksCommand
|
|
96
|
+
.command('list [tool]')
|
|
97
|
+
.description('List installed brainfile hooks')
|
|
98
|
+
.action((tool) => (0, hooks_1.listCommand)({ tool }));
|
|
68
99
|
program.parse();
|
|
69
100
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,2BAAkC;AAClC,+BAA4B;AAC5B,0CAA8C;AAC9C,wCAA4C;AAC5C,0CAA8C;AAC9C,kDAAsD;AACtD,0CAA8C;AAC9C,0CAA8C;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { SettingsScope } from '../utils/hook-settings';
|
|
2
|
+
/**
|
|
3
|
+
* Handle after-edit hook event
|
|
4
|
+
*/
|
|
5
|
+
export declare function afterEditCommand(): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Handle before-prompt hook event
|
|
8
|
+
*/
|
|
9
|
+
export declare function beforePromptCommand(): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Handle session-start hook event
|
|
12
|
+
*/
|
|
13
|
+
export declare function sessionStartCommand(): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Install hooks for a specific tool
|
|
16
|
+
*/
|
|
17
|
+
export declare function installCommand(options: {
|
|
18
|
+
tool: string;
|
|
19
|
+
scope: SettingsScope;
|
|
20
|
+
}): void;
|
|
21
|
+
/**
|
|
22
|
+
* Uninstall hooks for a specific tool
|
|
23
|
+
*/
|
|
24
|
+
export declare function uninstallCommand(options: {
|
|
25
|
+
tool: string;
|
|
26
|
+
scope: SettingsScope | 'all';
|
|
27
|
+
}): void;
|
|
28
|
+
/**
|
|
29
|
+
* List installed hooks
|
|
30
|
+
*/
|
|
31
|
+
export declare function listCommand(options: {
|
|
32
|
+
tool?: string;
|
|
33
|
+
}): void;
|
|
34
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/commands/hooks.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,aAAa,EAKd,MAAM,wBAAwB,CAAC;AA+BhC;;GAEG;AACH,wBAAsB,gBAAgB,kBAgCrC;AAED;;GAEG;AACH,wBAAsB,mBAAmB,kBA8CxC;AAED;;GAEG;AACH,wBAAsB,mBAAmB,kBAqBxC;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE,QA2C7E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,aAAa,GAAG,KAAK,CAAA;CAAE,QAoCvF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,QA6CrD"}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.afterEditCommand = afterEditCommand;
|
|
40
|
+
exports.beforePromptCommand = beforePromptCommand;
|
|
41
|
+
exports.sessionStartCommand = sessionStartCommand;
|
|
42
|
+
exports.installCommand = installCommand;
|
|
43
|
+
exports.uninstallCommand = uninstallCommand;
|
|
44
|
+
exports.listCommand = listCommand;
|
|
45
|
+
const readline = __importStar(require("readline"));
|
|
46
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
47
|
+
const hook_settings_1 = require("../utils/hook-settings");
|
|
48
|
+
const brainfile_finder_1 = require("../utils/brainfile-finder");
|
|
49
|
+
const git_helper_1 = require("../utils/git-helper");
|
|
50
|
+
const hook_parser_1 = require("../utils/hook-parser");
|
|
51
|
+
/**
|
|
52
|
+
* Read JSON from stdin
|
|
53
|
+
*/
|
|
54
|
+
async function readStdin() {
|
|
55
|
+
return new Promise((resolve) => {
|
|
56
|
+
let data = '';
|
|
57
|
+
const rl = readline.createInterface({
|
|
58
|
+
input: process.stdin,
|
|
59
|
+
output: process.stdout,
|
|
60
|
+
terminal: false
|
|
61
|
+
});
|
|
62
|
+
rl.on('line', (line) => {
|
|
63
|
+
data += line;
|
|
64
|
+
});
|
|
65
|
+
rl.on('close', () => {
|
|
66
|
+
try {
|
|
67
|
+
resolve(JSON.parse(data));
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
resolve({});
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Handle after-edit hook event
|
|
77
|
+
*/
|
|
78
|
+
async function afterEditCommand() {
|
|
79
|
+
try {
|
|
80
|
+
const input = await readStdin();
|
|
81
|
+
const parsed = (0, hook_parser_1.parseHookInput)(input);
|
|
82
|
+
// Skip if no file path
|
|
83
|
+
if (!parsed.filePath) {
|
|
84
|
+
process.exit(0);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
// Skip if editing brainfile itself
|
|
88
|
+
if (parsed.filePath.includes('brainfile.md')) {
|
|
89
|
+
process.exit(0);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
// Check if brainfile exists
|
|
93
|
+
const brainfilePath = (0, brainfile_finder_1.findBrainfile)();
|
|
94
|
+
if (!brainfilePath) {
|
|
95
|
+
process.exit(0);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
// Output reminder
|
|
99
|
+
console.log('💡 Consider updating @brainfile.md');
|
|
100
|
+
process.exit(0);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
// Fail silently
|
|
104
|
+
process.exit(0);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Handle before-prompt hook event
|
|
109
|
+
*/
|
|
110
|
+
async function beforePromptCommand() {
|
|
111
|
+
try {
|
|
112
|
+
const input = await readStdin();
|
|
113
|
+
const outputJSON = (0, hook_parser_1.shouldOutputJSON)(input);
|
|
114
|
+
// Find brainfile
|
|
115
|
+
const brainfilePath = (0, brainfile_finder_1.findBrainfile)();
|
|
116
|
+
if (!brainfilePath) {
|
|
117
|
+
if (outputJSON) {
|
|
118
|
+
console.log(JSON.stringify({ continue: true }));
|
|
119
|
+
}
|
|
120
|
+
process.exit(0);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
// Check if brainfile is stale (>5 minutes old)
|
|
124
|
+
const ageMinutes = (0, brainfile_finder_1.getFileAgeMinutes)(brainfilePath);
|
|
125
|
+
if (ageMinutes < 5) {
|
|
126
|
+
if (outputJSON) {
|
|
127
|
+
console.log(JSON.stringify({ continue: true }));
|
|
128
|
+
}
|
|
129
|
+
process.exit(0);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
// Check for uncommitted changes (excluding brainfile)
|
|
133
|
+
const hasChanges = await (0, git_helper_1.hasUncommittedChanges)(['brainfile.md', '.brainfile.md']);
|
|
134
|
+
if (hasChanges) {
|
|
135
|
+
console.log('\n⚠️ Files modified but @brainfile.md hasn\'t been updated.');
|
|
136
|
+
console.log('Update task status before continuing.\n');
|
|
137
|
+
}
|
|
138
|
+
if (outputJSON) {
|
|
139
|
+
console.log(JSON.stringify({ continue: true }));
|
|
140
|
+
}
|
|
141
|
+
process.exit(0);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
// Fail silently with proper JSON response for Cursor
|
|
145
|
+
const input = await readStdin();
|
|
146
|
+
if ((0, hook_parser_1.shouldOutputJSON)(input)) {
|
|
147
|
+
console.log(JSON.stringify({ continue: true }));
|
|
148
|
+
}
|
|
149
|
+
process.exit(0);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Handle session-start hook event
|
|
154
|
+
*/
|
|
155
|
+
async function sessionStartCommand() {
|
|
156
|
+
try {
|
|
157
|
+
await readStdin(); // Read input even though we don't use it
|
|
158
|
+
// Find brainfile
|
|
159
|
+
const brainfilePath = (0, brainfile_finder_1.findBrainfile)();
|
|
160
|
+
if (!brainfilePath) {
|
|
161
|
+
process.exit(0);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
// Output welcome message
|
|
165
|
+
const fileName = brainfilePath.split('/').pop();
|
|
166
|
+
console.log(`✅ Brainfile detected: @${fileName}`);
|
|
167
|
+
console.log('Remember to update task status as you work.');
|
|
168
|
+
process.exit(0);
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
// Fail silently
|
|
172
|
+
process.exit(0);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Install hooks for a specific tool
|
|
177
|
+
*/
|
|
178
|
+
function installCommand(options) {
|
|
179
|
+
try {
|
|
180
|
+
const tool = options.tool;
|
|
181
|
+
// Validate tool
|
|
182
|
+
if (tool !== 'claude-code' && tool !== 'cursor') {
|
|
183
|
+
console.error(chalk_1.default.red(`Error: Unknown tool '${options.tool}'`));
|
|
184
|
+
console.log(chalk_1.default.gray('Supported tools: claude-code, cursor'));
|
|
185
|
+
process.exit(1);
|
|
186
|
+
}
|
|
187
|
+
// Install hooks
|
|
188
|
+
(0, hook_settings_1.installBrainfileHooks)(tool, options.scope);
|
|
189
|
+
const settingsPath = (0, hook_settings_1.getSettingsPath)(tool, options.scope);
|
|
190
|
+
const toolName = tool === 'claude-code' ? 'Claude Code' : 'Cursor';
|
|
191
|
+
console.log(chalk_1.default.green(`✅ Brainfile hooks installed for ${toolName}!`));
|
|
192
|
+
console.log(chalk_1.default.gray(` Settings: ${settingsPath}`));
|
|
193
|
+
console.log(chalk_1.default.gray(` Scope: ${options.scope}`));
|
|
194
|
+
console.log('');
|
|
195
|
+
console.log(chalk_1.default.white('Hooks configured:'));
|
|
196
|
+
if (tool === 'claude-code') {
|
|
197
|
+
console.log(chalk_1.default.gray(' • PostToolUse → brainfile hooks after-edit'));
|
|
198
|
+
console.log(chalk_1.default.gray(' • UserPromptSubmit → brainfile hooks before-prompt'));
|
|
199
|
+
console.log(chalk_1.default.gray(' • SessionStart → brainfile hooks session-start'));
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
console.log(chalk_1.default.gray(' • afterFileEdit → brainfile hooks after-edit'));
|
|
203
|
+
console.log(chalk_1.default.gray(' • beforeSubmitPrompt → brainfile hooks before-prompt'));
|
|
204
|
+
console.log(chalk_1.default.gray(' • stop → brainfile hooks session-start'));
|
|
205
|
+
}
|
|
206
|
+
console.log('');
|
|
207
|
+
console.log(chalk_1.default.gray('Next steps:'));
|
|
208
|
+
console.log(chalk_1.default.gray(` 1. Restart ${toolName} to activate hooks`));
|
|
209
|
+
console.log(chalk_1.default.gray(' 2. Edit files and watch for brainfile reminders'));
|
|
210
|
+
console.log(chalk_1.default.gray(' 3. Run \'brainfile hooks list\' to verify installation'));
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
console.error(chalk_1.default.red('Error:'), error instanceof Error ? error.message : String(error));
|
|
214
|
+
process.exit(1);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Uninstall hooks for a specific tool
|
|
219
|
+
*/
|
|
220
|
+
function uninstallCommand(options) {
|
|
221
|
+
try {
|
|
222
|
+
const tool = options.tool;
|
|
223
|
+
// Validate tool
|
|
224
|
+
if (tool !== 'claude-code' && tool !== 'cursor') {
|
|
225
|
+
console.error(chalk_1.default.red(`Error: Unknown tool '${options.tool}'`));
|
|
226
|
+
console.log(chalk_1.default.gray('Supported tools: claude-code, cursor'));
|
|
227
|
+
process.exit(1);
|
|
228
|
+
}
|
|
229
|
+
const scopes = options.scope === 'all'
|
|
230
|
+
? ['user', 'project']
|
|
231
|
+
: [options.scope];
|
|
232
|
+
let removed = false;
|
|
233
|
+
for (const scope of scopes) {
|
|
234
|
+
if ((0, hook_settings_1.areBrainfileHooksInstalled)(tool, scope)) {
|
|
235
|
+
(0, hook_settings_1.uninstallBrainfileHooks)(tool, scope);
|
|
236
|
+
removed = true;
|
|
237
|
+
const settingsPath = (0, hook_settings_1.getSettingsPath)(tool, scope);
|
|
238
|
+
console.log(chalk_1.default.green(`✓ Removed brainfile hooks from ${scope} settings`));
|
|
239
|
+
console.log(chalk_1.default.gray(` ${settingsPath}`));
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (!removed) {
|
|
243
|
+
console.log(chalk_1.default.yellow('No brainfile hooks found to remove'));
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
console.error(chalk_1.default.red('Error:'), error instanceof Error ? error.message : String(error));
|
|
248
|
+
process.exit(1);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* List installed hooks
|
|
253
|
+
*/
|
|
254
|
+
function listCommand(options) {
|
|
255
|
+
try {
|
|
256
|
+
const tools = options.tool
|
|
257
|
+
? [options.tool]
|
|
258
|
+
: ['claude-code', 'cursor'];
|
|
259
|
+
console.log(chalk_1.default.bold.white('\nBrainfile Hooks Status\n'));
|
|
260
|
+
for (const tool of tools) {
|
|
261
|
+
const toolName = tool === 'claude-code' ? 'Claude Code' : 'Cursor';
|
|
262
|
+
console.log(chalk_1.default.cyan(toolName + ':'));
|
|
263
|
+
// Check user scope
|
|
264
|
+
const userInstalled = (0, hook_settings_1.areBrainfileHooksInstalled)(tool, 'user');
|
|
265
|
+
const userPath = (0, hook_settings_1.getSettingsPath)(tool, 'user');
|
|
266
|
+
console.log(chalk_1.default.white(` User scope (${userPath}):`));
|
|
267
|
+
if (userInstalled) {
|
|
268
|
+
console.log(chalk_1.default.green(' ✓ PostToolUse/afterFileEdit → brainfile hooks after-edit'));
|
|
269
|
+
console.log(chalk_1.default.green(' ✓ UserPromptSubmit/beforeSubmitPrompt → brainfile hooks before-prompt'));
|
|
270
|
+
console.log(chalk_1.default.green(' ✓ SessionStart/stop → brainfile hooks session-start'));
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
console.log(chalk_1.default.gray(' ✗ Not installed'));
|
|
274
|
+
}
|
|
275
|
+
// Check project scope
|
|
276
|
+
const projectInstalled = (0, hook_settings_1.areBrainfileHooksInstalled)(tool, 'project');
|
|
277
|
+
const projectPath = (0, hook_settings_1.getSettingsPath)(tool, 'project');
|
|
278
|
+
console.log(chalk_1.default.white(` Project scope (${projectPath}):`));
|
|
279
|
+
if (projectInstalled) {
|
|
280
|
+
console.log(chalk_1.default.green(' ✓ PostToolUse/afterFileEdit → brainfile hooks after-edit'));
|
|
281
|
+
console.log(chalk_1.default.green(' ✓ UserPromptSubmit/beforeSubmitPrompt → brainfile hooks before-prompt'));
|
|
282
|
+
console.log(chalk_1.default.green(' ✓ SessionStart/stop → brainfile hooks session-start'));
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
console.log(chalk_1.default.gray(' ✗ Not installed'));
|
|
286
|
+
}
|
|
287
|
+
console.log('');
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
console.error(chalk_1.default.red('Error:'), error instanceof Error ? error.message : String(error));
|
|
292
|
+
process.exit(1);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/commands/hooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Find brainfile.md or .brainfile.md in the current directory
|
|
3
|
+
* @returns Absolute path to brainfile, or null if not found
|
|
4
|
+
*/
|
|
5
|
+
export declare function findBrainfile(): string | null;
|
|
6
|
+
/**
|
|
7
|
+
* Get the age of a file in minutes
|
|
8
|
+
* @param filePath Absolute path to file
|
|
9
|
+
* @returns Age in minutes, or Infinity if file doesn't exist
|
|
10
|
+
*/
|
|
11
|
+
export declare function getFileAgeMinutes(filePath: string): number;
|
|
12
|
+
//# sourceMappingURL=brainfile-finder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brainfile-finder.d.ts","sourceRoot":"","sources":["../../src/utils/brainfile-finder.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAa7C;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAY1D"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.findBrainfile = findBrainfile;
|
|
37
|
+
exports.getFileAgeMinutes = getFileAgeMinutes;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
/**
|
|
41
|
+
* Find brainfile.md or .brainfile.md in the current directory
|
|
42
|
+
* @returns Absolute path to brainfile, or null if not found
|
|
43
|
+
*/
|
|
44
|
+
function findBrainfile() {
|
|
45
|
+
const cwd = process.cwd();
|
|
46
|
+
const possibleNames = ['brainfile.md', '.brainfile.md'];
|
|
47
|
+
for (const name of possibleNames) {
|
|
48
|
+
const filePath = path.join(cwd, name);
|
|
49
|
+
if (fs.existsSync(filePath)) {
|
|
50
|
+
return filePath;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Get the age of a file in minutes
|
|
57
|
+
* @param filePath Absolute path to file
|
|
58
|
+
* @returns Age in minutes, or Infinity if file doesn't exist
|
|
59
|
+
*/
|
|
60
|
+
function getFileAgeMinutes(filePath) {
|
|
61
|
+
try {
|
|
62
|
+
const stats = fs.statSync(filePath);
|
|
63
|
+
const now = Date.now();
|
|
64
|
+
const modifiedTime = stats.mtimeMs;
|
|
65
|
+
const ageMs = now - modifiedTime;
|
|
66
|
+
const ageMinutes = ageMs / 1000 / 60; // Convert to minutes
|
|
67
|
+
// Handle edge case where mtime might be slightly in the future due to timing
|
|
68
|
+
return Math.max(0, ageMinutes);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return Infinity;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=brainfile-finder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brainfile-finder.js","sourceRoot":"","sources":["../../src/utils/brainfile-finder.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,sCAaC;AAOD,8CAYC;AAvCD,uCAAyB;AACzB,2CAA6B;AAE7B;;;GAGG;AACH,SAAgB,aAAa;IAC3B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1B,MAAM,aAAa,GAAG,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;IAExD,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACtC,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,SAAgB,iBAAiB,CAAC,QAAgB;IAChD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC;QACnC,MAAM,KAAK,GAAG,GAAG,GAAG,YAAY,CAAC;QACjC,MAAM,UAAU,GAAG,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,qBAAqB;QAC3D,6EAA6E;QAC7E,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if current directory is a git repository
|
|
3
|
+
*/
|
|
4
|
+
export declare function isGitRepo(): Promise<boolean>;
|
|
5
|
+
/**
|
|
6
|
+
* Check if there are uncommitted changes (excluding specified files)
|
|
7
|
+
*/
|
|
8
|
+
export declare function hasUncommittedChanges(excludePatterns?: string[]): Promise<boolean>;
|
|
9
|
+
/**
|
|
10
|
+
* Get list of modified files (both staged and unstaged)
|
|
11
|
+
*/
|
|
12
|
+
export declare function getModifiedFiles(): Promise<string[]>;
|
|
13
|
+
//# sourceMappingURL=git-helper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-helper.d.ts","sourceRoot":"","sources":["../../src/utils/git-helper.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAOlD;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,eAAe,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAiB5F;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAc1D"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isGitRepo = isGitRepo;
|
|
4
|
+
exports.hasUncommittedChanges = hasUncommittedChanges;
|
|
5
|
+
exports.getModifiedFiles = getModifiedFiles;
|
|
6
|
+
const child_process_1 = require("child_process");
|
|
7
|
+
const util_1 = require("util");
|
|
8
|
+
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
9
|
+
/**
|
|
10
|
+
* Check if current directory is a git repository
|
|
11
|
+
*/
|
|
12
|
+
async function isGitRepo() {
|
|
13
|
+
try {
|
|
14
|
+
await execAsync('git rev-parse --git-dir');
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Check if there are uncommitted changes (excluding specified files)
|
|
23
|
+
*/
|
|
24
|
+
async function hasUncommittedChanges(excludePatterns = []) {
|
|
25
|
+
try {
|
|
26
|
+
const isRepo = await isGitRepo();
|
|
27
|
+
if (!isRepo)
|
|
28
|
+
return false;
|
|
29
|
+
// Build exclude arguments for git
|
|
30
|
+
const excludeArgs = excludePatterns
|
|
31
|
+
.map(pattern => `:(exclude)${pattern}`)
|
|
32
|
+
.join(' ');
|
|
33
|
+
const cmd = `git diff --name-only -- . ${excludeArgs}`.trim();
|
|
34
|
+
const { stdout } = await execAsync(cmd);
|
|
35
|
+
return stdout.trim().length > 0;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get list of modified files (both staged and unstaged)
|
|
43
|
+
*/
|
|
44
|
+
async function getModifiedFiles() {
|
|
45
|
+
try {
|
|
46
|
+
const isRepo = await isGitRepo();
|
|
47
|
+
if (!isRepo)
|
|
48
|
+
return [];
|
|
49
|
+
const { stdout } = await execAsync('git status --porcelain');
|
|
50
|
+
return stdout
|
|
51
|
+
.split('\n')
|
|
52
|
+
.filter(line => line.trim().length > 0)
|
|
53
|
+
.map(line => line.substring(3).trim());
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=git-helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-helper.js","sourceRoot":"","sources":["../../src/utils/git-helper.ts"],"names":[],"mappings":";;AAQA,8BAOC;AAKD,sDAiBC;AAKD,4CAcC;AAxDD,iDAAqC;AACrC,+BAAiC;AAEjC,MAAM,SAAS,GAAG,IAAA,gBAAS,EAAC,oBAAI,CAAC,CAAC;AAElC;;GAEG;AACI,KAAK,UAAU,SAAS;IAC7B,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,yBAAyB,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,qBAAqB,CAAC,kBAA4B,EAAE;IACxE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAE1B,kCAAkC;QAClC,MAAM,WAAW,GAAG,eAAe;aAChC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,aAAa,OAAO,EAAE,CAAC;aACtC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEb,MAAM,GAAG,GAAG,6BAA6B,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;QAC9D,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;QAExC,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,CAAC;QAEvB,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,wBAAwB,CAAC,CAAC;QAE7D,OAAO,MAAM;aACV,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;aACtC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse hook input JSON and extract relevant information
|
|
3
|
+
* Handles different input formats from different tools
|
|
4
|
+
*/
|
|
5
|
+
export declare function parseHookInput(input: any): {
|
|
6
|
+
filePath?: string;
|
|
7
|
+
command?: string;
|
|
8
|
+
prompt?: string;
|
|
9
|
+
tool?: 'claude-code' | 'cursor' | 'unknown';
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Determine if we should output JSON for Cursor's beforeSubmitPrompt
|
|
13
|
+
*/
|
|
14
|
+
export declare function shouldOutputJSON(input: any): boolean;
|
|
15
|
+
//# sourceMappingURL=hook-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook-parser.d.ts","sourceRoot":"","sources":["../../src/utils/hook-parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,GAAG,GAAG;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,aAAa,GAAG,QAAQ,GAAG,SAAS,CAAC;CAC7C,CAoCA;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAEpD"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseHookInput = parseHookInput;
|
|
4
|
+
exports.shouldOutputJSON = shouldOutputJSON;
|
|
5
|
+
/**
|
|
6
|
+
* Parse hook input JSON and extract relevant information
|
|
7
|
+
* Handles different input formats from different tools
|
|
8
|
+
*/
|
|
9
|
+
function parseHookInput(input) {
|
|
10
|
+
// Handle null or undefined input
|
|
11
|
+
if (!input) {
|
|
12
|
+
return {
|
|
13
|
+
tool: 'unknown'
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
// Claude Code format
|
|
17
|
+
if (input.tool_input) {
|
|
18
|
+
return {
|
|
19
|
+
filePath: input.tool_input.file_path,
|
|
20
|
+
command: input.tool_input.command,
|
|
21
|
+
tool: 'claude-code'
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
// Cursor format
|
|
25
|
+
if (input.file_path) {
|
|
26
|
+
return {
|
|
27
|
+
filePath: input.file_path,
|
|
28
|
+
tool: 'cursor'
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
// Prompt-related hooks
|
|
32
|
+
if (input.prompt) {
|
|
33
|
+
return {
|
|
34
|
+
prompt: input.prompt,
|
|
35
|
+
tool: input.hook_event_name ? 'cursor' : 'claude-code'
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
tool: 'unknown'
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Determine if we should output JSON for Cursor's beforeSubmitPrompt
|
|
44
|
+
*/
|
|
45
|
+
function shouldOutputJSON(input) {
|
|
46
|
+
return input.hook_event_name === 'beforeSubmitPrompt';
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=hook-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook-parser.js","sourceRoot":"","sources":["../../src/utils/hook-parser.ts"],"names":[],"mappings":";;AAIA,wCAyCC;AAKD,4CAEC;AApDD;;;GAGG;AACH,SAAgB,cAAc,CAAC,KAAU;IAMvC,iCAAiC;IACjC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO;YACL,IAAI,EAAE,SAAS;SAChB,CAAC;IACJ,CAAC;IAED,qBAAqB;IACrB,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACrB,OAAO;YACL,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,SAAS;YACpC,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,OAAO;YACjC,IAAI,EAAE,aAAa;SACpB,CAAC;IACJ,CAAC;IAED,gBAAgB;IAChB,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,OAAO;YACL,QAAQ,EAAE,KAAK,CAAC,SAAS;YACzB,IAAI,EAAE,QAAQ;SACf,CAAC;IACJ,CAAC;IAED,uBAAuB;IACvB,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,OAAO;YACL,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,IAAI,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa;SACvD,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,SAAS;KAChB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,KAAU;IACzC,OAAO,KAAK,CAAC,eAAe,KAAK,oBAAoB,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type SupportedTool = 'claude-code' | 'cursor';
|
|
2
|
+
export type SettingsScope = 'user' | 'project';
|
|
3
|
+
/**
|
|
4
|
+
* Get settings path for a specific tool and scope
|
|
5
|
+
*/
|
|
6
|
+
export declare function getSettingsPath(tool: SupportedTool, scope: SettingsScope): string;
|
|
7
|
+
/**
|
|
8
|
+
* Read tool settings (returns empty object if file doesn't exist)
|
|
9
|
+
*/
|
|
10
|
+
export declare function readToolSettings(tool: SupportedTool, scope: SettingsScope): any;
|
|
11
|
+
/**
|
|
12
|
+
* Write tool settings
|
|
13
|
+
*/
|
|
14
|
+
export declare function writeToolSettings(tool: SupportedTool, scope: SettingsScope, settings: any): void;
|
|
15
|
+
/**
|
|
16
|
+
* Add brainfile hooks to tool settings
|
|
17
|
+
*/
|
|
18
|
+
export declare function installBrainfileHooks(tool: SupportedTool, scope: SettingsScope): void;
|
|
19
|
+
/**
|
|
20
|
+
* Remove brainfile hooks from tool settings
|
|
21
|
+
*/
|
|
22
|
+
export declare function uninstallBrainfileHooks(tool: SupportedTool, scope: SettingsScope): void;
|
|
23
|
+
/**
|
|
24
|
+
* Check if brainfile hooks are installed for a tool
|
|
25
|
+
*/
|
|
26
|
+
export declare function areBrainfileHooksInstalled(tool: SupportedTool, scope: SettingsScope): boolean;
|
|
27
|
+
//# sourceMappingURL=hook-settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook-settings.d.ts","sourceRoot":"","sources":["../../src/utils/hook-settings.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,QAAQ,CAAC;AACrD,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,CAAC;AAE/C;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,CAmBjF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,GAAG,CAa/E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,GAAG,IAAI,CAUhG;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI,CA0GrF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI,CAgDvF;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CA4C7F"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getSettingsPath = getSettingsPath;
|
|
37
|
+
exports.readToolSettings = readToolSettings;
|
|
38
|
+
exports.writeToolSettings = writeToolSettings;
|
|
39
|
+
exports.installBrainfileHooks = installBrainfileHooks;
|
|
40
|
+
exports.uninstallBrainfileHooks = uninstallBrainfileHooks;
|
|
41
|
+
exports.areBrainfileHooksInstalled = areBrainfileHooksInstalled;
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const path = __importStar(require("path"));
|
|
44
|
+
const os = __importStar(require("os"));
|
|
45
|
+
/**
|
|
46
|
+
* Get settings path for a specific tool and scope
|
|
47
|
+
*/
|
|
48
|
+
function getSettingsPath(tool, scope) {
|
|
49
|
+
const homeDir = os.homedir();
|
|
50
|
+
if (scope === 'user') {
|
|
51
|
+
switch (tool) {
|
|
52
|
+
case 'claude-code':
|
|
53
|
+
return path.join(homeDir, '.claude', 'settings.json');
|
|
54
|
+
case 'cursor':
|
|
55
|
+
return path.join(homeDir, '.cursor', 'hooks.json');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// project scope
|
|
60
|
+
switch (tool) {
|
|
61
|
+
case 'claude-code':
|
|
62
|
+
return path.join(process.cwd(), '.claude', 'settings.json');
|
|
63
|
+
case 'cursor':
|
|
64
|
+
return path.join(process.cwd(), '.cursor', 'hooks.json');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Read tool settings (returns empty object if file doesn't exist)
|
|
70
|
+
*/
|
|
71
|
+
function readToolSettings(tool, scope) {
|
|
72
|
+
const settingsPath = getSettingsPath(tool, scope);
|
|
73
|
+
if (!fs.existsSync(settingsPath)) {
|
|
74
|
+
return tool === 'cursor' ? { version: 1, hooks: {} } : {};
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
const content = fs.readFileSync(settingsPath, 'utf-8');
|
|
78
|
+
return JSON.parse(content);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return tool === 'cursor' ? { version: 1, hooks: {} } : {};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Write tool settings
|
|
86
|
+
*/
|
|
87
|
+
function writeToolSettings(tool, scope, settings) {
|
|
88
|
+
const settingsPath = getSettingsPath(tool, scope);
|
|
89
|
+
const settingsDir = path.dirname(settingsPath);
|
|
90
|
+
// Create directory if it doesn't exist
|
|
91
|
+
if (!fs.existsSync(settingsDir)) {
|
|
92
|
+
fs.mkdirSync(settingsDir, { recursive: true });
|
|
93
|
+
}
|
|
94
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf-8');
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Add brainfile hooks to tool settings
|
|
98
|
+
*/
|
|
99
|
+
function installBrainfileHooks(tool, scope) {
|
|
100
|
+
const settings = readToolSettings(tool, scope);
|
|
101
|
+
if (tool === 'claude-code') {
|
|
102
|
+
if (!settings.hooks) {
|
|
103
|
+
settings.hooks = {};
|
|
104
|
+
}
|
|
105
|
+
settings.hooks.PostToolUse = settings.hooks.PostToolUse || [];
|
|
106
|
+
settings.hooks.UserPromptSubmit = settings.hooks.UserPromptSubmit || [];
|
|
107
|
+
settings.hooks.SessionStart = settings.hooks.SessionStart || [];
|
|
108
|
+
// Add PostToolUse hook if not already present
|
|
109
|
+
const hasPostToolUse = settings.hooks.PostToolUse.some((h) => h.hooks?.some((hook) => hook.command?.includes('brainfile hooks after-edit')));
|
|
110
|
+
if (!hasPostToolUse) {
|
|
111
|
+
settings.hooks.PostToolUse.push({
|
|
112
|
+
matcher: 'Edit|Write|Create',
|
|
113
|
+
hooks: [
|
|
114
|
+
{
|
|
115
|
+
type: 'command',
|
|
116
|
+
command: 'brainfile hooks after-edit'
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
// Add UserPromptSubmit hook if not already present
|
|
122
|
+
const hasUserPromptSubmit = settings.hooks.UserPromptSubmit.some((h) => h.hooks?.some((hook) => hook.command?.includes('brainfile hooks before-prompt')));
|
|
123
|
+
if (!hasUserPromptSubmit) {
|
|
124
|
+
settings.hooks.UserPromptSubmit.push({
|
|
125
|
+
matcher: '',
|
|
126
|
+
hooks: [
|
|
127
|
+
{
|
|
128
|
+
type: 'command',
|
|
129
|
+
command: 'brainfile hooks before-prompt'
|
|
130
|
+
}
|
|
131
|
+
]
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
// Add SessionStart hook if not already present
|
|
135
|
+
const hasSessionStart = settings.hooks.SessionStart.some((h) => h.hooks?.some((hook) => hook.command?.includes('brainfile hooks session-start')));
|
|
136
|
+
if (!hasSessionStart) {
|
|
137
|
+
settings.hooks.SessionStart.push({
|
|
138
|
+
matcher: '',
|
|
139
|
+
hooks: [
|
|
140
|
+
{
|
|
141
|
+
type: 'command',
|
|
142
|
+
command: 'brainfile hooks session-start'
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else if (tool === 'cursor') {
|
|
149
|
+
if (!settings.hooks) {
|
|
150
|
+
settings.hooks = {};
|
|
151
|
+
}
|
|
152
|
+
settings.hooks.afterFileEdit = settings.hooks.afterFileEdit || [];
|
|
153
|
+
settings.hooks.beforeSubmitPrompt = settings.hooks.beforeSubmitPrompt || [];
|
|
154
|
+
settings.hooks.stop = settings.hooks.stop || [];
|
|
155
|
+
// Add afterFileEdit hook if not already present
|
|
156
|
+
const hasAfterFileEdit = settings.hooks.afterFileEdit.some((h) => h.command?.includes('brainfile hooks after-edit'));
|
|
157
|
+
if (!hasAfterFileEdit) {
|
|
158
|
+
settings.hooks.afterFileEdit.push({
|
|
159
|
+
command: 'brainfile hooks after-edit'
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
// Add beforeSubmitPrompt hook if not already present
|
|
163
|
+
const hasBeforeSubmitPrompt = settings.hooks.beforeSubmitPrompt.some((h) => h.command?.includes('brainfile hooks before-prompt'));
|
|
164
|
+
if (!hasBeforeSubmitPrompt) {
|
|
165
|
+
settings.hooks.beforeSubmitPrompt.push({
|
|
166
|
+
command: 'brainfile hooks before-prompt'
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
// Add stop hook if not already present
|
|
170
|
+
const hasStop = settings.hooks.stop.some((h) => h.command?.includes('brainfile hooks session-start'));
|
|
171
|
+
if (!hasStop) {
|
|
172
|
+
settings.hooks.stop.push({
|
|
173
|
+
command: 'brainfile hooks session-start'
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
writeToolSettings(tool, scope, settings);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Remove brainfile hooks from tool settings
|
|
181
|
+
*/
|
|
182
|
+
function uninstallBrainfileHooks(tool, scope) {
|
|
183
|
+
const settings = readToolSettings(tool, scope);
|
|
184
|
+
if (!settings.hooks) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
if (tool === 'claude-code') {
|
|
188
|
+
// Remove brainfile hooks from each event type
|
|
189
|
+
if (settings.hooks.PostToolUse) {
|
|
190
|
+
settings.hooks.PostToolUse = settings.hooks.PostToolUse.filter((h) => !h.hooks?.some((hook) => hook.command?.includes('brainfile hooks')));
|
|
191
|
+
}
|
|
192
|
+
if (settings.hooks.UserPromptSubmit) {
|
|
193
|
+
settings.hooks.UserPromptSubmit = settings.hooks.UserPromptSubmit.filter((h) => !h.hooks?.some((hook) => hook.command?.includes('brainfile hooks')));
|
|
194
|
+
}
|
|
195
|
+
if (settings.hooks.SessionStart) {
|
|
196
|
+
settings.hooks.SessionStart = settings.hooks.SessionStart.filter((h) => !h.hooks?.some((hook) => hook.command?.includes('brainfile hooks')));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
else if (tool === 'cursor') {
|
|
200
|
+
// Remove brainfile hooks from each event type
|
|
201
|
+
if (settings.hooks.afterFileEdit) {
|
|
202
|
+
settings.hooks.afterFileEdit = settings.hooks.afterFileEdit.filter((h) => !h.command?.includes('brainfile hooks'));
|
|
203
|
+
}
|
|
204
|
+
if (settings.hooks.beforeSubmitPrompt) {
|
|
205
|
+
settings.hooks.beforeSubmitPrompt = settings.hooks.beforeSubmitPrompt.filter((h) => !h.command?.includes('brainfile hooks'));
|
|
206
|
+
}
|
|
207
|
+
if (settings.hooks.stop) {
|
|
208
|
+
settings.hooks.stop = settings.hooks.stop.filter((h) => !h.command?.includes('brainfile hooks'));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
writeToolSettings(tool, scope, settings);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Check if brainfile hooks are installed for a tool
|
|
215
|
+
*/
|
|
216
|
+
function areBrainfileHooksInstalled(tool, scope) {
|
|
217
|
+
const settingsPath = getSettingsPath(tool, scope);
|
|
218
|
+
if (!fs.existsSync(settingsPath)) {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
const settings = readToolSettings(tool, scope);
|
|
222
|
+
if (!settings.hooks) {
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
if (tool === 'claude-code') {
|
|
226
|
+
const hasPostToolUse = settings.hooks.PostToolUse?.some((h) => h.hooks?.some((hook) => hook.command?.includes('brainfile hooks after-edit'))) || false;
|
|
227
|
+
const hasUserPromptSubmit = settings.hooks.UserPromptSubmit?.some((h) => h.hooks?.some((hook) => hook.command?.includes('brainfile hooks before-prompt'))) || false;
|
|
228
|
+
const hasSessionStart = settings.hooks.SessionStart?.some((h) => h.hooks?.some((hook) => hook.command?.includes('brainfile hooks session-start'))) || false;
|
|
229
|
+
return hasPostToolUse || hasUserPromptSubmit || hasSessionStart;
|
|
230
|
+
}
|
|
231
|
+
else if (tool === 'cursor') {
|
|
232
|
+
const hasAfterFileEdit = settings.hooks.afterFileEdit?.some((h) => h.command?.includes('brainfile hooks after-edit')) || false;
|
|
233
|
+
const hasBeforeSubmitPrompt = settings.hooks.beforeSubmitPrompt?.some((h) => h.command?.includes('brainfile hooks before-prompt')) || false;
|
|
234
|
+
const hasStop = settings.hooks.stop?.some((h) => h.command?.includes('brainfile hooks session-start')) || false;
|
|
235
|
+
return hasAfterFileEdit || hasBeforeSubmitPrompt || hasStop;
|
|
236
|
+
}
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=hook-settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook-settings.js","sourceRoot":"","sources":["../../src/utils/hook-settings.ts"],"names":[],"mappings":"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"}
|