sqlew 4.0.4 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1805 -1762
- package/LICENSE +177 -39
- package/NOTICE +24 -0
- package/README.md +409 -390
- package/assets/claude-md-snippets/plan-mode-integration.md +17 -6
- package/assets/config.example.toml +282 -284
- package/assets/sample-agents/README.md +36 -40
- package/assets/sample-agents/sqlew-architect.md +321 -322
- package/assets/sample-agents/sqlew-researcher.md +292 -293
- package/assets/sample-agents/sqlew-scrum-master.md +286 -287
- package/assets/sample-commands/README.md +56 -57
- package/assets/sample-skills/sqlew-plan-guidance/SKILL.md +33 -26
- package/dist/cli/hooks/check-completion.d.ts +19 -0
- package/dist/cli/hooks/check-completion.d.ts.map +1 -0
- package/dist/cli/hooks/check-completion.js +104 -0
- package/dist/cli/hooks/check-completion.js.map +1 -0
- package/dist/cli/hooks/init-hooks.d.ts +35 -0
- package/dist/cli/hooks/init-hooks.d.ts.map +1 -0
- package/dist/cli/hooks/init-hooks.js +425 -0
- package/dist/cli/hooks/init-hooks.js.map +1 -0
- package/dist/cli/hooks/mark-done.d.ts +25 -0
- package/dist/cli/hooks/mark-done.d.ts.map +1 -0
- package/dist/cli/hooks/mark-done.js +128 -0
- package/dist/cli/hooks/mark-done.js.map +1 -0
- package/dist/cli/hooks/plan-id-utils.d.ts +83 -0
- package/dist/cli/hooks/plan-id-utils.d.ts.map +1 -0
- package/dist/cli/hooks/plan-id-utils.js +183 -0
- package/dist/cli/hooks/plan-id-utils.js.map +1 -0
- package/dist/cli/hooks/save.d.ts +23 -0
- package/dist/cli/hooks/save.d.ts.map +1 -0
- package/dist/cli/hooks/save.js +90 -0
- package/dist/cli/hooks/save.js.map +1 -0
- package/dist/cli/hooks/stdin-parser.d.ts +139 -0
- package/dist/cli/hooks/stdin-parser.d.ts.map +1 -0
- package/dist/cli/hooks/stdin-parser.js +127 -0
- package/dist/cli/hooks/stdin-parser.js.map +1 -0
- package/dist/cli/hooks/suggest.d.ts +19 -0
- package/dist/cli/hooks/suggest.d.ts.map +1 -0
- package/dist/cli/hooks/suggest.js +157 -0
- package/dist/cli/hooks/suggest.js.map +1 -0
- package/dist/cli/hooks/track-plan.d.ts +36 -0
- package/dist/cli/hooks/track-plan.d.ts.map +1 -0
- package/dist/cli/hooks/track-plan.js +152 -0
- package/dist/cli/hooks/track-plan.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +56 -16
- package/dist/cli.js.map +1 -1
- package/dist/config/global-config.d.ts +187 -0
- package/dist/config/global-config.d.ts.map +1 -0
- package/dist/config/global-config.js +206 -0
- package/dist/config/global-config.js.map +1 -0
- package/dist/config/loader.d.ts +42 -0
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +96 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/constants.d.ts +4 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +10 -0
- package/dist/constants.js.map +1 -1
- package/dist/database/operations/queries.d.ts.map +1 -1
- package/dist/database/operations/queries.js +11 -2
- package/dist/database/operations/queries.js.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/init-agents.js +0 -1
- package/dist/init-agents.js.map +1 -1
- package/dist/init-skills.d.ts +4 -3
- package/dist/init-skills.d.ts.map +1 -1
- package/dist/init-skills.js +10 -3
- package/dist/init-skills.js.map +1 -1
- package/dist/server/setup.d.ts +8 -0
- package/dist/server/setup.d.ts.map +1 -1
- package/dist/server/setup.js +141 -21
- package/dist/server/setup.js.map +1 -1
- package/dist/sync-agents.d.ts.map +1 -1
- package/dist/sync-agents.js +48 -3
- package/dist/sync-agents.js.map +1 -1
- package/dist/sync-commands.d.ts.map +1 -1
- package/dist/sync-commands.js +43 -3
- package/dist/sync-commands.js.map +1 -1
- package/dist/tools/constraints/actions/get.d.ts.map +1 -1
- package/dist/tools/constraints/actions/get.js +5 -8
- package/dist/tools/constraints/actions/get.js.map +1 -1
- package/dist/tools/constraints/help/help.d.ts.map +1 -1
- package/dist/tools/constraints/help/help.js +1 -6
- package/dist/tools/constraints/help/help.js.map +1 -1
- package/dist/tools/context/actions/get.d.ts.map +1 -1
- package/dist/tools/context/actions/get.js.map +1 -1
- package/dist/tools/context/actions/search-layer.d.ts.map +1 -1
- package/dist/tools/context/actions/search-layer.js +5 -3
- package/dist/tools/context/actions/search-layer.js.map +1 -1
- package/dist/tools/context/actions/set-from-policy.d.ts +2 -1
- package/dist/tools/context/actions/set-from-policy.d.ts.map +1 -1
- package/dist/tools/context/actions/set-from-policy.js.map +1 -1
- package/dist/tools/context/help/help.d.ts.map +1 -1
- package/dist/tools/context/help/help.js +1 -7
- package/dist/tools/context/help/help.js.map +1 -1
- package/dist/tools/context/internal/queries.d.ts.map +1 -1
- package/dist/tools/context/internal/queries.js +5 -2
- package/dist/tools/context/internal/queries.js.map +1 -1
- package/dist/tools/context/types.d.ts +1 -1
- package/dist/tools/context/types.d.ts.map +1 -1
- package/dist/tools/files/actions/get.d.ts.map +1 -1
- package/dist/tools/files/actions/get.js +4 -6
- package/dist/tools/files/actions/get.js.map +1 -1
- package/dist/tools/files/help/help.d.ts.map +1 -1
- package/dist/tools/files/help/help.js +1 -6
- package/dist/tools/files/help/help.js.map +1 -1
- package/dist/tools/suggest/help/constraint-help.d.ts.map +1 -1
- package/dist/tools/suggest/help/constraint-help.js +0 -2
- package/dist/tools/suggest/help/constraint-help.js.map +1 -1
- package/dist/tools/suggest/internal/constraint-queries.d.ts.map +1 -1
- package/dist/tools/suggest/internal/constraint-queries.js +12 -5
- package/dist/tools/suggest/internal/constraint-queries.js.map +1 -1
- package/dist/tools/suggest/internal/queries.js +2 -2
- package/dist/tools/suggest/internal/queries.js.map +1 -1
- package/dist/tools/tasks/help/help.d.ts.map +1 -1
- package/dist/tools/tasks/help/help.js +0 -6
- package/dist/tools/tasks/help/help.js.map +1 -1
- package/dist/tools/tasks/help/use-case.d.ts.map +1 -1
- package/dist/tools/tasks/help/use-case.js +0 -1
- package/dist/tools/tasks/help/use-case.js.map +1 -1
- package/dist/tools/tasks/watcher/status.d.ts.map +1 -1
- package/dist/tools/tasks/watcher/status.js +5 -1
- package/dist/tools/tasks/watcher/status.js.map +1 -1
- package/dist/types/decision/params.d.ts +7 -6
- package/dist/types/decision/params.d.ts.map +1 -1
- package/dist/types/decision/templates.d.ts +3 -2
- package/dist/types/decision/templates.d.ts.map +1 -1
- package/dist/types/view-entities.d.ts +2 -1
- package/dist/types/view-entities.d.ts.map +1 -1
- package/dist/types.d.ts +19 -11
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/enum-converter.d.ts +72 -0
- package/dist/utils/enum-converter.d.ts.map +1 -0
- package/dist/utils/enum-converter.js +76 -0
- package/dist/utils/enum-converter.js.map +1 -0
- package/dist/utils/hook-queue.d.ts +81 -0
- package/dist/utils/hook-queue.d.ts.map +1 -0
- package/dist/utils/hook-queue.js +156 -0
- package/dist/utils/hook-queue.js.map +1 -0
- package/dist/utils/project-root.d.ts +9 -2
- package/dist/utils/project-root.d.ts.map +1 -1
- package/dist/utils/project-root.js +16 -2
- package/dist/utils/project-root.js.map +1 -1
- package/dist/utils/tag-parser.d.ts.map +1 -1
- package/dist/utils/tag-parser.js +6 -0
- package/dist/utils/tag-parser.js.map +1 -1
- package/dist/utils/validators.d.ts +1 -1
- package/dist/utils/validators.d.ts.map +1 -1
- package/dist/utils/validators.js +1 -1
- package/dist/utils/validators.js.map +1 -1
- package/dist/utils/vcs-adapter.d.ts +44 -0
- package/dist/utils/vcs-adapter.d.ts.map +1 -1
- package/dist/utils/vcs-adapter.js +88 -0
- package/dist/utils/vcs-adapter.js.map +1 -1
- package/dist/utils/view-queries.d.ts.map +1 -1
- package/dist/utils/view-queries.js +9 -19
- package/dist/utils/view-queries.js.map +1 -1
- package/dist/watcher/base-watcher.d.ts +69 -0
- package/dist/watcher/base-watcher.d.ts.map +1 -0
- package/dist/watcher/base-watcher.js +130 -0
- package/dist/watcher/base-watcher.js.map +1 -0
- package/dist/watcher/index.d.ts +3 -0
- package/dist/watcher/index.d.ts.map +1 -1
- package/dist/watcher/index.js +2 -0
- package/dist/watcher/index.js.map +1 -1
- package/dist/watcher/queue-watcher.d.ts +64 -0
- package/dist/watcher/queue-watcher.d.ts.map +1 -0
- package/dist/watcher/queue-watcher.js +187 -0
- package/dist/watcher/queue-watcher.js.map +1 -0
- package/docs/ADR_CONCEPTS.md +140 -0
- package/docs/CONFIGURATION.md +922 -925
- package/docs/CROSS_DATABASE.md +153 -0
- package/docs/DATABASE_AUTH.md +70 -356
- package/docs/HOOKS_GUIDE.md +159 -0
- package/docs/SLASH_COMMANDS.md +329 -337
- package/docs/TASK_SYSTEM_DEPRECATED.md +88 -0
- package/docs/changelogs/CHANGELOG_ARCHIVE_v3.4_and_older.md +293 -296
- package/docs/cli/DATA_EXPORT_IMPORT.md +699 -700
- package/docs/cli/README.md +276 -277
- package/package.json +123 -119
- package/docs/ACCEPTANCE_CRITERIA.md +0 -625
- package/docs/AI_AGENT_GUIDE.md +0 -198
- package/docs/ARCHITECTURE.md +0 -167
- package/docs/AUTO_FILE_TRACKING.md +0 -841
- package/docs/BATCH_VALIDATION.md +0 -617
- package/docs/BEST_PRACTICES.md +0 -168
- package/docs/CONSTRAINT_INTELLIGENCE.md +0 -339
- package/docs/DECISION_CONTEXT.md +0 -675
- package/docs/DECISION_INTELLIGENCE.md +0 -605
- package/docs/GIT_AWARE_AUTO_COMPLETE.md +0 -646
- package/docs/MIGRATION_GUIDE_V3.9.0.md +0 -371
- package/docs/SHARED_CONCEPTS.md +0 -225
- package/docs/SPECIALIZED_AGENTS.md +0 -126
- package/docs/TASK_ACTIONS.md +0 -1177
- package/docs/TASK_OVERVIEW.md +0 -452
- package/docs/TASK_PRUNING.md +0 -594
- package/docs/TOOL_REFERENCE.md +0 -1077
- package/docs/TOOL_SELECTION.md +0 -83
- package/docs/WORKFLOWS.md +0 -941
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Watcher - Common file watching functionality
|
|
3
|
+
*
|
|
4
|
+
* Provides shared infrastructure for file watchers:
|
|
5
|
+
* - chokidar v4 initialization
|
|
6
|
+
* - WSL detection and handling
|
|
7
|
+
* - Debounce management
|
|
8
|
+
* - Start/stop lifecycle
|
|
9
|
+
*
|
|
10
|
+
* @since v4.1.0
|
|
11
|
+
*/
|
|
12
|
+
import chokidar from 'chokidar';
|
|
13
|
+
import { execSync } from 'child_process';
|
|
14
|
+
import { debugLog } from '../utils/debug-logger.js';
|
|
15
|
+
/**
|
|
16
|
+
* Abstract base class for file watchers
|
|
17
|
+
*/
|
|
18
|
+
export class BaseWatcher {
|
|
19
|
+
watcher = null;
|
|
20
|
+
isRunning = false;
|
|
21
|
+
debounceTimers = new Map();
|
|
22
|
+
debounceMs;
|
|
23
|
+
watcherName;
|
|
24
|
+
constructor(name, debounceMs = 2000) {
|
|
25
|
+
this.watcherName = name;
|
|
26
|
+
this.debounceMs = debounceMs;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Detect if running on WSL (Windows Subsystem for Linux)
|
|
30
|
+
*/
|
|
31
|
+
isWSL() {
|
|
32
|
+
if (process.platform !== 'linux') {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const result = execSync('uname -r', {
|
|
37
|
+
encoding: 'utf-8',
|
|
38
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
39
|
+
});
|
|
40
|
+
return (result.toLowerCase().includes('microsoft') ||
|
|
41
|
+
result.toLowerCase().includes('wsl'));
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Initialize chokidar watcher with common options
|
|
49
|
+
*/
|
|
50
|
+
initializeWatcher(options) {
|
|
51
|
+
const isWSL = this.isWSL();
|
|
52
|
+
if (isWSL) {
|
|
53
|
+
debugLog('INFO', `${this.watcherName}: WSL detected`);
|
|
54
|
+
}
|
|
55
|
+
const watcherConfig = {
|
|
56
|
+
persistent: true,
|
|
57
|
+
ignoreInitial: options.ignoreInitial ?? true,
|
|
58
|
+
awaitWriteFinish: {
|
|
59
|
+
stabilityThreshold: options.debounceMs ?? this.debounceMs,
|
|
60
|
+
pollInterval: 100,
|
|
61
|
+
},
|
|
62
|
+
usePolling: options.usePolling ?? false,
|
|
63
|
+
interval: options.pollInterval ?? 100,
|
|
64
|
+
};
|
|
65
|
+
if (options.ignored && watcherConfig) {
|
|
66
|
+
watcherConfig.ignored = options.ignored;
|
|
67
|
+
}
|
|
68
|
+
return chokidar.watch(options.paths, watcherConfig);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Debounced handler - calls handler after debounce period
|
|
72
|
+
*/
|
|
73
|
+
debounce(key, handler) {
|
|
74
|
+
// Clear existing timer for this key
|
|
75
|
+
const existingTimer = this.debounceTimers.get(key);
|
|
76
|
+
if (existingTimer) {
|
|
77
|
+
clearTimeout(existingTimer);
|
|
78
|
+
}
|
|
79
|
+
// Set new timer
|
|
80
|
+
const timer = setTimeout(async () => {
|
|
81
|
+
this.debounceTimers.delete(key);
|
|
82
|
+
try {
|
|
83
|
+
await handler();
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
debugLog('ERROR', `${this.watcherName}: Error in debounced handler`, {
|
|
87
|
+
error,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}, this.debounceMs);
|
|
91
|
+
this.debounceTimers.set(key, timer);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Stop the watcher
|
|
95
|
+
*/
|
|
96
|
+
async stop() {
|
|
97
|
+
if (!this.isRunning) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
// Clear all debounce timers
|
|
102
|
+
this.debounceTimers.forEach((timer) => clearTimeout(timer));
|
|
103
|
+
this.debounceTimers.clear();
|
|
104
|
+
// Close watcher
|
|
105
|
+
if (this.watcher) {
|
|
106
|
+
await this.watcher.close();
|
|
107
|
+
this.watcher = null;
|
|
108
|
+
}
|
|
109
|
+
this.isRunning = false;
|
|
110
|
+
debugLog('INFO', `${this.watcherName}: Stopped`);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
debugLog('ERROR', `${this.watcherName}: Error stopping`, { error });
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Check if watcher is running
|
|
119
|
+
*/
|
|
120
|
+
getIsRunning() {
|
|
121
|
+
return this.isRunning;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get watcher name for logging
|
|
125
|
+
*/
|
|
126
|
+
getName() {
|
|
127
|
+
return this.watcherName;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=base-watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-watcher.js","sourceRoot":"","sources":["../../src/watcher/base-watcher.ts"],"names":[],"mappings":"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"}
|
package/dist/watcher/index.d.ts
CHANGED
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
* Watcher module exports
|
|
3
3
|
* Provides file watching and test execution functionality
|
|
4
4
|
*/
|
|
5
|
+
export { BaseWatcher } from './base-watcher.js';
|
|
6
|
+
export type { WatcherOptions } from './base-watcher.js';
|
|
5
7
|
export { FileWatcher } from './file-watcher.js';
|
|
8
|
+
export { QueueWatcher, startQueueWatcher, stopQueueWatcher } from './queue-watcher.js';
|
|
6
9
|
export { executeAcceptanceCriteria } from './test-executor.js';
|
|
7
10
|
export type { CheckResult } from './test-executor.js';
|
|
8
11
|
export { GitIgnoreParser, createGitIgnoreParser, BUILT_IN_IGNORE_PATTERNS } from './gitignore-parser.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/watcher/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/watcher/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACvF,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/watcher/index.js
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
* Watcher module exports
|
|
3
3
|
* Provides file watching and test execution functionality
|
|
4
4
|
*/
|
|
5
|
+
export { BaseWatcher } from './base-watcher.js';
|
|
5
6
|
export { FileWatcher } from './file-watcher.js';
|
|
7
|
+
export { QueueWatcher, startQueueWatcher, stopQueueWatcher } from './queue-watcher.js';
|
|
6
8
|
export { executeAcceptanceCriteria } from './test-executor.js';
|
|
7
9
|
export { GitIgnoreParser, createGitIgnoreParser, BUILT_IN_IGNORE_PATTERNS } from './gitignore-parser.js';
|
|
8
10
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/watcher/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAE/D,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/watcher/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACvF,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAE/D,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue Watcher - Monitors hook queue file for changes
|
|
3
|
+
*
|
|
4
|
+
* Watches `.sqlew/queue/pending.json` and processes queued decisions
|
|
5
|
+
* when hooks write to the queue file.
|
|
6
|
+
*
|
|
7
|
+
* Flow:
|
|
8
|
+
* 1. Hook writes to queue file (fast, <100ms)
|
|
9
|
+
* 2. QueueWatcher detects change
|
|
10
|
+
* 3. processHookQueue() registers decisions in DB
|
|
11
|
+
*
|
|
12
|
+
* @since v4.1.0
|
|
13
|
+
*/
|
|
14
|
+
import { BaseWatcher } from './base-watcher.js';
|
|
15
|
+
/**
|
|
16
|
+
* QueueWatcher - Singleton for monitoring hook queue
|
|
17
|
+
*/
|
|
18
|
+
export declare class QueueWatcher extends BaseWatcher {
|
|
19
|
+
private static instance;
|
|
20
|
+
private projectRoot;
|
|
21
|
+
private processing;
|
|
22
|
+
private constructor();
|
|
23
|
+
/**
|
|
24
|
+
* Get singleton instance
|
|
25
|
+
*/
|
|
26
|
+
static getInstance(projectRoot?: string): QueueWatcher;
|
|
27
|
+
/**
|
|
28
|
+
* Reset singleton (for testing)
|
|
29
|
+
*/
|
|
30
|
+
static reset(): void;
|
|
31
|
+
/**
|
|
32
|
+
* Start watching the queue file
|
|
33
|
+
*/
|
|
34
|
+
start(): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Handle queue file change
|
|
37
|
+
*/
|
|
38
|
+
private handleQueueChange;
|
|
39
|
+
/**
|
|
40
|
+
* Process queue if items exist
|
|
41
|
+
*/
|
|
42
|
+
private processQueueIfNeeded;
|
|
43
|
+
/**
|
|
44
|
+
* Process a single queue item
|
|
45
|
+
*/
|
|
46
|
+
private processItem;
|
|
47
|
+
/**
|
|
48
|
+
* Get watcher status
|
|
49
|
+
*/
|
|
50
|
+
getStatus(): {
|
|
51
|
+
running: boolean;
|
|
52
|
+
projectRoot: string;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Start the queue watcher
|
|
57
|
+
* Called from MCP server setup after DB initialization
|
|
58
|
+
*/
|
|
59
|
+
export declare function startQueueWatcher(projectRoot: string): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Stop the queue watcher
|
|
62
|
+
*/
|
|
63
|
+
export declare function stopQueueWatcher(): Promise<void>;
|
|
64
|
+
//# sourceMappingURL=queue-watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-watcher.d.ts","sourceRoot":"","sources":["../../src/watcher/queue-watcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAOhD;;GAEG;AACH,qBAAa,YAAa,SAAQ,WAAW;IAC3C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA6B;IACpD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAkB;IAEpC,OAAO;IAKP;;OAEG;WACW,WAAW,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,YAAY;IAU7D;;OAEG;WACW,KAAK,IAAI,IAAI;IAO3B;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA4CnC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAczB;;OAEG;YACW,oBAAoB;IAuBlC;;OAEG;YACW,WAAW;IAwBzB;;OAEG;IACI,SAAS,IAAI;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE;CAM9D;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG1E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAOtD"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue Watcher - Monitors hook queue file for changes
|
|
3
|
+
*
|
|
4
|
+
* Watches `.sqlew/queue/pending.json` and processes queued decisions
|
|
5
|
+
* when hooks write to the queue file.
|
|
6
|
+
*
|
|
7
|
+
* Flow:
|
|
8
|
+
* 1. Hook writes to queue file (fast, <100ms)
|
|
9
|
+
* 2. QueueWatcher detects change
|
|
10
|
+
* 3. processHookQueue() registers decisions in DB
|
|
11
|
+
*
|
|
12
|
+
* @since v4.1.0
|
|
13
|
+
*/
|
|
14
|
+
import { dirname } from 'path';
|
|
15
|
+
import { existsSync, mkdirSync } from 'fs';
|
|
16
|
+
import { BaseWatcher } from './base-watcher.js';
|
|
17
|
+
import { getQueuePath, hasQueueItems, processQueue } from '../utils/hook-queue.js';
|
|
18
|
+
import { quickSetDecision } from '../tools/context/actions/quick-set.js';
|
|
19
|
+
import { setDecision } from '../tools/context/actions/set.js';
|
|
20
|
+
import { debugLog } from '../utils/debug-logger.js';
|
|
21
|
+
/**
|
|
22
|
+
* QueueWatcher - Singleton for monitoring hook queue
|
|
23
|
+
*/
|
|
24
|
+
export class QueueWatcher extends BaseWatcher {
|
|
25
|
+
static instance = null;
|
|
26
|
+
projectRoot;
|
|
27
|
+
processing = false;
|
|
28
|
+
constructor(projectRoot) {
|
|
29
|
+
super('QueueWatcher', 500); // 500ms debounce for queue changes
|
|
30
|
+
this.projectRoot = projectRoot;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get singleton instance
|
|
34
|
+
*/
|
|
35
|
+
static getInstance(projectRoot) {
|
|
36
|
+
if (!QueueWatcher.instance) {
|
|
37
|
+
if (!projectRoot) {
|
|
38
|
+
throw new Error('QueueWatcher: projectRoot required for first initialization');
|
|
39
|
+
}
|
|
40
|
+
QueueWatcher.instance = new QueueWatcher(projectRoot);
|
|
41
|
+
}
|
|
42
|
+
return QueueWatcher.instance;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Reset singleton (for testing)
|
|
46
|
+
*/
|
|
47
|
+
static reset() {
|
|
48
|
+
if (QueueWatcher.instance) {
|
|
49
|
+
QueueWatcher.instance.stop().catch(() => { });
|
|
50
|
+
}
|
|
51
|
+
QueueWatcher.instance = null;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Start watching the queue file
|
|
55
|
+
*/
|
|
56
|
+
async start() {
|
|
57
|
+
if (this.isRunning) {
|
|
58
|
+
debugLog('WARN', `${this.watcherName}: Already running`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
const queuePath = getQueuePath(this.projectRoot);
|
|
63
|
+
const queueDir = dirname(queuePath);
|
|
64
|
+
// Ensure queue directory exists
|
|
65
|
+
if (!existsSync(queueDir)) {
|
|
66
|
+
mkdirSync(queueDir, { recursive: true });
|
|
67
|
+
}
|
|
68
|
+
// Watch the queue directory (not just file, to catch file creation)
|
|
69
|
+
this.watcher = this.initializeWatcher({
|
|
70
|
+
paths: queueDir,
|
|
71
|
+
debounceMs: this.debounceMs,
|
|
72
|
+
ignoreInitial: false, // Process existing queue on startup
|
|
73
|
+
});
|
|
74
|
+
// Handle file changes
|
|
75
|
+
this.watcher.on('add', (path) => this.handleQueueChange(path));
|
|
76
|
+
this.watcher.on('change', (path) => this.handleQueueChange(path));
|
|
77
|
+
this.watcher.on('error', (error) => {
|
|
78
|
+
debugLog('ERROR', `${this.watcherName}: Watch error`, { error });
|
|
79
|
+
});
|
|
80
|
+
this.isRunning = true;
|
|
81
|
+
debugLog('INFO', `${this.watcherName}: Started`, {
|
|
82
|
+
projectRoot: this.projectRoot,
|
|
83
|
+
queueDir,
|
|
84
|
+
});
|
|
85
|
+
// Process any existing queue items on startup
|
|
86
|
+
await this.processQueueIfNeeded();
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
debugLog('ERROR', `${this.watcherName}: Failed to start`, { error });
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Handle queue file change
|
|
95
|
+
*/
|
|
96
|
+
handleQueueChange(path) {
|
|
97
|
+
// Only process pending.json
|
|
98
|
+
if (!path.endsWith('pending.json')) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
debugLog('INFO', `${this.watcherName}: Queue file changed`);
|
|
102
|
+
// Debounce to avoid processing during rapid writes
|
|
103
|
+
this.debounce('queue-process', async () => {
|
|
104
|
+
await this.processQueueIfNeeded();
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Process queue if items exist
|
|
109
|
+
*/
|
|
110
|
+
async processQueueIfNeeded() {
|
|
111
|
+
// Prevent concurrent processing
|
|
112
|
+
if (this.processing) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (!hasQueueItems(this.projectRoot)) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
this.processing = true;
|
|
119
|
+
try {
|
|
120
|
+
const count = await processQueue(this.projectRoot, this.processItem.bind(this));
|
|
121
|
+
if (count > 0) {
|
|
122
|
+
debugLog('INFO', `${this.watcherName}: Processed ${count} queue items`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
debugLog('ERROR', `${this.watcherName}: Error processing queue`, { error });
|
|
127
|
+
}
|
|
128
|
+
finally {
|
|
129
|
+
this.processing = false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Process a single queue item
|
|
134
|
+
*/
|
|
135
|
+
async processItem(item) {
|
|
136
|
+
const { action, data } = item;
|
|
137
|
+
debugLog('INFO', `${this.watcherName}: Processing ${action}`, { key: data.key });
|
|
138
|
+
if (action === 'create') {
|
|
139
|
+
await quickSetDecision({
|
|
140
|
+
key: data.key,
|
|
141
|
+
value: data.value,
|
|
142
|
+
status: data.status,
|
|
143
|
+
layer: data.layer,
|
|
144
|
+
tags: data.tags,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
else if (action === 'update') {
|
|
148
|
+
await setDecision({
|
|
149
|
+
key: data.key,
|
|
150
|
+
value: data.value || `Updated: ${data.key}`,
|
|
151
|
+
status: data.status,
|
|
152
|
+
layer: data.layer,
|
|
153
|
+
tags: data.tags,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get watcher status
|
|
159
|
+
*/
|
|
160
|
+
getStatus() {
|
|
161
|
+
return {
|
|
162
|
+
running: this.isRunning,
|
|
163
|
+
projectRoot: this.projectRoot,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Start the queue watcher
|
|
169
|
+
* Called from MCP server setup after DB initialization
|
|
170
|
+
*/
|
|
171
|
+
export async function startQueueWatcher(projectRoot) {
|
|
172
|
+
const watcher = QueueWatcher.getInstance(projectRoot);
|
|
173
|
+
await watcher.start();
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Stop the queue watcher
|
|
177
|
+
*/
|
|
178
|
+
export async function stopQueueWatcher() {
|
|
179
|
+
try {
|
|
180
|
+
const watcher = QueueWatcher.getInstance();
|
|
181
|
+
await watcher.stop();
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
// Instance not initialized, nothing to stop
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=queue-watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-watcher.js","sourceRoot":"","sources":["../../src/watcher/queue-watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# ADR (Architecture Decision Record) Concepts
|
|
2
|
+
|
|
3
|
+
**Architecture Decision Records (ADR)** document the architectural decisions made on a project, including context, consequences, and alternatives considered. sqlew extends this proven pattern to AI agents.
|
|
4
|
+
|
|
5
|
+
## How It Works
|
|
6
|
+
|
|
7
|
+
```mermaid
|
|
8
|
+
flowchart LR
|
|
9
|
+
subgraph Claude Code
|
|
10
|
+
A[Plan Mode] -->|Create Plan| B[User Approval]
|
|
11
|
+
B -->|ExitPlanMode| C[Hook Triggered]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
subgraph sqlew
|
|
15
|
+
C -->|Enqueue| D[Queue File]
|
|
16
|
+
D -->|QueueWatcher| E[(SQL Database)]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
subgraph Next Session
|
|
20
|
+
F[AI Agent] -->|Query| E
|
|
21
|
+
E -->|Past Decisions| F
|
|
22
|
+
end
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Zero-effort knowledge accumulation:**
|
|
26
|
+
1. You plan your work normally in Claude Code
|
|
27
|
+
2. Hooks automatically capture decisions
|
|
28
|
+
3. Next session, AI queries past decisions via SQL
|
|
29
|
+
|
|
30
|
+
## Core ADR Concepts in sqlew
|
|
31
|
+
|
|
32
|
+
**Decisions** capture architectural choices with full context:
|
|
33
|
+
- **What** was decided (the decision itself)
|
|
34
|
+
- **Why** it was chosen (rationale, trade-offs)
|
|
35
|
+
- **What else** was considered (alternatives rejected)
|
|
36
|
+
- **Impact** on the system (consequences, affected components)
|
|
37
|
+
|
|
38
|
+
**Constraints** define architectural principles and rules:
|
|
39
|
+
- **Performance requirements** (response time limits, throughput goals)
|
|
40
|
+
- **Technology choices** ("must use PostgreSQL", "avoid microservices")
|
|
41
|
+
- **Coding standards** ("async/await only", "no any types")
|
|
42
|
+
- **Security policies** (authentication patterns, data handling rules)
|
|
43
|
+
|
|
44
|
+
**Implementation tracking** connects decisions to reality:
|
|
45
|
+
- **File tracking** shows which code was affected by decisions
|
|
46
|
+
- **Status evolution** tracks decision lifecycle (draft → active → deprecated)
|
|
47
|
+
- **Auto-capture via Hooks** records decisions automatically from Plan Mode
|
|
48
|
+
|
|
49
|
+
```mermaid
|
|
50
|
+
erDiagram
|
|
51
|
+
DECISION ||--o{ TAG : has
|
|
52
|
+
DECISION ||--o{ FILE : affects
|
|
53
|
+
DECISION {
|
|
54
|
+
string key
|
|
55
|
+
string value
|
|
56
|
+
string layer
|
|
57
|
+
string status
|
|
58
|
+
timestamp updated
|
|
59
|
+
}
|
|
60
|
+
CONSTRAINT ||--o{ TAG : has
|
|
61
|
+
CONSTRAINT {
|
|
62
|
+
string text
|
|
63
|
+
string category
|
|
64
|
+
int priority
|
|
65
|
+
}
|
|
66
|
+
TAG {
|
|
67
|
+
string name
|
|
68
|
+
}
|
|
69
|
+
FILE {
|
|
70
|
+
string path
|
|
71
|
+
string action
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Why SQL for ADR?
|
|
76
|
+
|
|
77
|
+
Traditional text-based ADR forces AI to:
|
|
78
|
+
- Read complete files even for simple queries
|
|
79
|
+
- Parse unstructured text to find relationships
|
|
80
|
+
- Manually detect duplicate or conflicting decisions
|
|
81
|
+
|
|
82
|
+
sqlew's **SQL-backed ADR repository** enables AI to:
|
|
83
|
+
- Query by layer, tags, status in milliseconds (2-50ms)
|
|
84
|
+
- Join decisions with constraints and files
|
|
85
|
+
- Leverage similarity algorithms to prevent duplicates
|
|
86
|
+
- Scale to thousands of decisions without context explosion
|
|
87
|
+
|
|
88
|
+
**Token efficiency**: 60-75% reduction compared to reading Markdown ADRs
|
|
89
|
+
|
|
90
|
+
## Why RDBMS + MCP for ADR?
|
|
91
|
+
|
|
92
|
+
**RDBMS (Relational Database)** provides efficient structured queries:
|
|
93
|
+
- **Indexed searches** – Find decisions by tags/layers in milliseconds, not seconds
|
|
94
|
+
- **JOIN operations** – Query related decisions and constraints in a single operation
|
|
95
|
+
- **Transaction support** – ACID guarantees ensure data integrity across concurrent AI agents
|
|
96
|
+
- **Scalability** – Handle thousands of ADRs without performance degradation
|
|
97
|
+
|
|
98
|
+
**MCP (Model Context Protocol)** enables seamless AI integration:
|
|
99
|
+
- **Direct tool access** – AI agents call ADR operations as native functions
|
|
100
|
+
- **Token efficiency** – Retrieve only required data, avoiding full-file reads
|
|
101
|
+
- **Type safety** – Structured parameters prevent errors and guide correct usage
|
|
102
|
+
- **Cross-session persistence** – ADRs survive beyond individual chat sessions
|
|
103
|
+
|
|
104
|
+
**Together**: AI agents gain SQL-powered ADR capabilities without managing databases directly.
|
|
105
|
+
|
|
106
|
+
## Traditional vs sqlew ADR
|
|
107
|
+
|
|
108
|
+
| Traditional ADR (Markdown) | sqlew ADR (SQL) |
|
|
109
|
+
|---------------------------|-----------------|
|
|
110
|
+
| Read entire files | Query specific decisions |
|
|
111
|
+
| Manual duplicate checking | Automatic similarity detection |
|
|
112
|
+
| Text parsing required | Structured, typed data |
|
|
113
|
+
| Linear token scaling | Constant-time lookups |
|
|
114
|
+
| File-based organization | Relational queries with JOINs |
|
|
115
|
+
|
|
116
|
+
## Key Benefits for AI-Driven Development
|
|
117
|
+
|
|
118
|
+
### 📚 Persistent Architectural Memory
|
|
119
|
+
- **Zero context loss** – AI agents remember every architectural decision across sessions
|
|
120
|
+
- **Rationale preservation** – Never forget WHY a decision was made, not just WHAT
|
|
121
|
+
- **Alternative tracking** – Document rejected options to prevent circular debates
|
|
122
|
+
- **Evolution history** – See how decisions changed over time with full version history
|
|
123
|
+
|
|
124
|
+
### 🛡️ Prevent Architectural Drift
|
|
125
|
+
- **Constraint enforcement** – Define architectural rules once, AI follows them forever
|
|
126
|
+
- **Pattern consistency** – AI generates code matching established patterns automatically
|
|
127
|
+
- **Anti-pattern prevention** – Document "what NOT to do" as enforceable constraints
|
|
128
|
+
- **Regression prevention** – AI won't reintroduce previously rejected approaches
|
|
129
|
+
|
|
130
|
+
### 🔍 Intelligent Decision Discovery
|
|
131
|
+
- **Three-tier duplicate detection** – Gentle nudge (35-44), hard block (45-59), or auto-update (60+) based on similarity score
|
|
132
|
+
- **Similarity detection** – AI identifies duplicate or related decisions before creating new ones
|
|
133
|
+
- **Context-aware search** – Query by layer, tags, or relationships to find relevant decisions
|
|
134
|
+
- **Impact analysis** – Trace which files are affected by each decision
|
|
135
|
+
- **Conflict detection** – Find decisions that contradict or supersede each other
|
|
136
|
+
|
|
137
|
+
### ⚡ Extreme Efficiency
|
|
138
|
+
- **60-75% token reduction** – Query only relevant decisions instead of reading all ADRs
|
|
139
|
+
- **Millisecond queries** – 2-50ms response times even with thousands of decisions
|
|
140
|
+
- **Scalable architecture** – Perform well with large decision histories
|