agentic-qe 3.7.20 → 3.7.22
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/.claude/agents/v3/qe-deployment-advisor.md +14 -0
- package/.claude/agents/v3/qe-gap-detector.md +8 -0
- package/.claude/agents/v3/qe-impact-analyzer.md +11 -0
- package/.claude/agents/v3/qe-queen-coordinator.md +45 -0
- package/.claude/agents/v3/qe-root-cause-analyzer.md +11 -0
- package/.claude/agents/v3/qe-security-scanner.md +25 -16
- package/.claude/helpers/brain-checkpoint.cjs +7 -4
- package/.claude/helpers/statusline-v3.cjs +7 -4
- package/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +34 -0
- package/README.md +0 -12
- package/assets/agents/v3/qe-deployment-advisor.md +14 -0
- package/assets/agents/v3/qe-gap-detector.md +8 -0
- package/assets/agents/v3/qe-impact-analyzer.md +11 -0
- package/assets/agents/v3/qe-queen-coordinator.md +45 -0
- package/assets/agents/v3/qe-root-cause-analyzer.md +11 -0
- package/assets/agents/v3/qe-security-scanner.md +25 -16
- package/assets/helpers/statusline-v3.cjs +7 -4
- package/dist/adapters/claude-flow/model-router-bridge.d.ts +0 -6
- package/dist/adapters/claude-flow/model-router-bridge.js +4 -17
- package/dist/adapters/claude-flow/pretrain-bridge.d.ts +0 -6
- package/dist/adapters/claude-flow/pretrain-bridge.js +6 -19
- package/dist/adapters/claude-flow/trajectory-bridge.d.ts +0 -6
- package/dist/adapters/claude-flow/trajectory-bridge.js +21 -23
- package/dist/cli/brain-commands.js +6 -10
- package/dist/cli/bundle.js +3124 -3622
- package/dist/cli/commands/hooks.js +29 -6
- package/dist/cli/commands/init.js +1 -73
- package/dist/cli/commands/learning.js +164 -12
- package/dist/cli/handlers/init-handler.d.ts +0 -1
- package/dist/cli/handlers/init-handler.js +0 -6
- package/dist/cli/index.js +0 -2
- package/dist/context/sources/defect-source.js +2 -2
- package/dist/context/sources/memory-source.js +2 -2
- package/dist/context/sources/requirements-source.js +2 -2
- package/dist/coordination/protocols/security-audit.d.ts +3 -6
- package/dist/coordination/protocols/security-audit.js +8 -88
- package/dist/coordination/queen-coordinator.d.ts +13 -0
- package/dist/coordination/queen-coordinator.js +76 -0
- package/dist/coordination/queen-task-management.d.ts +2 -0
- package/dist/coordination/queen-task-management.js +10 -0
- package/dist/coordination/queen-types.d.ts +3 -0
- package/dist/coordination/task-executor.js +7 -5
- package/dist/domains/security-compliance/services/scanners/sast-scanner.d.ts +25 -1
- package/dist/domains/security-compliance/services/scanners/sast-scanner.js +140 -11
- package/dist/domains/security-compliance/services/scanners/scanner-types.d.ts +2 -0
- package/dist/domains/security-compliance/services/scanners/scanner-types.js +1 -0
- package/dist/domains/test-execution/services/mincut-test-optimizer.js +2 -0
- package/dist/init/agents-installer.d.ts +2 -0
- package/dist/init/agents-installer.js +13 -0
- package/dist/init/enhancements/claude-flow-adapter.js +51 -24
- package/dist/init/index.d.ts +0 -2
- package/dist/init/index.js +0 -1
- package/dist/init/init-wizard-steps.d.ts +10 -0
- package/dist/init/init-wizard-steps.js +87 -1
- package/dist/init/init-wizard.d.ts +1 -9
- package/dist/init/init-wizard.js +3 -69
- package/dist/init/orchestrator.js +0 -1
- package/dist/init/phases/01-detection.js +0 -27
- package/dist/init/phases/07-hooks.js +12 -10
- package/dist/init/phases/phase-interface.d.ts +0 -1
- package/dist/init/settings-merge.js +1 -1
- package/dist/integrations/ruvector/brain-rvf-exporter.js +14 -2
- package/dist/kernel/unified-memory.js +5 -6
- package/dist/learning/experience-capture-middleware.js +23 -1
- package/dist/learning/index.d.ts +0 -2
- package/dist/learning/index.js +0 -4
- package/dist/learning/metrics-tracker.js +15 -13
- package/dist/learning/pattern-lifecycle.d.ts +1 -1
- package/dist/learning/pattern-lifecycle.js +18 -20
- package/dist/learning/qe-reasoning-bank.js +3 -3
- package/dist/learning/qe-unified-memory.js +1 -28
- package/dist/learning/sqlite-persistence.js +16 -0
- package/dist/learning/token-tracker.js +4 -2
- package/dist/mcp/bundle.js +1162 -478
- package/dist/routing/agent-dependency-graph.d.ts +77 -0
- package/dist/routing/agent-dependency-graph.js +359 -0
- package/dist/routing/co-execution-repository.d.ts +68 -0
- package/dist/routing/co-execution-repository.js +184 -0
- package/dist/routing/index.d.ts +6 -0
- package/dist/routing/index.js +6 -0
- package/dist/routing/qe-task-router.d.ts +7 -0
- package/dist/routing/qe-task-router.js +63 -1
- package/dist/routing/signal-merger.d.ts +81 -0
- package/dist/routing/signal-merger.js +136 -0
- package/dist/routing/types.d.ts +1 -0
- package/dist/shared/llm/providers/azure-openai.js +3 -2
- package/dist/shared/llm/providers/bedrock.js +3 -2
- package/dist/shared/llm/providers/claude.js +3 -2
- package/dist/shared/llm/providers/gemini.js +3 -2
- package/dist/shared/llm/providers/openai.js +3 -2
- package/dist/shared/llm/providers/openrouter.js +3 -2
- package/dist/shared/llm/retry.d.ts +10 -0
- package/dist/shared/llm/retry.js +16 -0
- package/dist/shared/llm/router/agent-router-config.d.ts +2 -1
- package/dist/shared/llm/router/agent-router-config.js +38 -88
- package/dist/validation/index.d.ts +2 -0
- package/dist/validation/index.js +4 -0
- package/dist/validation/steps/agent-mcp-validator.d.ts +88 -0
- package/dist/validation/steps/agent-mcp-validator.js +254 -0
- package/package.json +1 -1
- package/dist/cli/commands/migrate.d.ts +0 -9
- package/dist/cli/commands/migrate.js +0 -566
- package/dist/init/init-wizard-migration.d.ts +0 -52
- package/dist/init/init-wizard-migration.js +0 -345
- package/dist/init/migration/config-migrator.d.ts +0 -31
- package/dist/init/migration/config-migrator.js +0 -149
- package/dist/init/migration/data-migrator.d.ts +0 -72
- package/dist/init/migration/data-migrator.js +0 -232
- package/dist/init/migration/detector.d.ts +0 -44
- package/dist/init/migration/detector.js +0 -105
- package/dist/init/migration/index.d.ts +0 -8
- package/dist/init/migration/index.js +0 -8
- package/dist/learning/v2-to-v3-migration.d.ts +0 -86
- package/dist/learning/v2-to-v3-migration.js +0 -529
|
@@ -11,9 +11,18 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { detectClaudeFlow } from '../../adapters/claude-flow/detect.js';
|
|
13
13
|
import { safeJsonParse } from '../../shared/safe-json.js';
|
|
14
|
-
/** Shared
|
|
15
|
-
const
|
|
16
|
-
|
|
14
|
+
/** Shared execFileSync options */
|
|
15
|
+
const EXEC_OPTS = { encoding: 'utf-8' };
|
|
16
|
+
/**
|
|
17
|
+
* Build args array for npx @claude-flow/cli calls.
|
|
18
|
+
* Using execFileSync with explicit args prevents shell injection.
|
|
19
|
+
*/
|
|
20
|
+
function cfCliArgs(...subcommand) {
|
|
21
|
+
return {
|
|
22
|
+
bin: 'npx',
|
|
23
|
+
args: ['--no-install', '@claude-flow/cli', ...subcommand],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
17
26
|
/**
|
|
18
27
|
* Claude Flow Adapter Implementation
|
|
19
28
|
* Falls back gracefully when Claude Flow is not available
|
|
@@ -86,9 +95,12 @@ export class ClaudeFlowAdapterImpl {
|
|
|
86
95
|
return `aqe-trajectory-${Date.now()}`;
|
|
87
96
|
}
|
|
88
97
|
try {
|
|
89
|
-
const {
|
|
90
|
-
const
|
|
91
|
-
|
|
98
|
+
const { execFileSync } = await import('child_process');
|
|
99
|
+
const { bin, args } = cfCliArgs('hooks', 'intelligence', 'trajectory-start', '--task', task);
|
|
100
|
+
if (agent) {
|
|
101
|
+
args.push('--agent', agent);
|
|
102
|
+
}
|
|
103
|
+
const result = execFileSync(bin, args, { ...EXEC_OPTS, timeout: 10000 });
|
|
92
104
|
// Parse trajectory ID from result
|
|
93
105
|
const match = result.match(/trajectoryId[:\s]+["']?([^"'\s]+)/i);
|
|
94
106
|
return match?.[1] || `cf-trajectory-${Date.now()}`;
|
|
@@ -104,10 +116,15 @@ export class ClaudeFlowAdapterImpl {
|
|
|
104
116
|
if (!this.available)
|
|
105
117
|
return;
|
|
106
118
|
try {
|
|
107
|
-
const {
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
119
|
+
const { execFileSync } = await import('child_process');
|
|
120
|
+
const { bin, args } = cfCliArgs('hooks', 'intelligence', 'trajectory-step', '--trajectory-id', trajectoryId, '--action', action);
|
|
121
|
+
if (result) {
|
|
122
|
+
args.push('--result', result);
|
|
123
|
+
}
|
|
124
|
+
if (quality !== undefined) {
|
|
125
|
+
args.push('--quality', String(quality));
|
|
126
|
+
}
|
|
127
|
+
execFileSync(bin, args, { ...EXEC_OPTS, timeout: 10000 });
|
|
111
128
|
}
|
|
112
129
|
catch (error) {
|
|
113
130
|
// Non-critical: trajectory tracking is optional
|
|
@@ -121,9 +138,12 @@ export class ClaudeFlowAdapterImpl {
|
|
|
121
138
|
if (!this.available)
|
|
122
139
|
return;
|
|
123
140
|
try {
|
|
124
|
-
const {
|
|
125
|
-
const
|
|
126
|
-
|
|
141
|
+
const { execFileSync } = await import('child_process');
|
|
142
|
+
const { bin, args } = cfCliArgs('hooks', 'intelligence', 'trajectory-end', '--trajectory-id', trajectoryId, '--success', String(success));
|
|
143
|
+
if (feedback) {
|
|
144
|
+
args.push('--feedback', feedback);
|
|
145
|
+
}
|
|
146
|
+
execFileSync(bin, args, { ...EXEC_OPTS, timeout: 10000 });
|
|
127
147
|
}
|
|
128
148
|
catch (error) {
|
|
129
149
|
// Non-critical: trajectory end is optional
|
|
@@ -139,8 +159,9 @@ export class ClaudeFlowAdapterImpl {
|
|
|
139
159
|
return { model: 'sonnet', confidence: 0.5 };
|
|
140
160
|
}
|
|
141
161
|
try {
|
|
142
|
-
const {
|
|
143
|
-
const
|
|
162
|
+
const { execFileSync } = await import('child_process');
|
|
163
|
+
const { bin, args } = cfCliArgs('hooks', 'model-route', '--task', task);
|
|
164
|
+
const result = execFileSync(bin, args, { ...EXEC_OPTS, timeout: 10000 });
|
|
144
165
|
// Parse result
|
|
145
166
|
const modelMatch = result.match(/model[:\s]+["']?(haiku|sonnet|opus)/i);
|
|
146
167
|
const confMatch = result.match(/confidence[:\s]+([0-9.]+)/i);
|
|
@@ -162,8 +183,9 @@ export class ClaudeFlowAdapterImpl {
|
|
|
162
183
|
if (!this.available)
|
|
163
184
|
return;
|
|
164
185
|
try {
|
|
165
|
-
const {
|
|
166
|
-
|
|
186
|
+
const { execFileSync } = await import('child_process');
|
|
187
|
+
const { bin, args } = cfCliArgs('hooks', 'model-outcome', '--task', task, '--model', model, '--outcome', outcome);
|
|
188
|
+
execFileSync(bin, args, { ...EXEC_OPTS, timeout: 10000 });
|
|
167
189
|
}
|
|
168
190
|
catch (error) {
|
|
169
191
|
// Non-critical: outcome recording is optional
|
|
@@ -178,8 +200,9 @@ export class ClaudeFlowAdapterImpl {
|
|
|
178
200
|
return { success: false, reason: 'Claude Flow not available' };
|
|
179
201
|
}
|
|
180
202
|
try {
|
|
181
|
-
const {
|
|
182
|
-
const
|
|
203
|
+
const { execFileSync } = await import('child_process');
|
|
204
|
+
const { bin, args } = cfCliArgs('hooks', 'pretrain', '--path', path, '--depth', depth);
|
|
205
|
+
const result = execFileSync(bin, args, { ...EXEC_OPTS, timeout: 60000 });
|
|
183
206
|
// Try to parse JSON result
|
|
184
207
|
try {
|
|
185
208
|
return safeJsonParse(result);
|
|
@@ -199,9 +222,12 @@ export class ClaudeFlowAdapterImpl {
|
|
|
199
222
|
if (!this.available)
|
|
200
223
|
return;
|
|
201
224
|
try {
|
|
202
|
-
const {
|
|
203
|
-
const
|
|
204
|
-
|
|
225
|
+
const { execFileSync } = await import('child_process');
|
|
226
|
+
const { bin, args } = cfCliArgs('hooks', 'intelligence', 'pattern-store', '--pattern', pattern, '--type', type, '--confidence', String(confidence));
|
|
227
|
+
if (metadata) {
|
|
228
|
+
args.push('--metadata', JSON.stringify(metadata));
|
|
229
|
+
}
|
|
230
|
+
execFileSync(bin, args, { ...EXEC_OPTS, timeout: 10000 });
|
|
205
231
|
}
|
|
206
232
|
catch (error) {
|
|
207
233
|
// Non-critical: pattern storage is optional
|
|
@@ -216,8 +242,9 @@ export class ClaudeFlowAdapterImpl {
|
|
|
216
242
|
return [];
|
|
217
243
|
}
|
|
218
244
|
try {
|
|
219
|
-
const {
|
|
220
|
-
const
|
|
245
|
+
const { execFileSync } = await import('child_process');
|
|
246
|
+
const { bin, args } = cfCliArgs('hooks', 'intelligence', 'pattern-search', '--query', query, '--top-k', String(topK));
|
|
247
|
+
const result = execFileSync(bin, args, { ...EXEC_OPTS, timeout: 10000 });
|
|
221
248
|
// Try to parse JSON result
|
|
222
249
|
try {
|
|
223
250
|
const parsed = safeJsonParse(result);
|
package/dist/init/index.d.ts
CHANGED
|
@@ -41,6 +41,4 @@ export type { WindsurfInstallerOptions, WindsurfInstallResult } from './windsurf
|
|
|
41
41
|
export { WindsurfInstaller, createWindsurfInstaller } from './windsurf-installer.js';
|
|
42
42
|
export type { ContinueDevInstallerOptions, ContinueDevInstallResult } from './continuedev-installer.js';
|
|
43
43
|
export { ContinueDevInstaller, createContinueDevInstaller } from './continuedev-installer.js';
|
|
44
|
-
export type { V2DetectionInfo, MigrationResult, } from './migration/index.js';
|
|
45
|
-
export { V2Detector, createV2Detector, V2DataMigrator, createV2DataMigrator, V2ConfigMigrator, createV2ConfigMigrator, } from './migration/index.js';
|
|
46
44
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/init/index.js
CHANGED
|
@@ -24,5 +24,4 @@ export { RooCodeInstaller, createRooCodeInstaller } from './roocode-installer.js
|
|
|
24
24
|
export { CodexInstaller, createCodexInstaller } from './codex-installer.js';
|
|
25
25
|
export { WindsurfInstaller, createWindsurfInstaller } from './windsurf-installer.js';
|
|
26
26
|
export { ContinueDevInstaller, createContinueDevInstaller } from './continuedev-installer.js';
|
|
27
|
-
export { V2Detector, createV2Detector, V2DataMigrator, createV2DataMigrator, V2ConfigMigrator, createV2ConfigMigrator, } from './migration/index.js';
|
|
28
27
|
//# sourceMappingURL=index.js.map
|
|
@@ -6,6 +6,16 @@
|
|
|
6
6
|
* Extracted from init-wizard.ts.
|
|
7
7
|
*/
|
|
8
8
|
import type { AQEInitConfig, PretrainedLibrary } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Read AQE version directly from memory.db without full initialization.
|
|
11
|
+
* Returns undefined if no version is stored.
|
|
12
|
+
*/
|
|
13
|
+
export declare function readVersionFromDb(dbPath: string): string | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Write AQE version to memory.db in _system namespace.
|
|
16
|
+
* Used by init wizard to mark installation version.
|
|
17
|
+
*/
|
|
18
|
+
export declare function writeVersionToDb(projectRoot: string, version: string): Promise<boolean>;
|
|
9
19
|
/**
|
|
10
20
|
* Initialize the persistence database (REQUIRED).
|
|
11
21
|
* Creates the SQLite database file with proper schema.
|
|
@@ -6,12 +6,98 @@
|
|
|
6
6
|
* Extracted from init-wizard.ts.
|
|
7
7
|
*/
|
|
8
8
|
import { existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
9
|
-
import { join } from 'path';
|
|
9
|
+
import { join, dirname } from 'path';
|
|
10
10
|
import { createSkillsInstaller } from './skills-installer.js';
|
|
11
11
|
import { createAgentsInstaller } from './agents-installer.js';
|
|
12
12
|
import { createN8nInstaller } from './n8n-installer.js';
|
|
13
13
|
import { toErrorMessage } from '../shared/error-utils.js';
|
|
14
14
|
import { openDatabase } from '../shared/safe-db.js';
|
|
15
|
+
import { safeJsonParse } from '../shared/safe-json.js';
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Version Management
|
|
18
|
+
// ============================================================================
|
|
19
|
+
/**
|
|
20
|
+
* Read AQE version directly from memory.db without full initialization.
|
|
21
|
+
* Returns undefined if no version is stored.
|
|
22
|
+
*/
|
|
23
|
+
export function readVersionFromDb(dbPath) {
|
|
24
|
+
try {
|
|
25
|
+
const db = openDatabase(dbPath, { readonly: true, fileMustExist: true });
|
|
26
|
+
try {
|
|
27
|
+
const tableExists = db.prepare(`
|
|
28
|
+
SELECT name FROM sqlite_master
|
|
29
|
+
WHERE type='table' AND name='kv_store'
|
|
30
|
+
`).get();
|
|
31
|
+
if (!tableExists) {
|
|
32
|
+
db.close();
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
const row = db.prepare(`
|
|
36
|
+
SELECT value FROM kv_store
|
|
37
|
+
WHERE key = 'aqe_version' AND namespace = '_system'
|
|
38
|
+
`).get();
|
|
39
|
+
db.close();
|
|
40
|
+
if (row) {
|
|
41
|
+
return safeJsonParse(row.value);
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
db.close();
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Write AQE version to memory.db in _system namespace.
|
|
56
|
+
* Used by init wizard to mark installation version.
|
|
57
|
+
*/
|
|
58
|
+
export async function writeVersionToDb(projectRoot, version) {
|
|
59
|
+
const memoryDbPath = join(projectRoot, '.agentic-qe', 'memory.db');
|
|
60
|
+
try {
|
|
61
|
+
const dir = dirname(memoryDbPath);
|
|
62
|
+
if (!existsSync(dir)) {
|
|
63
|
+
mkdirSync(dir, { recursive: true });
|
|
64
|
+
}
|
|
65
|
+
const db = openDatabase(memoryDbPath);
|
|
66
|
+
try {
|
|
67
|
+
db.exec(`
|
|
68
|
+
CREATE TABLE IF NOT EXISTS kv_store (
|
|
69
|
+
key TEXT NOT NULL,
|
|
70
|
+
namespace TEXT NOT NULL,
|
|
71
|
+
value TEXT NOT NULL,
|
|
72
|
+
expires_at INTEGER,
|
|
73
|
+
created_at INTEGER DEFAULT (strftime('%s', 'now') * 1000),
|
|
74
|
+
PRIMARY KEY (namespace, key)
|
|
75
|
+
);
|
|
76
|
+
`);
|
|
77
|
+
const now = Date.now();
|
|
78
|
+
db.prepare(`
|
|
79
|
+
INSERT OR REPLACE INTO kv_store (key, namespace, value, created_at)
|
|
80
|
+
VALUES (?, '_system', ?, ?)
|
|
81
|
+
`).run('aqe_version', JSON.stringify(version), now);
|
|
82
|
+
db.prepare(`
|
|
83
|
+
INSERT OR REPLACE INTO kv_store (key, namespace, value, created_at)
|
|
84
|
+
VALUES (?, '_system', ?, ?)
|
|
85
|
+
`).run('init_timestamp', JSON.stringify(new Date().toISOString()), now);
|
|
86
|
+
db.close();
|
|
87
|
+
console.log(` ✓ Version ${version} written to memory.db`);
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
db.close();
|
|
92
|
+
console.warn(` ⚠ Could not write version: ${toErrorMessage(err)}`);
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
console.warn(` ⚠ Could not open memory.db: ${toErrorMessage(err)}`);
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
15
101
|
// ============================================================================
|
|
16
102
|
// Persistence Database
|
|
17
103
|
// ============================================================================
|
|
@@ -6,11 +6,9 @@
|
|
|
6
6
|
*
|
|
7
7
|
* This is a facade module. Implementation details are extracted to:
|
|
8
8
|
* - init-wizard-hooks.ts (hook configuration, MCP, CLAUDE.md generation)
|
|
9
|
-
* - init-wizard-
|
|
10
|
-
* - init-wizard-steps.ts (persistence, learning, workers, skills, agents, config)
|
|
9
|
+
* - init-wizard-steps.ts (persistence, learning, workers, skills, agents, config, version)
|
|
11
10
|
*/
|
|
12
11
|
import type { InitResult, WizardStep, PretrainedLibrary } from './types.js';
|
|
13
|
-
export type { V2DetectionResult } from './init-wizard-migration.js';
|
|
14
12
|
export interface InitOrchestratorOptions {
|
|
15
13
|
/** Project root directory */
|
|
16
14
|
projectRoot: string;
|
|
@@ -31,8 +29,6 @@ export interface InitOrchestratorOptions {
|
|
|
31
29
|
baseUrl?: string;
|
|
32
30
|
apiKey?: string;
|
|
33
31
|
};
|
|
34
|
-
/** Automatically migrate from v2 if detected */
|
|
35
|
-
autoMigrate?: boolean;
|
|
36
32
|
}
|
|
37
33
|
export declare class InitOrchestrator {
|
|
38
34
|
private projectRoot;
|
|
@@ -49,10 +45,6 @@ export declare class InitOrchestrator {
|
|
|
49
45
|
* Get wizard steps
|
|
50
46
|
*/
|
|
51
47
|
getWizardSteps(): WizardStep[];
|
|
52
|
-
/**
|
|
53
|
-
* Handle V2 detection - returns early result if migration not auto, null otherwise.
|
|
54
|
-
*/
|
|
55
|
-
private handleV2Detection;
|
|
56
48
|
/**
|
|
57
49
|
* Run a single initialization step with timing and status tracking
|
|
58
50
|
*/
|
package/dist/init/init-wizard.js
CHANGED
|
@@ -6,16 +6,15 @@
|
|
|
6
6
|
*
|
|
7
7
|
* This is a facade module. Implementation details are extracted to:
|
|
8
8
|
* - init-wizard-hooks.ts (hook configuration, MCP, CLAUDE.md generation)
|
|
9
|
-
* - init-wizard-
|
|
10
|
-
* - init-wizard-steps.ts (persistence, learning, workers, skills, agents, config)
|
|
9
|
+
* - init-wizard-steps.ts (persistence, learning, workers, skills, agents, config, version)
|
|
11
10
|
*/
|
|
12
11
|
import { createDefaultConfig } from './types.js';
|
|
13
12
|
import { createProjectAnalyzer } from './project-analyzer.js';
|
|
14
13
|
import { createSelfConfigurator } from './self-configurator.js';
|
|
15
|
-
|
|
14
|
+
// Import from extracted modules
|
|
16
15
|
import { configureHooks, configureMCP, generateCLAUDEmd, } from './init-wizard-hooks.js';
|
|
17
16
|
import { toErrorMessage } from '../shared/error-utils.js';
|
|
18
|
-
import { initializePersistenceDatabase, checkCodeIntelligenceIndex, runCodeIntelligenceScan, getKGEntryCount, initializeLearningSystem, startWorkers, installSkills, installAgents, installN8n, saveConfig, } from './init-wizard-steps.js';
|
|
17
|
+
import { initializePersistenceDatabase, checkCodeIntelligenceIndex, runCodeIntelligenceScan, getKGEntryCount, initializeLearningSystem, startWorkers, installSkills, installAgents, installN8n, saveConfig, writeVersionToDb, } from './init-wizard-steps.js';
|
|
19
18
|
// ============================================================================
|
|
20
19
|
// Wizard Step Definitions
|
|
21
20
|
// ============================================================================
|
|
@@ -105,13 +104,6 @@ export class InitOrchestrator {
|
|
|
105
104
|
async initialize() {
|
|
106
105
|
const startTime = Date.now();
|
|
107
106
|
try {
|
|
108
|
-
// Step 0: Check for existing v2 installation
|
|
109
|
-
const v2Detection = await detectV2Installation(this.projectRoot);
|
|
110
|
-
if (v2Detection.detected) {
|
|
111
|
-
const earlyResult = this.handleV2Detection(v2Detection, startTime);
|
|
112
|
-
if (earlyResult)
|
|
113
|
-
return earlyResult;
|
|
114
|
-
}
|
|
115
107
|
// Step 1: Analyze project
|
|
116
108
|
const analysis = await this.runStep('Project Analysis', async () => {
|
|
117
109
|
return await this.analyzer.analyze();
|
|
@@ -251,64 +243,6 @@ export class InitOrchestrator {
|
|
|
251
243
|
getWizardSteps() {
|
|
252
244
|
return WIZARD_STEPS;
|
|
253
245
|
}
|
|
254
|
-
/**
|
|
255
|
-
* Handle V2 detection - returns early result if migration not auto, null otherwise.
|
|
256
|
-
*/
|
|
257
|
-
handleV2Detection(v2Detection, startTime) {
|
|
258
|
-
console.log('\n' + '='.repeat(60));
|
|
259
|
-
console.log(' EXISTING V2 INSTALLATION DETECTED');
|
|
260
|
-
console.log('='.repeat(60) + '\n');
|
|
261
|
-
console.log('Found v2 installation at:');
|
|
262
|
-
if (v2Detection.hasMemoryDb) {
|
|
263
|
-
console.log(` - Memory DB: .agentic-qe/memory.db`);
|
|
264
|
-
}
|
|
265
|
-
if (v2Detection.hasConfig) {
|
|
266
|
-
console.log(` - Config: .agentic-qe/config/`);
|
|
267
|
-
}
|
|
268
|
-
if (v2Detection.hasAgents) {
|
|
269
|
-
console.log(` - Agents: .claude/agents/`);
|
|
270
|
-
}
|
|
271
|
-
console.log('');
|
|
272
|
-
if (this.options.autoMigrate) {
|
|
273
|
-
console.log('Auto-migrate mode enabled. Running migration...\n');
|
|
274
|
-
// Fire and forget - the caller will await initialize() which runs migration inline
|
|
275
|
-
runV2Migration(this.projectRoot, v2Detection).catch(() => { });
|
|
276
|
-
return null;
|
|
277
|
-
}
|
|
278
|
-
// Warn and suggest migration
|
|
279
|
-
console.log('RECOMMENDED: Run migration before init:\n');
|
|
280
|
-
console.log(' npx aqe migrate status # Check what needs migration');
|
|
281
|
-
console.log(' npx aqe migrate run --dry-run # Preview changes');
|
|
282
|
-
console.log(' npx aqe migrate run # Execute migration\n');
|
|
283
|
-
console.log('Or continue with:');
|
|
284
|
-
console.log(' aqe init --auto-migrate # Auto-migrate during init\n');
|
|
285
|
-
console.log('='.repeat(60) + '\n');
|
|
286
|
-
return {
|
|
287
|
-
success: false,
|
|
288
|
-
config: createDefaultConfig('unknown', this.projectRoot),
|
|
289
|
-
steps: [{
|
|
290
|
-
step: 'V2 Detection',
|
|
291
|
-
status: 'error',
|
|
292
|
-
message: 'Existing v2 installation detected. Run migration first.',
|
|
293
|
-
durationMs: Date.now() - startTime,
|
|
294
|
-
}],
|
|
295
|
-
summary: {
|
|
296
|
-
projectAnalyzed: false,
|
|
297
|
-
configGenerated: false,
|
|
298
|
-
codeIntelligenceIndexed: 0,
|
|
299
|
-
patternsLoaded: 0,
|
|
300
|
-
skillsInstalled: 0,
|
|
301
|
-
agentsInstalled: 0,
|
|
302
|
-
hooksConfigured: false,
|
|
303
|
-
mcpConfigured: false,
|
|
304
|
-
claudeMdGenerated: false,
|
|
305
|
-
workersStarted: 0,
|
|
306
|
-
},
|
|
307
|
-
totalDurationMs: Date.now() - startTime,
|
|
308
|
-
timestamp: new Date(),
|
|
309
|
-
v2Detected: true,
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
246
|
/**
|
|
313
247
|
* Run a single initialization step with timing and status tracking
|
|
314
248
|
*/
|
|
@@ -32,7 +32,6 @@ export class ModularInitOrchestrator {
|
|
|
32
32
|
upgrade: options.upgrade,
|
|
33
33
|
skipPatterns: options.skipPatterns,
|
|
34
34
|
minimal: options.minimal,
|
|
35
|
-
autoMigrate: options.autoMigrate,
|
|
36
35
|
withN8n: options.withN8n,
|
|
37
36
|
withOpenCode: options.withOpenCode,
|
|
38
37
|
withKiro: options.withKiro,
|
|
@@ -27,33 +27,6 @@ export class DetectionPhase extends BasePhase {
|
|
|
27
27
|
const freshInstall = !v2Detected && !v3Detected;
|
|
28
28
|
// Store v2 detection in context for other phases
|
|
29
29
|
context.v2Detection = v2Detection;
|
|
30
|
-
if (v2Detected && !context.options.autoMigrate) {
|
|
31
|
-
context.services.log('');
|
|
32
|
-
context.services.log('═'.repeat(60));
|
|
33
|
-
context.services.log('⚠️ EXISTING V2 INSTALLATION DETECTED');
|
|
34
|
-
context.services.log('═'.repeat(60));
|
|
35
|
-
context.services.log('');
|
|
36
|
-
context.services.log('Found v2 installation at:');
|
|
37
|
-
if (v2Detection.hasMemoryDb) {
|
|
38
|
-
context.services.log(' • Memory DB: .agentic-qe/memory.db');
|
|
39
|
-
}
|
|
40
|
-
if (v2Detection.hasConfig) {
|
|
41
|
-
context.services.log(' • Config: .agentic-qe/config/');
|
|
42
|
-
}
|
|
43
|
-
if (v2Detection.hasAgents) {
|
|
44
|
-
context.services.log(' • Agents: .claude/agents/');
|
|
45
|
-
}
|
|
46
|
-
context.services.log('');
|
|
47
|
-
context.services.log('📋 RECOMMENDED: Run with --auto-migrate:');
|
|
48
|
-
context.services.log(' aqe init --auto-migrate');
|
|
49
|
-
context.services.log('');
|
|
50
|
-
return {
|
|
51
|
-
v2Detected: true,
|
|
52
|
-
v3Detected,
|
|
53
|
-
freshInstall: false,
|
|
54
|
-
v2Detection,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
30
|
return {
|
|
58
31
|
v2Detected,
|
|
59
32
|
v3Detected,
|
|
@@ -285,23 +285,24 @@ export class HooksPhase extends BasePhase {
|
|
|
285
285
|
*/
|
|
286
286
|
const fs = require('fs');
|
|
287
287
|
const path = require('path');
|
|
288
|
-
const {
|
|
288
|
+
const { execFileSync } = require('child_process');
|
|
289
289
|
|
|
290
|
-
function q(
|
|
290
|
+
function q(bin, args, d) { try { return execFileSync(bin, args, { encoding: 'utf-8', timeout: 3000, stdio: ['pipe', 'pipe', 'pipe'] }).trim(); } catch { return d || ''; } }
|
|
291
291
|
|
|
292
|
-
const dir =
|
|
292
|
+
const dir = path.resolve(__dirname, '..', '..');
|
|
293
293
|
const dbPath = path.join(dir, '.agentic-qe', 'memory.db');
|
|
294
294
|
let patterns = 0;
|
|
295
295
|
try {
|
|
296
296
|
if (fs.existsSync(dbPath)) {
|
|
297
297
|
const Database = require('better-sqlite3');
|
|
298
298
|
const db = new Database(dbPath, { readonly: true, fileMustExist: true });
|
|
299
|
+
db.pragma('busy_timeout = 5000');
|
|
299
300
|
patterns = db.prepare('SELECT COUNT(*) AS c FROM qe_patterns').get()?.c || 0;
|
|
300
301
|
db.close();
|
|
301
302
|
}
|
|
302
303
|
} catch { /* ignore */ }
|
|
303
304
|
|
|
304
|
-
const branch = q('git branch --show-current
|
|
305
|
+
const branch = q('git', ['branch', '--show-current']);
|
|
305
306
|
const branchStr = branch ? \` \\x1b[34m⎇ \${branch}\\x1b[0m\` : '';
|
|
306
307
|
const patStr = patterns > 0 ? \` \\x1b[35m🎓 \${patterns} patterns\\x1b[0m\` : '';
|
|
307
308
|
|
|
@@ -321,11 +322,12 @@ console.log(\`\\x1b[1m\\x1b[35m▊ Agentic QE v3\\x1b[0m\${branchStr}\${patStr}\
|
|
|
321
322
|
* node brain-checkpoint.cjs export # Export brain to aqe.rvf (session-end)
|
|
322
323
|
* node brain-checkpoint.cjs verify # Verify aqe.rvf exists (session-start)
|
|
323
324
|
*/
|
|
324
|
-
const {
|
|
325
|
+
const { execFileSync } = require('child_process');
|
|
325
326
|
const fs = require('fs');
|
|
326
327
|
const path = require('path');
|
|
327
328
|
|
|
328
|
-
const
|
|
329
|
+
const PROJECT_ROOT = path.resolve(__dirname, '..', '..');
|
|
330
|
+
const AQE_DIR = path.join(PROJECT_ROOT, '.agentic-qe');
|
|
329
331
|
const RVF_PATH = path.join(AQE_DIR, 'aqe.rvf');
|
|
330
332
|
const DB_PATH = path.join(AQE_DIR, 'memory.db');
|
|
331
333
|
const MAX_AGE_HOURS = 24;
|
|
@@ -338,8 +340,8 @@ function exportBrain() {
|
|
|
338
340
|
if (fs.existsSync(RVF_PATH)) fs.unlinkSync(RVF_PATH);
|
|
339
341
|
const idmap = RVF_PATH + '.idmap.json';
|
|
340
342
|
if (fs.existsSync(idmap)) fs.unlinkSync(idmap);
|
|
341
|
-
const result =
|
|
342
|
-
'npx agentic-qe brain export -o
|
|
343
|
+
const result = execFileSync(
|
|
344
|
+
'npx', ['agentic-qe', 'brain', 'export', '-o', RVF_PATH, '--format', 'rvf'],
|
|
343
345
|
{ timeout: 60000, encoding: 'utf-8' }
|
|
344
346
|
);
|
|
345
347
|
const m = result.match(/Patterns:\\s+(\\d+)/);
|
|
@@ -496,7 +498,7 @@ if (process.argv.includes('--json')) process.stdout.write(JSON.stringify(result)
|
|
|
496
498
|
hooks: [
|
|
497
499
|
{
|
|
498
500
|
type: 'command',
|
|
499
|
-
command: 'node
|
|
501
|
+
command: 'node "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.claude/helpers/brain-checkpoint.cjs" verify --json',
|
|
500
502
|
timeout: 5000,
|
|
501
503
|
continueOnError: true,
|
|
502
504
|
},
|
|
@@ -518,7 +520,7 @@ if (process.argv.includes('--json')) process.stdout.write(JSON.stringify(result)
|
|
|
518
520
|
hooks: [
|
|
519
521
|
{
|
|
520
522
|
type: 'command',
|
|
521
|
-
command: 'node
|
|
523
|
+
command: 'node "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.claude/helpers/brain-checkpoint.cjs" export --json',
|
|
522
524
|
timeout: 60000,
|
|
523
525
|
continueOnError: true,
|
|
524
526
|
},
|
|
@@ -73,7 +73,6 @@ export interface InitOptions {
|
|
|
73
73
|
/** Minimal configuration (no skills, patterns, workers) */
|
|
74
74
|
minimal?: boolean;
|
|
75
75
|
/** Automatically migrate from v2 if detected */
|
|
76
|
-
autoMigrate?: boolean;
|
|
77
76
|
/** Install n8n workflow testing platform */
|
|
78
77
|
withN8n?: boolean;
|
|
79
78
|
/** N8n API configuration */
|
|
@@ -97,7 +97,7 @@ export function generateV3SettingsSections(config) {
|
|
|
97
97
|
},
|
|
98
98
|
statusLine: {
|
|
99
99
|
type: 'command',
|
|
100
|
-
command: 'node
|
|
100
|
+
command: 'node "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.claude/helpers/statusline-v3.cjs" 2>/dev/null || echo "▊ Agentic QE v3"',
|
|
101
101
|
refreshMs: 5000,
|
|
102
102
|
enabled: true,
|
|
103
103
|
},
|
|
@@ -195,7 +195,13 @@ export function importBrainFromRvf(db, rvfPath, options) {
|
|
|
195
195
|
if (!kernel || !kernel.image) {
|
|
196
196
|
throw new Error('No brain data found in RVF file (missing kernel segment)');
|
|
197
197
|
}
|
|
198
|
-
|
|
198
|
+
let brainData;
|
|
199
|
+
try {
|
|
200
|
+
brainData = JSON.parse(kernel.image.toString('utf-8'));
|
|
201
|
+
}
|
|
202
|
+
catch (parseErr) {
|
|
203
|
+
throw new Error(`Failed to parse brain kernel data as JSON: ${parseErr instanceof Error ? parseErr.message : parseErr}`);
|
|
204
|
+
}
|
|
199
205
|
if (options.dryRun) {
|
|
200
206
|
let total = 0;
|
|
201
207
|
if (brainData.tables) {
|
|
@@ -296,7 +302,13 @@ export function brainInfoFromRvf(rvfPath) {
|
|
|
296
302
|
throw new Error('No brain data found in RVF file');
|
|
297
303
|
}
|
|
298
304
|
const brainJson = kernel.image.toString('utf-8');
|
|
299
|
-
|
|
305
|
+
let brainData;
|
|
306
|
+
try {
|
|
307
|
+
brainData = JSON.parse(brainJson);
|
|
308
|
+
}
|
|
309
|
+
catch (parseErr) {
|
|
310
|
+
throw new Error(`Failed to parse brain kernel data as JSON: ${parseErr instanceof Error ? parseErr.message : parseErr}`);
|
|
311
|
+
}
|
|
300
312
|
const status = rvf.status();
|
|
301
313
|
const fileSize = statSync(filePath).size;
|
|
302
314
|
const t = brainData.tables;
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* - unified-memory-hnsw.ts: HNSW index + BinaryHeap
|
|
22
22
|
* - unified-memory.ts: UnifiedMemoryManager class (this file, facade)
|
|
23
23
|
*/
|
|
24
|
-
import
|
|
24
|
+
import { openDatabase as openSafeDatabase } from '../shared/safe-db.js';
|
|
25
25
|
import { safeJsonParse } from '../shared/safe-json.js';
|
|
26
26
|
import { toErrorMessage } from '../shared/error-utils.js';
|
|
27
27
|
import * as fs from 'fs';
|
|
@@ -278,13 +278,12 @@ export class UnifiedMemoryManager {
|
|
|
278
278
|
dbSizeBefore = newest.size;
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
|
-
this.db =
|
|
282
|
-
|
|
283
|
-
this.
|
|
284
|
-
}
|
|
281
|
+
this.db = openSafeDatabase(this.config.dbPath, {
|
|
282
|
+
walMode: this.config.walMode,
|
|
283
|
+
busyTimeout: this.config.busyTimeout,
|
|
284
|
+
});
|
|
285
285
|
this.db.pragma(`mmap_size = ${this.config.mmapSize}`);
|
|
286
286
|
this.db.pragma(`cache_size = ${this.config.cacheSize}`);
|
|
287
|
-
this.db.pragma(`busy_timeout = ${this.config.busyTimeout}`);
|
|
288
287
|
this.db.pragma('foreign_keys = ON');
|
|
289
288
|
await this.runMigrations();
|
|
290
289
|
// DATA LOSS PREVENTION: After migration, if the DB existed before and was
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
import { v4 as uuidv4 } from 'uuid';
|
|
15
15
|
import { getUnifiedMemory } from '../kernel/unified-memory.js';
|
|
16
16
|
import { toErrorMessage } from '../shared/error-utils.js';
|
|
17
|
+
import { createLogger } from '../logging/logger-factory.js';
|
|
18
|
+
const ecLogger = createLogger('ExperienceCapture');
|
|
17
19
|
// ============================================================================
|
|
18
20
|
// Active Experience Tracking
|
|
19
21
|
// ============================================================================
|
|
@@ -168,6 +170,26 @@ async function doInitialize() {
|
|
|
168
170
|
CREATE INDEX IF NOT EXISTS idx_captured_exp_agent ON captured_experiences(agent);
|
|
169
171
|
CREATE INDEX IF NOT EXISTS idx_captured_exp_completed ON captured_experiences(completed_at DESC);
|
|
170
172
|
`);
|
|
173
|
+
// Add consolidation columns if missing (needed by ExperienceConsolidator)
|
|
174
|
+
const colNames = new Set(db.prepare('PRAGMA table_info(captured_experiences)').all().map(c => c.name));
|
|
175
|
+
const consolidationCols = [
|
|
176
|
+
['application_count', 'INTEGER DEFAULT 0'],
|
|
177
|
+
['avg_token_savings', 'REAL DEFAULT 0'],
|
|
178
|
+
['embedding', 'BLOB'],
|
|
179
|
+
['embedding_dimension', 'INTEGER'],
|
|
180
|
+
['tags', 'TEXT'],
|
|
181
|
+
['last_applied_at', 'TEXT'],
|
|
182
|
+
['consolidated_into', 'TEXT DEFAULT NULL'],
|
|
183
|
+
['consolidation_count', 'INTEGER DEFAULT 1'],
|
|
184
|
+
['quality_updated_at', 'TEXT DEFAULT NULL'],
|
|
185
|
+
['reuse_success_count', 'INTEGER DEFAULT 0'],
|
|
186
|
+
['reuse_failure_count', 'INTEGER DEFAULT 0'],
|
|
187
|
+
];
|
|
188
|
+
for (const [col, def] of consolidationCols) {
|
|
189
|
+
if (!colNames.has(col)) {
|
|
190
|
+
db.exec(`ALTER TABLE captured_experiences ADD COLUMN ${col} ${def}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
171
193
|
}
|
|
172
194
|
// Start periodic cleanup of stale experiences
|
|
173
195
|
startCleanupTimer();
|
|
@@ -269,7 +291,7 @@ async function persistExperience(context, outcome) {
|
|
|
269
291
|
`);
|
|
270
292
|
stmt.run(outcome.id, context.task, context.agent, context.domain, outcome.success ? 1 : 0, outcome.quality, outcome.durationMs, context.modelTier || null, safeJsonStringify(context.routing), safeJsonStringify(outcome.steps), safeJsonStringify(outcome.result), outcome.error || null, context.startedAt.toISOString(), 'middleware');
|
|
271
293
|
// Fire-and-forget: compute and store embedding for this experience
|
|
272
|
-
computeExperienceEmbedding(db, outcome.id, context.task, context.domain).catch(() => { });
|
|
294
|
+
computeExperienceEmbedding(db, outcome.id, context.task, context.domain).catch((e) => { ecLogger.warn('Embedding computation failed', { error: e instanceof Error ? e.message : String(e), experienceId: outcome.id, domain: context.domain }); });
|
|
273
295
|
}
|
|
274
296
|
catch (error) {
|
|
275
297
|
console.error('[ExperienceCaptureMiddleware] Failed to persist experience:', error);
|