agentic-qe 3.8.12 → 3.8.14

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.
Files changed (46) hide show
  1. package/.claude/skills/qe-code-intelligence/SKILL.md +29 -20
  2. package/.claude/skills/qe-code-intelligence/evals/qe-code-intelligence.yaml +3 -3
  3. package/.claude/skills/qe-quality-assessment/SKILL.md +1 -1
  4. package/.claude/skills/qe-test-generation/SKILL.md +1 -1
  5. package/.claude/skills/skills-manifest.json +1 -1
  6. package/CHANGELOG.md +41 -0
  7. package/README.md +9 -0
  8. package/assets/skills/qe-code-intelligence/SKILL.md +29 -20
  9. package/assets/skills/qe-code-intelligence/evals/qe-code-intelligence.yaml +3 -3
  10. package/assets/skills/qe-quality-assessment/SKILL.md +1 -1
  11. package/assets/skills/qe-test-generation/SKILL.md +1 -1
  12. package/dist/audit/witness-chain.js +15 -3
  13. package/dist/cli/bundle.js +815 -795
  14. package/dist/cli/commands/code.js +149 -11
  15. package/dist/cli/commands/init.js +3 -2
  16. package/dist/cli/handlers/init-handler.d.ts +1 -0
  17. package/dist/cli/handlers/init-handler.js +15 -10
  18. package/dist/cli/utils/file-discovery.d.ts +1 -0
  19. package/dist/cli/utils/file-discovery.js +1 -1
  20. package/dist/domains/test-generation/generators/base-test-generator.d.ts +1 -1
  21. package/dist/domains/test-generation/generators/base-test-generator.js +11 -11
  22. package/dist/domains/test-generation/generators/go-test-generator.js +12 -12
  23. package/dist/domains/test-generation/generators/junit5-generator.js +9 -9
  24. package/dist/domains/test-generation/generators/kotlin-junit-generator.js +10 -10
  25. package/dist/domains/test-generation/generators/pytest-generator.js +8 -8
  26. package/dist/domains/test-generation/generators/swift-testing-generator.js +8 -8
  27. package/dist/domains/test-generation/generators/test-value-helpers.d.ts +20 -0
  28. package/dist/domains/test-generation/generators/test-value-helpers.js +48 -0
  29. package/dist/domains/test-generation/generators/xunit-generator.js +11 -11
  30. package/dist/index.d.ts +1 -1
  31. package/dist/index.js +1 -2
  32. package/dist/init/init-wizard-hooks.js +15 -1
  33. package/dist/init/orchestrator.js +1 -0
  34. package/dist/init/phases/07-hooks.js +2 -2
  35. package/dist/init/phases/08-mcp.js +4 -4
  36. package/dist/init/phases/phase-interface.d.ts +3 -1
  37. package/dist/init/settings-merge.js +3 -7
  38. package/dist/mcp/bundle.js +327 -327
  39. package/dist/mcp/http-server.js +4 -1
  40. package/dist/mcp/index.d.ts +2 -2
  41. package/dist/mcp/index.js +5 -4
  42. package/dist/mcp/protocol-server.d.ts +5 -0
  43. package/dist/mcp/protocol-server.js +10 -1
  44. package/package.json +1 -1
  45. package/dist/mcp/server.d.ts +0 -46
  46. package/dist/mcp/server.js +0 -802
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Lightweight test value generators — replaces @faker-js/faker in generators.
3
+ *
4
+ * These produce plausible string literals for generated test code.
5
+ * They do NOT need cryptographic randomness or statistical distributions —
6
+ * they only produce placeholder values embedded in source code output.
7
+ */
8
+ import { randomBytes, randomInt, randomUUID } from 'node:crypto';
9
+ function randomHex(bytes) {
10
+ return randomBytes(bytes).toString('hex');
11
+ }
12
+ export const testValues = {
13
+ uuid: () => randomUUID(),
14
+ email: () => `user_${randomHex(3)}@example.com`,
15
+ fullName: () => {
16
+ const first = ['Alice', 'Bob', 'Carol', 'Dave', 'Eve', 'Frank'];
17
+ const last = ['Smith', 'Jones', 'Lee', 'Garcia', 'Chen', 'Novak'];
18
+ return `${first[randomInt(first.length)]} ${last[randomInt(last.length)]}`;
19
+ },
20
+ url: () => `https://example.com/${randomHex(4)}`,
21
+ recentDate: () => new Date(Date.now() - randomInt(7 * 86400000)).toISOString(),
22
+ phone: () => `+1${String(randomInt(2000000000, 9999999999))}`,
23
+ streetAddress: () => `${randomInt(1, 9999)} Main St`,
24
+ word: () => {
25
+ const words = ['alpha', 'bravo', 'charlie', 'delta', 'echo', 'foxtrot', 'golf', 'hotel'];
26
+ return words[randomInt(words.length)];
27
+ },
28
+ int: (min = 1, max = 100) => {
29
+ if (min > max) {
30
+ const t = min;
31
+ min = max;
32
+ max = t;
33
+ }
34
+ return randomInt(min, max + 1);
35
+ },
36
+ float: (min = 0, max = 100, fractionDigits = 2) => {
37
+ if (min > max) {
38
+ const t = min;
39
+ min = max;
40
+ max = t;
41
+ }
42
+ if (min === max)
43
+ return min;
44
+ const raw = min + (randomInt(0, 1_000_001) / 1_000_000) * (max - min);
45
+ return Number(raw.toFixed(fractionDigits));
46
+ },
47
+ };
48
+ //# sourceMappingURL=test-value-helpers.js.map
@@ -11,7 +11,7 @@
11
11
  *
