@planu/cli 1.10.0 → 1.11.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 (153) hide show
  1. package/dist/config/license-plans.json +5 -0
  2. package/dist/engine/compliance/evidence-builder.d.ts +19 -0
  3. package/dist/engine/compliance/evidence-builder.d.ts.map +1 -0
  4. package/dist/engine/compliance/evidence-builder.js +36 -0
  5. package/dist/engine/compliance/evidence-builder.js.map +1 -0
  6. package/dist/engine/compliance/framework-catalog.d.ts +15 -0
  7. package/dist/engine/compliance/framework-catalog.d.ts.map +1 -0
  8. package/dist/engine/compliance/framework-catalog.js +134 -0
  9. package/dist/engine/compliance/framework-catalog.js.map +1 -0
  10. package/dist/engine/compliance/gap-analyzer.d.ts +11 -0
  11. package/dist/engine/compliance/gap-analyzer.d.ts.map +1 -0
  12. package/dist/engine/compliance/gap-analyzer.js +39 -0
  13. package/dist/engine/compliance/gap-analyzer.js.map +1 -0
  14. package/dist/engine/distribution/cost-estimator.d.ts +8 -0
  15. package/dist/engine/distribution/cost-estimator.d.ts.map +1 -0
  16. package/dist/engine/distribution/cost-estimator.js +113 -0
  17. package/dist/engine/distribution/cost-estimator.js.map +1 -0
  18. package/dist/engine/distribution/diagram-generator.d.ts +12 -0
  19. package/dist/engine/distribution/diagram-generator.d.ts.map +1 -0
  20. package/dist/engine/distribution/diagram-generator.js +59 -0
  21. package/dist/engine/distribution/diagram-generator.js.map +1 -0
  22. package/dist/engine/distribution/readiness-analyzer.d.ts +4 -0
  23. package/dist/engine/distribution/readiness-analyzer.d.ts.map +1 -0
  24. package/dist/engine/distribution/readiness-analyzer.js +61 -0
  25. package/dist/engine/distribution/readiness-analyzer.js.map +1 -0
  26. package/dist/engine/distribution/runbook-generator.d.ts +7 -0
  27. package/dist/engine/distribution/runbook-generator.d.ts.map +1 -0
  28. package/dist/engine/distribution/runbook-generator.js +42 -0
  29. package/dist/engine/distribution/runbook-generator.js.map +1 -0
  30. package/dist/engine/mcp-hub/adapter-registry.d.ts +23 -0
  31. package/dist/engine/mcp-hub/adapter-registry.d.ts.map +1 -0
  32. package/dist/engine/mcp-hub/adapter-registry.js +19 -0
  33. package/dist/engine/mcp-hub/adapter-registry.js.map +1 -0
  34. package/dist/engine/mcp-hub/adapters/github-adapter.d.ts +4 -0
  35. package/dist/engine/mcp-hub/adapters/github-adapter.d.ts.map +1 -0
  36. package/dist/engine/mcp-hub/adapters/github-adapter.js +44 -0
  37. package/dist/engine/mcp-hub/adapters/github-adapter.js.map +1 -0
  38. package/dist/engine/mcp-hub/adapters/supabase-adapter.d.ts +4 -0
  39. package/dist/engine/mcp-hub/adapters/supabase-adapter.d.ts.map +1 -0
  40. package/dist/engine/mcp-hub/adapters/supabase-adapter.js +41 -0
  41. package/dist/engine/mcp-hub/adapters/supabase-adapter.js.map +1 -0
  42. package/dist/engine/mcp-hub/event-router.d.ts +19 -0
  43. package/dist/engine/mcp-hub/event-router.d.ts.map +1 -0
  44. package/dist/engine/mcp-hub/event-router.js +47 -0
  45. package/dist/engine/mcp-hub/event-router.js.map +1 -0
  46. package/dist/engine/productivity/calibration-engine.d.ts +17 -0
  47. package/dist/engine/productivity/calibration-engine.d.ts.map +1 -0
  48. package/dist/engine/productivity/calibration-engine.js +49 -0
  49. package/dist/engine/productivity/calibration-engine.js.map +1 -0
  50. package/dist/engine/productivity/time-tracker.d.ts +6 -0
  51. package/dist/engine/productivity/time-tracker.d.ts.map +1 -0
  52. package/dist/engine/productivity/time-tracker.js +28 -0
  53. package/dist/engine/productivity/time-tracker.js.map +1 -0
  54. package/dist/engine/productivity/vibe-tax-calculator.d.ts +14 -0
  55. package/dist/engine/productivity/vibe-tax-calculator.d.ts.map +1 -0
  56. package/dist/engine/productivity/vibe-tax-calculator.js +63 -0
  57. package/dist/engine/productivity/vibe-tax-calculator.js.map +1 -0
  58. package/dist/engine/quality-gates/gate-catalog.d.ts +6 -0
  59. package/dist/engine/quality-gates/gate-catalog.d.ts.map +1 -0
  60. package/dist/engine/quality-gates/gate-catalog.js +351 -0
  61. package/dist/engine/quality-gates/gate-catalog.js.map +1 -0
  62. package/dist/engine/quality-gates/gate-evaluator.d.ts +3 -0
  63. package/dist/engine/quality-gates/gate-evaluator.d.ts.map +1 -0
  64. package/dist/engine/quality-gates/gate-evaluator.js +25 -0
  65. package/dist/engine/quality-gates/gate-evaluator.js.map +1 -0
  66. package/dist/engine/quality-gates/gate-injector.d.ts +20 -0
  67. package/dist/engine/quality-gates/gate-injector.d.ts.map +1 -0
  68. package/dist/engine/quality-gates/gate-injector.js +75 -0
  69. package/dist/engine/quality-gates/gate-injector.js.map +1 -0
  70. package/dist/index.js +10 -0
  71. package/dist/index.js.map +1 -1
  72. package/dist/storage/compliance-audit-store.d.ts +12 -0
  73. package/dist/storage/compliance-audit-store.d.ts.map +1 -0
  74. package/dist/storage/compliance-audit-store.js +40 -0
  75. package/dist/storage/compliance-audit-store.js.map +1 -0
  76. package/dist/storage/mcp-hub-store.d.ts +9 -0
  77. package/dist/storage/mcp-hub-store.d.ts.map +1 -0
  78. package/dist/storage/mcp-hub-store.js +28 -0
  79. package/dist/storage/mcp-hub-store.js.map +1 -0
  80. package/dist/storage/time-tracking-store.d.ts +6 -0
  81. package/dist/storage/time-tracking-store.d.ts.map +1 -0
  82. package/dist/storage/time-tracking-store.js +34 -0
  83. package/dist/storage/time-tracking-store.js.map +1 -0
  84. package/dist/tools/compliance-gap-handler.d.ts +5 -0
  85. package/dist/tools/compliance-gap-handler.d.ts.map +1 -0
  86. package/dist/tools/compliance-gap-handler.js +64 -0
  87. package/dist/tools/compliance-gap-handler.js.map +1 -0
  88. package/dist/tools/distribution-readiness-handler.d.ts +3 -0
  89. package/dist/tools/distribution-readiness-handler.d.ts.map +1 -0
  90. package/dist/tools/distribution-readiness-handler.js +24 -0
  91. package/dist/tools/distribution-readiness-handler.js.map +1 -0
  92. package/dist/tools/generate-cost-estimate-handler.d.ts +3 -0
  93. package/dist/tools/generate-cost-estimate-handler.d.ts.map +1 -0
  94. package/dist/tools/generate-cost-estimate-handler.js +29 -0
  95. package/dist/tools/generate-cost-estimate-handler.js.map +1 -0
  96. package/dist/tools/generate-deployment-diagram-handler.d.ts +3 -0
  97. package/dist/tools/generate-deployment-diagram-handler.d.ts.map +1 -0
  98. package/dist/tools/generate-deployment-diagram-handler.js +26 -0
  99. package/dist/tools/generate-deployment-diagram-handler.js.map +1 -0
  100. package/dist/tools/generate-runbook-handler.d.ts +3 -0
  101. package/dist/tools/generate-runbook-handler.d.ts.map +1 -0
  102. package/dist/tools/generate-runbook-handler.js +18 -0
  103. package/dist/tools/generate-runbook-handler.js.map +1 -0
  104. package/dist/tools/inject-quality-gates-handler.d.ts +7 -0
  105. package/dist/tools/inject-quality-gates-handler.d.ts.map +1 -0
  106. package/dist/tools/inject-quality-gates-handler.js +59 -0
  107. package/dist/tools/inject-quality-gates-handler.js.map +1 -0
  108. package/dist/tools/mcp-hub-handler.d.ts +7 -0
  109. package/dist/tools/mcp-hub-handler.d.ts.map +1 -0
  110. package/dist/tools/mcp-hub-handler.js +73 -0
  111. package/dist/tools/mcp-hub-handler.js.map +1 -0
  112. package/dist/tools/productivity-report-handler.d.ts +4 -0
  113. package/dist/tools/productivity-report-handler.d.ts.map +1 -0
  114. package/dist/tools/productivity-report-handler.js +98 -0
  115. package/dist/tools/productivity-report-handler.js.map +1 -0
  116. package/dist/tools/register-distribution.d.ts +3 -0
  117. package/dist/tools/register-distribution.d.ts.map +1 -0
  118. package/dist/tools/register-distribution.js +103 -0
  119. package/dist/tools/register-distribution.js.map +1 -0
  120. package/dist/tools/register-enterprise-compliance.d.ts +3 -0
  121. package/dist/tools/register-enterprise-compliance.d.ts.map +1 -0
  122. package/dist/tools/register-enterprise-compliance.js +30 -0
  123. package/dist/tools/register-enterprise-compliance.js.map +1 -0
  124. package/dist/tools/register-mcp-hub.d.ts +3 -0
  125. package/dist/tools/register-mcp-hub.d.ts.map +1 -0
  126. package/dist/tools/register-mcp-hub.js +47 -0
  127. package/dist/tools/register-mcp-hub.js.map +1 -0
  128. package/dist/tools/register-productivity.d.ts +3 -0
  129. package/dist/tools/register-productivity.d.ts.map +1 -0
  130. package/dist/tools/register-productivity.js +25 -0
  131. package/dist/tools/register-productivity.js.map +1 -0
  132. package/dist/tools/register-quality-gates.d.ts +3 -0
  133. package/dist/tools/register-quality-gates.d.ts.map +1 -0
  134. package/dist/tools/register-quality-gates.js +47 -0
  135. package/dist/tools/register-quality-gates.js.map +1 -0
  136. package/dist/types/analysis.d.ts +30 -0
  137. package/dist/types/analysis.d.ts.map +1 -1
  138. package/dist/types/docs.d.ts +43 -0
  139. package/dist/types/docs.d.ts.map +1 -1
  140. package/dist/types/env.d.ts +23 -0
  141. package/dist/types/env.d.ts.map +1 -1
  142. package/dist/types/estimation.d.ts +30 -0
  143. package/dist/types/estimation.d.ts.map +1 -1
  144. package/dist/types/orchestration/index.d.ts +1 -0
  145. package/dist/types/orchestration/index.d.ts.map +1 -1
  146. package/dist/types/orchestration/mcp-hub.d.ts +29 -0
  147. package/dist/types/orchestration/mcp-hub.d.ts.map +1 -0
  148. package/dist/types/orchestration/mcp-hub.js +3 -0
  149. package/dist/types/orchestration/mcp-hub.js.map +1 -0
  150. package/dist/types/orchestration.d.ts +1 -1
  151. package/dist/types/orchestration.d.ts.map +1 -1
  152. package/package.json +1 -1
  153. package/src/config/license-plans.json +5 -0
