@planu/cli 0.97.2 → 0.99.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.
Files changed (122) hide show
  1. package/dist/config/license-plans.json +8 -3
  2. package/dist/config/mobile-ci-templates/android-github-actions.yml +149 -0
  3. package/dist/config/mobile-ci-templates/ios-github-actions.yml +120 -0
  4. package/dist/engine/api-validation/graphql-schema-validator.d.ts +3 -0
  5. package/dist/engine/api-validation/graphql-schema-validator.d.ts.map +1 -0
  6. package/dist/engine/api-validation/graphql-schema-validator.js +134 -0
  7. package/dist/engine/api-validation/graphql-schema-validator.js.map +1 -0
  8. package/dist/engine/api-validation/index.d.ts +3 -0
  9. package/dist/engine/api-validation/index.d.ts.map +1 -0
  10. package/dist/engine/api-validation/index.js +4 -0
  11. package/dist/engine/api-validation/index.js.map +1 -0
  12. package/dist/engine/api-validation/openapi-impl-validator.d.ts +3 -0
  13. package/dist/engine/api-validation/openapi-impl-validator.d.ts.map +1 -0
  14. package/dist/engine/api-validation/openapi-impl-validator.js +205 -0
  15. package/dist/engine/api-validation/openapi-impl-validator.js.map +1 -0
  16. package/dist/engine/ci-generator/android-jobs.d.ts +17 -0
  17. package/dist/engine/ci-generator/android-jobs.d.ts.map +1 -0
  18. package/dist/engine/ci-generator/android-jobs.js +168 -0
  19. package/dist/engine/ci-generator/android-jobs.js.map +1 -0
  20. package/dist/engine/ci-generator/ios-jobs.d.ts +17 -0
  21. package/dist/engine/ci-generator/ios-jobs.d.ts.map +1 -0
  22. package/dist/engine/ci-generator/ios-jobs.js +151 -0
  23. package/dist/engine/ci-generator/ios-jobs.js.map +1 -0
  24. package/dist/engine/ci-generator/yaml-builder.d.ts +10 -1
  25. package/dist/engine/ci-generator/yaml-builder.d.ts.map +1 -1
  26. package/dist/engine/ci-generator/yaml-builder.js +46 -1
  27. package/dist/engine/ci-generator/yaml-builder.js.map +1 -1
  28. package/dist/engine/coverage-gap-analyzer.d.ts +6 -0
  29. package/dist/engine/coverage-gap-analyzer.d.ts.map +1 -0
  30. package/dist/engine/coverage-gap-analyzer.js +177 -0
  31. package/dist/engine/coverage-gap-analyzer.js.map +1 -0
  32. package/dist/engine/dashboard/templates-kanban.d.ts.map +1 -1
  33. package/dist/engine/dashboard/templates-kanban.js +22 -0
  34. package/dist/engine/dashboard/templates-kanban.js.map +1 -1
  35. package/dist/engine/dashboard/templates-layout.d.ts.map +1 -1
  36. package/dist/engine/dashboard/templates-layout.js +59 -7
  37. package/dist/engine/dashboard/templates-layout.js.map +1 -1
  38. package/dist/engine/mutation-config-generator.d.ts +6 -0
  39. package/dist/engine/mutation-config-generator.d.ts.map +1 -0
  40. package/dist/engine/mutation-config-generator.js +111 -0
  41. package/dist/engine/mutation-config-generator.js.map +1 -0
  42. package/dist/engine/product-intelligence/index.d.ts +7 -0
  43. package/dist/engine/product-intelligence/index.d.ts.map +1 -0
  44. package/dist/engine/product-intelligence/index.js +211 -0
  45. package/dist/engine/product-intelligence/index.js.map +1 -0
  46. package/dist/engine/tdd-scaffold-generator.d.ts +7 -0
  47. package/dist/engine/tdd-scaffold-generator.d.ts.map +1 -0
  48. package/dist/engine/tdd-scaffold-generator.js +252 -0
  49. package/dist/engine/tdd-scaffold-generator.js.map +1 -0
  50. package/dist/engine/telemetry/error-reporter.d.ts +9 -2
  51. package/dist/engine/telemetry/error-reporter.d.ts.map +1 -1
  52. package/dist/engine/telemetry/error-reporter.js +31 -4
  53. package/dist/engine/telemetry/error-reporter.js.map +1 -1
  54. package/dist/engine/version-resolver.d.ts +10 -0
  55. package/dist/engine/version-resolver.d.ts.map +1 -0
  56. package/dist/engine/version-resolver.js +144 -0
  57. package/dist/engine/version-resolver.js.map +1 -0
  58. package/dist/engine/web-fetcher/stack-advisor.d.ts.map +1 -1
  59. package/dist/engine/web-fetcher/stack-advisor.js +32 -4
  60. package/dist/engine/web-fetcher/stack-advisor.js.map +1 -1
  61. package/dist/index.js +9 -11
  62. package/dist/index.js.map +1 -1
  63. package/dist/tools/checkpoint-handler.d.ts.map +1 -1
  64. package/dist/tools/checkpoint-handler.js +24 -1
  65. package/dist/tools/checkpoint-handler.js.map +1 -1
  66. package/dist/tools/dashboard.d.ts.map +1 -1
  67. package/dist/tools/dashboard.js +2 -0
  68. package/dist/tools/dashboard.js.map +1 -1
  69. package/dist/tools/product-insights-handler.d.ts +11 -0
  70. package/dist/tools/product-insights-handler.d.ts.map +1 -0
  71. package/dist/tools/product-insights-handler.js +102 -0
  72. package/dist/tools/product-insights-handler.js.map +1 -0
  73. package/dist/tools/register-product-insights-tools.d.ts +3 -0
  74. package/dist/tools/register-product-insights-tools.d.ts.map +1 -0
  75. package/dist/tools/register-product-insights-tools.js +22 -0
  76. package/dist/tools/register-product-insights-tools.js.map +1 -0
  77. package/dist/tools/register-spec-322-tools.d.ts +3 -0
  78. package/dist/tools/register-spec-322-tools.d.ts.map +1 -0
  79. package/dist/tools/register-spec-322-tools.js +41 -0
  80. package/dist/tools/register-spec-322-tools.js.map +1 -0
  81. package/dist/tools/register-spec-323-tools.d.ts +3 -0
  82. package/dist/tools/register-spec-323-tools.d.ts.map +1 -0
  83. package/dist/tools/register-spec-323-tools.js +57 -0
  84. package/dist/tools/register-spec-323-tools.js.map +1 -0
  85. package/dist/tools/safe-handler.d.ts.map +1 -1
  86. package/dist/tools/safe-handler.js +19 -1
  87. package/dist/tools/safe-handler.js.map +1 -1
  88. package/dist/tools/tdd-scaffold-handler.d.ts +5 -0
  89. package/dist/tools/tdd-scaffold-handler.d.ts.map +1 -0
  90. package/dist/tools/tdd-scaffold-handler.js +92 -0
  91. package/dist/tools/tdd-scaffold-handler.js.map +1 -0
  92. package/dist/tools/validate-api-contract-handler.d.ts +3 -0
  93. package/dist/tools/validate-api-contract-handler.d.ts.map +1 -0
  94. package/dist/tools/validate-api-contract-handler.js +74 -0
  95. package/dist/tools/validate-api-contract-handler.js.map +1 -0
  96. package/dist/tools/validate.d.ts.map +1 -1
  97. package/dist/tools/validate.js +24 -2
  98. package/dist/tools/validate.js.map +1 -1
  99. package/dist/types/api-contract.d.ts +58 -0
  100. package/dist/types/api-contract.d.ts.map +1 -1
  101. package/dist/types/ci.d.ts +8 -0
  102. package/dist/types/ci.d.ts.map +1 -1
  103. package/dist/types/index.d.ts +2 -0
  104. package/dist/types/index.d.ts.map +1 -1
  105. package/dist/types/index.js +2 -0
  106. package/dist/types/index.js.map +1 -1
  107. package/dist/types/product-intelligence.d.ts +60 -0
  108. package/dist/types/product-intelligence.d.ts.map +1 -0
  109. package/dist/types/product-intelligence.js +3 -0
  110. package/dist/types/product-intelligence.js.map +1 -0
  111. package/dist/types/telemetry.d.ts +1 -1
  112. package/dist/types/telemetry.d.ts.map +1 -1
  113. package/dist/types/testing.d.ts +60 -0
  114. package/dist/types/testing.d.ts.map +1 -1
  115. package/dist/types/version-resolution.d.ts +23 -0
  116. package/dist/types/version-resolution.d.ts.map +1 -0
  117. package/dist/types/version-resolution.js +3 -0
  118. package/dist/types/version-resolution.js.map +1 -0
  119. package/package.json +1 -1
  120. package/src/config/license-plans.json +8 -3
  121. package/src/config/mobile-ci-templates/android-github-actions.yml +149 -0
  122. package/src/config/mobile-ci-templates/ios-github-actions.yml +120 -0