12
12
  * @module test-generation/generators
13
13
  */
14
- import { faker } from '@faker-js/faker';
14
+ import { testValues } from './test-value-helpers';
15
15
  import { BaseTestGenerator } from './base-test-generator';
16
16
  /**
17
17
  * XUnitGenerator - Test generator for C#'s xUnit framework
@@ -363,25 +363,25 @@ namespace Tests.${className}.Coverage
363
363
  const name = param.name.toLowerCase();
364
364
  // Infer from param name
365
365
  if (name.includes('id') && (type.includes('int') || type === 'unknown')) {
366
- return String(faker.number.int({ min: 1, max: 1000 }));
366
+ return String(testValues.int(1, 1000));
367
367
  }
368
368
  if (name.includes('id'))
369
- return `"${faker.string.uuid()}"`;
369
+ return `"${testValues.uuid()}"`;
370
370
  if (name.includes('name'))
371
- return `"${faker.person.fullName()}"`;
371
+ return `"${testValues.fullName()}"`;
372
372
  if (name.includes('email'))
373
- return `"${faker.internet.email()}"`;
373
+ return `"${testValues.email()}"`;
374
374
  if (name.includes('url'))
375
- return `"${faker.internet.url()}"`;
375
+ return `"${testValues.url()}"`;
376
376
  // Infer from type
377
377
  if (type === 'int' || type === 'int32' || type === 'int64' || type === 'long') {
378
- return String(faker.number.int({ min: 1, max: 100 }));
378
+ return String(testValues.int(1, 100));
379
379
  }
380
380
  if (type === 'double' || type === 'float' || type === 'decimal') {
381
- return `${faker.number.float({ min: 0, max: 100, fractionDigits: 2 })}m`;
381
+ return `${testValues.float(0, 100, 2)}m`;
382
382
  }
383
383
  if (type === 'string' || type.includes('string'))
384
- return `"${faker.lorem.word()}"`;
384
+ return `"${testValues.word()}"`;
385
385
  if (type === 'bool' || type === 'boolean')
386
386
  return 'true';
387
387
  if (type.includes('list<') || type.includes('ienumerable<') || type.includes('[]')) {
@@ -467,10 +467,10 @@ namespace Tests.${className}.Coverage
467
467
  const values = params.map(p => {
468
468
  const type = p.type?.toLowerCase() || '';
469
469
  if (type.includes('int') || type.includes('number')) {
470
- return String(faker.number.int({ min: 1, max: 100 }));
470
+ return String(testValues.int(1, 100));
471
471
  }
472
472
  if (type.includes('string') || type === 'unknown') {
473
- return `"${faker.lorem.word()}"`;
473
+ return `"${testValues.word()}"`;
474
474
  }
475
475
  return 'null';
476
476
  });
package/dist/index.d.ts CHANGED
@@ -12,7 +12,7 @@ export { CrossPhaseHookExecutor, getCrossPhaseHookExecutor, resetCrossPhaseHookE
12
12
  export type { TeammateIdleHookConfig, TaskQueue, PendingTask, TeammateIdleStats, TaskCompletedHookConfig, ExtractedPattern, PatternStore, CompletionAction, CompletionHandler, GateCheckResult, } from './hooks';
13
13
  export { DevilsAdvocate, ClaimVerifier } from './agents';
14
14
  export * from './domains';
15
- export { MCPServer, createMCPServer, ToolRegistry, createToolRegistry, } from './mcp';
15
+ export { MCPProtocolServer, createMCPProtocolServer, MCPServer, createMCPServer, ToolRegistry, createToolRegistry, } from './mcp';
16
16
  export { createQEReasoningBank, QEReasoningBank, RealQEReasoningBank, createRealQEReasoningBank, detectQEDomain, detectQEDomains, mapQEDomainToAQE, QE_DOMAIN_LIST, QE_DOMAINS, } from './learning';
17
17
  export type { QEPattern, QEPatternType, QEPatternTemplate, QEPatternContext, QEDomain, CreateQEPatternOptions, LearningOutcome, PatternSearchOptions, PatternSearchResult, QERoutingRequest, QERoutingResult, } from './learning';
18
18
  export { createTestOutcomeTracker, createCoverageLearner, createQualityScoreCalculator, createPatternPromotionManager, createQualityFeedbackLoop, createInitializedFeedbackLoop, QualityFeedbackLoop, TestOutcomeTracker, CoverageLearner, QualityScoreCalculator, PatternPromotionManager, DEFAULT_FEEDBACK_CONFIG, DEFAULT_QUALITY_WEIGHTS, DEFAULT_PROMOTION_CRITERIA, } from './feedback';
package/dist/index.js CHANGED
@@ -24,8 +24,7 @@ export { DevilsAdvocate, ClaimVerifier } from './agents';
24
24
  // Domain Interfaces - export as namespaces
25
25
  export * from './domains';
26
26
  // MCP Server - Model Context Protocol integration
27
- // Export only what's available from mcp module
28
- export { MCPServer, createMCPServer, ToolRegistry, createToolRegistry, } from './mcp';
27
+ export { MCPProtocolServer, createMCPProtocolServer, MCPServer, createMCPServer, ToolRegistry, createToolRegistry, } from './mcp';
29
28
  // Learning Module - QE ReasoningBank for pattern learning (ADR-021)
30
29
  // Exclude types that conflict with routing (ComplexityLevel, ProgrammingLanguage, TestFramework)
31
30
  export { createQEReasoningBank, QEReasoningBank, RealQEReasoningBank, createRealQEReasoningBank, detectQEDomain, detectQEDomains, mapQEDomainToAQE, QE_DOMAIN_LIST, QE_DOMAINS, } from './learning';
@@ -174,9 +174,23 @@ export async function configureHooks(projectRoot, config) {
174
174
  ...generateAqeEnvVars(config),
175
175
  };
176
176
  // Apply v3 settings sections
177
+ // Permissions are union-merged to preserve user entries (#362)
177
178
  const v3Sections = generateV3SettingsSections(config, projectRoot);
178
179
  for (const [key, value] of Object.entries(v3Sections)) {
179
- settings[key] = value;
180
+ if (key === '_aqePermissions') {
181
+ // Union-merge: add AQE entries without removing user-added permissions
182
+ const existingPerms = settings.permissions || {};
183
+ const existingAllow = existingPerms.allow || [];
184
+ const aqeEntries = value;
185
+ const merged = [...new Set([...existingAllow, ...aqeEntries])];
186
+ settings.permissions = {
187
+ ...existingPerms,
188
+ allow: merged,
189
+ };
190
+ }
191
+ else {
192
+ settings[key] = value;
193
+ }
180
194
  }
181
195
  // Enable MCP servers (deduplicate, replace old 'aqe' with 'agentic-qe')
182
196
  let existingMcp = settings.enabledMcpjsonServers || [];
@@ -47,6 +47,7 @@ export class ModularInitOrchestrator {
47
47
  n8nApiConfig: options.n8nApiConfig,
48
48
  wizardAnswers: options.wizardAnswers,
49
49
  noGovernance: options.noGovernance,
50
+ noMcp: options.noMcp,
50
51
  },
51
52
  config: {},
52
53
  enhancements: {
@@ -512,7 +512,7 @@ if (process.argv.includes('--json')) process.stdout.write(JSON.stringify(result)
512
512
  hooks: [
513
513
  {
514
514
  type: 'command',
515
- command: 'node .claude/helpers/brain-checkpoint.cjs verify --json',
515
+ command: 'sh -c \'exec node "${CLAUDE_PROJECT_DIR:-.}/.claude/helpers/brain-checkpoint.cjs" verify --json\'',
516
516
  timeout: 5000,
517
517
  continueOnError: true,
518
518
  },
@@ -534,7 +534,7 @@ if (process.argv.includes('--json')) process.stdout.write(JSON.stringify(result)
534
534
  hooks: [
535
535
  {
536
536
  type: 'command',
537
- command: 'node .claude/helpers/brain-checkpoint.cjs export --json',
537
+ command: 'sh -c \'exec node "${CLAUDE_PROJECT_DIR:-.}/.claude/helpers/brain-checkpoint.cjs" export --json\'',
538
538
  timeout: 60000,
539
539
  continueOnError: true,
540
540
  },
@@ -26,10 +26,10 @@ export class MCPPhase extends BasePhase {
26
26
  requiresPhases = ['configuration', 'database'];
27
27
  async run(context) {
28
28
  const { projectRoot } = context;
29
- // MCP is opt-in: skip unless --with-mcp is passed
30
- if (!context.options.withMcp) {
31
- context.services.log(' MCP: skipped (opt-in — use --with-mcp to enable)');
32
- context.services.log(' All QE commands available via CLI: aqe memory, aqe test, aqe coverage, etc.');
29
+ // MCP is enabled by default — skip only with --no-mcp
30
+ if (context.options.noMcp) {
31
+ context.services.log(' MCP: skipped (--no-mcp)');
32
+ context.services.log(' CLI commands available: aqe memory, aqe test, aqe coverage, etc.');
33
33
  return {
34
34
  configured: false,
35
35
  mcpPath: '',
@@ -106,7 +106,9 @@ export interface InitOptions {
106
106
  withContinueDev?: boolean;
107
107
  /** Install all coding agent platform configurations */
