specweave 1.0.569 → 1.0.571
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 +83 -0
- package/dist/src/cli/commands/analytics-push.d.ts +27 -0
- package/dist/src/cli/commands/analytics-push.d.ts.map +1 -0
- package/dist/src/cli/commands/analytics-push.js +74 -0
- package/dist/src/cli/commands/analytics-push.js.map +1 -0
- package/dist/src/cli/commands/session.d.ts +34 -0
- package/dist/src/cli/commands/session.d.ts.map +1 -0
- package/dist/src/cli/commands/session.js +142 -0
- package/dist/src/cli/commands/session.js.map +1 -0
- package/dist/src/cli/commands/sync-flush.d.ts +31 -0
- package/dist/src/cli/commands/sync-flush.d.ts.map +1 -0
- package/dist/src/cli/commands/sync-flush.js +114 -0
- package/dist/src/cli/commands/sync-flush.js.map +1 -0
- package/dist/src/core/analytics/event-writer.d.ts +33 -0
- package/dist/src/core/analytics/event-writer.d.ts.map +1 -0
- package/dist/src/core/analytics/event-writer.js +63 -0
- package/dist/src/core/analytics/event-writer.js.map +1 -0
- package/dist/src/core/hooks/handlers/hook-router.d.ts +1 -1
- package/dist/src/core/hooks/handlers/hook-router.d.ts.map +1 -1
- package/dist/src/core/hooks/handlers/hook-router.js +7 -10
- package/dist/src/core/hooks/handlers/hook-router.js.map +1 -1
- package/dist/src/core/hooks/handlers/pre-tool-use.d.ts.map +1 -1
- package/dist/src/core/hooks/handlers/pre-tool-use.js +23 -17
- package/dist/src/core/hooks/handlers/pre-tool-use.js.map +1 -1
- package/dist/src/core/hooks/handlers/types.d.ts +1 -1
- package/dist/src/core/hooks/handlers/types.d.ts.map +1 -1
- package/dist/src/core/hooks/handlers/types.js +0 -7
- package/dist/src/core/hooks/handlers/types.js.map +1 -1
- package/dist/src/core/hooks/handlers/user-prompt-submit.d.ts.map +1 -1
- package/dist/src/core/hooks/handlers/user-prompt-submit.js +21 -14
- package/dist/src/core/hooks/handlers/user-prompt-submit.js.map +1 -1
- package/dist/src/core/session/auto-scanner.d.ts +37 -0
- package/dist/src/core/session/auto-scanner.d.ts.map +1 -0
- package/dist/src/core/{hooks/handlers/stop-auto.js → session/auto-scanner.js} +33 -43
- package/dist/src/core/session/auto-scanner.js.map +1 -0
- package/dist/src/core/session/reflect-checker.d.ts +19 -0
- package/dist/src/core/session/reflect-checker.d.ts.map +1 -0
- package/dist/src/core/session/reflect-checker.js +30 -0
- package/dist/src/core/session/reflect-checker.js.map +1 -0
- package/dist/src/core/session/session-lifecycle.d.ts +44 -0
- package/dist/src/core/session/session-lifecycle.d.ts.map +1 -0
- package/dist/src/core/{hooks/handlers/session-start.js → session/session-lifecycle.js} +71 -32
- package/dist/src/core/session/session-lifecycle.js.map +1 -0
- package/dist/src/core/sync/event-queue-ops.d.ts +39 -0
- package/dist/src/core/sync/event-queue-ops.d.ts.map +1 -0
- package/dist/src/core/sync/event-queue-ops.js +109 -0
- package/dist/src/core/sync/event-queue-ops.js.map +1 -0
- package/dist/src/hooks/generate-settings.d.ts.map +1 -1
- package/dist/src/hooks/generate-settings.js +12 -13
- package/dist/src/hooks/generate-settings.js.map +1 -1
- package/package.json +1 -1
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.d.ts +0 -11
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.d.ts.map +0 -1
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.js +0 -75
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.js.map +0 -1
- package/dist/src/core/hooks/handlers/post-tool-use.d.ts +0 -11
- package/dist/src/core/hooks/handlers/post-tool-use.d.ts.map +0 -1
- package/dist/src/core/hooks/handlers/post-tool-use.js +0 -76
- package/dist/src/core/hooks/handlers/post-tool-use.js.map +0 -1
- package/dist/src/core/hooks/handlers/pre-compact.d.ts +0 -11
- package/dist/src/core/hooks/handlers/pre-compact.d.ts.map +0 -1
- package/dist/src/core/hooks/handlers/pre-compact.js +0 -77
- package/dist/src/core/hooks/handlers/pre-compact.js.map +0 -1
- package/dist/src/core/hooks/handlers/session-start.d.ts +0 -9
- package/dist/src/core/hooks/handlers/session-start.d.ts.map +0 -1
- package/dist/src/core/hooks/handlers/session-start.js.map +0 -1
- package/dist/src/core/hooks/handlers/stop-auto.d.ts +0 -16
- package/dist/src/core/hooks/handlers/stop-auto.d.ts.map +0 -1
- package/dist/src/core/hooks/handlers/stop-auto.js.map +0 -1
- package/dist/src/core/hooks/handlers/stop-reflect.d.ts +0 -14
- package/dist/src/core/hooks/handlers/stop-reflect.d.ts.map +0 -1
- package/dist/src/core/hooks/handlers/stop-reflect.js +0 -43
- package/dist/src/core/hooks/handlers/stop-reflect.js.map +0 -1
- package/dist/src/core/hooks/handlers/stop-sync.d.ts +0 -15
- package/dist/src/core/hooks/handlers/stop-sync.d.ts.map +0 -1
- package/dist/src/core/hooks/handlers/stop-sync.js +0 -68
- package/dist/src/core/hooks/handlers/stop-sync.js.map +0 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reflect checker core module.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from hooks/handlers/stop-reflect.ts.
|
|
5
|
+
* Checks if reflection is enabled in config and returns result.
|
|
6
|
+
*
|
|
7
|
+
* Never throws.
|
|
8
|
+
*
|
|
9
|
+
* @module core/session/reflect-checker
|
|
10
|
+
*/
|
|
11
|
+
import * as fs from 'fs';
|
|
12
|
+
/**
|
|
13
|
+
* Check if reflect is enabled in config. Default: true.
|
|
14
|
+
*/
|
|
15
|
+
export function checkReflectConfig(configPath) {
|
|
16
|
+
try {
|
|
17
|
+
if (!fs.existsSync(configPath)) {
|
|
18
|
+
return { enabled: true, reason: 'No config file — default enabled' };
|
|
19
|
+
}
|
|
20
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
21
|
+
if (config.reflect?.enabled === false) {
|
|
22
|
+
return { enabled: false, reason: 'Reflection disabled in config' };
|
|
23
|
+
}
|
|
24
|
+
return { enabled: true, reason: 'Reflection enabled in config' };
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return { enabled: true, reason: 'Config read error — default enabled' };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=reflect-checker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reflect-checker.js","sourceRoot":"","sources":["../../../../src/core/session/reflect-checker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAOzB;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAAkB;IACnD,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,kCAAkC,EAAE,CAAC;QACvE,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;QAC/D,IAAI,MAAM,CAAC,OAAO,EAAE,OAAO,KAAK,KAAK,EAAE,CAAC;YACtC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAC;QACrE,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,8BAA8B,EAAE,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,qCAAqC,EAAE,CAAC;IAC1E,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session lifecycle core module.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from hooks/handlers/session-start.ts.
|
|
5
|
+
* Provides reusable session initialization logic for CLI commands.
|
|
6
|
+
*
|
|
7
|
+
* All functions are idempotent and never throw.
|
|
8
|
+
*
|
|
9
|
+
* @module core/session/session-lifecycle
|
|
10
|
+
*/
|
|
11
|
+
export interface HealthCheckResult {
|
|
12
|
+
baseline: number;
|
|
13
|
+
claudeMdSize: number;
|
|
14
|
+
memoryMdSize: number;
|
|
15
|
+
skillBudget: number;
|
|
16
|
+
systemEstimate: number;
|
|
17
|
+
hookPerTurn: number;
|
|
18
|
+
warningLevel: 'normal' | 'warning' | 'critical';
|
|
19
|
+
checkedAt: string;
|
|
20
|
+
}
|
|
21
|
+
export interface SessionLifecycleResult {
|
|
22
|
+
staleFilesCleaned: number;
|
|
23
|
+
pressureReset: boolean;
|
|
24
|
+
healthWritten: boolean;
|
|
25
|
+
sessionDirCreated: boolean;
|
|
26
|
+
orphansCleaned: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Clear stale auto-mode files older than 24 hours.
|
|
30
|
+
*/
|
|
31
|
+
export declare function clearStaleAutoFiles(stateDir: string): number;
|
|
32
|
+
/**
|
|
33
|
+
* Reset context-pressure.json and prompt-health-alert.json.
|
|
34
|
+
*/
|
|
35
|
+
export declare function resetPressureFiles(stateDir: string): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Perform baseline prompt health check and write prompt-health.json.
|
|
38
|
+
*/
|
|
39
|
+
export declare function writeBaselineHealth(projectRoot: string, stateDir: string, timestamp: string): HealthCheckResult | null;
|
|
40
|
+
/**
|
|
41
|
+
* Clean orphaned state files (lock files without active sessions).
|
|
42
|
+
*/
|
|
43
|
+
export declare function cleanOrphaned(stateDir: string): boolean;
|
|
44
|
+
//# sourceMappingURL=session-lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-lifecycle.d.ts","sourceRoot":"","sources":["../../../../src/core/session/session-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAYH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;IAChD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,cAAc,EAAE,OAAO,CAAC;CACzB;AA+BD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAc5D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAQ5D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,iBAAiB,GAAG,IAAI,CA6C1B;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAavD"}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Session
|
|
2
|
+
* Session lifecycle core module.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Extracted from hooks/handlers/session-start.ts.
|
|
5
|
+
* Provides reusable session initialization logic for CLI commands.
|
|
6
|
+
*
|
|
7
|
+
* All functions are idempotent and never throw.
|
|
8
|
+
*
|
|
9
|
+
* @module core/session/session-lifecycle
|
|
6
10
|
*/
|
|
7
11
|
import * as fs from 'fs';
|
|
8
12
|
import * as path from 'path';
|
|
@@ -23,11 +27,15 @@ function isStale(filePath) {
|
|
|
23
27
|
}
|
|
24
28
|
function safeRemove(filePath) {
|
|
25
29
|
try {
|
|
26
|
-
fs.
|
|
30
|
+
if (fs.existsSync(filePath)) {
|
|
31
|
+
fs.unlinkSync(filePath);
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
27
34
|
}
|
|
28
35
|
catch {
|
|
29
|
-
//
|
|
36
|
+
// Never throw
|
|
30
37
|
}
|
|
38
|
+
return false;
|
|
31
39
|
}
|
|
32
40
|
function fileSize(filePath) {
|
|
33
41
|
try {
|
|
@@ -37,39 +45,51 @@ function fileSize(filePath) {
|
|
|
37
45
|
return 0;
|
|
38
46
|
}
|
|
39
47
|
}
|
|
40
|
-
|
|
41
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Clear stale auto-mode files older than 24 hours.
|
|
50
|
+
*/
|
|
51
|
+
export function clearStaleAutoFiles(stateDir) {
|
|
52
|
+
let cleaned = 0;
|
|
42
53
|
try {
|
|
43
|
-
|
|
54
|
+
const autoFile = path.join(stateDir, 'auto-mode.json');
|
|
55
|
+
if (fs.existsSync(autoFile) && isStale(autoFile)) {
|
|
56
|
+
if (safeRemove(autoFile))
|
|
57
|
+
cleaned++;
|
|
58
|
+
if (safeRemove(path.join(stateDir, '.stop-auto-dedup')))
|
|
59
|
+
cleaned++;
|
|
60
|
+
if (safeRemove(path.join(stateDir, '.stop-auto-dedup-prev')))
|
|
61
|
+
cleaned++;
|
|
62
|
+
if (safeRemove(path.join(stateDir, '.stop-auto-turns')))
|
|
63
|
+
cleaned++;
|
|
64
|
+
}
|
|
44
65
|
}
|
|
45
66
|
catch {
|
|
46
|
-
|
|
67
|
+
// Never throw
|
|
47
68
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
// Never throw from logging
|
|
61
|
-
}
|
|
69
|
+
return cleaned;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Reset context-pressure.json and prompt-health-alert.json.
|
|
73
|
+
*/
|
|
74
|
+
export function resetPressureFiles(stateDir) {
|
|
75
|
+
try {
|
|
76
|
+
safeRemove(path.join(stateDir, 'context-pressure.json'));
|
|
77
|
+
safeRemove(path.join(stateDir, 'prompt-health-alert.json'));
|
|
78
|
+
return true;
|
|
62
79
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
80
|
+
catch {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Perform baseline prompt health check and write prompt-health.json.
|
|
86
|
+
*/
|
|
87
|
+
export function writeBaselineHealth(projectRoot, stateDir, timestamp) {
|
|
67
88
|
try {
|
|
68
89
|
const claudeMdSize = fileSize(path.join(projectRoot, 'CLAUDE.md'));
|
|
69
90
|
const memoryDir = path.join(projectRoot, '.claude', 'projects');
|
|
70
91
|
let memoryMdSize = 0;
|
|
71
92
|
try {
|
|
72
|
-
// Find MEMORY.md in any project subdirectory
|
|
73
93
|
if (fs.existsSync(memoryDir)) {
|
|
74
94
|
const entries = fs.readdirSync(memoryDir, { withFileTypes: true });
|
|
75
95
|
for (const entry of entries) {
|
|
@@ -101,11 +121,30 @@ export const handle = async (_input, context) => {
|
|
|
101
121
|
warningLevel,
|
|
102
122
|
checkedAt: timestamp,
|
|
103
123
|
};
|
|
124
|
+
fs.mkdirSync(stateDir, { recursive: true });
|
|
104
125
|
fs.writeFileSync(path.join(stateDir, 'prompt-health.json'), JSON.stringify(health));
|
|
126
|
+
return health;
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Clean orphaned state files (lock files without active sessions).
|
|
134
|
+
*/
|
|
135
|
+
export function cleanOrphaned(stateDir) {
|
|
136
|
+
try {
|
|
137
|
+
const lockFiles = ['.lock', 'session.lock'];
|
|
138
|
+
for (const lock of lockFiles) {
|
|
139
|
+
const lockPath = path.join(stateDir, lock);
|
|
140
|
+
if (fs.existsSync(lockPath) && isStale(lockPath)) {
|
|
141
|
+
safeRemove(lockPath);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return true;
|
|
105
145
|
}
|
|
106
146
|
catch {
|
|
107
|
-
|
|
147
|
+
return false;
|
|
108
148
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
//# sourceMappingURL=session-start.js.map
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=session-lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-lifecycle.js","sourceRoot":"","sources":["../../../../src/core/session/session-lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event queue operations core module.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from hooks/handlers/post-tool-use.ts (queue append)
|
|
5
|
+
* and hooks/handlers/stop-sync.ts (flush + dedup).
|
|
6
|
+
*
|
|
7
|
+
* Operates on .specweave/state/event-queue/pending.jsonl.
|
|
8
|
+
* Never throws.
|
|
9
|
+
*
|
|
10
|
+
* @module core/sync/event-queue-ops
|
|
11
|
+
*/
|
|
12
|
+
export interface QueuedEvent {
|
|
13
|
+
event?: string;
|
|
14
|
+
incrementId?: string;
|
|
15
|
+
timestamp?: string;
|
|
16
|
+
data?: Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
export interface QueueResult {
|
|
19
|
+
queued: number;
|
|
20
|
+
}
|
|
21
|
+
export interface FlushResult {
|
|
22
|
+
flushed: number;
|
|
23
|
+
incrementIds: string[];
|
|
24
|
+
events: QueuedEvent[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Append an event to the pending queue.
|
|
28
|
+
*/
|
|
29
|
+
export declare function queueEvent(stateDir: string, event: string, incrementId: string, timestamp: string, data?: Record<string, unknown>): QueueResult;
|
|
30
|
+
/**
|
|
31
|
+
* Read all pending events without clearing.
|
|
32
|
+
*/
|
|
33
|
+
export declare function readPendingEvents(stateDir: string): QueuedEvent[];
|
|
34
|
+
/**
|
|
35
|
+
* Flush the event queue: read, deduplicate by increment ID, clear.
|
|
36
|
+
* Returns the unique increment IDs and events that were flushed.
|
|
37
|
+
*/
|
|
38
|
+
export declare function flushEventQueue(stateDir: string): FlushResult;
|
|
39
|
+
//# sourceMappingURL=event-queue-ops.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-queue-ops.d.ts","sourceRoot":"","sources":["../../../../src/core/sync/event-queue-ops.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAcD;;GAEG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,WAAW,CAkBb;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE,CAgBjE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAwC7D"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event queue operations core module.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from hooks/handlers/post-tool-use.ts (queue append)
|
|
5
|
+
* and hooks/handlers/stop-sync.ts (flush + dedup).
|
|
6
|
+
*
|
|
7
|
+
* Operates on .specweave/state/event-queue/pending.jsonl.
|
|
8
|
+
* Never throws.
|
|
9
|
+
*
|
|
10
|
+
* @module core/sync/event-queue-ops
|
|
11
|
+
*/
|
|
12
|
+
import * as fs from 'fs';
|
|
13
|
+
import * as path from 'path';
|
|
14
|
+
function getPendingPath(stateDir) {
|
|
15
|
+
return path.join(stateDir, 'event-queue', 'pending.jsonl');
|
|
16
|
+
}
|
|
17
|
+
function parseEventLine(line) {
|
|
18
|
+
try {
|
|
19
|
+
return JSON.parse(line);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Append an event to the pending queue.
|
|
27
|
+
*/
|
|
28
|
+
export function queueEvent(stateDir, event, incrementId, timestamp, data) {
|
|
29
|
+
try {
|
|
30
|
+
const queueDir = path.join(stateDir, 'event-queue');
|
|
31
|
+
fs.mkdirSync(queueDir, { recursive: true });
|
|
32
|
+
const entry = {
|
|
33
|
+
event,
|
|
34
|
+
incrementId,
|
|
35
|
+
timestamp,
|
|
36
|
+
...(data ? { data } : {}),
|
|
37
|
+
};
|
|
38
|
+
fs.appendFileSync(path.join(queueDir, 'pending.jsonl'), JSON.stringify(entry) + '\n');
|
|
39
|
+
return { queued: 1 };
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return { queued: 0 };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Read all pending events without clearing.
|
|
47
|
+
*/
|
|
48
|
+
export function readPendingEvents(stateDir) {
|
|
49
|
+
try {
|
|
50
|
+
const pendingPath = getPendingPath(stateDir);
|
|
51
|
+
if (!fs.existsSync(pendingPath))
|
|
52
|
+
return [];
|
|
53
|
+
const content = fs.readFileSync(pendingPath, 'utf8').trim();
|
|
54
|
+
if (!content)
|
|
55
|
+
return [];
|
|
56
|
+
return content
|
|
57
|
+
.split('\n')
|
|
58
|
+
.filter((l) => l.trim())
|
|
59
|
+
.map(parseEventLine)
|
|
60
|
+
.filter((e) => e !== null);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Flush the event queue: read, deduplicate by increment ID, clear.
|
|
68
|
+
* Returns the unique increment IDs and events that were flushed.
|
|
69
|
+
*/
|
|
70
|
+
export function flushEventQueue(stateDir) {
|
|
71
|
+
try {
|
|
72
|
+
const pendingPath = getPendingPath(stateDir);
|
|
73
|
+
if (!fs.existsSync(pendingPath)) {
|
|
74
|
+
return { flushed: 0, incrementIds: [], events: [] };
|
|
75
|
+
}
|
|
76
|
+
const content = fs.readFileSync(pendingPath, 'utf8').trim();
|
|
77
|
+
if (!content) {
|
|
78
|
+
return { flushed: 0, incrementIds: [], events: [] };
|
|
79
|
+
}
|
|
80
|
+
const lines = content.split('\n').filter((l) => l.trim());
|
|
81
|
+
const seenIncrements = new Set();
|
|
82
|
+
const events = [];
|
|
83
|
+
for (const line of lines) {
|
|
84
|
+
const event = parseEventLine(line);
|
|
85
|
+
if (!event?.incrementId)
|
|
86
|
+
continue;
|
|
87
|
+
if (!seenIncrements.has(event.incrementId)) {
|
|
88
|
+
seenIncrements.add(event.incrementId);
|
|
89
|
+
events.push(event);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Clear the queue
|
|
93
|
+
try {
|
|
94
|
+
fs.writeFileSync(pendingPath, '');
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// Non-critical
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
flushed: seenIncrements.size,
|
|
101
|
+
incrementIds: [...seenIncrements],
|
|
102
|
+
events,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return { flushed: 0, incrementIds: [], events: [] };
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=event-queue-ops.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-queue-ops.js","sourceRoot":"","sources":["../../../../src/core/sync/event-queue-ops.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-settings.d.ts","sourceRoot":"","sources":["../../../src/hooks/generate-settings.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate-settings.d.ts","sourceRoot":"","sources":["../../../src/hooks/generate-settings.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAGpE;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,uBAAuB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA8B/F;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CA6BtE"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
const HTTP_EVENTS = [
|
|
4
|
-
'PreToolUse', '
|
|
5
|
-
'TaskCompleted', 'UserPromptSubmit', 'PostToolUseFailure',
|
|
6
|
-
'PermissionRequest',
|
|
4
|
+
'PreToolUse', 'UserPromptSubmit',
|
|
7
5
|
];
|
|
8
|
-
|
|
6
|
+
/** Stale hook keys from previous versions that must be actively removed */
|
|
7
|
+
const STALE_HOOK_KEYS = [
|
|
8
|
+
'PostToolUse', 'Stop', 'SubagentStop', 'TaskCompleted',
|
|
9
|
+
'PostToolUseFailure', 'PermissionRequest',
|
|
9
10
|
'SessionStart', 'SessionEnd', 'Notification', 'SubagentStart',
|
|
10
11
|
'ConfigChange', 'PreCompact', 'TeammateIdle',
|
|
11
12
|
];
|
|
@@ -30,20 +31,13 @@ export function generateHooksSettings(options) {
|
|
|
30
31
|
// Resolve bridge path relative to this module's location (works in both src/ and dist/)
|
|
31
32
|
const bridgePath = path.resolve(path.dirname(new URL(import.meta.url).pathname), 'command-bridge.mjs');
|
|
32
33
|
const hooks = {};
|
|
33
|
-
// HTTP
|
|
34
|
+
// Only PreToolUse and UserPromptSubmit remain as HTTP hooks
|
|
34
35
|
for (const event of HTTP_EVENTS) {
|
|
35
36
|
hooks[event] = [{
|
|
36
37
|
type: 'http',
|
|
37
38
|
url: `http://localhost:${configPort}/api/hooks/${event}`,
|
|
38
39
|
}];
|
|
39
40
|
}
|
|
40
|
-
// Command events
|
|
41
|
-
for (const event of COMMAND_EVENTS) {
|
|
42
|
-
hooks[event] = [{
|
|
43
|
-
type: 'command',
|
|
44
|
-
command: `node ${bridgePath} ${event}`,
|
|
45
|
-
}];
|
|
46
|
-
}
|
|
47
41
|
return { hooks };
|
|
48
42
|
}
|
|
49
43
|
export function writeSettings(projectRoot, port) {
|
|
@@ -64,7 +58,12 @@ export function writeSettings(projectRoot, port) {
|
|
|
64
58
|
// Deep-merge hooks to preserve user-defined hook configurations
|
|
65
59
|
const existingHooks = (existing.hooks ?? {});
|
|
66
60
|
const newHooks = (settings.hooks ?? {});
|
|
67
|
-
const
|
|
61
|
+
const mergedHooks = { ...existingHooks, ...newHooks };
|
|
62
|
+
// Actively remove stale hook keys from previous versions
|
|
63
|
+
for (const staleKey of STALE_HOOK_KEYS) {
|
|
64
|
+
delete mergedHooks[staleKey];
|
|
65
|
+
}
|
|
66
|
+
const merged = { ...existing, hooks: mergedHooks };
|
|
68
67
|
fs.writeFileSync(settingsPath, JSON.stringify(merged, null, 2) + '\n');
|
|
69
68
|
}
|
|
70
69
|
//# sourceMappingURL=generate-settings.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-settings.js","sourceRoot":"","sources":["../../../src/hooks/generate-settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,MAAM,WAAW,GAAG;IAClB,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"generate-settings.js","sourceRoot":"","sources":["../../../src/hooks/generate-settings.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specweave",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.571",
|
|
4
4
|
"description": "100+ domain-expert AI skills — PM, Architect, Frontend, QA, Security and more. Skills learn your team's patterns permanently. Spec-first planning, autonomous execution, multi-agent teams, synced to GitHub/JIRA. Claude Code, Cursor, Copilot & more.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PostToolUse analytics handler — tracks Skill and Task (subagent) usage.
|
|
3
|
-
*
|
|
4
|
-
* Appends events to `<stateDir>/analytics/events.jsonl`.
|
|
5
|
-
* Non-blocking, never throws.
|
|
6
|
-
*
|
|
7
|
-
* @module core/hooks/handlers/post-tool-use-analytics
|
|
8
|
-
*/
|
|
9
|
-
import type { HandlerFn } from './types.js';
|
|
10
|
-
export declare const handle: HandlerFn;
|
|
11
|
-
//# sourceMappingURL=post-tool-use-analytics.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"post-tool-use-analytics.d.ts","sourceRoot":"","sources":["../../../../../src/core/hooks/handlers/post-tool-use-analytics.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,YAAY,CAAC;AA0BvD,eAAO,MAAM,MAAM,EAAE,SAoCpB,CAAC"}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PostToolUse analytics handler — tracks Skill and Task (subagent) usage.
|
|
3
|
-
*
|
|
4
|
-
* Appends events to `<stateDir>/analytics/events.jsonl`.
|
|
5
|
-
* Non-blocking, never throws.
|
|
6
|
-
*
|
|
7
|
-
* @module core/hooks/handlers/post-tool-use-analytics
|
|
8
|
-
*/
|
|
9
|
-
import * as fs from 'fs';
|
|
10
|
-
import * as path from 'path';
|
|
11
|
-
const CONTINUE = { continue: true };
|
|
12
|
-
function getToolInput(input) {
|
|
13
|
-
return (input.tool_input ?? input.toolInput ?? {});
|
|
14
|
-
}
|
|
15
|
-
function resolveToolName(input) {
|
|
16
|
-
const explicit = (input.tool_name ?? input.toolName ?? '');
|
|
17
|
-
if (explicit)
|
|
18
|
-
return explicit;
|
|
19
|
-
// Fallback: detect from input fields
|
|
20
|
-
const ti = getToolInput(input);
|
|
21
|
-
if (ti.skill)
|
|
22
|
-
return 'Skill';
|
|
23
|
-
if (ti.subagent_type)
|
|
24
|
-
return 'Task';
|
|
25
|
-
return '';
|
|
26
|
-
}
|
|
27
|
-
function extractPlugin(skillName) {
|
|
28
|
-
if (!skillName.includes(':'))
|
|
29
|
-
return 'specweave';
|
|
30
|
-
const prefix = skillName.split(':')[0];
|
|
31
|
-
return prefix === 'sw' ? 'specweave' : prefix;
|
|
32
|
-
}
|
|
33
|
-
export const handle = async (input, context) => {
|
|
34
|
-
const toolName = resolveToolName(input);
|
|
35
|
-
const ti = getToolInput(input);
|
|
36
|
-
if (toolName === 'Skill') {
|
|
37
|
-
const skillName = (ti.skill ?? '');
|
|
38
|
-
if (!skillName)
|
|
39
|
-
return CONTINUE;
|
|
40
|
-
const plugin = extractPlugin(skillName);
|
|
41
|
-
const event = {
|
|
42
|
-
timestamp: context.timestamp,
|
|
43
|
-
type: 'skill',
|
|
44
|
-
name: skillName,
|
|
45
|
-
success: true,
|
|
46
|
-
plugin,
|
|
47
|
-
};
|
|
48
|
-
appendEvent(context.stateDir, event);
|
|
49
|
-
return CONTINUE;
|
|
50
|
-
}
|
|
51
|
-
if (toolName === 'Task') {
|
|
52
|
-
const agentType = (ti.subagent_type ?? 'general');
|
|
53
|
-
const event = {
|
|
54
|
-
timestamp: context.timestamp,
|
|
55
|
-
type: 'agent',
|
|
56
|
-
name: agentType,
|
|
57
|
-
success: true,
|
|
58
|
-
plugin: 'specweave',
|
|
59
|
-
};
|
|
60
|
-
appendEvent(context.stateDir, event);
|
|
61
|
-
return CONTINUE;
|
|
62
|
-
}
|
|
63
|
-
return CONTINUE;
|
|
64
|
-
};
|
|
65
|
-
function appendEvent(stateDir, event) {
|
|
66
|
-
try {
|
|
67
|
-
const analyticsDir = path.join(stateDir, 'analytics');
|
|
68
|
-
fs.mkdirSync(analyticsDir, { recursive: true });
|
|
69
|
-
fs.appendFileSync(path.join(analyticsDir, 'events.jsonl'), JSON.stringify(event) + '\n');
|
|
70
|
-
}
|
|
71
|
-
catch {
|
|
72
|
-
// Never throw from analytics
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
//# sourceMappingURL=post-tool-use-analytics.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"post-tool-use-analytics.js","sourceRoot":"","sources":["../../../../../src/core/hooks/handlers/post-tool-use-analytics.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PostToolUse hook handler — non-blocking event detector and queue writer.
|
|
3
|
-
*
|
|
4
|
-
* Detects changes to increment files and queues events to pending.jsonl
|
|
5
|
-
* for later processing by stop-sync.
|
|
6
|
-
*
|
|
7
|
-
* @module core/hooks/handlers/post-tool-use
|
|
8
|
-
*/
|
|
9
|
-
import type { HandlerFn } from './types.js';
|
|
10
|
-
export declare const handle: HandlerFn;
|
|
11
|
-
//# sourceMappingURL=post-tool-use.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"post-tool-use.d.ts","sourceRoot":"","sources":["../../../../../src/core/hooks/handlers/post-tool-use.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,YAAY,CAAC;AA2CvD,eAAO,MAAM,MAAM,EAAE,SA+CpB,CAAC"}
|