@@ -0,0 +1,102 @@
1
+ // tools/product-insights-handler.ts — SPEC-328: Product Intelligence Layer handler.
2
+ // Formats ProductInsightsReport as clean markdown for MCP tool response.
3
+ import { generateProductInsights } from '../engine/product-intelligence/index.js';
4
+ function formatAdoptionTable(report) {
5
+ if (report.adoption.length === 0) {
6
+ return '';
7
+ }
8
+ const rows = report.adoption
9
+ .slice(0, 20)
10
+ .map((r) => `| ${r.tool} | ${r.totalCalls} | ${r.uniqueInstalls} | ${(r.errorRate * 100).toFixed(1)}% | ${(r.blockedRate * 100).toFixed(1)}% | ${r.trend} |`)
11
+ .join('\n');
12
+ return [
13
+ '## Tool Adoption',
14
+ '| Tool | Calls | Installs | Error% | Blocked% | Trend |',
15
+ '|------|-------|----------|--------|----------|-------|',
16
+ rows,
17
+ ].join('\n');
18
+ }
19
+ function formatFrictionTable(report) {
20
+ if (report.frictionPoints.length === 0) {
21
+ return '';
22
+ }
23
+ const rows = report.frictionPoints
24
+ .slice(0, 15)
25
+ .map((r) => `| ${r.tool} | ${r.blockedCount} | ${(r.blockedRate * 100).toFixed(1)}% | ${r.topMessage ?? '-'} |`)
26
+ .join('\n');
27
+ return [
28
+ '## Friction Points',
29
+ '| Tool | Blocked | Rate | Top Message |',
30
+ '|------|---------|------|-------------|',
31
+ rows,
32
+ ].join('\n');
33
+ }
34
+ function formatVersionTable(report) {
35
+ if (report.versionAdoption.length === 0) {
36
+ return '';
37
+ }
38
+ const rows = report.versionAdoption
39
+ .map((r) => `| ${r.planVersion}${r.isLatest ? ' ✓' : ''} | ${r.userCount} | ${(r.pct * 100).toFixed(1)}% |`)
40
+ .join('\n');
41
+ return [
42
+ '## Version Adoption',
43
+ '| Version | Users | Share |',
44
+ '|---------|-------|-------|',
45
+ rows,
46
+ ].join('\n');
47
+ }
48
+ function formatDeadTools(report) {
49
+ if (report.deadTools.length === 0) {
50
+ return '';
51
+ }
52
+ return `## Dead / Unused Tools\n${report.deadTools.map((t) => `- ${t}`).join('\n')}`;
53
+ }
54
+ function formatReport(report) {
55
+ const sections = [
56
+ `# Product Insights — ${report.periodDays}d period`,
57
+ `**Generated:** ${report.generatedAt}`,
58
+ `**Events:** ${report.totalEvents} | **Unique installs:** ${report.uniqueInstalls}`,
59
+ '',
60
+ `**Summary:** ${report.summary}`,
61
+ ];
62
+ const adoption = formatAdoptionTable(report);
63
+ if (adoption) {
64
+ sections.push('', adoption);
65
+ }
66
+ const friction = formatFrictionTable(report);
67
+ if (friction) {
68
+ sections.push('', friction);
69
+ }
70
+ const versions = formatVersionTable(report);
71
+ if (versions) {
72
+ sections.push('', versions);
73
+ }
74
+ const dead = formatDeadTools(report);
75
+ if (dead) {
76
+ sections.push('', dead);
77
+ }
78
+ return sections.join('\n');
79
+ }
80
+ /**
81
+ * Handles the product_insights MCP tool call.
82
+ * Returns isError:true if Supabase is unreachable or misconfigured.
83
+ */
84
+ export async function handleProductInsights(args) {
85
+ try {
86
+ const report = await generateProductInsights(args.report, args.periodDays ?? 30);
87
+ return { content: [{ type: 'text', text: formatReport(report) }] };
88
+ }
89
+ catch (error) {
90
+ const message = error instanceof Error ? error.message : String(error);
91
+ return {
92
+ content: [
93
+ {
94
+ type: 'text',
95
+ text: `Failed to generate product insights: ${message}\n\nEnsure PLANU_SUPABASE_URL and PLANU_SUPABASE_KEY are configured, or that the default Supabase project is accessible.`,
96
+ },
97
+ ],
98
+ isError: true,
99
+ };
100
+ }
101
+ }
102
+ //# sourceMappingURL=product-insights-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-insights-handler.js","sourceRoot":"","sources":["../../src/tools/product-insights-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerProductInsightsTools(server: McpServer): void;
3
+ //# sourceMappingURL=register-product-insights-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-product-insights-tools.d.ts","sourceRoot":"","sources":["../../src/tools/register-product-insights-tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAuBpE"}
@@ -0,0 +1,22 @@
1
+ // tools/register-product-insights-tools.ts — SPEC-328: Product Intelligence Layer registration.
2
+ import { z } from 'zod';
3
+ import { safeLicensed } from './safe-handler.js';
4
+ import { handleProductInsights } from './product-insights-handler.js';
5
+ export function registerProductInsightsTools(server) {
6
+ server.registerTool('product_insights', {
7
+ description: 'Analyze Planu telemetry to generate product intelligence reports: tool adoption rates, friction points (blocked calls), version upgrade patterns, and dead tools. Admin-only — requires Supabase access.',
8
+ annotations: { readOnlyHint: true },
9
+ inputSchema: {
10
+ report: z
11
+ .enum(['adoption', 'friction', 'versions', 'dead_tools', 'full'])
12
+ .describe('Report type: adoption (tool usage), friction (blocked rate), versions (upgrade rates), dead_tools (unused tools), full (all)'),
13
+ periodDays: z
14
+ .number()
15
+ .min(1)
16
+ .max(365)
17
+ .optional()
18
+ .describe('Analysis period in days (default: 30)'),
19
+ },
20
+ }, safeLicensed('product_insights', async (args) => handleProductInsights(args)));
21
+ }
22
+ //# sourceMappingURL=register-product-insights-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-product-insights-tools.js","sourceRoot":"","sources":["../../src/tools/register-product-insights-tools.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAGhG,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,MAAM,UAAU,4BAA4B,CAAC,MAAiB;IAC5D,MAAM,CAAC,YAAY,CACjB,kBAAkB,EAClB;QACE,WAAW,EACT,0MAA0M;QAC5M,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;QACnC,WAAW,EAAE;YACX,MAAM,EAAE,CAAC;iBACN,IAAI,CAAC,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;iBAChE,QAAQ,CACP,8HAA8H,CAC/H;YACH,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,GAAG,CAAC;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,uCAAuC,CAAC;SACrD;KACF,EACD,YAAY,CAAC,kBAAkB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAC9E,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerApiContractValidationTools(server: McpServer): void;
3
+ //# sourceMappingURL=register-spec-322-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-spec-322-tools.d.ts","sourceRoot":"","sources":["../../src/tools/register-spec-322-tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA8C1E"}
@@ -0,0 +1,41 @@
1
+ // tools/register-spec-322-tools.ts — Register validate_api_contract tool (SPEC-322)
2
+ import { z } from 'zod';
3
+ import { safeTracked } from './safe-handler.js';
4
+ import { handleValidateApiContract } from './validate-api-contract-handler.js';
5
+ export function registerApiContractValidationTools(server) {
6
+ server.registerTool('validate_api_contract', {
7
+ description: 'Validate an OpenAPI 3.x/Swagger or GraphQL SDL contract against the actual implementation in a project. ' +
8
+ 'Scans source files for route handlers (Express, Fastify, Hono, Next.js API routes, FastAPI) or ' +
9
+ 'GraphQL resolvers and reports: missing implementations, undocumented endpoints, schema drift, and ' +
10
+ 'breaking changes. Useful for keeping API documentation in sync with the codebase.',
11
+ annotations: {
12
+ title: 'Validate API Contract vs Implementation',
13
+ readOnlyHint: true,
14
+ destructiveHint: false,
15
+ },
16
+ inputSchema: {
17
+ projectPath: z
18
+ .string()
19
+ .min(1)
20
+ .max(4096)
21
+ .describe('Absolute path to the project root to scan for route implementations.'),
22
+ contractPath: z
23
+ .string()
24
+ .min(1)
25
+ .max(4096)
26
+ .describe('Absolute path to the API contract file. ' +
27
+ 'For OpenAPI: .json or .yaml file. For GraphQL: .graphql, .gql, or .sdl file.'),
28
+ contractFormat: z
29
+ .enum(['openapi', 'graphql', 'auto'])
30
+ .optional()
31
+ .describe('Format of the contract file. Valid values: openapi, graphql, auto. ' +
32
+ 'auto (default) detects format from the file extension: ' +
33
+ '.json/.yaml → openapi, .graphql/.gql/.sdl → graphql.'),
34
+ },
35
+ }, safeTracked('validate_api_contract', async (args) => handleValidateApiContract({
36
+ projectPath: args.projectPath,
37
+ contractPath: args.contractPath,
38
+ contractFormat: args.contractFormat,
39
+ })));
40
+ }
41
+ //# sourceMappingURL=register-spec-322-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-spec-322-tools.js","sourceRoot":"","sources":["../../src/tools/register-spec-322-tools.ts"],"names":[],"mappings":"AAAA,oFAAoF;AAGpF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAE/E,MAAM,UAAU,kCAAkC,CAAC,MAAiB;IAClE,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,WAAW,EACT,0GAA0G;YAC1G,iGAAiG;YACjG,oGAAoG;YACpG,mFAAmF;QACrF,WAAW,EAAE;YACX,KAAK,EAAE,yCAAyC;YAChD,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;SACvB;QACD,WAAW,EAAE;YACX,WAAW,EAAE,CAAC;iBACX,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,IAAI,CAAC;iBACT,QAAQ,CAAC,sEAAsE,CAAC;YACnF,YAAY,EAAE,CAAC;iBACZ,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,IAAI,CAAC;iBACT,QAAQ,CACP,0CAA0C;gBACxC,8EAA8E,CACjF;YACH,cAAc,EAAE,CAAC;iBACd,IAAI,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;iBACpC,QAAQ,EAAE;iBACV,QAAQ,CACP,qEAAqE;gBACnE,yDAAyD;gBACzD,sDAAsD,CACzD;SACJ;KACF,EACD,WAAW,CAAC,uBAAuB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAClD,yBAAyB,CAAC;QACxB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,cAAc,EAAE,IAAI,CAAC,cAAc;KACpC,CAAC,CACH,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerSpec323Tools(server: McpServer): void;
3
+ //# sourceMappingURL=register-spec-323-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-spec-323-tools.d.ts","sourceRoot":"","sources":["../../src/tools/register-spec-323-tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASzE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgF5D"}
@@ -0,0 +1,57 @@
1
+ // tools/register-spec-323-tools.ts — Registers TDD scaffold + coverage gap tools (SPEC-323)
2
+ import { z } from 'zod';
3
+ import { safeTracked } from './safe-handler.js';
4
+ import { handleTddScaffold, handleCoverageGapAnalyzer, handleRunMutationHints, } from './tdd-scaffold-handler.js';
5
+ export function registerSpec323Tools(server) {
6
+ // tdd_scaffold — free tier
7
+ server.registerTool('tdd_scaffold', {
8
+ description: 'Generate a test-first TDD scaffold from spec acceptance criteria. Creates a failing test stub for each "- [ ] criterion" in spec.md and an implementation skeleton. Supports vitest, jest, mocha, pytest, and junit — auto-detected from package.json or build files. Use this BEFORE writing implementation code.',
9
+ inputSchema: {
10
+ specPath: z
11
+ .string()
12
+ .min(1)
13
+ .max(4096)
14
+ .describe('Absolute path to the spec directory (e.g. /project/planu/specs/SPEC-042-payments) or directly to spec.md.'),
15
+ projectPath: z
16
+ .string()
17
+ .min(1)
18
+ .max(4096)
19
+ .describe('Absolute path to the project root. Used to detect test framework.'),
20
+ },
21
+ }, safeTracked('tdd_scaffold', async (args) => handleTddScaffold({
22
+ specPath: args.specPath,
23
+ projectPath: args.projectPath,
24
+ })));
25
+ // coverage_gap_analyzer — pro tier
26
+ server.registerTool('coverage_gap_analyzer', {
27
+ description: 'Analyze which acceptance criteria from a spec are NOT covered by existing tests. Scans tests/**/*.test.ts and similar patterns, maps each AC to test content via keyword matching, and ranks untested ACs by risk domain: auth/payment/data-integrity/security = HIGH, api/notification = MEDIUM, ui/cosmetic = LOW. Returns a coverage score and actionable recommendations.',
28
+ annotations: { readOnlyHint: true },
29
+ inputSchema: {
30
+ specPath: z
31
+ .string()
32
+ .min(1)
33
+ .max(4096)
34
+ .describe('Absolute path to the spec directory or spec.md file to analyze.'),
35
+ projectPath: z
36
+ .string()
37
+ .min(1)
38
+ .max(4096)
39
+ .describe('Absolute path to the project root. Test files are discovered relative to this.'),
40
+ },
41
+ }, safeTracked('coverage_gap_analyzer', async (args) => handleCoverageGapAnalyzer({
42
+ specPath: args.specPath,
43
+ projectPath: args.projectPath,
44
+ })));
45
+ // run_mutation_hints — pro tier
46
+ server.registerTool('run_mutation_hints', {
47
+ description: 'Generate a mutation testing configuration file for the detected project stack. Detects vitest → stryker.config.mjs, pytest → setup.cfg (mutmut), junit → pom.xml pitest plugin. Returns the config file content and the CI step command to add to your pipeline. Run after achieving >=90% test coverage.',
48
+ inputSchema: {
49
+ projectPath: z
50
+ .string()
51
+ .min(1)
52
+ .max(4096)
53
+ .describe('Absolute path to the project root. Used to detect language and test framework.'),
54
+ },
55
+ }, safeTracked('run_mutation_hints', async (args) => handleRunMutationHints({ projectPath: args.projectPath })));
56
+ }
57
+ //# sourceMappingURL=register-spec-323-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-spec-323-tools.js","sourceRoot":"","sources":["../../src/tools/register-spec-323-tools.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAG5F,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,UAAU,oBAAoB,CAAC,MAAiB;IACpD,2BAA2B;IAC3B,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,WAAW,EACT,oTAAoT;QACtT,WAAW,EAAE;YACX,QAAQ,EAAE,CAAC;iBACR,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,IAAI,CAAC;iBACT,QAAQ,CACP,2GAA2G,CAC5G;YACH,WAAW,EAAE,CAAC;iBACX,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,IAAI,CAAC;iBACT,QAAQ,CAAC,mEAAmE,CAAC;SACjF;KACF,EACD,WAAW,CAAC,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CACzC,iBAAiB,CAAC;QAChB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,WAAW,EAAE,IAAI,CAAC,WAAW;KAC9B,CAAC,CACH,CACF,CAAC;IAEF,mCAAmC;IACnC,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,WAAW,EACT,+WAA+W;QACjX,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;QACnC,WAAW,EAAE;YACX,QAAQ,EAAE,CAAC;iBACR,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,IAAI,CAAC;iBACT,QAAQ,CAAC,iEAAiE,CAAC;YAC9E,WAAW,EAAE,CAAC;iBACX,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,IAAI,CAAC;iBACT,QAAQ,CACP,gFAAgF,CACjF;SACJ;KACF,EACD,WAAW,CAAC,uBAAuB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAClD,yBAAyB,CAAC;QACxB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,WAAW,EAAE,IAAI,CAAC,WAAW;KAC9B,CAAC,CACH,CACF,CAAC;IAEF,gCAAgC;IAChC,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,WAAW,EACT,2SAA2S;QAC7S,WAAW,EAAE;YACX,WAAW,EAAE,CAAC;iBACX,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,IAAI,CAAC;iBACT,QAAQ,CACP,gFAAgF,CACjF;SACJ;KACF,EACD,WAAW,CAAC,oBAAoB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAC/C,sBAAsB,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAC1D,CACF,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"safe-handler.d.ts","sourceRoot":"","sources":["../../src/tools/safe-handler.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAkCpD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAEhE;AA4ID;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,CAAC,EACpB,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,GACxC,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,CAElC;AA4ED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,GACxC,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,CAElC;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,GACxC,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,CAKlC"}
1
+ {"version":3,"file":"safe-handler.d.ts","sourceRoot":"","sources":["../../src/tools/safe-handler.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAwCpD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAEhE;AA4ID;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,CAAC,EACpB,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,GACxC,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,CAElC;AA6FD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,GACxC,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,CAElC;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,GACxC,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,CAKlC"}
@@ -7,7 +7,9 @@ import { ensureHooksStarted } from './start-hooks.js';
7
7
  import { ensureWorkersStarted } from '../engine/workers/index.js';
8
8
  import { recordError } from '../storage/error-telemetry-store.js';
9
9
  import { hashProjectPath } from '../storage/base-store.js';
10
- import { reportToolError, reportToolValidationError } from '../engine/telemetry/error-reporter.js';
10
+ import { reportToolError, reportToolValidationError, isErrorReportingEnabled, } from '../engine/telemetry/error-reporter.js';
11
+ import { sendTelemetryEvent } from '../engine/telemetry/telemetry-client.js';
12
+ import { PLANU_VERSION } from '../config/version.js';
11
13
  import { recordToolTokens, extractOutputText } from './token-recording.js';
12
14
  import { DriftCacheStore } from '../storage/drift-cache-store.js';
13
15
  import { existsSync } from 'node:fs';
@@ -194,6 +196,7 @@ function safeWithTelemetry(toolName, handler) {
194
196
  const projectPath = safeArgs !== null && typeof safeArgs === 'object'
195
197
  ? safeArgs.projectPath
196
198
  : undefined;
199
+ const startTime = Date.now();
197
200
  try {
198
201
  const result = await withTimeout(() => handler(safeArgs), getTimeoutMs());
199
202
  // Inject pending drift banner (non-blocking, informational only)
@@ -209,6 +212,21 @@ function safeWithTelemetry(toolName, handler) {
209
212
  const outputText = extractOutputText(finalResult);
210
213
  recordToolTokens(toolName, projectPath, args, outputText, SESSION_ID);
211
214
  }
215
+ // Emit tool_used telemetry for successful calls (fire-and-forget)
216
+ /* v8 ignore start */
217
+ if (toolName !== undefined && finalResult.isError !== true && isErrorReportingEnabled()) {
218
+ sendTelemetryEvent({
219
+ event: 'tool_used',
220
+ properties: {
221
+ tool: toolName,
222
+ planVersion: PLANU_VERSION,
223
+ nodeVersion: process.version,
224
+ durationMs: Date.now() - startTime,
225
+ },
226
+ installationId: 'anonymous',
227
+ });
228
+ }
229
+ /* v8 ignore stop */
212
230
  return finalResult;
213
231
  }
214
232
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"safe-handler.js","sourceRoot":"","sources":["../../src/tools/safe-handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"safe-handler.js","sourceRoot":"","sources":["../../src/tools/safe-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { ToolResult, TddScaffoldArgs, CoverageGapArgs, MutationHintsArgs } from '../types/index.js';
2
+ export declare function handleTddScaffold(args: TddScaffoldArgs): Promise<ToolResult>;
3
+ export declare function handleCoverageGapAnalyzer(args: CoverageGapArgs): Promise<ToolResult>;
4
+ export declare function handleRunMutationHints(args: MutationHintsArgs): Promise<ToolResult>;
5
+ //# sourceMappingURL=tdd-scaffold-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tdd-scaffold-handler.d.ts","sourceRoot":"","sources":["../../src/tools/tdd-scaffold-handler.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EACf,eAAe,EACf,iBAAiB,EAClB,MAAM,mBAAmB,CAAC;AAM3B,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CA+BlF;AAMD,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CA4B1F;AAMD,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,CAyBzF"}
@@ -0,0 +1,92 @@
1
+ // tools/tdd-scaffold-handler.ts — SPEC-323
2
+ // Wraps tdd-scaffold-generator + coverage-gap-analyzer for MCP tool handlers.
3
+ import { generateTddScaffold } from '../engine/tdd-scaffold-generator.js';
4
+ import { analyzeCoverageGaps } from '../engine/coverage-gap-analyzer.js';
5
+ import { generateMutationConfig } from '../engine/mutation-config-generator.js';
6
+ // ---------------------------------------------------------------------------
7
+ // tdd_scaffold handler
8
+ // ---------------------------------------------------------------------------
9
+ export async function handleTddScaffold(args) {
10
+ const result = await generateTddScaffold(args.specPath, args.projectPath);
11
+ const lines = [
12
+ '## TDD Scaffold Generated',
13
+ '',
14
+ `**Framework detected:** ${result.framework}`,
15
+ `**Stubs generated:** ${result.stubs.length}`,
16
+ '',
17
+ '### Test file',
18
+ `\`${result.testFilePath}\``,
19
+ '',
20
+ '```',
21
+ result.testContent,
22
+ '```',
23
+ '',
24
+ '### Implementation skeleton',
25
+ `\`${result.implFilePath}\``,
26
+ '',
27
+ '```',
28
+ result.implContent,
29
+ '```',
30
+ '',
31
+ '### Next steps',
32
+ ...result.instructions.map((i) => `- ${i}`),
33
+ ];
34
+ return {
35
+ content: [{ type: 'text', text: lines.join('\n') }],
36
+ structuredContent: result,
37
+ };
38
+ }
39
+ // ---------------------------------------------------------------------------
40
+ // coverage_gap_analyzer handler
41
+ // ---------------------------------------------------------------------------
42
+ export async function handleCoverageGapAnalyzer(args) {
43
+ const report = await analyzeCoverageGaps(args.specPath, args.projectPath);
44
+ const gapLines = report.gaps.map((g) => `- [${g.riskLevel.toUpperCase()}] **${g.riskDomain}** — ${g.criterion}\n → ${g.recommendation}`);
45
+ const lines = [
46
+ '## Coverage Gap Analysis',
47
+ '',
48
+ `**Coverage score:** ${report.coverageScore}% (${report.coveredCriteria}/${report.totalCriteria} ACs covered)`,
49
+ `**Test files scanned:** ${report.testFilesScanned}`,
50
+ `**Gaps found:** ${report.gaps.length}`,
51
+ '',
52
+ ];
53
+ if (report.gaps.length === 0) {
54
+ lines.push('All acceptance criteria appear to be covered by existing tests.');
55
+ }
56
+ else {
57
+ lines.push('### Untested Acceptance Criteria (ranked by risk)', '');
58
+ lines.push(...gapLines);
59
+ }
60
+ return {
61
+ content: [{ type: 'text', text: lines.join('\n') }],
62
+ structuredContent: report,
63
+ };
64
+ }
65
+ // ---------------------------------------------------------------------------
66
+ // run_mutation_hints handler
67
+ // ---------------------------------------------------------------------------
68
+ export async function handleRunMutationHints(args) {
69
+ const result = await generateMutationConfig(args.projectPath);
70
+ const lines = [
71
+ '## Mutation Testing Config',
72
+ '',
73
+ `**Tool:** ${result.tool}`,
74
+ `**Framework:** ${result.framework}`,
75
+ `**Config file:** \`${result.configFileName}\``,
76
+ '',
77
+ '### CI step',
78
+ '```bash',
79
+ result.ciStep,
80
+ '```',
81
+ '',
82
+ '### Config content',
83
+ '```',
84
+ result.configContent,
85
+ '```',
86
+ ];
87
+ return {
88
+ content: [{ type: 'text', text: lines.join('\n') }],
89
+ structuredContent: result,
90
+ };
91
+ }
92
+ //# sourceMappingURL=tdd-scaffold-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tdd-scaffold-handler.js","sourceRoot":"","sources":["../../src/tools/tdd-scaffold-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ToolResult, ValidateApiContractInput } from '../types/index.js';
2
+ export declare function handleValidateApiContract(args: ValidateApiContractInput): Promise<ToolResult>;
3
+ //# sourceMappingURL=validate-api-contract-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-api-contract-handler.d.ts","sourceRoot":"","sources":["../../src/tools/validate-api-contract-handler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,wBAAwB,EAAqB,MAAM,mBAAmB,CAAC;AAwEjG,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,UAAU,CAAC,CAoBrB"}
@@ -0,0 +1,74 @@
1
+ // tools/validate-api-contract-handler.ts — Handler for validate_api_contract (SPEC-322)
2
+ import { validateOpenApiContract } from '../engine/api-validation/openapi-impl-validator.js';
3
+ import { validateGraphQLSchema } from '../engine/api-validation/graphql-schema-validator.js';
4
+ // ---------------------------------------------------------------------------
5
+ // Format auto-detection
6
+ // ---------------------------------------------------------------------------
7
+ function detectFormat(contractPath) {
8
+ const lower = contractPath.toLowerCase();
9
+ if (lower.endsWith('.graphql') || lower.endsWith('.gql') || lower.endsWith('.sdl')) {
10
+ return 'graphql';
11
+ }
12
+ return 'openapi';
13
+ }
14
+ // ---------------------------------------------------------------------------
15
+ // Result formatter
16
+ // ---------------------------------------------------------------------------
17
+ function formatReport(report) {
18
+ const lines = [
19
+ `## API Contract Validation — ${report.contractTitle}`,
20
+ `Format: ${report.contractFormat.toUpperCase()} | Version: ${report.contractVersion}`,
21
+ `Contract endpoints: ${report.totalContractEndpoints} | Implementation endpoints: ${report.totalImplEndpoints}`,
22
+ '',
23
+ `**Summary:** ${report.summary}`,
24
+ ];
25
+ if (report.missingEndpoints.length > 0) {
26
+ lines.push('', `### Missing Implementations (${report.missingEndpoints.length})`);
27
+ for (const f of report.missingEndpoints) {
28
+ lines.push(`- [${f.severity.toUpperCase()}] \`${f.method} ${f.path}\`: ${f.message}`);
29
+ }
30
+ }
31
+ if (report.undocumentedEndpoints.length > 0) {
32
+ lines.push('', `### Undocumented Endpoints (${report.undocumentedEndpoints.length})`);
33
+ for (const f of report.undocumentedEndpoints) {
34
+ lines.push(`- [${f.severity.toUpperCase()}] \`${f.method} ${f.path}\`: ${f.message}`);
35
+ }
36
+ }
37
+ if (report.schemaDrift.length > 0) {
38
+ lines.push('', `### Schema Drift (${report.schemaDrift.length})`);
39
+ for (const f of report.schemaDrift) {
40
+ lines.push(`- [${f.severity.toUpperCase()}] \`${f.path}\`: ${f.message}`);
41
+ }
42
+ }
43
+ if (report.breakingChanges.length > 0) {
44
+ lines.push('', `### Breaking Changes (${report.breakingChanges.length})`);
45
+ for (const f of report.breakingChanges) {
46
+ lines.push(`- [${f.severity.toUpperCase()}] \`${f.path}\`: ${f.message}`);
47
+ }
48
+ }
49
+ const criticalCount = report.findings.filter((f) => f.severity === 'critical').length;
50
+ const warningCount = report.findings.filter((f) => f.severity === 'warning').length;
51
+ lines.push('', `**Total findings:** ${report.findings.length} (${criticalCount} critical, ${warningCount} warnings)`);
52
+ return lines.join('\n');
53
+ }
54
+ // ---------------------------------------------------------------------------
55
+ // Main handler
56
+ // ---------------------------------------------------------------------------
57
+ export async function handleValidateApiContract(args) {
58
+ const { projectPath, contractPath } = args;
59
+ const format = args.contractFormat === 'auto' || args.contractFormat === undefined
60
+ ? detectFormat(contractPath)
61
+ : args.contractFormat;
62
+ let report;
63
+ if (format === 'graphql') {
64
+ report = await validateGraphQLSchema(contractPath, projectPath);
65
+ }
66
+ else {
67
+ report = await validateOpenApiContract(contractPath, projectPath);
68
+ }
69
+ const text = formatReport(report);
70
+ return {
71
+ content: [{ type: 'text', text }],
72
+ };
73
+ }
74
+ //# sourceMappingURL=validate-api-contract-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-api-contract-handler.js","sourceRoot":"","sources":["../../src/tools/validate-api-contract-handler.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/tools/validate.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAClF,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,YAAY,EACZ,kBAAkB,EAGnB,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAAE,0BAA0B,EAAE,CAAC;AACtC,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,CAAC;AAEjD,wBAAsB,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,CAkP7E"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/tools/validate.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAClF,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,YAAY,EACZ,kBAAkB,EAGnB,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAAE,0BAA0B,EAAE,CAAC;AACtC,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,CAAC;AAEjD,wBAAsB,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,CA2P7E"}
@@ -1,6 +1,6 @@
1
1
  // tools/validate.ts — Compare spec vs implementation
2
2
  // Uses the validator engine to check coverage, missing items, quality issues.
3
- import { execSync } from 'node:child_process';
3
+ import { execSync, execFileSync } from 'node:child_process';
4
4
  import { compactObj } from '../engine/compact-obj.js';
5
5
  import { specStore, knowledgeStore } from '../storage/index.js';
6
6
  import { validateSpec, generateDoR, generateDoD } from '../engine/validator.js';
@@ -220,12 +220,19 @@ export async function handleValidate(args) {
220
220
  const commitReminder = scoreValue >= 80
221
221
  ? `\n\n> 💡 Good score! Remember to save progress with git: \`git add planu/ && git commit -m "chore: ${specId} progress checkpoint"\``
222
222
  : '';
223
+ // SPEC-326: Pending HTML changes notification
224
+ const planuChanges = checkPlanuUncommittedChanges(projectPath);
225
+ const planuReminder = planuChanges
226
+ ? '\n\n📁 HTML reports updated — commit to save: `git add planu/ && git commit -m "chore(planu): update reports"`'
227
+ : '';
223
228
  return {
224
229
  phaseEvent: createBasicPhaseEvent('validate', 'completed', 100, 'validating'),
225
230
  content: [
226
231
  {
227
232
  type: 'text',
228
- text: ti('tools.validate.success', { score: String(result.score) }) + commitReminder,
233
+ text: ti('tools.validate.success', { score: String(result.score) }) +
234
+ commitReminder +
235
+ planuReminder,
229
236
  },
230
237
  ],
231
238
  structuredContent: outputWithSuggestions,
@@ -274,6 +281,21 @@ function parseLintIssueCount(output) {
274
281
  }
275
282
  return output.split('\n').filter((l) => l.trim().length > 0).length;
276
283
  }
284
+ /** Check if planu/ directory has uncommitted changes via git status --porcelain */
285
+ function checkPlanuUncommittedChanges(projectPath) {
286
+ try {
287
+ const output = execFileSync('git', ['status', '--porcelain', 'planu/'], {
288
+ cwd: projectPath,
289
+ encoding: 'utf-8',
290
+ timeout: 5_000,
291
+ stdio: ['pipe', 'pipe', 'pipe'],
292
+ });
293
+ return output.trim().length > 0;
294
+ }
295
+ catch {
296
+ return false;
297
+ }
298
+ }
277
299
  function scoreToGrade(score) {
278
300
  if (score >= 90) {
279
301
  return 'A';