specweave 1.0.551 → 1.0.552
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/bin/specweave.js +23 -1
- package/dist/src/cli/commands/hook.d.ts +15 -0
- package/dist/src/cli/commands/hook.d.ts.map +1 -0
- package/dist/src/cli/commands/hook.js +61 -0
- package/dist/src/cli/commands/hook.js.map +1 -0
- package/dist/src/config/types.d.ts +2 -2
- package/dist/src/core/hooks/handlers/hook-router.d.ts +19 -0
- package/dist/src/core/hooks/handlers/hook-router.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/hook-router.js +75 -0
- package/dist/src/core/hooks/handlers/hook-router.js.map +1 -0
- package/dist/src/core/hooks/handlers/index.d.ts +10 -0
- package/dist/src/core/hooks/handlers/index.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/index.js +9 -0
- package/dist/src/core/hooks/handlers/index.js.map +1 -0
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.d.ts +11 -0
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.js +73 -0
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.js.map +1 -0
- package/dist/src/core/hooks/handlers/post-tool-use.d.ts +11 -0
- package/dist/src/core/hooks/handlers/post-tool-use.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/post-tool-use.js +76 -0
- package/dist/src/core/hooks/handlers/post-tool-use.js.map +1 -0
- package/dist/src/core/hooks/handlers/pre-compact.d.ts +11 -0
- package/dist/src/core/hooks/handlers/pre-compact.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/pre-compact.js +77 -0
- package/dist/src/core/hooks/handlers/pre-compact.js.map +1 -0
- package/dist/src/core/hooks/handlers/pre-tool-use.d.ts +11 -0
- package/dist/src/core/hooks/handlers/pre-tool-use.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/pre-tool-use.js +318 -0
- package/dist/src/core/hooks/handlers/pre-tool-use.js.map +1 -0
- package/dist/src/core/hooks/handlers/session-start.d.ts +9 -0
- package/dist/src/core/hooks/handlers/session-start.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/session-start.js +111 -0
- package/dist/src/core/hooks/handlers/session-start.js.map +1 -0
- package/dist/src/core/hooks/handlers/stop-auto.d.ts +16 -0
- package/dist/src/core/hooks/handlers/stop-auto.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/stop-auto.js +122 -0
- package/dist/src/core/hooks/handlers/stop-auto.js.map +1 -0
- package/dist/src/core/hooks/handlers/stop-reflect.d.ts +14 -0
- package/dist/src/core/hooks/handlers/stop-reflect.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/stop-reflect.js +43 -0
- package/dist/src/core/hooks/handlers/stop-reflect.js.map +1 -0
- package/dist/src/core/hooks/handlers/stop-sync.d.ts +15 -0
- package/dist/src/core/hooks/handlers/stop-sync.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/stop-sync.js +68 -0
- package/dist/src/core/hooks/handlers/stop-sync.js.map +1 -0
- package/dist/src/core/hooks/handlers/types.d.ts +63 -0
- package/dist/src/core/hooks/handlers/types.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/types.js +27 -0
- package/dist/src/core/hooks/handlers/types.js.map +1 -0
- package/dist/src/core/hooks/handlers/user-prompt-submit.d.ts +14 -0
- package/dist/src/core/hooks/handlers/user-prompt-submit.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/user-prompt-submit.js +173 -0
- package/dist/src/core/hooks/handlers/user-prompt-submit.js.map +1 -0
- package/dist/src/core/hooks/handlers/utils.d.ts +25 -0
- package/dist/src/core/hooks/handlers/utils.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/utils.js +64 -0
- package/dist/src/core/hooks/handlers/utils.js.map +1 -0
- package/dist/src/init/research/types.d.ts +1 -1
- package/dist/src/sync/sync-target-resolver.js.map +1 -1
- package/dist/src/utils/lock-manager.d.ts.map +1 -1
- package/dist/src/utils/lock-manager.js +5 -0
- package/dist/src/utils/lock-manager.js.map +1 -1
- package/dist/src/utils/plugin-copier.d.ts.map +1 -1
- package/dist/src/utils/plugin-copier.js +3 -30
- package/dist/src/utils/plugin-copier.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/hooks/hooks.json +10 -10
- package/plugins/specweave/hooks/README.md +0 -493
- package/plugins/specweave/hooks/_archive/stop-auto-v4-legacy.sh +0 -1319
- package/plugins/specweave/hooks/lib/common-setup.sh +0 -144
- package/plugins/specweave/hooks/lib/hook-errors.sh +0 -414
- package/plugins/specweave/hooks/lib/migrate-increment-work.sh +0 -245
- package/plugins/specweave/hooks/lib/resolve-package.sh +0 -146
- package/plugins/specweave/hooks/lib/scheduler-startup.sh +0 -135
- package/plugins/specweave/hooks/lib/score-increment.sh +0 -87
- package/plugins/specweave/hooks/lib/sync-spec-content.sh +0 -193
- package/plugins/specweave/hooks/lib/update-active-increment.sh +0 -95
- package/plugins/specweave/hooks/lib/update-status-line.sh +0 -233
- package/plugins/specweave/hooks/lib/validate-spec-status.sh +0 -171
- package/plugins/specweave/hooks/llm-judge-validator.sh +0 -219
- package/plugins/specweave/hooks/log-decision.sh +0 -168
- package/plugins/specweave/hooks/pre-compact.sh +0 -64
- package/plugins/specweave/hooks/startup-health-check.sh +0 -64
- package/plugins/specweave/hooks/stop-auto-v5.sh +0 -276
- package/plugins/specweave/hooks/stop-reflect.sh +0 -336
- package/plugins/specweave/hooks/stop-sync.sh +0 -283
- package/plugins/specweave/hooks/tests/test-auto-context-integration.sh +0 -126
- package/plugins/specweave/hooks/tests/test-stop-auto-enriched.sh +0 -128
- package/plugins/specweave/hooks/universal/dispatcher.mjs +0 -336
- package/plugins/specweave/hooks/universal/fail-fast-wrapper.sh +0 -325
- package/plugins/specweave/hooks/universal/hook-wrapper.cmd +0 -26
- package/plugins/specweave/hooks/universal/hook-wrapper.sh +0 -69
- package/plugins/specweave/hooks/universal/run-hook.sh +0 -20
- package/plugins/specweave/hooks/universal/session-start.cmd +0 -16
- package/plugins/specweave/hooks/universal/session-start.ps1 +0 -16
- package/plugins/specweave/hooks/user-prompt-submit.sh +0 -2550
- package/plugins/specweave/hooks/v2/detectors/lifecycle-detector.sh +0 -87
- package/plugins/specweave/hooks/v2/detectors/us-completion-detector.sh +0 -186
- package/plugins/specweave/hooks/v2/dispatchers/post-tool-use-analytics.sh +0 -83
- package/plugins/specweave/hooks/v2/dispatchers/post-tool-use.sh +0 -447
- package/plugins/specweave/hooks/v2/dispatchers/pre-tool-use.sh +0 -104
- package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +0 -270
- package/plugins/specweave/hooks/v2/guards/completion-guard.sh +0 -14
- package/plugins/specweave/hooks/v2/guards/increment-duplicate-guard.sh +0 -14
- package/plugins/specweave/hooks/v2/guards/increment-existence-guard.sh +0 -240
- package/plugins/specweave/hooks/v2/guards/interview-enforcement-guard.sh +0 -171
- package/plugins/specweave/hooks/v2/guards/metadata-json-guard.sh +0 -14
- package/plugins/specweave/hooks/v2/guards/skill-chain-enforcement-guard.sh +0 -222
- package/plugins/specweave/hooks/v2/guards/spec-template-enforcement-guard.sh +0 -21
- package/plugins/specweave/hooks/v2/guards/spec-validation-guard.sh +0 -14
- package/plugins/specweave/hooks/v2/guards/status-completion-guard.sh +0 -84
- package/plugins/specweave/hooks/v2/guards/task-ac-sync-guard.sh +0 -475
- package/plugins/specweave/hooks/v2/guards/tdd-enforcement-guard.sh +0 -268
- package/plugins/specweave/hooks/v2/handlers/ac-sync-dispatcher.sh +0 -332
- package/plugins/specweave/hooks/v2/handlers/ac-validation-handler.sh +0 -50
- package/plugins/specweave/hooks/v2/handlers/github-sync-handler.sh +0 -347
- package/plugins/specweave/hooks/v2/handlers/living-docs-handler.sh +0 -83
- package/plugins/specweave/hooks/v2/handlers/living-specs-handler.sh +0 -268
- package/plugins/specweave/hooks/v2/handlers/project-bridge-handler.sh +0 -104
- package/plugins/specweave/hooks/v2/handlers/status-line-handler.sh +0 -165
- package/plugins/specweave/hooks/v2/handlers/status-update.sh +0 -61
- package/plugins/specweave/hooks/v2/handlers/universal-auto-create-dispatcher.sh +0 -270
- package/plugins/specweave/hooks/v2/integrations/ado-post-living-docs-update.sh +0 -367
- package/plugins/specweave/hooks/v2/integrations/ado-post-task.sh +0 -179
- package/plugins/specweave/hooks/v2/integrations/github-auto-create-handler.sh +0 -553
- package/plugins/specweave/hooks/v2/integrations/github-post-task.sh +0 -345
- package/plugins/specweave/hooks/v2/integrations/jira-post-task.sh +0 -180
- package/plugins/specweave/hooks/v2/lib/check-provider-enabled.sh +0 -52
- package/plugins/specweave/hooks/v2/queue/enqueue.sh +0 -81
- package/plugins/specweave/hooks/v2/session-end.sh +0 -139
- package/plugins/specweave/hooks/validate-skill-activations.sh +0 -227
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PreToolUse hook handler — inlines all guard logic:
|
|
3
|
+
* 1. Status Completion Guard (Edit metadata.json → "completed")
|
|
4
|
+
* 2. Interview Enforcement Guard (Write spec.md with strict interview)
|
|
5
|
+
* 3. Increment Existence Guard (TeamCreate without valid spec)
|
|
6
|
+
*
|
|
7
|
+
* @module core/hooks/handlers/pre-tool-use
|
|
8
|
+
*/
|
|
9
|
+
import * as fs from 'fs';
|
|
10
|
+
import * as path from 'path';
|
|
11
|
+
const ALLOW = { decision: 'allow' };
|
|
12
|
+
const TEMPLATE_MARKERS = [
|
|
13
|
+
'[Story Title]',
|
|
14
|
+
'[user type]',
|
|
15
|
+
'[goal]',
|
|
16
|
+
'[benefit]',
|
|
17
|
+
'[Specific, testable criterion]',
|
|
18
|
+
'[Component 1]',
|
|
19
|
+
'[High-level description',
|
|
20
|
+
'{{RESOLVED_PROJECT}}',
|
|
21
|
+
'TEMPLATE FILE',
|
|
22
|
+
];
|
|
23
|
+
const DEFAULT_INTERVIEW_CATEGORIES = [
|
|
24
|
+
'architecture',
|
|
25
|
+
'integrations',
|
|
26
|
+
'ui-ux',
|
|
27
|
+
'performance',
|
|
28
|
+
'security',
|
|
29
|
+
'edge-cases',
|
|
30
|
+
];
|
|
31
|
+
const NON_IMPL_PREFIXES = [
|
|
32
|
+
'review-',
|
|
33
|
+
'brainstorm-',
|
|
34
|
+
'analysis-',
|
|
35
|
+
'audit-',
|
|
36
|
+
'explore-',
|
|
37
|
+
'ideate-',
|
|
38
|
+
'research-',
|
|
39
|
+
'plan-',
|
|
40
|
+
];
|
|
41
|
+
const NON_IMPL_KEYWORDS = [
|
|
42
|
+
'review',
|
|
43
|
+
'brainstorm',
|
|
44
|
+
'analyze',
|
|
45
|
+
'audit',
|
|
46
|
+
'explore',
|
|
47
|
+
'ideate',
|
|
48
|
+
'pull request',
|
|
49
|
+
'pr #',
|
|
50
|
+
'pr review',
|
|
51
|
+
'code review',
|
|
52
|
+
'architecture review',
|
|
53
|
+
'security audit',
|
|
54
|
+
'performance audit',
|
|
55
|
+
'code audit',
|
|
56
|
+
'ideation',
|
|
57
|
+
'exploration',
|
|
58
|
+
'research',
|
|
59
|
+
'planning',
|
|
60
|
+
'perspectives',
|
|
61
|
+
"devil's advocate",
|
|
62
|
+
'pros and cons',
|
|
63
|
+
];
|
|
64
|
+
function getToolName(input) {
|
|
65
|
+
return (input.tool_name ?? input.toolName ?? '');
|
|
66
|
+
}
|
|
67
|
+
function getToolInput(input) {
|
|
68
|
+
return (input.tool_input ?? input.toolInput ?? {});
|
|
69
|
+
}
|
|
70
|
+
function getFilePath(input) {
|
|
71
|
+
const ti = getToolInput(input);
|
|
72
|
+
return (ti.file_path ?? '');
|
|
73
|
+
}
|
|
74
|
+
function isIncrementFile(filePath) {
|
|
75
|
+
return filePath.includes('.specweave/increments/');
|
|
76
|
+
}
|
|
77
|
+
function extractIncrementId(filePath) {
|
|
78
|
+
const match = filePath.match(/(\d{4}[E]?-[^/]+)/);
|
|
79
|
+
return match ? match[1] : 'unknown';
|
|
80
|
+
}
|
|
81
|
+
function readJsonSafe(filePath) {
|
|
82
|
+
try {
|
|
83
|
+
if (!fs.existsSync(filePath))
|
|
84
|
+
return {};
|
|
85
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return {};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// Guard: Status Completion (Edit metadata.json → "completed")
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
function checkStatusCompletionGuard(input, context) {
|
|
95
|
+
const ti = getToolInput(input);
|
|
96
|
+
const filePath = getFilePath(input);
|
|
97
|
+
const newString = (ti.new_string ?? '');
|
|
98
|
+
// Only care about metadata.json in increments
|
|
99
|
+
if (!filePath.match(/\.specweave\/increments\/.*\/metadata\.json$/)) {
|
|
100
|
+
return ALLOW;
|
|
101
|
+
}
|
|
102
|
+
// Check if setting status to "completed"
|
|
103
|
+
if (!/"status"\s*:\s*"completed"/.test(newString)) {
|
|
104
|
+
return ALLOW;
|
|
105
|
+
}
|
|
106
|
+
// Allow if sw-done marker exists
|
|
107
|
+
const doneMarker = path.join(context.stateDir, '.sw-done-in-progress');
|
|
108
|
+
if (fs.existsSync(doneMarker)) {
|
|
109
|
+
return ALLOW;
|
|
110
|
+
}
|
|
111
|
+
// Allow if auto-mode active with testsVerified
|
|
112
|
+
const autoSession = path.join(context.stateDir, 'auto', 'session.json');
|
|
113
|
+
if (fs.existsSync(autoSession)) {
|
|
114
|
+
const session = readJsonSafe(autoSession);
|
|
115
|
+
if (session.status === 'active' && session.testsVerified === true) {
|
|
116
|
+
return ALLOW;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const incrementId = extractIncrementId(filePath);
|
|
120
|
+
return {
|
|
121
|
+
decision: 'block',
|
|
122
|
+
reason: `Direct status change to 'completed' is blocked for ${incrementId}. Use /sw:done or /sw:auto instead.`,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
// Guard: Interview Enforcement (Write spec.md with strict interview)
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
function checkInterviewGuard(input, context) {
|
|
129
|
+
const filePath = getFilePath(input);
|
|
130
|
+
const ti = getToolInput(input);
|
|
131
|
+
const content = (ti.content ?? '');
|
|
132
|
+
// Only care about spec.md in increments
|
|
133
|
+
if (!filePath.match(/\.specweave\/increments\/\d{4}-[^/]+\/spec\.md$/)) {
|
|
134
|
+
return ALLOW;
|
|
135
|
+
}
|
|
136
|
+
// Allow template writes through
|
|
137
|
+
for (const marker of TEMPLATE_MARKERS) {
|
|
138
|
+
if (content.includes(marker)) {
|
|
139
|
+
return ALLOW;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Read config to check if strict interview enabled
|
|
143
|
+
const config = readJsonSafe(context.configPath);
|
|
144
|
+
const planning = (config.planning ?? {});
|
|
145
|
+
const di = (planning.deepInterview ?? {});
|
|
146
|
+
if (di.enabled !== true || di.enforcement !== 'strict') {
|
|
147
|
+
return ALLOW;
|
|
148
|
+
}
|
|
149
|
+
const incrementId = extractIncrementId(filePath);
|
|
150
|
+
const categories = di.categories ?? DEFAULT_INTERVIEW_CATEGORIES;
|
|
151
|
+
// Check interview state file
|
|
152
|
+
const interviewState = path.join(context.stateDir, `interview-${incrementId}.json`);
|
|
153
|
+
if (!fs.existsSync(interviewState)) {
|
|
154
|
+
return {
|
|
155
|
+
decision: 'block',
|
|
156
|
+
reason: `Strict Interview Enforcement: Interview Required. Deep Interview has not been started for ${incrementId}. Start and cover all categories before writing spec.md.`,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
// Check covered categories
|
|
160
|
+
const state = readJsonSafe(interviewState);
|
|
161
|
+
const covered = state.coveredCategories;
|
|
162
|
+
const coveredKeys = covered ? Object.keys(covered) : [];
|
|
163
|
+
const missing = categories.filter((c) => !coveredKeys.includes(c));
|
|
164
|
+
if (missing.length > 0) {
|
|
165
|
+
return {
|
|
166
|
+
decision: 'block',
|
|
167
|
+
reason: `Strict Interview Enforcement: Incomplete Interview for ${incrementId}. Missing categories: ${missing.join(', ')}`,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
return ALLOW;
|
|
171
|
+
}
|
|
172
|
+
// ---------------------------------------------------------------------------
|
|
173
|
+
// Guard: Increment Existence (TeamCreate without valid spec)
|
|
174
|
+
// ---------------------------------------------------------------------------
|
|
175
|
+
function isNonImplTeam(input) {
|
|
176
|
+
const ti = getToolInput(input);
|
|
177
|
+
const teamName = (ti.team_name ?? '').toLowerCase();
|
|
178
|
+
const description = (ti.description ?? '').toLowerCase();
|
|
179
|
+
// Check team name prefix
|
|
180
|
+
for (const prefix of NON_IMPL_PREFIXES) {
|
|
181
|
+
if (teamName.startsWith(prefix))
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
// Check description keywords
|
|
185
|
+
for (const keyword of NON_IMPL_KEYWORDS) {
|
|
186
|
+
if (description.includes(keyword))
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
function hasValidSpec(specPath) {
|
|
192
|
+
try {
|
|
193
|
+
if (!fs.existsSync(specPath))
|
|
194
|
+
return false;
|
|
195
|
+
const content = fs.readFileSync(specPath, 'utf-8');
|
|
196
|
+
// Min 500 bytes
|
|
197
|
+
if (Buffer.byteLength(content) <= 500)
|
|
198
|
+
return false;
|
|
199
|
+
// No template markers
|
|
200
|
+
for (const marker of TEMPLATE_MARKERS) {
|
|
201
|
+
if (content.includes(marker))
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
// No {{UPPERCASE}} mustache placeholders
|
|
205
|
+
if (/\{\{[A-Z_]+\}\}/.test(content))
|
|
206
|
+
return false;
|
|
207
|
+
// Must have at least one acceptance criterion
|
|
208
|
+
if (!/AC-US\d+-\d+|AC-\d+/.test(content))
|
|
209
|
+
return false;
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
function checkIncrementExistenceGuard(_input, context) {
|
|
217
|
+
// Env var bypass
|
|
218
|
+
if (process.env.SPECWEAVE_NO_INCREMENT === '1') {
|
|
219
|
+
return ALLOW;
|
|
220
|
+
}
|
|
221
|
+
// Scan increments for valid specs with active/in-progress status
|
|
222
|
+
const incDir = path.join(context.projectRoot, '.specweave', 'increments');
|
|
223
|
+
if (fs.existsSync(incDir)) {
|
|
224
|
+
try {
|
|
225
|
+
const entries = fs.readdirSync(incDir, { withFileTypes: true });
|
|
226
|
+
for (const entry of entries) {
|
|
227
|
+
if (entry.isDirectory()) {
|
|
228
|
+
const specPath = path.join(incDir, entry.name, 'spec.md');
|
|
229
|
+
if (!hasValidSpec(specPath))
|
|
230
|
+
continue;
|
|
231
|
+
// Check metadata.json for qualifying status
|
|
232
|
+
const metaPath = path.join(incDir, entry.name, 'metadata.json');
|
|
233
|
+
if (fs.existsSync(metaPath)) {
|
|
234
|
+
try {
|
|
235
|
+
const meta = JSON.parse(fs.readFileSync(metaPath, 'utf8'));
|
|
236
|
+
const status = meta?.status ?? '';
|
|
237
|
+
const qualifying = ['active', 'in-progress', 'ready_for_review', 'planned'];
|
|
238
|
+
if (qualifying.includes(status))
|
|
239
|
+
return ALLOW;
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
// Unreadable metadata — skip this increment
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
// No metadata.json but valid spec — allow (legacy increments)
|
|
247
|
+
return ALLOW;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
// scan failure — don't block
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// Scan multi-repo increments
|
|
257
|
+
const reposDir = path.join(context.projectRoot, 'repositories');
|
|
258
|
+
if (fs.existsSync(reposDir)) {
|
|
259
|
+
try {
|
|
260
|
+
const orgs = fs.readdirSync(reposDir, { withFileTypes: true });
|
|
261
|
+
for (const org of orgs) {
|
|
262
|
+
if (!org.isDirectory())
|
|
263
|
+
continue;
|
|
264
|
+
const orgPath = path.join(reposDir, org.name);
|
|
265
|
+
const repos = fs.readdirSync(orgPath, { withFileTypes: true });
|
|
266
|
+
for (const repo of repos) {
|
|
267
|
+
if (!repo.isDirectory())
|
|
268
|
+
continue;
|
|
269
|
+
const repoIncDir = path.join(orgPath, repo.name, '.specweave', 'increments');
|
|
270
|
+
if (!fs.existsSync(repoIncDir))
|
|
271
|
+
continue;
|
|
272
|
+
const incs = fs.readdirSync(repoIncDir, { withFileTypes: true });
|
|
273
|
+
for (const inc of incs) {
|
|
274
|
+
if (inc.isDirectory()) {
|
|
275
|
+
const specPath = path.join(repoIncDir, inc.name, 'spec.md');
|
|
276
|
+
if (hasValidSpec(specPath))
|
|
277
|
+
return ALLOW;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
catch {
|
|
284
|
+
// scan failure — don't block
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
decision: 'block',
|
|
289
|
+
reason: 'Increment Required Before Team Creation. No qualifying increment with a valid spec.md found. Run /sw:increment first, or use a mode-prefixed team name (review-*, brainstorm-*, analysis-*, research-*) for non-implementation work.',
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
// ---------------------------------------------------------------------------
|
|
293
|
+
// Main handler
|
|
294
|
+
// ---------------------------------------------------------------------------
|
|
295
|
+
export const handle = async (input, context) => {
|
|
296
|
+
const toolName = getToolName(input);
|
|
297
|
+
const filePath = getFilePath(input);
|
|
298
|
+
// Fast path: not targeting increment files AND not TeamCreate
|
|
299
|
+
if (!isIncrementFile(filePath) && toolName !== 'TeamCreate') {
|
|
300
|
+
return ALLOW;
|
|
301
|
+
}
|
|
302
|
+
// Edit guard: status completion
|
|
303
|
+
if (toolName === 'Edit') {
|
|
304
|
+
return checkStatusCompletionGuard(input, context);
|
|
305
|
+
}
|
|
306
|
+
// Write guard: interview enforcement
|
|
307
|
+
if (toolName === 'Write') {
|
|
308
|
+
return checkInterviewGuard(input, context);
|
|
309
|
+
}
|
|
310
|
+
// TeamCreate guard: increment existence
|
|
311
|
+
if (toolName === 'TeamCreate') {
|
|
312
|
+
if (isNonImplTeam(input))
|
|
313
|
+
return ALLOW;
|
|
314
|
+
return checkIncrementExistenceGuard(input, context);
|
|
315
|
+
}
|
|
316
|
+
return ALLOW;
|
|
317
|
+
};
|
|
318
|
+
//# sourceMappingURL=pre-tool-use.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pre-tool-use.js","sourceRoot":"","sources":["../../../../../src/core/hooks/handlers/pre-tool-use.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session-start hook handler — session initialization.
|
|
3
|
+
*
|
|
4
|
+
* Clears stale auto-mode files, resets context pressure,
|
|
5
|
+
* and performs baseline prompt health check.
|
|
6
|
+
*/
|
|
7
|
+
import type { HandlerFn } from './types.js';
|
|
8
|
+
export declare const handle: HandlerFn;
|
|
9
|
+
//# sourceMappingURL=session-start.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-start.d.ts","sourceRoot":"","sources":["../../../../../src/core/hooks/handlers/session-start.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAkC5C,eAAO,MAAM,MAAM,EAAE,SA6EpB,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session-start hook handler — session initialization.
|
|
3
|
+
*
|
|
4
|
+
* Clears stale auto-mode files, resets context pressure,
|
|
5
|
+
* and performs baseline prompt health check.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
const STALE_THRESHOLD_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
10
|
+
const WARNING_THRESHOLD = 80000;
|
|
11
|
+
const CRITICAL_THRESHOLD = 120000;
|
|
12
|
+
const SYSTEM_ESTIMATE = 12000;
|
|
13
|
+
const SKILL_BUDGET = 15000;
|
|
14
|
+
const HOOK_PER_TURN = 3000;
|
|
15
|
+
function isStale(filePath) {
|
|
16
|
+
try {
|
|
17
|
+
const stat = fs.statSync(filePath);
|
|
18
|
+
return Date.now() - stat.mtimeMs > STALE_THRESHOLD_MS;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function safeRemove(filePath) {
|
|
25
|
+
try {
|
|
26
|
+
fs.unlinkSync(filePath);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Ignore
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function fileSize(filePath) {
|
|
33
|
+
try {
|
|
34
|
+
return fs.statSync(filePath).size;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export const handle = async (_input, context) => {
|
|
41
|
+
const { projectRoot, stateDir, logsDir, timestamp } = context;
|
|
42
|
+
try {
|
|
43
|
+
fs.mkdirSync(stateDir, { recursive: true });
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return { continue: true };
|
|
47
|
+
}
|
|
48
|
+
// --- Auto-mode cleanup: remove stale session files (>24h) ---
|
|
49
|
+
const autoFile = path.join(stateDir, 'auto-mode.json');
|
|
50
|
+
if (fs.existsSync(autoFile) && isStale(autoFile)) {
|
|
51
|
+
safeRemove(autoFile);
|
|
52
|
+
safeRemove(path.join(stateDir, '.stop-auto-dedup'));
|
|
53
|
+
safeRemove(path.join(stateDir, '.stop-auto-dedup-prev'));
|
|
54
|
+
safeRemove(path.join(stateDir, '.stop-auto-turns'));
|
|
55
|
+
try {
|
|
56
|
+
fs.mkdirSync(logsDir, { recursive: true });
|
|
57
|
+
fs.appendFileSync(path.join(logsDir, 'session.log'), `[${timestamp}] SessionStart: Cleared stale auto-mode session files (>24h)\n`);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Never throw from logging
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// --- Context pressure reset ---
|
|
64
|
+
safeRemove(path.join(stateDir, 'context-pressure.json'));
|
|
65
|
+
safeRemove(path.join(stateDir, 'prompt-health-alert.json'));
|
|
66
|
+
// --- Baseline health check ---
|
|
67
|
+
try {
|
|
68
|
+
const claudeMdSize = fileSize(path.join(projectRoot, 'CLAUDE.md'));
|
|
69
|
+
const memoryDir = path.join(projectRoot, '.claude', 'projects');
|
|
70
|
+
let memoryMdSize = 0;
|
|
71
|
+
try {
|
|
72
|
+
// Find MEMORY.md in any project subdirectory
|
|
73
|
+
if (fs.existsSync(memoryDir)) {
|
|
74
|
+
const entries = fs.readdirSync(memoryDir, { withFileTypes: true });
|
|
75
|
+
for (const entry of entries) {
|
|
76
|
+
if (entry.isDirectory()) {
|
|
77
|
+
const memPath = path.join(memoryDir, entry.name, 'memory', 'MEMORY.md');
|
|
78
|
+
memoryMdSize += fileSize(memPath);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Best-effort
|
|
85
|
+
}
|
|
86
|
+
const baseline = claudeMdSize + memoryMdSize + SYSTEM_ESTIMATE + SKILL_BUDGET + HOOK_PER_TURN;
|
|
87
|
+
let warningLevel = 'normal';
|
|
88
|
+
if (baseline > CRITICAL_THRESHOLD) {
|
|
89
|
+
warningLevel = 'critical';
|
|
90
|
+
}
|
|
91
|
+
else if (baseline > WARNING_THRESHOLD) {
|
|
92
|
+
warningLevel = 'warning';
|
|
93
|
+
}
|
|
94
|
+
const health = {
|
|
95
|
+
baseline,
|
|
96
|
+
claudeMdSize,
|
|
97
|
+
memoryMdSize,
|
|
98
|
+
skillBudget: SKILL_BUDGET,
|
|
99
|
+
systemEstimate: SYSTEM_ESTIMATE,
|
|
100
|
+
hookPerTurn: HOOK_PER_TURN,
|
|
101
|
+
warningLevel,
|
|
102
|
+
checkedAt: timestamp,
|
|
103
|
+
};
|
|
104
|
+
fs.writeFileSync(path.join(stateDir, 'prompt-health.json'), JSON.stringify(health));
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// Health check is best-effort
|
|
108
|
+
}
|
|
109
|
+
return { continue: true };
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=session-start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-start.js","sourceRoot":"","sources":["../../../../../src/core/hooks/handlers/session-start.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,MAAM,kBAAkB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW;AAC3D,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAChC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC,MAAM,eAAe,GAAG,KAAK,CAAC;AAC9B,MAAM,YAAY,GAAG,KAAK,CAAC;AAC3B,MAAM,aAAa,GAAG,IAAI,CAAC;AAE3B,SAAS,OAAO,CAAC,QAAgB;IAC/B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,GAAG,kBAAkB,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,QAAgB;IAClC,IAAI,CAAC;QACH,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,QAAgB;IAChC,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAc,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;IACzD,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAE9D,IAAI,CAAC;QACH,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC5B,CAAC;IAED,+DAA+D;IAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;IACvD,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjD,UAAU,CAAC,QAAQ,CAAC,CAAC;QACrB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC;QACpD,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,uBAAuB,CAAC,CAAC,CAAC;QACzD,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC;QAEpD,IAAI,CAAC;YACH,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3C,EAAE,CAAC,cAAc,CACf,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,EACjC,IAAI,SAAS,gEAAgE,CAC9E,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,2BAA2B;QAC7B,CAAC;IACH,CAAC;IAED,iCAAiC;IACjC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,uBAAuB,CAAC,CAAC,CAAC;IACzD,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,0BAA0B,CAAC,CAAC,CAAC;IAE5D,gCAAgC;IAChC,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;QACnE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;QAChE,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC;YACH,6CAA6C;YAC7C,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC7B,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;gBACnE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;oBAC5B,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;wBACxB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;wBACxE,YAAY,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC;oBACpC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,cAAc;QAChB,CAAC;QACD,MAAM,QAAQ,GAAG,YAAY,GAAG,YAAY,GAAG,eAAe,GAAG,YAAY,GAAG,aAAa,CAAC;QAE9F,IAAI,YAAY,GAAG,QAAQ,CAAC;QAC5B,IAAI,QAAQ,GAAG,kBAAkB,EAAE,CAAC;YAClC,YAAY,GAAG,UAAU,CAAC;QAC5B,CAAC;aAAM,IAAI,QAAQ,GAAG,iBAAiB,EAAE,CAAC;YACxC,YAAY,GAAG,SAAS,CAAC;QAC3B,CAAC;QAED,MAAM,MAAM,GAAG;YACb,QAAQ;YACR,YAAY;YACZ,YAAY;YACZ,WAAW,EAAE,YAAY;YACzB,cAAc,EAAE,eAAe;YAC/B,WAAW,EAAE,aAAa;YAC1B,YAAY;YACZ,SAAS,EAAE,SAAS;SACrB,CAAC;QAEF,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,oBAAoB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACtF,CAAC;IAAC,MAAM,CAAC;QACP,8BAA8B;IAChC,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC5B,CAAC,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stop-auto hook handler.
|
|
3
|
+
*
|
|
4
|
+
* Fires when a session ends. Checks if an auto-mode session is active:
|
|
5
|
+
* 1. Look for auto-mode.json (per-session or global)
|
|
6
|
+
* 2. Check session staleness
|
|
7
|
+
* 3. Scan active increments for pending tasks
|
|
8
|
+
* 4. Include progress context but always approve
|
|
9
|
+
*
|
|
10
|
+
* Stop hooks should NEVER block session exit.
|
|
11
|
+
*
|
|
12
|
+
* @module core/hooks/handlers/stop-auto
|
|
13
|
+
*/
|
|
14
|
+
import type { HandlerFn } from './types.js';
|
|
15
|
+
export declare const handle: HandlerFn;
|
|
16
|
+
//# sourceMappingURL=stop-auto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop-auto.d.ts","sourceRoot":"","sources":["../../../../../src/core/hooks/handlers/stop-auto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAwE5C,eAAO,MAAM,MAAM,EAAE,SAyCpB,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stop-auto hook handler.
|
|
3
|
+
*
|
|
4
|
+
* Fires when a session ends. Checks if an auto-mode session is active:
|
|
5
|
+
* 1. Look for auto-mode.json (per-session or global)
|
|
6
|
+
* 2. Check session staleness
|
|
7
|
+
* 3. Scan active increments for pending tasks
|
|
8
|
+
* 4. Include progress context but always approve
|
|
9
|
+
*
|
|
10
|
+
* Stop hooks should NEVER block session exit.
|
|
11
|
+
*
|
|
12
|
+
* @module core/hooks/handlers/stop-auto
|
|
13
|
+
*/
|
|
14
|
+
import * as fs from 'fs';
|
|
15
|
+
import * as path from 'path';
|
|
16
|
+
import { logHook } from './utils.js';
|
|
17
|
+
/** Read JSON safely, return null on error */
|
|
18
|
+
function readJsonSafe(filePath) {
|
|
19
|
+
try {
|
|
20
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** Get auto-mode session file path (per-session or global fallback) */
|
|
27
|
+
function getSessionPath(stateDir) {
|
|
28
|
+
const sessionId = process.env.CLAUDE_SESSION_ID;
|
|
29
|
+
if (sessionId) {
|
|
30
|
+
const perSession = path.join(stateDir, 'sessions', sessionId, 'auto-mode.json');
|
|
31
|
+
if (fs.existsSync(perSession))
|
|
32
|
+
return perSession;
|
|
33
|
+
}
|
|
34
|
+
return path.join(stateDir, 'auto-mode.json');
|
|
35
|
+
}
|
|
36
|
+
/** Check if session file is stale (older than maxSessionAge seconds) */
|
|
37
|
+
function isSessionStale(sessionPath, maxSessionAge) {
|
|
38
|
+
try {
|
|
39
|
+
const stat = fs.statSync(sessionPath);
|
|
40
|
+
const ageMs = Date.now() - stat.mtimeMs;
|
|
41
|
+
return ageMs > maxSessionAge * 1000;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Count pending tasks across active increments */
|
|
48
|
+
function scanPendingTasks(projectRoot) {
|
|
49
|
+
const incDir = path.join(projectRoot, '.specweave', 'increments');
|
|
50
|
+
let pending = 0;
|
|
51
|
+
let completed = 0;
|
|
52
|
+
const incrementIds = [];
|
|
53
|
+
try {
|
|
54
|
+
if (!fs.existsSync(incDir))
|
|
55
|
+
return { pending, completed, incrementIds };
|
|
56
|
+
const dirs = fs.readdirSync(incDir);
|
|
57
|
+
for (const dir of dirs) {
|
|
58
|
+
const metaPath = path.join(incDir, dir, 'metadata.json');
|
|
59
|
+
if (!fs.existsSync(metaPath))
|
|
60
|
+
continue;
|
|
61
|
+
const meta = readJsonSafe(metaPath);
|
|
62
|
+
if (!meta || (meta.status !== 'active' && meta.status !== 'in-progress'))
|
|
63
|
+
continue;
|
|
64
|
+
const tasksPath = path.join(incDir, dir, 'tasks.md');
|
|
65
|
+
try {
|
|
66
|
+
const tasks = fs.readFileSync(tasksPath, 'utf8');
|
|
67
|
+
const p = (tasks.match(/\[ \]/g) || []).length;
|
|
68
|
+
const c = (tasks.match(/\[x\]/g) || []).length;
|
|
69
|
+
if (p > 0) {
|
|
70
|
+
pending += p;
|
|
71
|
+
completed += c;
|
|
72
|
+
incrementIds.push(dir);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// No tasks file
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// fs errors
|
|
82
|
+
}
|
|
83
|
+
return { pending, completed, incrementIds };
|
|
84
|
+
}
|
|
85
|
+
export const handle = async (input, context) => {
|
|
86
|
+
try {
|
|
87
|
+
// 1. Find auto-mode session file
|
|
88
|
+
const sessionPath = getSessionPath(context.stateDir);
|
|
89
|
+
if (!fs.existsSync(sessionPath)) {
|
|
90
|
+
logHook(context, 'stop-auto', 'No auto session');
|
|
91
|
+
return { decision: 'approve' };
|
|
92
|
+
}
|
|
93
|
+
// 2. Read session data
|
|
94
|
+
const session = readJsonSafe(sessionPath);
|
|
95
|
+
if (!session || session.active !== true) {
|
|
96
|
+
logHook(context, 'stop-auto', 'Session not active');
|
|
97
|
+
return { decision: 'approve' };
|
|
98
|
+
}
|
|
99
|
+
// 3. Read config for maxSessionAge
|
|
100
|
+
const config = readJsonSafe(context.configPath);
|
|
101
|
+
const maxSessionAge = config?.auto?.maxSessionAge ?? 7200;
|
|
102
|
+
// 4. Check staleness
|
|
103
|
+
if (isSessionStale(sessionPath, maxSessionAge)) {
|
|
104
|
+
logHook(context, 'stop-auto', 'Stale session — expired');
|
|
105
|
+
return { decision: 'approve' };
|
|
106
|
+
}
|
|
107
|
+
// 5. Scan active increments for pending tasks
|
|
108
|
+
const { pending, completed, incrementIds } = scanPendingTasks(context.projectRoot);
|
|
109
|
+
if (pending === 0) {
|
|
110
|
+
logHook(context, 'stop-auto', 'All tasks complete');
|
|
111
|
+
return { decision: 'approve' };
|
|
112
|
+
}
|
|
113
|
+
// 6. Pending tasks exist — include progress context but still approve
|
|
114
|
+
logHook(context, 'stop-auto', `Pending tasks: ${pending} across ${incrementIds.length} increment(s)`);
|
|
115
|
+
return { decision: 'approve' };
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// Never throw — always approve
|
|
119
|
+
return { decision: 'approve' };
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
//# sourceMappingURL=stop-auto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop-auto.js","sourceRoot":"","sources":["../../../../../src/core/hooks/handlers/stop-auto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,6CAA6C;AAC7C,SAAS,YAAY,CAAC,QAAgB;IACpC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,uEAAuE;AACvE,SAAS,cAAc,CAAC,QAAgB;IACtC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAChD,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC;QAChF,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE,OAAO,UAAU,CAAC;IACnD,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;AAC/C,CAAC;AAED,wEAAwE;AACxE,SAAS,cAAc,CAAC,WAAmB,EAAE,aAAqB;IAChE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QACxC,OAAO,KAAK,GAAG,aAAa,GAAG,IAAI,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,mDAAmD;AACnD,SAAS,gBAAgB,CAAC,WAAmB;IAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;IAClE,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;QAExE,MAAM,IAAI,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACpC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,eAAe,CAAC,CAAC;YACzD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAEvC,MAAM,IAAI,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;YACpC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,aAAa,CAAC;gBAAE,SAAS;YAEnF,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;YACrD,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;gBACjD,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;gBAC/C,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;gBAC/C,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;oBACV,OAAO,IAAI,CAAC,CAAC;oBACb,SAAS,IAAI,CAAC,CAAC;oBACf,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACzB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,gBAAgB;YAClB,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAc,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IACxD,IAAI,CAAC;QACH,iCAAiC;QACjC,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACrD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC;YACjD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;QACjC,CAAC;QAED,uBAAuB;QACvB,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;QAC1C,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACxC,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,oBAAoB,CAAC,CAAC;YACpD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;QACjC,CAAC;QAED,mCAAmC;QACnC,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAChD,MAAM,aAAa,GAAG,MAAM,EAAE,IAAI,EAAE,aAAa,IAAI,IAAI,CAAC;QAE1D,qBAAqB;QACrB,IAAI,cAAc,CAAC,WAAW,EAAE,aAAa,CAAC,EAAE,CAAC;YAC/C,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,yBAAyB,CAAC,CAAC;YACzD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;QACjC,CAAC;QAED,8CAA8C;QAC9C,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAEnF,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;YAClB,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,oBAAoB,CAAC,CAAC;YACpD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;QACjC,CAAC;QAED,sEAAsE;QACtE,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,kBAAkB,OAAO,WAAW,YAAY,CAAC,MAAM,eAAe,CAAC,CAAC;QACtG,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,+BAA+B;QAC/B,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;IACjC,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stop-reflect hook handler.
|
|
3
|
+
*
|
|
4
|
+
* Fires when a session ends. Checks if reflection is enabled in config.
|
|
5
|
+
* If enabled, logs that reflection was requested (actual reflection logic
|
|
6
|
+
* will call `specweave reflect-stop` CLI in a follow-up).
|
|
7
|
+
*
|
|
8
|
+
* NEVER blocks — always returns approve.
|
|
9
|
+
*
|
|
10
|
+
* @module core/hooks/handlers/stop-reflect
|
|
11
|
+
*/
|
|
12
|
+
import type { HandlerFn } from './types.js';
|
|
13
|
+
export declare const handle: HandlerFn;
|
|
14
|
+
//# sourceMappingURL=stop-reflect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop-reflect.d.ts","sourceRoot":"","sources":["../../../../../src/core/hooks/handlers/stop-reflect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAe5C,eAAO,MAAM,MAAM,EAAE,SAgBpB,CAAC"}
|