108
108
  withAllPlatforms?: boolean;
109
- /** Install MCP server config (opt-in CLI commands work without MCP) */
109
+ /** Skip MCP server config (MCP is enabled by default) */
110
+ noMcp?: boolean;
111
+ /** @deprecated Use default behavior instead — MCP is now enabled by default */
110
112
  withMcp?: boolean;
111
113
  }
112
114
  /**
@@ -97,18 +97,14 @@ export function generateV3SettingsSections(config, projectRoot) {
97
97
  },
98
98
  statusLine: {
99
99
  type: 'command',
100
- command: 'node .claude/helpers/statusline-v3.cjs 2>/dev/null || echo "▊ Agentic QE v3"',
100
+ command: 'sh -c \'node "${CLAUDE_PROJECT_DIR:-.}/.claude/helpers/statusline-v3.cjs" 2>/dev/null || echo "▊ Agentic QE v3"\'',
101
101
  refreshMs: 5000,
102
102
  enabled: true,
103
103
  },
104
104
  // permissions are union-merged in 07-hooks.ts — not set here to avoid overwriting user entries (#362)
105
105
  _aqePermissions: [
106
- 'Bash(npx ruflo:*)',
107
- 'Bash(npx @ruflo/cli:*)',
108
- 'Bash(npx claude-flow:*)',
109
- 'Bash(npx @claude-flow/cli:*)',
110
- 'mcp__ruflo__:*',
111
- 'mcp__claude-flow__:*',
106
+ 'Bash(npx agentic-qe:*)',
107
+ 'Bash(npx @anthropics/agentic-qe:*)',
112
108
  'mcp__agentic-qe__*',
113
109
  ],
114
110
  includeCoAuthoredBy: true,