@@ -0,0 +1,42 @@
1
+ export function generateRunbook(input) {
2
+ const { projectName, provider, services } = input;
3
+ const date = new Date().toISOString().split('T')[0];
4
+ return `# Operational Runbook — ${projectName}
5
+ Generated: ${date} | Provider: ${provider}
6
+
7
+ ## 1. Pre-Deployment Checklist
8
+ - [ ] All tests passing in CI
9
+ - [ ] Environment variables configured in ${provider} dashboard
10
+ - [ ] Database migrations reviewed and tested on staging
11
+ - [ ] Rollback plan documented (see section 3)
12
+ - [ ] On-call engineer notified
13
+
14
+ ## 2. Deployment Steps
15
+ ${services.map((s, i) => `${i + 1}. Deploy ${s} to ${provider}`).join('\n')}
16
+ ${services.length + 1}. Run health check endpoints
17
+ ${services.length + 2}. Verify monitoring dashboards show green
18
+
19
+ ## 3. Rollback Procedure
20
+ 1. Identify the last stable deployment tag
21
+ 2. Trigger rollback in ${provider} dashboard → select previous deployment
22
+ 3. Verify rollback successful via health check
23
+ 4. Notify team in incident channel
24
+
25
+ ## 4. Health Checks
26
+ ${services.map((s) => `- GET /${s.toLowerCase().replace(/\s+/g, '-')}/health → 200 OK`).join('\n')}
27
+
28
+ ## 5. Alerting Thresholds
29
+ | Metric | Warning | Critical |
30
+ |--------|---------|----------|
31
+ | Error rate | >1% | >5% |
32
+ | P99 latency | >500ms | >2000ms |
33
+ | CPU usage | >70% | >90% |
34
+ | Memory | >80% | >95% |
35
+
36
+ ## 6. Incident Response
37
+ - P1 (production down): Page on-call immediately, start incident bridge
38
+ - P2 (degraded): Notify team, investigate within 30 minutes
39
+ - P3 (minor): Track in issue tracker, fix in next sprint
40
+ `;
41
+ }
42
+ //# sourceMappingURL=runbook-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runbook-generator.js","sourceRoot":"","sources":["../../../src/engine/distribution/runbook-generator.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,eAAe,CAAC,KAAmB;IACjD,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAClD,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,OAAO,2BAA2B,WAAW;aAClC,IAAI,gBAAgB,QAAQ;;;;4CAIG,QAAQ;;;;;;EAMlD,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;EACzE,QAAQ,CAAC,MAAM,GAAG,CAAC;EACnB,QAAQ,CAAC,MAAM,GAAG,CAAC;;;;yBAII,QAAQ;;;;;EAK/B,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;;;;;;;;;CAcjG,CAAC;AACF,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { McpAdapterStatus, McpSpecEvent, McpAdapterHandleResult } from '../../types/index.js';
2
+ export type AdapterStatus = McpAdapterStatus;
3
+ export type SpecEvent = McpSpecEvent;
4
+ export type AdapterHandleResult = McpAdapterHandleResult;
5
+ export interface McpAdapter {
6
+ id: string;
7
+ name: string;
8
+ description: string;
9
+ triggers: SpecEvent[];
10
+ isConfigured: (config: Record<string, unknown>) => boolean;
11
+ getStatus: (config: Record<string, unknown>) => AdapterStatus;
12
+ handleEvent: (event: SpecEvent, specId: string, config: Record<string, unknown>) => Promise<AdapterHandleResult>;
13
+ }
14
+ export interface AdapterRegistration {
15
+ adapter: McpAdapter;
16
+ enabled: boolean;
17
+ config: Record<string, unknown>;
18
+ }
19
+ export declare function registerAdapter(adapter: McpAdapter): void;
20
+ export declare function getAdapter(id: string): McpAdapter | undefined;
21
+ export declare function listAdapters(): McpAdapter[];
22
+ export declare function getAdapterStatus(adapterId: string, config: Record<string, unknown>): AdapterStatus;
23
+ //# sourceMappingURL=adapter-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-registry.d.ts","sourceRoot":"","sources":["../../../src/engine/mcp-hub/adapter-registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAGnG,MAAM,MAAM,aAAa,GAAG,gBAAgB,CAAC;AAE7C,MAAM,MAAM,SAAS,GAAG,YAAY,CAAC;AAErC,MAAM,MAAM,mBAAmB,GAAG,sBAAsB,CAAC;AAGzD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC;IAC3D,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,aAAa,CAAC;IAC9D,WAAW,EAAE,CACX,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACnC;AAGD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAKD,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAEzD;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAE7D;AAED,wBAAgB,YAAY,IAAI,UAAU,EAAE,CAE3C;AAED,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,aAAa,CAMf"}
@@ -0,0 +1,19 @@
1
+ // Built-in adapter registry
2
+ const REGISTRY = new Map();
3
+ export function registerAdapter(adapter) {
4
+ REGISTRY.set(adapter.id, adapter);
5
+ }
6
+ export function getAdapter(id) {
7
+ return REGISTRY.get(id);
8
+ }
9
+ export function listAdapters() {
10
+ return Array.from(REGISTRY.values());
11
+ }
12
+ export function getAdapterStatus(adapterId, config) {
13
+ const adapter = REGISTRY.get(adapterId);
14
+ if (!adapter) {
15
+ return 'not-configured';
16
+ }
17
+ return adapter.getStatus(config);
18
+ }
19
+ //# sourceMappingURL=adapter-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-registry.js","sourceRoot":"","sources":["../../../src/engine/mcp-hub/adapter-registry.ts"],"names":[],"mappings":"AAgCA,4BAA4B;AAC5B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAsB,CAAC;AAE/C,MAAM,UAAU,eAAe,CAAC,OAAmB;IACjD,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EAAU;IACnC,OAAO,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,SAAiB,EACjB,MAA+B;IAE/B,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IACD,OAAO,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;AACnC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type McpAdapter } from '../adapter-registry.js';
2
+ declare const githubAdapter: McpAdapter;
3
+ export { githubAdapter };
4
+ //# sourceMappingURL=github-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-adapter.d.ts","sourceRoot":"","sources":["../../../../src/engine/mcp-hub/adapters/github-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAA6C,MAAM,wBAAwB,CAAC;AAEpG,QAAA,MAAM,aAAa,EAAE,UAyCpB,CAAC;AAGF,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,44 @@
1
+ // github-adapter.ts — GitHub MCP adapter (SPEC-403)
2
+ import { registerAdapter } from '../adapter-registry.js';
3
+ const githubAdapter = {
4
+ id: 'github',
5
+ name: 'GitHub',
6
+ description: 'Creates GitHub issues on spec approval and closes them on spec completion',
7
+ triggers: ['spec:approved', 'spec:done', 'spec:implementing'],
8
+ isConfigured: (config) => typeof config.token === 'string' && typeof config.repo === 'string',
9
+ getStatus: (config) => {
10
+ if (typeof config.token !== 'string' || typeof config.repo !== 'string') {
11
+ return 'not-configured';
12
+ }
13
+ return 'connected';
14
+ },
15
+ handleEvent: (event, specId, config) => {
16
+ const token = config.token;
17
+ const repo = config.repo;
18
+ if (!token || !repo) {
19
+ return Promise.resolve({
20
+ adapterId: 'github',
21
+ event,
22
+ specId,
23
+ success: false,
24
+ message: 'GitHub token and repo required',
25
+ });
26
+ }
27
+ const action = event === 'spec:approved'
28
+ ? `Would create GitHub issue for ${specId} in ${repo}`
29
+ : event === 'spec:done'
30
+ ? `Would close GitHub issue for ${specId} in ${repo}`
31
+ : `Would update GitHub issue for ${specId} in ${repo}`;
32
+ return Promise.resolve({
33
+ adapterId: 'github',
34
+ event,
35
+ specId,
36
+ success: true,
37
+ message: action,
38
+ externalId: `github-issue-${specId}`,
39
+ });
40
+ },
41
+ };
42
+ registerAdapter(githubAdapter);
43
+ export { githubAdapter };
44
+ //# sourceMappingURL=github-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-adapter.js","sourceRoot":"","sources":["../../../../src/engine/mcp-hub/adapters/github-adapter.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,OAAO,EAA6C,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEpG,MAAM,aAAa,GAAe;IAChC,EAAE,EAAE,QAAQ;IACZ,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,2EAA2E;IACxF,QAAQ,EAAE,CAAC,eAAe,EAAE,WAAW,EAAE,mBAAmB,CAAC;IAC7D,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ;IAC7F,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;QACpB,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACxE,OAAO,gBAAgB,CAAC;QAC1B,CAAC;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAgC,EAAE;QACnE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,MAAM,IAAI,GAAG,MAAM,CAAC,IAA0B,CAAC;QAC/C,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;YACpB,OAAO,OAAO,CAAC,OAAO,CAAC;gBACrB,SAAS,EAAE,QAAQ;gBACnB,KAAK;gBACL,MAAM;gBACN,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,gCAAgC;aAC1C,CAAC,CAAC;QACL,CAAC;QAED,MAAM,MAAM,GACV,KAAK,KAAK,eAAe;YACvB,CAAC,CAAC,iCAAiC,MAAM,OAAO,IAAI,EAAE;YACtD,CAAC,CAAC,KAAK,KAAK,WAAW;gBACrB,CAAC,CAAC,gCAAgC,MAAM,OAAO,IAAI,EAAE;gBACrD,CAAC,CAAC,iCAAiC,MAAM,OAAO,IAAI,EAAE,CAAC;QAE7D,OAAO,OAAO,CAAC,OAAO,CAAC;YACrB,SAAS,EAAE,QAAQ;YACnB,KAAK;YACL,MAAM;YACN,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,MAAM;YACf,UAAU,EAAE,gBAAgB,MAAM,EAAE;SACrC,CAAC,CAAC;IACL,CAAC;CACF,CAAC;AAEF,eAAe,CAAC,aAAa,CAAC,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type McpAdapter } from '../adapter-registry.js';
2
+ declare const supabaseAdapter: McpAdapter;
3
+ export { supabaseAdapter };
4
+ //# sourceMappingURL=supabase-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase-adapter.d.ts","sourceRoot":"","sources":["../../../../src/engine/mcp-hub/adapters/supabase-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAA6C,MAAM,wBAAwB,CAAC;AAEpG,QAAA,MAAM,eAAe,EAAE,UAuCtB,CAAC;AAGF,OAAO,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,41 @@
1
+ // supabase-adapter.ts — Supabase MCP adapter (SPEC-403)
2
+ import { registerAdapter } from '../adapter-registry.js';
3
+ const supabaseAdapter = {
4
+ id: 'supabase',
5
+ name: 'Supabase',
6
+ description: 'Scaffolds database migrations and creates Supabase branches for database-target specs',
7
+ triggers: ['spec:approved', 'spec:implementing'],
8
+ isConfigured: (config) => typeof config.projectRef === 'string',
9
+ getStatus: (config) => {
10
+ if (typeof config.projectRef !== 'string') {
11
+ return 'not-configured';
12
+ }
13
+ return 'connected';
14
+ },
15
+ handleEvent: (event, specId, config) => {
16
+ const projectRef = config.projectRef;
17
+ if (!projectRef) {
18
+ return Promise.resolve({
19
+ adapterId: 'supabase',
20
+ event,
21
+ specId,
22
+ success: false,
23
+ message: 'Supabase projectRef required',
24
+ });
25
+ }
26
+ const action = event === 'spec:approved'
27
+ ? `Would scaffold migration for ${specId} in Supabase project ${projectRef}`
28
+ : `Would create Supabase branch for ${specId} implementation`;
29
+ return Promise.resolve({
30
+ adapterId: 'supabase',
31
+ event,
32
+ specId,
33
+ success: true,
34
+ message: action,
35
+ externalId: `supabase-branch-${specId}`,
36
+ });
37
+ },
38
+ };
39
+ registerAdapter(supabaseAdapter);
40
+ export { supabaseAdapter };
41
+ //# sourceMappingURL=supabase-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase-adapter.js","sourceRoot":"","sources":["../../../../src/engine/mcp-hub/adapters/supabase-adapter.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,OAAO,EAA6C,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEpG,MAAM,eAAe,GAAe;IAClC,EAAE,EAAE,UAAU;IACd,IAAI,EAAE,UAAU;IAChB,WAAW,EACT,uFAAuF;IACzF,QAAQ,EAAE,CAAC,eAAe,EAAE,mBAAmB,CAAC;IAChD,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ;IAC/D,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;QACpB,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;YAC1C,OAAO,gBAAgB,CAAC;QAC1B,CAAC;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAgC,EAAE;QACnE,MAAM,UAAU,GAAG,MAAM,CAAC,UAAgC,CAAC;QAC3D,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,OAAO,CAAC,OAAO,CAAC;gBACrB,SAAS,EAAE,UAAU;gBACrB,KAAK;gBACL,MAAM;gBACN,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,8BAA8B;aACxC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,MAAM,GACV,KAAK,KAAK,eAAe;YACvB,CAAC,CAAC,gCAAgC,MAAM,wBAAwB,UAAU,EAAE;YAC5E,CAAC,CAAC,oCAAoC,MAAM,iBAAiB,CAAC;QAElE,OAAO,OAAO,CAAC,OAAO,CAAC;YACrB,SAAS,EAAE,UAAU;YACrB,KAAK;YACL,MAAM;YACN,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,MAAM;YACf,UAAU,EAAE,mBAAmB,MAAM,EAAE;SACxC,CAAC,CAAC;IACL,CAAC;CACF,CAAC;AAEF,eAAe,CAAC,eAAe,CAAC,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { type SpecEvent } from './adapter-registry.js';
2
+ import type { McpHubRoutingResult } from '../../types/index.js';
3
+ export interface HubConfig {
4
+ enabledAdapters: string[];
5
+ adapterConfigs: Record<string, Record<string, unknown>>;
6
+ }
7
+ export type RoutingResult = McpHubRoutingResult;
8
+ export declare function routeEvent(event: SpecEvent, specId: string, hubConfig: HubConfig): Promise<RoutingResult>;
9
+ export declare function buildHubStatus(hubConfig: HubConfig): {
10
+ totalAdapters: number;
11
+ enabledAdapters: number;
12
+ adapterStatuses: {
13
+ id: string;
14
+ name: string;
15
+ status: string;
16
+ triggers: string[];
17
+ }[];
18
+ };
19
+ //# sourceMappingURL=event-router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-router.d.ts","sourceRoot":"","sources":["../../../src/engine/mcp-hub/event-router.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,SAAS,EAGf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAGhE,MAAM,WAAW,SAAS;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACzD;AAGD,MAAM,MAAM,aAAa,GAAG,mBAAmB,CAAC;AAEhD,wBAAsB,UAAU,CAC9B,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,aAAa,CAAC,CAkCxB;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG;IACpD,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE;QACf,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,EAAE,CAAC;CACL,CAeA"}
@@ -0,0 +1,47 @@
1
+ // event-router.ts — MCP Hub event routing (SPEC-403)
2
+ import { listAdapters, getAdapterStatus, } from './adapter-registry.js';
3
+ export async function routeEvent(event, specId, hubConfig) {
4
+ const adapters = listAdapters().filter((a) => hubConfig.enabledAdapters.includes(a.id) && a.triggers.includes(event));
5
+ const results = [];
6
+ // Fire all adapters in parallel — failures don't block others
7
+ await Promise.all(adapters.map(async (adapter) => {
8
+ const config = hubConfig.adapterConfigs[adapter.id] ?? {};
9
+ try {
10
+ const result = await adapter.handleEvent(event, specId, config);
11
+ results.push(result);
12
+ }
13
+ catch (err) {
14
+ results.push({
15
+ adapterId: adapter.id,
16
+ event,
17
+ specId,
18
+ success: false,
19
+ message: err instanceof Error ? err.message : 'Unknown error',
20
+ });
21
+ }
22
+ }));
23
+ return {
24
+ event,
25
+ specId,
26
+ results,
27
+ successCount: results.filter((r) => r.success).length,
28
+ failureCount: results.filter((r) => !r.success).length,
29
+ skippedCount: adapters.length - results.length,
30
+ };
31
+ }
32
+ export function buildHubStatus(hubConfig) {
33
+ const allAdapters = listAdapters();
34
+ return {
35
+ totalAdapters: allAdapters.length,
36
+ enabledAdapters: hubConfig.enabledAdapters.length,
37
+ adapterStatuses: allAdapters.map((a) => ({
38
+ id: a.id,
39
+ name: a.name,
40
+ status: hubConfig.enabledAdapters.includes(a.id)
41
+ ? getAdapterStatus(a.id, hubConfig.adapterConfigs[a.id] ?? {})
42
+ : 'disabled',
43
+ triggers: a.triggers,
44
+ })),
45
+ };
46
+ }
47
+ //# sourceMappingURL=event-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-router.js","sourceRoot":"","sources":["../../../src/engine/mcp-hub/event-router.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,OAAO,EAGL,YAAY,EACZ,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAY/B,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAgB,EAChB,MAAc,EACd,SAAoB;IAEpB,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC,MAAM,CACpC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAC9E,CAAC;IAEF,MAAM,OAAO,GAA0B,EAAE,CAAC;IAE1C,8DAA8D;IAC9D,MAAM,OAAO,CAAC,GAAG,CACf,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,SAAS,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;QAC1D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YAChE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC;gBACX,SAAS,EAAE,OAAO,CAAC,EAAE;gBACrB,KAAK;gBACL,MAAM;gBACN,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;aAC9D,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CACH,CAAC;IAEF,OAAO;QACL,KAAK;QACL,MAAM;QACN,OAAO;QACP,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM;QACrD,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM;QACtD,YAAY,EAAE,QAAQ,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM;KAC/C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,SAAoB;IAUjD,MAAM,WAAW,GAAG,YAAY,EAAE,CAAC;IAEnC,OAAO;QACL,aAAa,EAAE,WAAW,CAAC,MAAM;QACjC,eAAe,EAAE,SAAS,CAAC,eAAe,CAAC,MAAM;QACjD,eAAe,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACvC,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,MAAM,EAAE,SAAS,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9C,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;gBAC9D,CAAC,CAAC,UAAU;YACd,QAAQ,EAAE,CAAC,CAAC,QAAQ;SACrB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ export interface CalibrationResult {
2
+ specCount: number;
3
+ averageActualHours: number;
4
+ averageEstimatedHours: number;
5
+ calibrationFactor: number;
6
+ accuracy: 'over-estimating' | 'under-estimating' | 'accurate';
7
+ recommendation: string;
8
+ trendDirection: 'improving' | 'stable' | 'worsening';
9
+ }
10
+ export interface EstimateDataPoint {
11
+ specId: string;
12
+ estimatedHours: number;
13
+ actualHours: number;
14
+ completedAt: string;
15
+ }
16
+ export declare function computeCalibration(dataPoints: EstimateDataPoint[]): CalibrationResult;
17
+ //# sourceMappingURL=calibration-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calibration-engine.d.ts","sourceRoot":"","sources":["../../../src/engine/productivity/calibration-engine.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,iBAAiB,GAAG,kBAAkB,GAAG,UAAU,CAAC;IAC9D,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;CACtD;AAGD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,CAwDrF"}
@@ -0,0 +1,49 @@
1
+ // engine/productivity/calibration-engine.ts — SPEC-404: Estimation calibration engine
2
+ export function computeCalibration(dataPoints) {
3
+ if (dataPoints.length === 0) {
4
+ return {
5
+ specCount: 0,
6
+ averageActualHours: 0,
7
+ averageEstimatedHours: 0,
8
+ calibrationFactor: 1,
9
+ accuracy: 'accurate',
10
+ recommendation: 'No completed specs with actuals yet',
11
+ trendDirection: 'stable',
12
+ };
13
+ }
14
+ const avgActual = dataPoints.reduce((s, d) => s + d.actualHours, 0) / dataPoints.length;
15
+ const avgEstimated = dataPoints.reduce((s, d) => s + d.estimatedHours, 0) / dataPoints.length;
16
+ const factor = avgEstimated > 0 ? Math.round((avgActual / avgEstimated) * 100) / 100 : 1;
17
+ const accuracy = factor > 1.2 ? 'under-estimating' : factor < 0.8 ? 'over-estimating' : 'accurate';
18
+ const recommendation = accuracy === 'under-estimating'
19
+ ? `Multiply estimates by ${factor.toFixed(1)}x to improve accuracy`
20
+ : accuracy === 'over-estimating'
21
+ ? `You consistently over-estimate — consider reducing estimates by ${Math.round((1 - factor) * 100)}%`
22
+ : 'Estimates are well-calibrated';
23
+ // Trend: compare first half vs second half variance
24
+ const half = Math.floor(dataPoints.length / 2);
25
+ const sorted = [...dataPoints].sort((a, b) => a.completedAt.localeCompare(b.completedAt));
26
+ let trendDirection = 'stable';
27
+ if (half > 0) {
28
+ const firstHalfVariance = sorted.slice(0, half).reduce((s, d) => s + Math.abs(d.actualHours - d.estimatedHours), 0) /
29
+ half;
30
+ const secondHalfVariance = sorted.slice(half).reduce((s, d) => s + Math.abs(d.actualHours - d.estimatedHours), 0) /
31
+ (sorted.length - half);
32
+ trendDirection =
33
+ secondHalfVariance < firstHalfVariance * 0.9
34
+ ? 'improving'
35
+ : secondHalfVariance > firstHalfVariance * 1.1
36
+ ? 'worsening'
37
+ : 'stable';
38
+ }
39
+ return {
40
+ specCount: dataPoints.length,
41
+ averageActualHours: Math.round(avgActual * 10) / 10,
42
+ averageEstimatedHours: Math.round(avgEstimated * 10) / 10,
43
+ calibrationFactor: factor,
44
+ accuracy,
45
+ recommendation,
46
+ trendDirection,
47
+ };
48
+ }
49
+ //# sourceMappingURL=calibration-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calibration-engine.js","sourceRoot":"","sources":["../../../src/engine/productivity/calibration-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { TimeRecord } from '../../types/index.js';
2
+ export type { TimeRecord };
3
+ export declare function computeActualHours(record: TimeRecord): number | null;
4
+ export declare function computeElapsedMinutes(startedAt: string): number;
5
+ export declare function formatDuration(hours: number): string;
6
+ //# sourceMappingURL=time-tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time-tracker.d.ts","sourceRoot":"","sources":["../../../src/engine/productivity/time-tracker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,YAAY,EAAE,UAAU,EAAE,CAAC;AAE3B,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAYpE;AAED,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAI/D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQpD"}
@@ -0,0 +1,28 @@
1
+ export function computeActualHours(record) {
2
+ if (record.actualHours !== undefined) {
3
+ return record.actualHours;
4
+ }
5
+ if (!record.implementingStartedAt || !record.doneAt) {
6
+ return null;
7
+ }
8
+ const start = new Date(record.implementingStartedAt).getTime();
9
+ const end = new Date(record.doneAt).getTime();
10
+ const msElapsed = end - start;
11
+ // Convert ms to hours — simple approximation: divide by 3.6M (1 hour in ms), cap at 200h
12
+ return Math.min(Math.round((msElapsed / 3_600_000) * 10) / 10, 200);
13
+ }
14
+ export function computeElapsedMinutes(startedAt) {
15
+ const start = new Date(startedAt).getTime();
16
+ const now = Date.now();
17
+ return Math.round((now - start) / 60_000);
18
+ }
19
+ export function formatDuration(hours) {
20
+ if (hours < 1) {
21
+ return `${Math.round(hours * 60)}m`;
22
+ }
23
+ if (hours < 24) {
24
+ return `${hours.toFixed(1)}h`;
25
+ }
26
+ return `${(hours / 8).toFixed(1)} days`;
27
+ }
28
+ //# sourceMappingURL=time-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time-tracker.js","sourceRoot":"","sources":["../../../src/engine/productivity/time-tracker.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,kBAAkB,CAAC,MAAkB;IACnD,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACrC,OAAO,MAAM,CAAC,WAAW,CAAC;IAC5B,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,qBAAqB,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,OAAO,EAAE,CAAC;IAC/D,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;IAC9C,MAAM,SAAS,GAAG,GAAG,GAAG,KAAK,CAAC;IAC9B,yFAAyF;IACzF,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,SAAiB;IACrD,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,MAAM,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,GAAG,CAAC;IACtC,CAAC;IACD,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;QACf,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IAChC,CAAC;IACD,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { VibeTaxResult } from '../../types/index.js';
2
+ export type { VibeTaxResult };
3
+ export interface ProjectVibeTaxSummary {
4
+ specCount: number;
5
+ averageVariancePct: number;
6
+ totalDebugHours: number;
7
+ totalVibeTaxHours: number;
8
+ worstSpecs: VibeTaxResult[];
9
+ bestSpecs: VibeTaxResult[];
10
+ overallAssessment: string;
11
+ }
12
+ export declare function calculateVibeTax(specId: string, estimatedHours: number, actualHours: number, debugHours?: number, scopeCreepCriteria?: number, validateFailures?: number): VibeTaxResult;
13
+ export declare function summarizeVibeTax(results: VibeTaxResult[]): ProjectVibeTaxSummary;
14
+ //# sourceMappingURL=vibe-tax-calculator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vibe-tax-calculator.d.ts","sourceRoot":"","sources":["../../../src/engine/productivity/vibe-tax-calculator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,YAAY,EAAE,aAAa,EAAE,CAAC;AAG9B,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,MAAM,EACnB,UAAU,SAAI,EACd,kBAAkB,SAAI,EACtB,gBAAgB,SAAI,GACnB,aAAa,CAmCf;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,qBAAqB,CAoChF"}
@@ -0,0 +1,63 @@
1
+ export function calculateVibeTax(specId, estimatedHours, actualHours, debugHours = 0, scopeCreepCriteria = 0, validateFailures = 0) {
2
+ const varianceHours = actualHours - estimatedHours;
3
+ const variancePct = estimatedHours > 0 ? Math.round((varianceHours / estimatedHours) * 100) : 0;
4
+ // Vibe tax score: weighted sum of variance, debug time, scope creep, failures
5
+ const varianceScore = Math.min(Math.max(variancePct, 0), 100);
6
+ const debugScore = Math.min(debugHours * 10, 50);
7
+ const scopeScore = Math.min(scopeCreepCriteria * 5, 30);
8
+ const failureScore = Math.min(validateFailures * 5, 20);
9
+ const vibeTaxScore = Math.min(Math.round(varianceScore * 0.5 + debugScore * 0.3 + scopeScore * 0.1 + failureScore * 0.1), 100);
10
+ const assessment = vibeTaxScore < 20
11
+ ? 'excellent'
12
+ : vibeTaxScore < 40
13
+ ? 'good'
14
+ : vibeTaxScore < 60
15
+ ? 'fair'
16
+ : 'poor';
17
+ return {
18
+ specId,
19
+ estimatedHours,
20
+ actualHours,
21
+ varianceHours,
22
+ variancePct,
23
+ debugHours,
24
+ scopeCreepCriteria,
25
+ validateFailures,
26
+ vibeTaxScore,
27
+ assessment,
28
+ };
29
+ }
30
+ export function summarizeVibeTax(results) {
31
+ if (results.length === 0) {
32
+ return {
33
+ specCount: 0,
34
+ averageVariancePct: 0,
35
+ totalDebugHours: 0,
36
+ totalVibeTaxHours: 0,
37
+ worstSpecs: [],
38
+ bestSpecs: [],
39
+ overallAssessment: 'No data yet — implement some specs to see productivity insights',
40
+ };
41
+ }
42
+ const totalDebugHours = results.reduce((s, r) => s + r.debugHours, 0);
43
+ const totalVibeTaxHours = results.reduce((s, r) => s + Math.max(r.varianceHours, 0), 0);
44
+ const avgVariance = Math.round(results.reduce((s, r) => s + r.variancePct, 0) / results.length);
45
+ const sorted = [...results].sort((a, b) => b.vibeTaxScore - a.vibeTaxScore);
46
+ const assessment = avgVariance < 20
47
+ ? 'Excellent — estimates are accurate, minimal vibe coding tax'
48
+ : avgVariance < 50
49
+ ? 'Good — some variance, but within acceptable range'
50
+ : avgVariance < 100
51
+ ? 'Fair — significant vibe coding overhead detected'
52
+ : 'Poor — high vibe coding tax, consider using more detailed specs';
53
+ return {
54
+ specCount: results.length,
55
+ averageVariancePct: avgVariance,
56
+ totalDebugHours,
57
+ totalVibeTaxHours,
58
+ worstSpecs: sorted.slice(0, 3),
59
+ bestSpecs: sorted.slice(-3).reverse(),
60
+ overallAssessment: assessment,
61
+ };
62
+ }
63
+ //# sourceMappingURL=vibe-tax-calculator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vibe-tax-calculator.js","sourceRoot":"","sources":["../../../src/engine/productivity/vibe-tax-calculator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { QualityGate } from '../../types/index.js';
2
+ export type { QualityGate };
3
+ export type GateCategory = 'security' | 'testing' | 'architecture' | 'performance';
4
+ export type StackType = 'typescript' | 'python' | 'java' | 'go' | 'generic';
5
+ export declare const GATE_CATALOG: QualityGate[];
6
+ //# sourceMappingURL=gate-catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-catalog.d.ts","sourceRoot":"","sources":["../../../src/engine/quality-gates/gate-catalog.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,YAAY,EAAE,WAAW,EAAE,CAAC;AAE5B,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,SAAS,GAAG,cAAc,GAAG,aAAa,CAAC;AAEnF,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;AAE5E,eAAO,MAAM,YAAY,EAAE,WAAW,EA6VrC,CAAC"}