@planu/cli 0.97.0 → 0.97.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.
@@ -0,0 +1,4 @@
1
+ import type { ToolResult } from '../../types/index.js';
2
+ import type { ConfigureHooksInput } from '../../types/file-hooks.js';
3
+ export declare function handleConfigureHooks(args: ConfigureHooksInput): Promise<ToolResult>;
4
+ //# sourceMappingURL=configure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../../../src/tools/start-hooks/configure.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAA6B,MAAM,sBAAsB,CAAC;AAClF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAQrE,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CA6CzF"}
@@ -0,0 +1,122 @@
1
+ // tools/start-hooks/configure.ts — handleConfigureHooks + plan-mode integration + template apply.
2
+ import { readFile, writeFile, mkdir } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ import { generateHookTemplate, mergeHookConfig } from '../../engine/hooks/hook-templates.js';
5
+ import { buildPlanModeHookScripts } from '../../engine/hooks/plan-mode-scripts.js';
6
+ import { ConfigLoader } from '../../engine/hooks/config-loader.js';
7
+ import { getConfigLoaderInstance, getEngineInstance } from './engine.js';
8
+ export async function handleConfigureHooks(args) {
9
+ if (args.action === 'enable-plan-mode-integration') {
10
+ return enablePlanModeIntegration(args.projectPath);
11
+ }
12
+ if (args.template) {
13
+ return applyHookTemplate(args);
14
+ }
15
+ const configLoader = getConfigLoaderInstance();
16
+ if (!configLoader) {
17
+ const loader = new ConfigLoader(args.projectPath);
18
+ const config = await loader.load();
19
+ loader.close();
20
+ return {
21
+ content: [
22
+ {
23
+ type: 'text',
24
+ text: JSON.stringify({ message: 'Hook engine not running. Current config:', config }, null, 2),
25
+ },
26
+ ],
27
+ };
28
+ }
29
+ const config = await configLoader.load();
30
+ return {
31
+ content: [
32
+ {
33
+ type: 'text',
34
+ text: JSON.stringify({
35
+ message: 'Configuration reloaded',
36
+ config,
37
+ engineRunning: getEngineInstance()?.status().running ?? false,
38
+ }, null, 2),
39
+ },
40
+ ],
41
+ };
42
+ }
43
+ async function enablePlanModeIntegration(projectPath) {
44
+ const hooksDir = join(projectPath, '.claude', 'hooks');
45
+ await mkdir(hooksDir, { recursive: true });
46
+ const scripts = buildPlanModeHookScripts();
47
+ const preHookPath = join(hooksDir, 'planu-pre-plan.sh');
48
+ const postHookPath = join(hooksDir, 'planu-post-plan.sh');
49
+ await writeFile(preHookPath, scripts.preScript, { mode: 0o755 });
50
+ await writeFile(postHookPath, scripts.postScript, { mode: 0o755 });
51
+ const settingsPath = join(projectPath, '.claude', 'settings.json');
52
+ let existing = {};
53
+ try {
54
+ const raw = await readFile(settingsPath, 'utf-8');
55
+ existing = JSON.parse(raw);
56
+ }
57
+ catch {
58
+ // File doesn't exist yet — start from empty
59
+ }
60
+ const preEntry = {
61
+ matcher: 'Task',
62
+ hooks: [{ type: 'command', command: `bash "${preHookPath}"` }],
63
+ };
64
+ const postEntry = {
65
+ matcher: 'exit_plan_mode',
66
+ hooks: [{ type: 'command', command: `bash "${postHookPath}"` }],
67
+ };
68
+ const existingHooks = (existing.hooks ?? {});
69
+ const merged = {
70
+ ...existing,
71
+ hooks: {
72
+ ...existingHooks,
73
+ PreToolUse: [...(existingHooks.PreToolUse ?? []), preEntry],
74
+ PostToolUse: [...(existingHooks.PostToolUse ?? []), postEntry],
75
+ },
76
+ };
77
+ await writeFile(settingsPath, JSON.stringify(merged, null, 2) + '\n', 'utf-8');
78
+ const result = {
79
+ action: 'enable-plan-mode-integration',
80
+ preHookPath,
81
+ postHookPath,
82
+ settingsPath,
83
+ message: 'Plan Mode integration enabled. Planu context will be injected automatically when Claude enters Plan Mode.',
84
+ };
85
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
86
+ }
87
+ async function applyHookTemplate(args) {
88
+ /* c8 ignore next 3 */
89
+ if (!args.template) {
90
+ return { content: [{ type: 'text', text: 'template is required' }], isError: true };
91
+ }
92
+ const generated = generateHookTemplate({
93
+ template: args.template,
94
+ notificationMatcher: args.notificationMatcher,
95
+ });
96
+ const settingsPath = join(args.projectPath, '.claude', 'settings.json');
97
+ let existing = {};
98
+ try {
99
+ const raw = await readFile(settingsPath, 'utf-8');
100
+ existing = JSON.parse(raw);
101
+ }
102
+ catch {
103
+ // File doesn't exist yet or is not valid JSON — start from empty object
104
+ }
105
+ const merged = mergeHookConfig(existing, generated);
106
+ await writeFile(settingsPath, JSON.stringify(merged, null, 2) + '\n', 'utf-8');
107
+ return {
108
+ content: [
109
+ {
110
+ type: 'text',
111
+ text: JSON.stringify({
112
+ message: `Hook template '${args.template}' applied`,
113
+ settingsPath,
114
+ description: generated.description,
115
+ mergeInstructions: generated.mergeInstructions,
116
+ generatedConfig: generated.hooks,
117
+ }, null, 2),
118
+ },
119
+ ],
120
+ };
121
+ }
122
+ //# sourceMappingURL=configure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configure.js","sourceRoot":"","sources":["../../../src/tools/start-hooks/configure.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { ToolResult } from '../../types/index.js';
2
+ import type { StartHooksInput, StopHooksInput } from '../../types/file-hooks.js';
3
+ import { HookEngine } from '../../engine/hooks/hook-engine.js';
4
+ import { FileWatcher } from '../../engine/hooks/file-watcher.js';
5
+ import { ConfigLoader } from '../../engine/hooks/config-loader.js';
6
+ export declare function getEngineInstance(): HookEngine | null;
7
+ export declare function getWatcherInstance(): FileWatcher | null;
8
+ export declare function getConfigLoaderInstance(): ConfigLoader | null;
9
+ export declare function ensureHooksStarted(projectPath: string): void;
10
+ export declare function handleStartHooks(args: StartHooksInput): Promise<ToolResult>;
11
+ export declare function handleStopHooks(_args: StopHooksInput): Promise<ToolResult>;
12
+ export declare function handleHookStatus(): Promise<ToolResult>;
13
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/tools/start-hooks/engine.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAQ,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAGV,eAAe,EACf,cAAc,EAGf,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAE/D,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AA0BnE,wBAAgB,iBAAiB,IAAI,UAAU,GAAG,IAAI,CAErD;AAED,wBAAgB,kBAAkB,IAAI,WAAW,GAAG,IAAI,CAEvD;AAED,wBAAgB,uBAAuB,IAAI,YAAY,GAAG,IAAI,CAE7D;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAmB5D;AAMD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CAwFjF;AAMD,wBAAsB,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAoBhF;AAMD,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,UAAU,CAAC,CAkC5D"}
@@ -0,0 +1,314 @@
1
+ // tools/start-hooks/engine.ts — Singleton state + lifecycle handlers for the hook engine.
2
+ import { HookEngine } from '../../engine/hooks/hook-engine.js';
3
+ import { EventBus } from '../../engine/hooks/event-bus.js';
4
+ import { FileWatcher } from '../../engine/hooks/file-watcher.js';
5
+ import { ConfigLoader } from '../../engine/hooks/config-loader.js';
6
+ import { Debouncer } from '../../engine/hooks/debouncer.js';
7
+ import { handleOnImplChange } from '../../engine/hooks/handlers/on-impl-change.js';
8
+ import { handleOnSpecChange } from '../../engine/hooks/handlers/on-spec-change.js';
9
+ import { handleOnPushCheck, getLastPushCheckResult, } from '../../engine/hooks/handlers/on-push-check.js';
10
+ import { handleOnSecurityCheck, isSecuritySensitiveFile, } from '../../engine/hooks/handlers/on-security-check.js';
11
+ import { subscribeStatusChangeHandler } from '../../engine/hooks/handlers/on-status-change.js';
12
+ import { listSpecs } from '../../storage/spec-store.js';
13
+ import { hashProjectPath } from '../../storage/base-store.js';
14
+ import { analyzeLivingSpec } from '../../engine/living-spec-analyzer.js';
15
+ // ---------------------------------------------------------------------------
16
+ // Singleton state
17
+ // ---------------------------------------------------------------------------
18
+ let engineInstance = null;
19
+ let watcherInstance = null;
20
+ let debouncerInstance = null;
21
+ let configLoaderInstance = null;
22
+ export function getEngineInstance() {
23
+ return engineInstance;
24
+ }
25
+ export function getWatcherInstance() {
26
+ return watcherInstance;
27
+ }
28
+ export function getConfigLoaderInstance() {
29
+ return configLoaderInstance;
30
+ }
31
+ export function ensureHooksStarted(projectPath) {
32
+ if (engineInstance?.status().running) {
33
+ return;
34
+ }
35
+ void handleStartHooks({
36
+ projectPath,
37
+ hooks: [
38
+ 'on-save',
39
+ 'on-create',
40
+ 'on-delete',
41
+ 'on-commit',
42
+ 'on-impl-change',
43
+ 'on-spec-change',
44
+ 'on-push-check',
45
+ 'on-security-check',
46
+ ],
47
+ }).catch(() => {
48
+ // Silently swallow — hooks are best-effort
49
+ });
50
+ }
51
+ // ---------------------------------------------------------------------------
52
+ // Start hooks
53
+ // ---------------------------------------------------------------------------
54
+ export async function handleStartHooks(args) {
55
+ if (engineInstance?.status().running) {
56
+ const status = engineInstance.status();
57
+ return {
58
+ content: [
59
+ {
60
+ type: 'text',
61
+ text: JSON.stringify({ message: 'Hook engine already running', ...status }, null, 2),
62
+ },
63
+ ],
64
+ };
65
+ }
66
+ const projectPath = args.projectPath;
67
+ const enabledHooks = args.hooks ?? [
68
+ 'on-save',
69
+ 'on-create',
70
+ 'on-delete',
71
+ 'on-impl-change',
72
+ 'on-spec-change',
73
+ 'on-security-check',
74
+ ];
75
+ configLoaderInstance = new ConfigLoader(projectPath);
76
+ const config = await configLoaderInstance.load();
77
+ const eventBus = new EventBus();
78
+ engineInstance = new HookEngine(eventBus);
79
+ watcherInstance = new FileWatcher({
80
+ rootDir: projectPath,
81
+ include: config.hooks['on-save']?.include,
82
+ exclude: config.hooks['on-save']?.exclude,
83
+ });
84
+ debouncerInstance = new Debouncer((event) => {
85
+ const hookTypes = getApplicableHookTypes(event);
86
+ for (const hookType of hookTypes) {
87
+ if (enabledHooks.includes(hookType)) {
88
+ void engineInstance?.dispatch(event, hookType);
89
+ }
90
+ }
91
+ }, { debounceMs: config.debounceMs, rateLimitPerFileMs: config.rateLimitPerFileMs });
92
+ watcherInstance.on('change', (event) => {
93
+ eventBus.emitEvent('file:change', {
94
+ path: event.path,
95
+ type: event.type,
96
+ timestamp: event.timestamp,
97
+ });
98
+ debouncerInstance?.push(event);
99
+ });
100
+ configLoaderInstance.startWatching();
101
+ engineInstance.start();
102
+ watcherInstance.start();
103
+ registerAdvancedHandlers(engineInstance, enabledHooks, projectPath, config);
104
+ const eventBusFromEngine = engineInstance.getEventBus();
105
+ subscribeStatusChangeHandler(eventBusFromEngine,
106
+ /* v8 ignore next 3 */ (_projectId) => Promise.resolve(true));
107
+ return {
108
+ content: [
109
+ {
110
+ type: 'text',
111
+ text: JSON.stringify({
112
+ message: 'Hook engine started',
113
+ projectPath,
114
+ enabledHooks,
115
+ config: {
116
+ debounceMs: config.debounceMs,
117
+ rateLimitPerFileMs: config.rateLimitPerFileMs,
118
+ },
119
+ }, null, 2),
120
+ },
121
+ ],
122
+ };
123
+ }
124
+ // ---------------------------------------------------------------------------
125
+ // Stop hooks
126
+ // ---------------------------------------------------------------------------
127
+ export async function handleStopHooks(_args) {
128
+ await Promise.resolve();
129
+ if (!engineInstance) {
130
+ return {
131
+ content: [{ type: 'text', text: JSON.stringify({ message: 'Hook engine not running' }) }],
132
+ };
133
+ }
134
+ engineInstance.stop();
135
+ watcherInstance?.close();
136
+ debouncerInstance?.dispose();
137
+ configLoaderInstance?.close();
138
+ const message = 'Hook engine stopped and resources cleaned up';
139
+ engineInstance = null;
140
+ watcherInstance = null;
141
+ debouncerInstance = null;
142
+ configLoaderInstance = null;
143
+ return { content: [{ type: 'text', text: JSON.stringify({ message }) }] };
144
+ }
145
+ // ---------------------------------------------------------------------------
146
+ // Hook status
147
+ // ---------------------------------------------------------------------------
148
+ export async function handleHookStatus() {
149
+ await Promise.resolve();
150
+ if (!engineInstance) {
151
+ return {
152
+ content: [
153
+ {
154
+ type: 'text',
155
+ text: JSON.stringify({
156
+ running: false,
157
+ activeHooks: [],
158
+ pendingEvents: 0,
159
+ telemetry: {},
160
+ eventHistory: 0,
161
+ }),
162
+ },
163
+ ],
164
+ };
165
+ }
166
+ const status = engineInstance.status();
167
+ const eventBus = engineInstance.getEventBus();
168
+ return {
169
+ content: [
170
+ {
171
+ type: 'text',
172
+ text: JSON.stringify({ ...status, eventHistory: eventBus.getFullHistory().length }, null, 2),
173
+ },
174
+ ],
175
+ };
176
+ }
177
+ // ---------------------------------------------------------------------------
178
+ // Private helpers
179
+ // ---------------------------------------------------------------------------
180
+ function getApplicableHookTypes(event) {
181
+ switch (event.type) {
182
+ case 'modify':
183
+ return ['on-save', 'on-impl-change', 'on-spec-change', 'on-security-check'];
184
+ case 'create':
185
+ return ['on-create', 'on-impl-change', 'on-spec-change', 'on-security-check'];
186
+ case 'delete':
187
+ return ['on-delete'];
188
+ /* v8 ignore next 2 */
189
+ default:
190
+ return [];
191
+ }
192
+ }
193
+ function specToMinimal(spec) {
194
+ return { id: spec.id, title: spec.title, status: spec.status, progressPath: spec.progressPath };
195
+ }
196
+ function makeAnalyzeSpecFn() {
197
+ return async (minimal, projectPath) => {
198
+ const specLike = {
199
+ id: minimal.id,
200
+ title: minimal.title,
201
+ slug: minimal.id
202
+ .toLowerCase()
203
+ .replace(/^spec-/, '')
204
+ .replace(/\s+/g, '-'),
205
+ status: minimal.status,
206
+ progressPath: minimal.progressPath,
207
+ };
208
+ const report = await analyzeLivingSpec(specLike, projectPath);
209
+ return {
210
+ completionPct: report.completionPercent,
211
+ progressUpdated: report.progressUpdated,
212
+ criterionResults: report.criteria.map((c) => ({
213
+ criterion: c.criterion,
214
+ met: c.status === 'met',
215
+ evidence: c.evidence,
216
+ })),
217
+ };
218
+ };
219
+ }
220
+ function registerAdvancedHandlers(engine, enabledHooks, projectPath, config) {
221
+ if (enabledHooks.includes('on-impl-change')) {
222
+ engine.register({
223
+ name: 'on-impl-change',
224
+ hookType: 'on-impl-change',
225
+ priority: 200,
226
+ execute: async (event) => {
227
+ const projectId = hashProjectPath(projectPath);
228
+ let specs = [];
229
+ try {
230
+ const fullSpecs = await listSpecs(projectId);
231
+ specs = fullSpecs.map(specToMinimal);
232
+ }
233
+ catch {
234
+ // Spec load failure — proceed without analysis
235
+ }
236
+ const analysisResult = await handleOnImplChange(event, projectPath, specs, makeAnalyzeSpecFn(), config.autoMarkDone !== false);
237
+ const firstSpecId = analysisResult
238
+ ? (analysisResult.specsAnalyzed[0]?.specId ?? null)
239
+ : null;
240
+ return {
241
+ hook: 'on-save',
242
+ specId: firstSpecId,
243
+ driftDelta: analysisResult ? analysisResult.specsAnalyzed.length : 0,
244
+ hashChanged: event.type === 'modify' || event.type === 'create',
245
+ annotationsValid: analysisResult !== undefined,
246
+ };
247
+ },
248
+ });
249
+ }
250
+ if (enabledHooks.includes('on-spec-change')) {
251
+ engine.register({
252
+ name: 'on-spec-change',
253
+ hookType: 'on-spec-change',
254
+ priority: 300,
255
+ execute: async (event) => {
256
+ await handleOnSpecChange(event, projectPath);
257
+ return {
258
+ hook: 'on-save',
259
+ specId: null,
260
+ driftDelta: 0,
261
+ hashChanged: event.type !== 'delete',
262
+ annotationsValid: true,
263
+ };
264
+ },
265
+ });
266
+ }
267
+ if (enabledHooks.includes('on-push-check')) {
268
+ engine.register({
269
+ name: 'on-push-check',
270
+ hookType: 'on-push-check',
271
+ priority: 150,
272
+ execute: async (event) => {
273
+ await handleOnPushCheck(event, projectPath);
274
+ const pushResult = getLastPushCheckResult(projectPath);
275
+ const findings = pushResult?.findings ?? [];
276
+ const driftWarnings = findings
277
+ .filter((f) => f.severity === 'warning')
278
+ .map((f) => f.message);
279
+ const HIGH_SEVERITY = ['critical', 'high'];
280
+ return {
281
+ hook: 'on-commit',
282
+ commitHash: event.path,
283
+ reconciledSpecs: [],
284
+ integrityResult: {
285
+ valid: findings.every((f) => !HIGH_SEVERITY.includes(f.severity)),
286
+ errors: findings
287
+ .filter((f) => HIGH_SEVERITY.includes(f.severity))
288
+ .map((f) => f.message),
289
+ },
290
+ driftWarnings,
291
+ };
292
+ },
293
+ });
294
+ }
295
+ if (enabledHooks.includes('on-security-check')) {
296
+ engine.register({
297
+ name: 'on-security-check',
298
+ hookType: 'on-security-check',
299
+ priority: 250,
300
+ execute: async (event) => {
301
+ await handleOnSecurityCheck(event, projectPath);
302
+ const isSensitive = isSecuritySensitiveFile(event.path);
303
+ return {
304
+ hook: 'on-save',
305
+ specId: null,
306
+ driftDelta: 0,
307
+ hashChanged: event.type !== 'delete',
308
+ annotationsValid: !isSensitive,
309
+ };
310
+ },
311
+ });
312
+ }
313
+ }
314
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/tools/start-hooks/engine.ts"],"names":[],"mappings":"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"}
@@ -1,24 +1,3 @@
1
- import type { ToolResult } from '../types/index.js';
2
- import type { StartHooksInput, StopHooksInput, ConfigureHooksInput } from '../types/file-hooks.js';
3
- import { HookEngine } from '../engine/hooks/hook-engine.js';
4
- import { FileWatcher } from '../engine/hooks/file-watcher.js';
5
- /**
6
- * Get the current engine instance (for testing/internal use).
7
- */
8
- export declare function getEngineInstance(): HookEngine | null;
9
- /**
10
- * Auto-start hook engine if not running. Called transparently from the tool
11
- * pipeline whenever a tool receives a projectPath arg. Idempotent and
12
- * fire-and-forget — errors are silently swallowed so tool execution is never
13
- * blocked by hook startup failures.
14
- */
15
- export declare function ensureHooksStarted(projectPath: string): void;
16
- /**
17
- * Get the current watcher instance (for testing/internal use).
18
- */
19
- export declare function getWatcherInstance(): FileWatcher | null;
20
- export declare function handleStartHooks(args: StartHooksInput): Promise<ToolResult>;
21
- export declare function handleStopHooks(_args: StopHooksInput): Promise<ToolResult>;
22
- export declare function handleHookStatus(): Promise<ToolResult>;
23
- export declare function handleConfigureHooks(args: ConfigureHooksInput): Promise<ToolResult>;
1
+ export { getEngineInstance, getWatcherInstance, getConfigLoaderInstance, ensureHooksStarted, handleStartHooks, handleStopHooks, handleHookStatus, } from './start-hooks/engine.js';
2
+ export { handleConfigureHooks } from './start-hooks/configure.js';
24
3
  //# sourceMappingURL=start-hooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"start-hooks.d.ts","sourceRoot":"","sources":["../../src/tools/start-hooks.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAmC,MAAM,mBAAmB,CAAC;AACrF,OAAO,KAAK,EAGV,eAAe,EACf,cAAc,EACd,mBAAmB,EAGpB,MAAM,wBAAwB,CAAC;AAKhC,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAE5D,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AA2B9D;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,UAAU,GAAG,IAAI,CAErD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAoB5D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,WAAW,GAAG,IAAI,CAEvD;AAMD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CAwOjF;AA0ED,wBAAsB,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAuBhF;AAMD,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,UAAU,CAAC,CAqC5D;AAMD,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAoDzF"}
