@soleri/cli 9.0.2 → 9.3.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/dist/commands/agent.js +116 -3
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/create.js +6 -2
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/hooks.js +36 -13
- package/dist/commands/hooks.js.map +1 -1
- package/dist/commands/install.d.ts +1 -0
- package/dist/commands/install.js +61 -12
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/pack.js +0 -1
- package/dist/commands/pack.js.map +1 -1
- package/dist/commands/staging.d.ts +2 -0
- package/dist/commands/staging.js +175 -0
- package/dist/commands/staging.js.map +1 -0
- package/dist/hook-packs/full/manifest.json +2 -2
- package/dist/hook-packs/installer.d.ts +4 -11
- package/dist/hook-packs/installer.js +197 -23
- package/dist/hook-packs/installer.js.map +1 -1
- package/dist/hook-packs/installer.ts +223 -38
- package/dist/hook-packs/registry.d.ts +16 -13
- package/dist/hook-packs/registry.js +11 -18
- package/dist/hook-packs/registry.js.map +1 -1
- package/dist/hook-packs/registry.ts +31 -30
- package/dist/hook-packs/yolo-safety/manifest.json +23 -0
- package/dist/hook-packs/yolo-safety/scripts/anti-deletion.sh +214 -0
- package/dist/hooks/templates.js +1 -1
- package/dist/hooks/templates.js.map +1 -1
- package/dist/main.js +2 -0
- package/dist/main.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/create.test.ts +6 -2
- package/src/__tests__/hook-packs.test.ts +67 -25
- package/src/__tests__/wizard-e2e.mjs +153 -58
- package/src/commands/agent.ts +146 -3
- package/src/commands/create.ts +8 -2
- package/src/commands/hooks.ts +36 -31
- package/src/commands/install.ts +65 -22
- package/src/commands/pack.ts +0 -1
- package/src/commands/staging.ts +208 -0
- package/src/hook-packs/full/manifest.json +2 -2
- package/src/hook-packs/installer.ts +223 -38
- package/src/hook-packs/registry.ts +31 -30
- package/src/hook-packs/yolo-safety/manifest.json +23 -0
- package/src/hook-packs/yolo-safety/scripts/anti-deletion.sh +214 -0
- package/src/hooks/templates.ts +1 -1
- package/src/main.ts +2 -0
- package/dist/commands/cognee.d.ts +0 -10
- package/dist/commands/cognee.js +0 -364
- package/dist/commands/cognee.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installer.js","sourceRoot":"","sources":["../../src/hook-packs/installer.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"installer.js","sourceRoot":"","sources":["../../src/hook-packs/installer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,29 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Hook pack installer — copies hookify files to ~/.claude/ (global) or project .claude/ (local).
|
|
2
|
+
* Hook pack installer — copies hookify files and scripts to ~/.claude/ (global) or project .claude/ (local).
|
|
3
|
+
* Also manages lifecycle hooks in ~/.claude/settings.json.
|
|
3
4
|
*/
|
|
4
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
existsSync,
|
|
7
|
+
copyFileSync,
|
|
8
|
+
unlinkSync,
|
|
9
|
+
mkdirSync,
|
|
10
|
+
readFileSync,
|
|
11
|
+
writeFileSync,
|
|
12
|
+
chmodSync,
|
|
13
|
+
} from 'node:fs';
|
|
5
14
|
import { join } from 'node:path';
|
|
6
15
|
import { homedir } from 'node:os';
|
|
7
16
|
import { getPack } from './registry.js';
|
|
17
|
+
import type { HookPackLifecycleHook } from './registry.js';
|
|
18
|
+
|
|
19
|
+
const PACK_MARKER = '_soleriPack';
|
|
8
20
|
|
|
9
|
-
/** Resolve the target .claude/ directory. */
|
|
10
21
|
function resolveClaudeDir(projectDir?: string): string {
|
|
11
22
|
if (projectDir) return join(projectDir, '.claude');
|
|
12
23
|
return join(homedir(), '.claude');
|
|
13
24
|
}
|
|
14
25
|
|
|
15
|
-
/**
|
|
16
|
-
* Resolve all hookify file paths for a pack, handling composed packs.
|
|
17
|
-
* Returns a map of hook name → source file path.
|
|
18
|
-
*/
|
|
19
26
|
function resolveHookFiles(packName: string): Map<string, string> {
|
|
20
27
|
const pack = getPack(packName);
|
|
21
28
|
if (!pack) return new Map();
|
|
22
|
-
|
|
23
29
|
const files = new Map<string, string>();
|
|
24
|
-
|
|
25
30
|
if (pack.manifest.composedFrom) {
|
|
26
|
-
// Composed pack: gather files from constituent packs
|
|
27
31
|
for (const subPackName of pack.manifest.composedFrom) {
|
|
28
32
|
const subFiles = resolveHookFiles(subPackName);
|
|
29
33
|
for (const [hook, path] of subFiles) {
|
|
@@ -31,7 +35,6 @@ function resolveHookFiles(packName: string): Map<string, string> {
|
|
|
31
35
|
}
|
|
32
36
|
}
|
|
33
37
|
} else {
|
|
34
|
-
// Direct pack: look for hookify files in the pack directory
|
|
35
38
|
for (const hook of pack.manifest.hooks) {
|
|
36
39
|
const filePath = join(pack.dir, `hookify.${hook}.local.md`);
|
|
37
40
|
if (existsSync(filePath)) {
|
|
@@ -39,30 +42,143 @@ function resolveHookFiles(packName: string): Map<string, string> {
|
|
|
39
42
|
}
|
|
40
43
|
}
|
|
41
44
|
}
|
|
42
|
-
|
|
43
45
|
return files;
|
|
44
46
|
}
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
function resolveScripts(
|
|
49
|
+
packName: string,
|
|
50
|
+
): Map<string, { sourcePath: string; targetDir: string; file: string }> {
|
|
51
|
+
const pack = getPack(packName);
|
|
52
|
+
if (!pack) return new Map();
|
|
53
|
+
const scripts = new Map<string, { sourcePath: string; targetDir: string; file: string }>();
|
|
54
|
+
if (pack.manifest.composedFrom) {
|
|
55
|
+
for (const subPackName of pack.manifest.composedFrom) {
|
|
56
|
+
const subScripts = resolveScripts(subPackName);
|
|
57
|
+
for (const [name, info] of subScripts) {
|
|
58
|
+
scripts.set(name, info);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
} else if (pack.manifest.scripts) {
|
|
62
|
+
for (const script of pack.manifest.scripts) {
|
|
63
|
+
const sourcePath = join(pack.dir, 'scripts', script.file);
|
|
64
|
+
if (existsSync(sourcePath)) {
|
|
65
|
+
scripts.set(script.name, { sourcePath, targetDir: script.targetDir, file: script.file });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return scripts;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function resolveLifecycleHooks(
|
|
73
|
+
packName: string,
|
|
74
|
+
): { packName: string; hook: HookPackLifecycleHook }[] {
|
|
75
|
+
const pack = getPack(packName);
|
|
76
|
+
if (!pack) return [];
|
|
77
|
+
const hooks: { packName: string; hook: HookPackLifecycleHook }[] = [];
|
|
78
|
+
if (pack.manifest.composedFrom) {
|
|
79
|
+
for (const subPackName of pack.manifest.composedFrom) {
|
|
80
|
+
hooks.push(...resolveLifecycleHooks(subPackName));
|
|
81
|
+
}
|
|
82
|
+
} else if (pack.manifest.lifecycleHooks) {
|
|
83
|
+
for (const hook of pack.manifest.lifecycleHooks) {
|
|
84
|
+
hooks.push({ packName: pack.manifest.name, hook });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return hooks;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
interface SettingsHookEntry {
|
|
91
|
+
type: 'command';
|
|
92
|
+
command: string;
|
|
93
|
+
timeout?: number;
|
|
94
|
+
[key: string]: unknown;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function readClaudeSettings(claudeDir: string): Record<string, unknown> {
|
|
98
|
+
const settingsPath = join(claudeDir, 'settings.json');
|
|
99
|
+
if (!existsSync(settingsPath)) return {};
|
|
100
|
+
try {
|
|
101
|
+
return JSON.parse(readFileSync(settingsPath, 'utf-8'));
|
|
102
|
+
} catch {
|
|
103
|
+
return {};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function writeClaudeSettings(claudeDir: string, settings: Record<string, unknown>): void {
|
|
108
|
+
const settingsPath = join(claudeDir, 'settings.json');
|
|
109
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function addLifecycleHooks(
|
|
113
|
+
claudeDir: string,
|
|
114
|
+
lifecycleHooks: { packName: string; hook: HookPackLifecycleHook }[],
|
|
115
|
+
): string[] {
|
|
116
|
+
if (lifecycleHooks.length === 0) return [];
|
|
117
|
+
const settings = readClaudeSettings(claudeDir);
|
|
118
|
+
const hooks = (settings['hooks'] ?? {}) as Record<string, unknown>;
|
|
119
|
+
const added: string[] = [];
|
|
120
|
+
for (const { packName: sourcePack, hook } of lifecycleHooks) {
|
|
121
|
+
const eventKey = hook.event;
|
|
122
|
+
const eventHooks = (hooks[eventKey] ?? []) as SettingsHookEntry[];
|
|
123
|
+
const alreadyExists = eventHooks.some(
|
|
124
|
+
(h) => h.command === hook.command && h[PACK_MARKER] === sourcePack,
|
|
125
|
+
);
|
|
126
|
+
if (!alreadyExists) {
|
|
127
|
+
const entry: SettingsHookEntry = {
|
|
128
|
+
type: hook.type,
|
|
129
|
+
command: hook.command,
|
|
130
|
+
[PACK_MARKER]: sourcePack,
|
|
131
|
+
};
|
|
132
|
+
if (hook.timeout) {
|
|
133
|
+
entry.timeout = hook.timeout;
|
|
134
|
+
}
|
|
135
|
+
eventHooks.push(entry);
|
|
136
|
+
hooks[eventKey] = eventHooks;
|
|
137
|
+
added.push(`${eventKey}:${hook.matcher}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
settings['hooks'] = hooks;
|
|
141
|
+
writeClaudeSettings(claudeDir, settings);
|
|
142
|
+
return added;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function removeLifecycleHooks(claudeDir: string, packName: string): string[] {
|
|
146
|
+
const settings = readClaudeSettings(claudeDir);
|
|
147
|
+
const hooks = (settings['hooks'] ?? {}) as Record<string, SettingsHookEntry[]>;
|
|
148
|
+
const removed: string[] = [];
|
|
149
|
+
for (const [eventKey, eventHooks] of Object.entries(hooks)) {
|
|
150
|
+
if (!Array.isArray(eventHooks)) continue;
|
|
151
|
+
const before = eventHooks.length;
|
|
152
|
+
const filtered = eventHooks.filter((h) => h[PACK_MARKER] !== packName);
|
|
153
|
+
if (filtered.length < before) {
|
|
154
|
+
removed.push(eventKey);
|
|
155
|
+
if (filtered.length === 0) {
|
|
156
|
+
delete hooks[eventKey];
|
|
157
|
+
} else {
|
|
158
|
+
hooks[eventKey] = filtered;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (removed.length > 0) {
|
|
163
|
+
settings['hooks'] = hooks;
|
|
164
|
+
writeClaudeSettings(claudeDir, settings);
|
|
165
|
+
}
|
|
166
|
+
return removed;
|
|
167
|
+
}
|
|
168
|
+
|
|
50
169
|
export function installPack(
|
|
51
170
|
packName: string,
|
|
52
171
|
options?: { projectDir?: string },
|
|
53
|
-
): { installed: string[]; skipped: string[] } {
|
|
172
|
+
): { installed: string[]; skipped: string[]; scripts: string[]; lifecycleHooks: string[] } {
|
|
54
173
|
const pack = getPack(packName);
|
|
55
174
|
if (!pack) {
|
|
56
175
|
throw new Error(`Unknown hook pack: "${packName}"`);
|
|
57
176
|
}
|
|
58
|
-
|
|
59
177
|
const claudeDir = resolveClaudeDir(options?.projectDir);
|
|
60
178
|
mkdirSync(claudeDir, { recursive: true });
|
|
61
|
-
|
|
62
179
|
const hookFiles = resolveHookFiles(packName);
|
|
63
180
|
const installed: string[] = [];
|
|
64
181
|
const skipped: string[] = [];
|
|
65
|
-
|
|
66
182
|
for (const [hook, sourcePath] of hookFiles) {
|
|
67
183
|
const destPath = join(claudeDir, `hookify.${hook}.local.md`);
|
|
68
184
|
if (existsSync(destPath)) {
|
|
@@ -72,25 +188,31 @@ export function installPack(
|
|
|
72
188
|
installed.push(hook);
|
|
73
189
|
}
|
|
74
190
|
}
|
|
75
|
-
|
|
76
|
-
|
|
191
|
+
const scriptFiles = resolveScripts(packName);
|
|
192
|
+
const installedScripts: string[] = [];
|
|
193
|
+
for (const [, { sourcePath, targetDir, file }] of scriptFiles) {
|
|
194
|
+
const destDir = join(claudeDir, targetDir);
|
|
195
|
+
mkdirSync(destDir, { recursive: true });
|
|
196
|
+
const destPath = join(destDir, file);
|
|
197
|
+
copyFileSync(sourcePath, destPath);
|
|
198
|
+
chmodSync(destPath, 0o755);
|
|
199
|
+
installedScripts.push(`${targetDir}/${file}`);
|
|
200
|
+
}
|
|
201
|
+
const lcHooks = resolveLifecycleHooks(packName);
|
|
202
|
+
const addedHooks = addLifecycleHooks(claudeDir, lcHooks);
|
|
203
|
+
return { installed, skipped, scripts: installedScripts, lifecycleHooks: addedHooks };
|
|
77
204
|
}
|
|
78
205
|
|
|
79
|
-
/**
|
|
80
|
-
* Remove a hook pack's files from target directory.
|
|
81
|
-
*/
|
|
82
206
|
export function removePack(
|
|
83
207
|
packName: string,
|
|
84
208
|
options?: { projectDir?: string },
|
|
85
|
-
): { removed: string[] } {
|
|
209
|
+
): { removed: string[]; scripts: string[]; lifecycleHooks: string[] } {
|
|
86
210
|
const pack = getPack(packName);
|
|
87
211
|
if (!pack) {
|
|
88
212
|
throw new Error(`Unknown hook pack: "${packName}"`);
|
|
89
213
|
}
|
|
90
|
-
|
|
91
214
|
const claudeDir = resolveClaudeDir(options?.projectDir);
|
|
92
215
|
const removed: string[] = [];
|
|
93
|
-
|
|
94
216
|
for (const hook of pack.manifest.hooks) {
|
|
95
217
|
const filePath = join(claudeDir, `hookify.${hook}.local.md`);
|
|
96
218
|
if (existsSync(filePath)) {
|
|
@@ -98,31 +220,94 @@ export function removePack(
|
|
|
98
220
|
removed.push(hook);
|
|
99
221
|
}
|
|
100
222
|
}
|
|
101
|
-
|
|
102
|
-
|
|
223
|
+
const removedScripts: string[] = [];
|
|
224
|
+
if (pack.manifest.scripts) {
|
|
225
|
+
for (const script of pack.manifest.scripts) {
|
|
226
|
+
const filePath = join(claudeDir, script.targetDir, script.file);
|
|
227
|
+
if (existsSync(filePath)) {
|
|
228
|
+
unlinkSync(filePath);
|
|
229
|
+
removedScripts.push(`${script.targetDir}/${script.file}`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (pack.manifest.composedFrom) {
|
|
234
|
+
for (const subPackName of pack.manifest.composedFrom) {
|
|
235
|
+
const subPack = getPack(subPackName);
|
|
236
|
+
if (subPack?.manifest.scripts) {
|
|
237
|
+
for (const script of subPack.manifest.scripts) {
|
|
238
|
+
const filePath = join(claudeDir, script.targetDir, script.file);
|
|
239
|
+
if (existsSync(filePath)) {
|
|
240
|
+
unlinkSync(filePath);
|
|
241
|
+
removedScripts.push(`${script.targetDir}/${script.file}`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
const removedHooks = removeLifecycleHooks(claudeDir, packName);
|
|
248
|
+
if (pack.manifest.composedFrom) {
|
|
249
|
+
for (const subPackName of pack.manifest.composedFrom) {
|
|
250
|
+
removedHooks.push(...removeLifecycleHooks(claudeDir, subPackName));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return { removed, scripts: removedScripts, lifecycleHooks: removedHooks };
|
|
103
254
|
}
|
|
104
255
|
|
|
105
|
-
/**
|
|
106
|
-
* Check if a pack is installed.
|
|
107
|
-
* Returns true (all hooks present), false (none present), or 'partial'.
|
|
108
|
-
*/
|
|
109
256
|
export function isPackInstalled(
|
|
110
257
|
packName: string,
|
|
111
258
|
options?: { projectDir?: string },
|
|
112
259
|
): boolean | 'partial' {
|
|
113
260
|
const pack = getPack(packName);
|
|
114
261
|
if (!pack) return false;
|
|
115
|
-
|
|
116
262
|
const claudeDir = resolveClaudeDir(options?.projectDir);
|
|
263
|
+
let total = 0;
|
|
117
264
|
let present = 0;
|
|
118
|
-
|
|
119
265
|
for (const hook of pack.manifest.hooks) {
|
|
266
|
+
total++;
|
|
120
267
|
if (existsSync(join(claudeDir, `hookify.${hook}.local.md`))) {
|
|
121
268
|
present++;
|
|
122
269
|
}
|
|
123
270
|
}
|
|
124
|
-
|
|
271
|
+
if (pack.manifest.scripts) {
|
|
272
|
+
for (const script of pack.manifest.scripts) {
|
|
273
|
+
total++;
|
|
274
|
+
if (existsSync(join(claudeDir, script.targetDir, script.file))) {
|
|
275
|
+
present++;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (pack.manifest.composedFrom) {
|
|
280
|
+
for (const subPackName of pack.manifest.composedFrom) {
|
|
281
|
+
const subPack = getPack(subPackName);
|
|
282
|
+
if (subPack?.manifest.scripts) {
|
|
283
|
+
for (const script of subPack.manifest.scripts) {
|
|
284
|
+
total++;
|
|
285
|
+
if (existsSync(join(claudeDir, script.targetDir, script.file))) {
|
|
286
|
+
present++;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
if (total === 0) {
|
|
293
|
+
const lcHooks = resolveLifecycleHooks(packName);
|
|
294
|
+
if (lcHooks.length > 0) {
|
|
295
|
+
const settings = readClaudeSettings(claudeDir);
|
|
296
|
+
const hooksObj = (settings['hooks'] ?? {}) as Record<string, SettingsHookEntry[]>;
|
|
297
|
+
for (const { packName: sourcePack, hook } of lcHooks) {
|
|
298
|
+
total++;
|
|
299
|
+
const eventHooks = hooksObj[hook.event];
|
|
300
|
+
if (
|
|
301
|
+
Array.isArray(eventHooks) &&
|
|
302
|
+
eventHooks.some((h) => h.command === hook.command && h[PACK_MARKER] === sourcePack)
|
|
303
|
+
) {
|
|
304
|
+
present++;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
if (total === 0) return false;
|
|
125
310
|
if (present === 0) return false;
|
|
126
|
-
if (present ===
|
|
311
|
+
if (present === total) return true;
|
|
127
312
|
return 'partial';
|
|
128
313
|
}
|
|
@@ -1,26 +1,29 @@
|
|
|
1
|
-
interface
|
|
1
|
+
export interface HookPackScript {
|
|
2
|
+
name: string;
|
|
3
|
+
file: string;
|
|
4
|
+
targetDir: string;
|
|
5
|
+
}
|
|
6
|
+
export interface HookPackLifecycleHook {
|
|
7
|
+
event: string;
|
|
8
|
+
matcher: string;
|
|
9
|
+
type: 'command';
|
|
10
|
+
command: string;
|
|
11
|
+
timeout?: number;
|
|
12
|
+
statusMessage?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface HookPackManifest {
|
|
2
15
|
name: string;
|
|
3
16
|
description: string;
|
|
4
17
|
hooks: string[];
|
|
5
18
|
composedFrom?: string[];
|
|
6
19
|
version?: string;
|
|
7
|
-
|
|
20
|
+
scripts?: HookPackScript[];
|
|
21
|
+
lifecycleHooks?: HookPackLifecycleHook[];
|
|
8
22
|
source?: 'built-in' | 'local';
|
|
9
23
|
}
|
|
10
|
-
/**
|
|
11
|
-
* List all available hook packs (built-in + local custom).
|
|
12
|
-
* Local packs in .soleri/hook-packs/ override built-in packs with the same name.
|
|
13
|
-
*/
|
|
14
24
|
export declare function listPacks(): HookPackManifest[];
|
|
15
|
-
/**
|
|
16
|
-
* Get a specific pack by name. Local packs take precedence.
|
|
17
|
-
*/
|
|
18
25
|
export declare function getPack(name: string): {
|
|
19
26
|
manifest: HookPackManifest;
|
|
20
27
|
dir: string;
|
|
21
28
|
} | null;
|
|
22
|
-
/**
|
|
23
|
-
* Get names of packs that are fully installed in ~/.claude/.
|
|
24
|
-
*/
|
|
25
29
|
export declare function getInstalledPacks(): string[];
|
|
26
|
-
export {};
|
|
@@ -7,15 +7,12 @@ import { fileURLToPath } from 'node:url';
|
|
|
7
7
|
import { homedir } from 'node:os';
|
|
8
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
9
|
const __dirname = dirname(__filename);
|
|
10
|
-
/** Root directory containing all built-in hook packs. */
|
|
11
10
|
function getBuiltinRoot() {
|
|
12
11
|
return __dirname;
|
|
13
12
|
}
|
|
14
|
-
/** Local custom packs directory. */
|
|
15
13
|
function getLocalRoot() {
|
|
16
14
|
return join(process.cwd(), '.soleri', 'hook-packs');
|
|
17
15
|
}
|
|
18
|
-
/** Scan a directory for pack manifests. */
|
|
19
16
|
function scanPacksDir(root, source) {
|
|
20
17
|
if (!existsSync(root))
|
|
21
18
|
return [];
|
|
@@ -33,19 +30,14 @@ function scanPacksDir(root, source) {
|
|
|
33
30
|
packs.push(manifest);
|
|
34
31
|
}
|
|
35
32
|
catch {
|
|
36
|
-
|
|
33
|
+
/* Skip malformed manifests */
|
|
37
34
|
}
|
|
38
35
|
}
|
|
39
36
|
return packs;
|
|
40
37
|
}
|
|
41
|
-
/**
|
|
42
|
-
* List all available hook packs (built-in + local custom).
|
|
43
|
-
* Local packs in .soleri/hook-packs/ override built-in packs with the same name.
|
|
44
|
-
*/
|
|
45
38
|
export function listPacks() {
|
|
46
39
|
const builtIn = scanPacksDir(getBuiltinRoot(), 'built-in');
|
|
47
40
|
const local = scanPacksDir(getLocalRoot(), 'local');
|
|
48
|
-
// Local packs override built-in packs with same name
|
|
49
41
|
const byName = new Map();
|
|
50
42
|
for (const pack of builtIn)
|
|
51
43
|
byName.set(pack.name, pack);
|
|
@@ -53,11 +45,7 @@ export function listPacks() {
|
|
|
53
45
|
byName.set(pack.name, pack);
|
|
54
46
|
return Array.from(byName.values());
|
|
55
47
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Get a specific pack by name. Local packs take precedence.
|
|
58
|
-
*/
|
|
59
48
|
export function getPack(name) {
|
|
60
|
-
// Check local first
|
|
61
49
|
const localDir = join(getLocalRoot(), name);
|
|
62
50
|
const localManifest = join(localDir, 'manifest.json');
|
|
63
51
|
if (existsSync(localManifest)) {
|
|
@@ -67,10 +55,9 @@ export function getPack(name) {
|
|
|
67
55
|
return { manifest, dir: localDir };
|
|
68
56
|
}
|
|
69
57
|
catch {
|
|
70
|
-
|
|
58
|
+
/* Fall through */
|
|
71
59
|
}
|
|
72
60
|
}
|
|
73
|
-
// Then built-in
|
|
74
61
|
const builtinDir = join(getBuiltinRoot(), name);
|
|
75
62
|
const builtinManifest = join(builtinDir, 'manifest.json');
|
|
76
63
|
if (!existsSync(builtinManifest))
|
|
@@ -84,14 +71,20 @@ export function getPack(name) {
|
|
|
84
71
|
return null;
|
|
85
72
|
}
|
|
86
73
|
}
|
|
87
|
-
/**
|
|
88
|
-
* Get names of packs that are fully installed in ~/.claude/.
|
|
89
|
-
*/
|
|
90
74
|
export function getInstalledPacks() {
|
|
91
75
|
const claudeDir = join(homedir(), '.claude');
|
|
92
76
|
const packs = listPacks();
|
|
93
77
|
const installed = [];
|
|
94
78
|
for (const pack of packs) {
|
|
79
|
+
if (pack.hooks.length === 0) {
|
|
80
|
+
if (pack.scripts && pack.scripts.length > 0) {
|
|
81
|
+
const allScripts = pack.scripts.every((script) => existsSync(join(claudeDir, script.targetDir, script.file)));
|
|
82
|
+
if (allScripts) {
|
|
83
|
+
installed.push(pack.name);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
95
88
|
const allPresent = pack.hooks.every((hook) => existsSync(join(claudeDir, `hookify.${hook}.local.md`)));
|
|
96
89
|
if (allPresent) {
|
|
97
90
|
installed.push(pack.name);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/hook-packs/registry.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/hook-packs/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,73 +6,71 @@ import { join, dirname } from 'node:path';
|
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
import { homedir } from 'node:os';
|
|
8
8
|
|
|
9
|
-
interface
|
|
9
|
+
export interface HookPackScript {
|
|
10
|
+
name: string;
|
|
11
|
+
file: string;
|
|
12
|
+
targetDir: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface HookPackLifecycleHook {
|
|
16
|
+
event: string;
|
|
17
|
+
matcher: string;
|
|
18
|
+
type: 'command';
|
|
19
|
+
command: string;
|
|
20
|
+
timeout?: number;
|
|
21
|
+
statusMessage?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface HookPackManifest {
|
|
10
25
|
name: string;
|
|
11
26
|
description: string;
|
|
12
27
|
hooks: string[];
|
|
13
28
|
composedFrom?: string[];
|
|
14
29
|
version?: string;
|
|
15
|
-
|
|
30
|
+
scripts?: HookPackScript[];
|
|
31
|
+
lifecycleHooks?: HookPackLifecycleHook[];
|
|
16
32
|
source?: 'built-in' | 'local';
|
|
17
33
|
}
|
|
18
34
|
|
|
19
35
|
const __filename = fileURLToPath(import.meta.url);
|
|
20
36
|
const __dirname = dirname(__filename);
|
|
21
37
|
|
|
22
|
-
/** Root directory containing all built-in hook packs. */
|
|
23
38
|
function getBuiltinRoot(): string {
|
|
24
39
|
return __dirname;
|
|
25
40
|
}
|
|
26
|
-
|
|
27
|
-
/** Local custom packs directory. */
|
|
28
41
|
function getLocalRoot(): string {
|
|
29
42
|
return join(process.cwd(), '.soleri', 'hook-packs');
|
|
30
43
|
}
|
|
31
44
|
|
|
32
|
-
/** Scan a directory for pack manifests. */
|
|
33
45
|
function scanPacksDir(root: string, source: 'built-in' | 'local'): HookPackManifest[] {
|
|
34
46
|
if (!existsSync(root)) return [];
|
|
35
47
|
const entries = readdirSync(root, { withFileTypes: true });
|
|
36
48
|
const packs: HookPackManifest[] = [];
|
|
37
|
-
|
|
38
49
|
for (const entry of entries) {
|
|
39
50
|
if (!entry.isDirectory()) continue;
|
|
40
51
|
const manifestPath = join(root, entry.name, 'manifest.json');
|
|
41
52
|
if (!existsSync(manifestPath)) continue;
|
|
42
|
-
|
|
43
53
|
try {
|
|
44
54
|
const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8')) as HookPackManifest;
|
|
45
55
|
manifest.source = source;
|
|
46
56
|
packs.push(manifest);
|
|
47
57
|
} catch {
|
|
48
|
-
|
|
58
|
+
/* Skip malformed manifests */
|
|
49
59
|
}
|
|
50
60
|
}
|
|
51
|
-
|
|
52
61
|
return packs;
|
|
53
62
|
}
|
|
54
63
|
|
|
55
|
-
/**
|
|
56
|
-
* List all available hook packs (built-in + local custom).
|
|
57
|
-
* Local packs in .soleri/hook-packs/ override built-in packs with the same name.
|
|
58
|
-
*/
|
|
59
64
|
export function listPacks(): HookPackManifest[] {
|
|
60
65
|
const builtIn = scanPacksDir(getBuiltinRoot(), 'built-in');
|
|
61
66
|
const local = scanPacksDir(getLocalRoot(), 'local');
|
|
62
|
-
|
|
63
|
-
// Local packs override built-in packs with same name
|
|
64
67
|
const byName = new Map<string, HookPackManifest>();
|
|
65
68
|
for (const pack of builtIn) byName.set(pack.name, pack);
|
|
66
69
|
for (const pack of local) byName.set(pack.name, pack);
|
|
67
|
-
|
|
68
70
|
return Array.from(byName.values());
|
|
69
71
|
}
|
|
70
72
|
|
|
71
|
-
/**
|
|
72
|
-
* Get a specific pack by name. Local packs take precedence.
|
|
73
|
-
*/
|
|
74
73
|
export function getPack(name: string): { manifest: HookPackManifest; dir: string } | null {
|
|
75
|
-
// Check local first
|
|
76
74
|
const localDir = join(getLocalRoot(), name);
|
|
77
75
|
const localManifest = join(localDir, 'manifest.json');
|
|
78
76
|
if (existsSync(localManifest)) {
|
|
@@ -81,15 +79,12 @@ export function getPack(name: string): { manifest: HookPackManifest; dir: string
|
|
|
81
79
|
manifest.source = 'local';
|
|
82
80
|
return { manifest, dir: localDir };
|
|
83
81
|
} catch {
|
|
84
|
-
|
|
82
|
+
/* Fall through */
|
|
85
83
|
}
|
|
86
84
|
}
|
|
87
|
-
|
|
88
|
-
// Then built-in
|
|
89
85
|
const builtinDir = join(getBuiltinRoot(), name);
|
|
90
86
|
const builtinManifest = join(builtinDir, 'manifest.json');
|
|
91
87
|
if (!existsSync(builtinManifest)) return null;
|
|
92
|
-
|
|
93
88
|
try {
|
|
94
89
|
const manifest = JSON.parse(readFileSync(builtinManifest, 'utf-8')) as HookPackManifest;
|
|
95
90
|
manifest.source = 'built-in';
|
|
@@ -99,15 +94,22 @@ export function getPack(name: string): { manifest: HookPackManifest; dir: string
|
|
|
99
94
|
}
|
|
100
95
|
}
|
|
101
96
|
|
|
102
|
-
/**
|
|
103
|
-
* Get names of packs that are fully installed in ~/.claude/.
|
|
104
|
-
*/
|
|
105
97
|
export function getInstalledPacks(): string[] {
|
|
106
98
|
const claudeDir = join(homedir(), '.claude');
|
|
107
99
|
const packs = listPacks();
|
|
108
100
|
const installed: string[] = [];
|
|
109
|
-
|
|
110
101
|
for (const pack of packs) {
|
|
102
|
+
if (pack.hooks.length === 0) {
|
|
103
|
+
if (pack.scripts && pack.scripts.length > 0) {
|
|
104
|
+
const allScripts = pack.scripts.every((script) =>
|
|
105
|
+
existsSync(join(claudeDir, script.targetDir, script.file)),
|
|
106
|
+
);
|
|
107
|
+
if (allScripts) {
|
|
108
|
+
installed.push(pack.name);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
111
113
|
const allPresent = pack.hooks.every((hook) =>
|
|
112
114
|
existsSync(join(claudeDir, `hookify.${hook}.local.md`)),
|
|
113
115
|
);
|
|
@@ -115,6 +117,5 @@ export function getInstalledPacks(): string[] {
|
|
|
115
117
|
installed.push(pack.name);
|
|
116
118
|
}
|
|
117
119
|
}
|
|
118
|
-
|
|
119
120
|
return installed;
|
|
120
121
|
}
|