1
+ {"version":3,"file":"start-hooks.d.ts","sourceRoot":"","sources":["../../src/tools/start-hooks.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -1,517 +1,5 @@
1
- // tools/start-hooks.ts — Start file watcher + hook engine (SPEC-130)
2
- import { readFile, writeFile, mkdir } from 'node:fs/promises';
3
- import { join } from 'node:path';
4
- import { generateHookTemplate, mergeHookConfig } from '../engine/hooks/hook-templates.js';
5
- import { buildPlanModeHookScripts } from '../engine/hooks/plan-mode-scripts.js';
6
- import { HookEngine } from '../engine/hooks/hook-engine.js';
7
- import { EventBus } from '../engine/hooks/event-bus.js';
8
- import { FileWatcher } from '../engine/hooks/file-watcher.js';
9
- import { ConfigLoader } from '../engine/hooks/config-loader.js';
10
- import { Debouncer } from '../engine/hooks/debouncer.js';
11
- import { handleOnImplChange } from '../engine/hooks/handlers/on-impl-change.js';
12
- import { handleOnSpecChange } from '../engine/hooks/handlers/on-spec-change.js';
13
- import { handleOnPushCheck, getLastPushCheckResult, } from '../engine/hooks/handlers/on-push-check.js';
14
- import { handleOnSecurityCheck, isSecuritySensitiveFile, } from '../engine/hooks/handlers/on-security-check.js';
15
- import { subscribeStatusChangeHandler } from '../engine/hooks/handlers/on-status-change.js';
16
- import { listSpecs } from '../storage/spec-store.js';
17
- import { hashProjectPath } from '../storage/base-store.js';
18
- import { analyzeLivingSpec } from '../engine/living-spec-analyzer.js';
19
- // ---------------------------------------------------------------------------
20
- // Singleton state
21
- // ---------------------------------------------------------------------------
22
- let engineInstance = null;
23
- let watcherInstance = null;
24
- let debouncerInstance = null;
25
- let configLoaderInstance = null;
26
- /**
27
- * Get the current engine instance (for testing/internal use).
28
- */
29
- export function getEngineInstance() {
30
- return engineInstance;
31
- }
32
- /**
33
- * Auto-start hook engine if not running. Called transparently from the tool
34
- * pipeline whenever a tool receives a projectPath arg. Idempotent and
35
- * fire-and-forget — errors are silently swallowed so tool execution is never
36
- * blocked by hook startup failures.
37
- */
38
- export function ensureHooksStarted(projectPath) {
39
- if (engineInstance?.status().running) {
40
- return;
41
- }
42
- // Fire-and-forget — don't block the tool call
43
- void handleStartHooks({
44
- projectPath,
45
- hooks: [
46
- 'on-save',
47
- 'on-create',
48
- 'on-delete',
49
- 'on-commit',
50
- 'on-impl-change',
51
- 'on-spec-change',
52
- 'on-push-check',
53
- 'on-security-check',
54
- ],
55
- }).catch(() => {
56
- // Silently swallow — hooks are best-effort
57
- });
58
- }
59
- /**
60
- * Get the current watcher instance (for testing/internal use).
61
- */
62
- export function getWatcherInstance() {
63
- return watcherInstance;
64
- }
65
- // ---------------------------------------------------------------------------
66
- // Start hooks
67
- // ---------------------------------------------------------------------------
68
- export async function handleStartHooks(args) {
69
- // Idempotent — if already running, return status
70
- if (engineInstance?.status().running) {
71
- const status = engineInstance.status();
72
- return {
73
- content: [
74
- {
75
- type: 'text',
76
- text: JSON.stringify({
77
- message: 'Hook engine already running',
78
- ...status,
79
- }, null, 2),
80
- },
81
- ],
82
- };
83
- }
84
- const projectPath = args.projectPath;
85
- const enabledHooks = args.hooks ?? [
86
- 'on-save',
87
- 'on-create',
88
- 'on-delete',
89
- 'on-impl-change',
90
- 'on-spec-change',
91
- 'on-security-check',
92
- ];
93
- // Load config
94
- configLoaderInstance = new ConfigLoader(projectPath);
95
- const config = await configLoaderInstance.load();
96
- // Create event bus and engine
97
- const eventBus = new EventBus();
98
- engineInstance = new HookEngine(eventBus);
99
- // Create file watcher
100
- watcherInstance = new FileWatcher({
101
- rootDir: projectPath,
102
- include: config.hooks['on-save']?.include,
103
- exclude: config.hooks['on-save']?.exclude,
104
- });
105
- // Create debouncer
106
- debouncerInstance = new Debouncer((event) => {
107
- const hookTypes = getApplicableHookTypes(event);
108
- for (const hookType of hookTypes) {
109
- if (enabledHooks.includes(hookType)) {
110
- void engineInstance?.dispatch(event, hookType);
111
- }
112
- }
113
- }, {
114
- debounceMs: config.debounceMs,
115
- rateLimitPerFileMs: config.rateLimitPerFileMs,
116
- });
117
- // Wire watcher -> debouncer
118
- watcherInstance.on('change', (event) => {
119
- eventBus.emitEvent('file:change', {
120
- path: event.path,
121
- type: event.type,
122
- timestamp: event.timestamp,
123
- });
124
- debouncerInstance?.push(event);
125
- });
126
- // Start watching config for live reload
127
- configLoaderInstance.startWatching();
128
- // Start engine and watcher
129
- engineInstance.start();
130
- watcherInstance.start();
131
- // ---------------------------------------------------------------------------
132
- // Register SPEC-137/138 handlers as HookPluginHandlers
133
- // ---------------------------------------------------------------------------
134
- const registerAdvancedHandlers = () => {
135
- /* v8 ignore next 3 */
136
- if (!engineInstance) {
137
- return;
138
- }
139
- // SPEC-137: on-impl-change — analyze implementation changes + auto-done
140
- if (enabledHooks.includes('on-impl-change')) {
141
- engineInstance.register({
142
- name: 'on-impl-change',
143
- hookType: 'on-impl-change',
144
- priority: 200,
145
- execute: async (event) => {
146
- const projectId = hashProjectPath(projectPath);
147
- let specs = [];
148
- try {
149
- const fullSpecs = await listSpecs(projectId);
150
- specs = fullSpecs.map(specToMinimal);
151
- }
152
- catch {
153
- // Spec load failure — proceed without analysis
154
- }
155
- const analysisResult = await handleOnImplChange(event, projectPath, specs, makeAnalyzeSpecFn(), config.autoMarkDone !== false);
156
- // Use the first analyzed spec's ID if available; null means no related spec was found.
157
- const firstSpecId = analysisResult
158
- ? (analysisResult.specsAnalyzed[0]?.specId ?? null)
159
- : null;
160
- return {
161
- hook: 'on-save',
162
- specId: firstSpecId,
163
- // driftDelta = number of specs analyzed (0 = no drift detected or file not relevant)
164
- driftDelta: analysisResult ? analysisResult.specsAnalyzed.length : 0,
165
- // hashChanged: true whenever a source file was actually modified (not a no-op event)
166
- hashChanged: event.type === 'modify' || event.type === 'create',
167
- annotationsValid: analysisResult !== undefined,
168
- };
169
- },
170
- });
171
- }
172
- // SPEC-137: on-spec-change — detect spec file edits
173
- if (enabledHooks.includes('on-spec-change')) {
174
- engineInstance.register({
175
- name: 'on-spec-change',
176
- hookType: 'on-spec-change',
177
- priority: 300,
178
- execute: async (event) => {
179
- await handleOnSpecChange(event, projectPath);
180
- return {
181
- hook: 'on-save',
182
- specId: null,
183
- // A spec file was saved — the hash of spec content is considered changed.
184
- driftDelta: 0,
185
- hashChanged: event.type !== 'delete',
186
- annotationsValid: true,
187
- };
188
- },
189
- });
190
- }
191
- // SPEC-138: on-push-check — drift detection on commits
192
- if (enabledHooks.includes('on-push-check')) {
193
- engineInstance.register({
194
- name: 'on-push-check',
195
- hookType: 'on-push-check',
196
- priority: 150,
197
- execute: async (event) => {
198
- await handleOnPushCheck(event, projectPath);
199
- // Retrieve the push-check result written by the handler for real data.
200
- const pushResult = getLastPushCheckResult(projectPath);
201
- const findings = pushResult?.findings ?? [];
202
- const driftWarnings = findings
203
- .filter((f) => f.severity === 'warning')
204
- .map((f) => f.message);
205
- const HIGH_SEVERITY = ['critical', 'high'];
206
- return {
207
- hook: 'on-commit',
208
- commitHash: event.path, // most accurate commit identifier available from the event
209
- reconciledSpecs: [],
210
- integrityResult: {
211
- valid: findings.every((f) => !HIGH_SEVERITY.includes(f.severity)),
212
- errors: findings
213
- .filter((f) => HIGH_SEVERITY.includes(f.severity))
214
- .map((f) => f.message),
215
- },
216
- driftWarnings,
217
- };
218
- },
219
- });
220
- }
221
- // SPEC-138: on-security-check — detect security-sensitive changes
222
- if (enabledHooks.includes('on-security-check')) {
223
- engineInstance.register({
224
- name: 'on-security-check',
225
- hookType: 'on-security-check',
226
- priority: 250,
227
- execute: async (event) => {
228
- await handleOnSecurityCheck(event, projectPath);
229
- // annotationsValid = false when the file is security-sensitive, triggering downstream review.
230
- const isSensitive = isSecuritySensitiveFile(event.path);
231
- return {
232
- hook: 'on-save',
233
- specId: null,
234
- driftDelta: 0,
235
- hashChanged: event.type !== 'delete',
236
- annotationsValid: !isSensitive,
237
- };
238
- },
239
- });
240
- }
241
- };
242
- registerAdvancedHandlers();
243
- // SPEC-137: Subscribe on-status-change to EventBus for dashboard regeneration
244
- const eventBusFromEngine = engineInstance.getEventBus();
245
- subscribeStatusChangeHandler(eventBusFromEngine,
246
- /* v8 ignore next 3 */ (_projectId) => {
247
- // Dashboard regeneration is handled by the existing update-status tool flow
248
- return Promise.resolve(true);
249
- });
250
- return {
251
- content: [
252
- {
253
- type: 'text',
254
- text: JSON.stringify({
255
- message: 'Hook engine started',
256
- projectPath,
257
- enabledHooks,
258
- config: {
259
- debounceMs: config.debounceMs,
260
- rateLimitPerFileMs: config.rateLimitPerFileMs,
261
- },
262
- }, null, 2),
263
- },
264
- ],
265
- };
266
- }
267
- // ---------------------------------------------------------------------------
268
- // Helpers
269
- // ---------------------------------------------------------------------------
270
- function getApplicableHookTypes(event) {
271
- switch (event.type) {
272
- case 'modify':
273
- return ['on-save', 'on-impl-change', 'on-spec-change', 'on-security-check'];
274
- case 'create':
275
- return ['on-create', 'on-impl-change', 'on-spec-change', 'on-security-check'];
276
- case 'delete':
277
- return ['on-delete'];
278
- /* v8 ignore next 2 */
279
- default:
280
- return [];
281
- }
282
- }
283
- // ---------------------------------------------------------------------------
284
- // Spec analysis helpers
285
- // ---------------------------------------------------------------------------
286
- /**
287
- * Convert a full Spec to the minimal shape required by handleOnImplChange.
288
- * criterionPaths is not on Spec, so it is omitted (defaults to undefined).
289
- */
290
- function specToMinimal(spec) {
291
- return {
292
- id: spec.id,
293
- title: spec.title,
294
- status: spec.status,
295
- progressPath: spec.progressPath,
296
- };
297
- }
298
- /**
299
- * Build an AnalyzeSpecFn that delegates to living-spec-analyzer.
300
- * Adapts the full analyzeLivingSpec return type to AnalyzeSpecFnResult.
301
- */
302
- function makeAnalyzeSpecFn() {
303
- return async (minimal, projectPath) => {
304
- // Build a minimal Spec shape — living-spec-analyzer only needs id, title, slug, progressPath
305
- const specLike = {
306
- id: minimal.id,
307
- title: minimal.title,
308
- slug: minimal.id
309
- .toLowerCase()
310
- .replace(/^spec-/, '')
311
- .replace(/\s+/g, '-'),
312
- status: minimal.status,
313
- progressPath: minimal.progressPath,
314
- };
315
- const report = await analyzeLivingSpec(specLike, projectPath);
316
- return {
317
- completionPct: report.completionPercent,
318
- progressUpdated: report.progressUpdated,
319
- criterionResults: report.criteria.map((c) => ({
320
- criterion: c.criterion,
321
- met: c.status === 'met',
322
- evidence: c.evidence,
323
- })),
324
- };
325
- };
326
- }
327
- // ---------------------------------------------------------------------------
328
- // Stop hooks
329
- // ---------------------------------------------------------------------------
330
- export async function handleStopHooks(_args) {
331
- await Promise.resolve(); // Ensure async for safeLicensed wrapper
332
- if (!engineInstance) {
333
- return {
334
- content: [{ type: 'text', text: JSON.stringify({ message: 'Hook engine not running' }) }],
335
- };
336
- }
337
- engineInstance.stop();
338
- watcherInstance?.close();
339
- debouncerInstance?.dispose();
340
- configLoaderInstance?.close();
341
- const message = 'Hook engine stopped and resources cleaned up';
342
- engineInstance = null;
343
- watcherInstance = null;
344
- debouncerInstance = null;
345
- configLoaderInstance = null;
346
- return {
347
- content: [{ type: 'text', text: JSON.stringify({ message }) }],
348
- };
349
- }
350
- // ---------------------------------------------------------------------------
351
- // Hook status
352
- // ---------------------------------------------------------------------------
353
- export async function handleHookStatus() {
354
- await Promise.resolve(); // Ensure async for safeLicensed wrapper
355
- if (!engineInstance) {
356
- return {
357
- content: [
358
- {
359
- type: 'text',
360
- text: JSON.stringify({
361
- running: false,
362
- activeHooks: [],
363
- pendingEvents: 0,
364
- telemetry: {},
365
- eventHistory: 0,
366
- }),
367
- },
368
- ],
369
- };
370
- }
371
- const status = engineInstance.status();
372
- const eventBus = engineInstance.getEventBus();
373
- return {
374
- content: [
375
- {
376
- type: 'text',
377
- text: JSON.stringify({
378
- ...status,
379
- eventHistory: eventBus.getFullHistory().length,
380
- }, null, 2),
381
- },
382
- ],
383
- };
384
- }
385
- // ---------------------------------------------------------------------------
386
- // Configure hooks
387
- // ---------------------------------------------------------------------------
388
- export async function handleConfigureHooks(args) {
389
- // SPEC-262 — Plan Mode integration action
390
- if (args.action === 'enable-plan-mode-integration') {
391
- return enablePlanModeIntegration(args.projectPath);
392
- }
393
- // SPEC-258 — Template mode: generate + merge into .claude/settings.json
394
- if (args.template) {
395
- return applyHookTemplate(args);
396
- }
397
- if (!configLoaderInstance) {
398
- // Not running — just load and report current config
399
- const loader = new ConfigLoader(args.projectPath);
400
- const config = await loader.load();
401
- loader.close();
402
- return {
403
- content: [
404
- {
405
- type: 'text',
406
- text: JSON.stringify({
407
- message: 'Hook engine not running. Current config:',
408
- config,
409
- }, null, 2),
410
- },
411
- ],
412
- };
413
- }
414
- // Reload config
415
- const config = await configLoaderInstance.load();
416
- return {
417
- content: [
418
- {
419
- type: 'text',
420
- text: JSON.stringify({
421
- message: 'Configuration reloaded',
422
- config,
423
- engineRunning: engineInstance?.status().running ?? false,
424
- }, null, 2),
425
- },
426
- ],
427
- };
428
- }
429
- // ---------------------------------------------------------------------------
430
- // SPEC-262 — Enable Plan Mode integration via Claude Code hooks
431
- // ---------------------------------------------------------------------------
432
- async function enablePlanModeIntegration(projectPath) {
433
- const hooksDir = join(projectPath, '.claude', 'hooks');
434
- await mkdir(hooksDir, { recursive: true });
435
- const scripts = buildPlanModeHookScripts();
436
- const preHookPath = join(hooksDir, 'planu-pre-plan.sh');
437
- const postHookPath = join(hooksDir, 'planu-post-plan.sh');
438
- await writeFile(preHookPath, scripts.preScript, { mode: 0o755 });
439
- await writeFile(postHookPath, scripts.postScript, { mode: 0o755 });
440
- // Merge PreToolUse / PostToolUse entries into .claude/settings.json
441
- const settingsPath = join(projectPath, '.claude', 'settings.json');
442
- let existing = {};
443
- try {
444
- const raw = await readFile(settingsPath, 'utf-8');
445
- existing = JSON.parse(raw);
446
- }
447
- catch {
448
- // File doesn't exist yet — start from empty
449
- }
450
- const preEntry = {
451
- matcher: 'Task',
452
- hooks: [{ type: 'command', command: `bash "${preHookPath}"` }],
453
- };
454
- const postEntry = {
455
- matcher: 'exit_plan_mode',
456
- hooks: [{ type: 'command', command: `bash "${postHookPath}"` }],
457
- };
458
- const existingHooks = (existing.hooks ?? {});
459
- const merged = {
460
- ...existing,
461
- hooks: {
462
- ...existingHooks,
463
- PreToolUse: [...(existingHooks.PreToolUse ?? []), preEntry],
464
- PostToolUse: [...(existingHooks.PostToolUse ?? []), postEntry],
465
- },
466
- };
467
- await writeFile(settingsPath, JSON.stringify(merged, null, 2) + '\n', 'utf-8');
468
- const result = {
469
- action: 'enable-plan-mode-integration',
470
- preHookPath,
471
- postHookPath,
472
- settingsPath,
473
- message: 'Plan Mode integration enabled. Planu context will be injected automatically when Claude enters Plan Mode.',
474
- };
475
- return {
476
- content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
477
- };
478
- }
479
- // ---------------------------------------------------------------------------
480
- // SPEC-258 — Apply Claude Code hook template to .claude/settings.json
481
- // ---------------------------------------------------------------------------
482
- async function applyHookTemplate(args) {
483
- /* c8 ignore next 3 */
484
- if (!args.template) {
485
- return { content: [{ type: 'text', text: 'template is required' }], isError: true };
486
- }
487
- const generated = generateHookTemplate({
488
- template: args.template,
489
- notificationMatcher: args.notificationMatcher,
490
- });
491
- const settingsPath = join(args.projectPath, '.claude', 'settings.json');
492
- let existing = {};
493
- try {
494
- const raw = await readFile(settingsPath, 'utf-8');
495
- existing = JSON.parse(raw);
496
- }
497
- catch {
498
- // File doesn't exist yet or is not valid JSON — start from empty object
499
- }
500
- const merged = mergeHookConfig(existing, generated);
501
- await writeFile(settingsPath, JSON.stringify(merged, null, 2) + '\n', 'utf-8');
502
- return {
503
- content: [
504
- {
505
- type: 'text',
506
- text: JSON.stringify({
507
- message: `Hook template '${args.template}' applied`,
508
- settingsPath,
509
- description: generated.description,
510
- mergeInstructions: generated.mergeInstructions,
511
- generatedConfig: generated.hooks,
512
- }, null, 2),
513
- },
514
- ],
515
- };
516
- }
1
+ // tools/start-hooks.ts — Barrel re-export. Implementation split into start-hooks/ subdirectory.
2
+ // Existing imports (register-hooks-tools.ts, safe-handler.ts) continue to work unchanged.
3
+ export { getEngineInstance, getWatcherInstance, getConfigLoaderInstance, ensureHooksStarted, handleStartHooks, handleStopHooks, handleHookStatus, } from './start-hooks/engine.js';
4
+ export { handleConfigureHooks } from './start-hooks/configure.js';
517
5
  //# sourceMappingURL=start-hooks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"start-hooks.js","sourceRoot":"","sources":["../../src/tools/start-hooks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"start-hooks.js","sourceRoot":"","sources":["../../src/tools/start-hooks.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,0FAA0F;AAE1F,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planu/cli",
3
- "version": "0.97.0",
3
+ "version": "0.97.1",
4
4
  "description": "Planu — MCP Server for Spec Driven Development. Manages specs, estimations, reverse engineering, and auto-learning across any language/framework.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",