vitek-plugin 0.2.0-beta → 0.2.2-beta

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 (263) hide show
  1. package/README.md +1 -1
  2. package/dist/adapters/dispatch/http-webhook.d.ts +10 -0
  3. package/dist/adapters/dispatch/http-webhook.d.ts.map +1 -0
  4. package/dist/adapters/dispatch/http-webhook.js +38 -0
  5. package/dist/adapters/node/console-structured-request-logger.d.ts +6 -0
  6. package/dist/adapters/node/console-structured-request-logger.d.ts.map +1 -0
  7. package/dist/adapters/node/console-structured-request-logger.js +31 -0
  8. package/dist/build/build-api-bundle.d.ts.map +1 -1
  9. package/dist/build/build-api-bundle.js +11 -0
  10. package/dist/build/build-sockets-bundle.d.ts.map +1 -1
  11. package/dist/build/build-sockets-bundle.js +11 -0
  12. package/dist/cli/contract.d.ts +11 -0
  13. package/dist/cli/contract.d.ts.map +1 -0
  14. package/dist/cli/contract.js +143 -0
  15. package/dist/cli/doctor.d.ts +2 -0
  16. package/dist/cli/doctor.d.ts.map +1 -0
  17. package/dist/cli/doctor.js +70 -0
  18. package/dist/cli/generate.d.ts +2 -0
  19. package/dist/cli/generate.d.ts.map +1 -0
  20. package/dist/cli/generate.js +56 -0
  21. package/dist/cli/mcp-docs.d.ts +2 -0
  22. package/dist/cli/mcp-docs.d.ts.map +1 -0
  23. package/dist/cli/mcp-docs.js +4 -0
  24. package/dist/cli/mcp-project-write-tools.d.ts +4 -0
  25. package/dist/cli/mcp-project-write-tools.d.ts.map +1 -0
  26. package/dist/cli/mcp-project-write-tools.js +64 -0
  27. package/dist/cli/schedule.d.ts +2 -0
  28. package/dist/cli/schedule.d.ts.map +1 -0
  29. package/dist/cli/schedule.js +66 -0
  30. package/dist/core/contract/compare-asyncapi.d.ts +3 -0
  31. package/dist/core/contract/compare-asyncapi.d.ts.map +1 -0
  32. package/dist/core/contract/compare-asyncapi.js +45 -0
  33. package/dist/core/contract/compare-openapi.d.ts +3 -0
  34. package/dist/core/contract/compare-openapi.d.ts.map +1 -0
  35. package/dist/core/contract/compare-openapi.js +116 -0
  36. package/dist/core/contract/http-methods.d.ts +2 -0
  37. package/dist/core/contract/http-methods.d.ts.map +1 -0
  38. package/dist/core/contract/http-methods.js +2 -0
  39. package/dist/core/contract/index.d.ts +9 -0
  40. package/dist/core/contract/index.d.ts.map +1 -0
  41. package/dist/core/contract/index.js +7 -0
  42. package/dist/core/contract/project-specs.d.ts +12 -0
  43. package/dist/core/contract/project-specs.d.ts.map +1 -0
  44. package/dist/core/contract/project-specs.js +27 -0
  45. package/dist/core/contract/sort-json.d.ts +2 -0
  46. package/dist/core/contract/sort-json.d.ts.map +1 -0
  47. package/dist/core/contract/sort-json.js +14 -0
  48. package/dist/core/contract/types.d.ts +7 -0
  49. package/dist/core/contract/types.d.ts.map +1 -0
  50. package/dist/core/contract/types.js +1 -0
  51. package/dist/core/dispatch/dispatchers.d.ts +4 -0
  52. package/dist/core/dispatch/dispatchers.d.ts.map +1 -0
  53. package/dist/core/dispatch/dispatchers.js +16 -0
  54. package/dist/core/dispatch/emit-safe.d.ts +3 -0
  55. package/dist/core/dispatch/emit-safe.d.ts.map +1 -0
  56. package/dist/core/dispatch/emit-safe.js +10 -0
  57. package/dist/core/dispatch/index.d.ts +4 -0
  58. package/dist/core/dispatch/index.d.ts.map +1 -0
  59. package/dist/core/dispatch/index.js +2 -0
  60. package/dist/core/dispatch/types.d.ts +22 -0
  61. package/dist/core/dispatch/types.d.ts.map +1 -0
  62. package/dist/core/dispatch/types.js +1 -0
  63. package/dist/core/doctor/index.d.ts +3 -0
  64. package/dist/core/doctor/index.d.ts.map +1 -0
  65. package/dist/core/doctor/index.js +1 -0
  66. package/dist/core/doctor/report.d.ts +4 -0
  67. package/dist/core/doctor/report.d.ts.map +1 -0
  68. package/dist/core/doctor/report.js +166 -0
  69. package/dist/core/doctor/scan.d.ts +3 -0
  70. package/dist/core/doctor/scan.d.ts.map +1 -0
  71. package/dist/core/doctor/scan.js +23 -0
  72. package/dist/core/doctor/types.d.ts +12 -0
  73. package/dist/core/doctor/types.d.ts.map +1 -0
  74. package/dist/core/doctor/types.js +1 -0
  75. package/dist/core/events/event-bus.d.ts +8 -0
  76. package/dist/core/events/event-bus.d.ts.map +1 -0
  77. package/dist/core/events/event-bus.js +26 -0
  78. package/dist/core/events/index.d.ts +3 -0
  79. package/dist/core/events/index.d.ts.map +1 -0
  80. package/dist/core/events/index.js +1 -0
  81. package/dist/core/generators/adapters/drizzle.d.ts +3 -0
  82. package/dist/core/generators/adapters/drizzle.d.ts.map +1 -0
  83. package/dist/core/generators/adapters/drizzle.js +26 -0
  84. package/dist/core/generators/adapters/prisma.d.ts +3 -0
  85. package/dist/core/generators/adapters/prisma.d.ts.map +1 -0
  86. package/dist/core/generators/adapters/prisma.js +136 -0
  87. package/dist/core/generators/adapters/sql.d.ts +3 -0
  88. package/dist/core/generators/adapters/sql.d.ts.map +1 -0
  89. package/dist/core/generators/adapters/sql.js +26 -0
  90. package/dist/core/generators/generate-crud.d.ts +8 -0
  91. package/dist/core/generators/generate-crud.d.ts.map +1 -0
  92. package/dist/core/generators/generate-crud.js +17 -0
  93. package/dist/core/generators/index.d.ts +3 -0
  94. package/dist/core/generators/index.d.ts.map +1 -0
  95. package/dist/core/generators/index.js +1 -0
  96. package/dist/core/generators/types.d.ts +16 -0
  97. package/dist/core/generators/types.d.ts.map +1 -0
  98. package/dist/core/generators/types.js +1 -0
  99. package/dist/core/generators/utils.d.ts +3 -0
  100. package/dist/core/generators/utils.d.ts.map +1 -0
  101. package/dist/core/generators/utils.js +10 -0
  102. package/dist/core/observability/with-span.d.ts +5 -0
  103. package/dist/core/observability/with-span.d.ts.map +1 -0
  104. package/dist/core/observability/with-span.js +7 -0
  105. package/dist/core/scheduler/define-schedule.d.ts +3 -0
  106. package/dist/core/scheduler/define-schedule.d.ts.map +1 -0
  107. package/dist/core/scheduler/define-schedule.js +3 -0
  108. package/dist/core/scheduler/in-memory-lock.d.ts +6 -0
  109. package/dist/core/scheduler/in-memory-lock.d.ts.map +1 -0
  110. package/dist/core/scheduler/in-memory-lock.js +12 -0
  111. package/dist/core/scheduler/index.d.ts +5 -0
  112. package/dist/core/scheduler/index.d.ts.map +1 -0
  113. package/dist/core/scheduler/index.js +3 -0
  114. package/dist/core/scheduler/runner.d.ts +6 -0
  115. package/dist/core/scheduler/runner.d.ts.map +1 -0
  116. package/dist/core/scheduler/runner.js +37 -0
  117. package/dist/core/scheduler/types.d.ts +21 -0
  118. package/dist/core/scheduler/types.d.ts.map +1 -0
  119. package/dist/core/scheduler/types.js +1 -0
  120. package/dist/core/server/request-log-meta.d.ts +5 -0
  121. package/dist/core/server/request-log-meta.d.ts.map +1 -0
  122. package/dist/core/server/request-log-meta.js +1 -0
  123. package/dist/mcp/write/apply-guard.d.ts +7 -0
  124. package/dist/mcp/write/apply-guard.d.ts.map +1 -0
  125. package/dist/mcp/write/apply-guard.js +22 -0
  126. package/dist/mcp/write/openapi-jsdoc.d.ts +2 -0
  127. package/dist/mcp/write/openapi-jsdoc.d.ts.map +1 -0
  128. package/dist/mcp/write/openapi-jsdoc.js +15 -0
  129. package/dist/mcp/write/project-write-handlers.d.ts +46 -0
  130. package/dist/mcp/write/project-write-handlers.d.ts.map +1 -0
  131. package/dist/mcp/write/project-write-handlers.js +304 -0
  132. package/dist/mcp/write/risks.d.ts +3 -0
  133. package/dist/mcp/write/risks.d.ts.map +1 -0
  134. package/dist/mcp/write/risks.js +20 -0
  135. package/dist/mcp/write/route-snippet.d.ts +5 -0
  136. package/dist/mcp/write/route-snippet.d.ts.map +1 -0
  137. package/dist/mcp/write/route-snippet.js +46 -0
  138. package/dist/mcp/write/safe-path.d.ts +3 -0
  139. package/dist/mcp/write/safe-path.d.ts.map +1 -0
  140. package/dist/mcp/write/safe-path.js +16 -0
  141. package/dist/mcp/write/test-file-content.d.ts +8 -0
  142. package/dist/mcp/write/test-file-content.d.ts.map +1 -0
  143. package/dist/mcp/write/test-file-content.js +31 -0
  144. package/dist/mcp/write/unified-diff.d.ts +2 -0
  145. package/dist/mcp/write/unified-diff.d.ts.map +1 -0
  146. package/dist/mcp/write/unified-diff.js +19 -0
  147. package/dist/mcp/write/validation-scaffold.d.ts +2 -0
  148. package/dist/mcp/write/validation-scaffold.d.ts.map +1 -0
  149. package/dist/mcp/write/validation-scaffold.js +31 -0
  150. package/dist/mcp-docs-server/resources/configuration.d.ts +3 -0
  151. package/dist/mcp-docs-server/resources/configuration.d.ts.map +1 -0
  152. package/dist/mcp-docs-server/resources/configuration.js +25 -0
  153. package/dist/mcp-docs-server/resources/context.d.ts +3 -0
  154. package/dist/mcp-docs-server/resources/context.d.ts.map +1 -0
  155. package/dist/mcp-docs-server/resources/context.js +34 -0
  156. package/dist/mcp-docs-server/resources/errors.d.ts +3 -0
  157. package/dist/mcp-docs-server/resources/errors.d.ts.map +1 -0
  158. package/dist/mcp-docs-server/resources/errors.js +27 -0
  159. package/dist/mcp-docs-server/resources/introspection.d.ts +3 -0
  160. package/dist/mcp-docs-server/resources/introspection.d.ts.map +1 -0
  161. package/dist/mcp-docs-server/resources/introspection.js +24 -0
  162. package/dist/mcp-docs-server/resources/middlewares.d.ts +3 -0
  163. package/dist/mcp-docs-server/resources/middlewares.d.ts.map +1 -0
  164. package/dist/mcp-docs-server/resources/middlewares.js +36 -0
  165. package/dist/mcp-docs-server/resources/plugin-api.d.ts +3 -0
  166. package/dist/mcp-docs-server/resources/plugin-api.d.ts.map +1 -0
  167. package/dist/mcp-docs-server/resources/plugin-api.js +32 -0
  168. package/dist/mcp-docs-server/resources/response.d.ts +3 -0
  169. package/dist/mcp-docs-server/resources/response.d.ts.map +1 -0
  170. package/dist/mcp-docs-server/resources/response.js +39 -0
  171. package/dist/mcp-docs-server/resources/routing.d.ts +3 -0
  172. package/dist/mcp-docs-server/resources/routing.d.ts.map +1 -0
  173. package/dist/mcp-docs-server/resources/routing.js +47 -0
  174. package/dist/mcp-docs-server/resources/validation.d.ts +3 -0
  175. package/dist/mcp-docs-server/resources/validation.d.ts.map +1 -0
  176. package/dist/mcp-docs-server/resources/validation.js +37 -0
  177. package/dist/mcp-docs-server/resources/websockets.d.ts +3 -0
  178. package/dist/mcp-docs-server/resources/websockets.d.ts.map +1 -0
  179. package/dist/mcp-docs-server/resources/websockets.js +42 -0
  180. package/dist/mcp-docs-server/start-mcp-docs-server.d.ts +2 -0
  181. package/dist/mcp-docs-server/start-mcp-docs-server.d.ts.map +1 -0
  182. package/dist/mcp-docs-server/start-mcp-docs-server.js +171 -0
  183. package/dist/mcp-docs-server/tools/create-middleware.d.ts +5 -0
  184. package/dist/mcp-docs-server/tools/create-middleware.d.ts.map +1 -0
  185. package/dist/mcp-docs-server/tools/create-middleware.js +29 -0
  186. package/dist/mcp-docs-server/tools/create-route.d.ts +5 -0
  187. package/dist/mcp-docs-server/tools/create-route.d.ts.map +1 -0
  188. package/dist/mcp-docs-server/tools/create-route.js +44 -0
  189. package/dist/mcp-docs-server/tools/create-socket.d.ts +5 -0
  190. package/dist/mcp-docs-server/tools/create-socket.d.ts.map +1 -0
  191. package/dist/mcp-docs-server/tools/create-socket.js +39 -0
  192. package/dist/mcp-docs-server/tools/suggest-vite-config.d.ts +11 -0
  193. package/dist/mcp-docs-server/tools/suggest-vite-config.d.ts.map +1 -0
  194. package/dist/mcp-docs-server/tools/suggest-vite-config.js +30 -0
  195. package/dist/mcp-docs-server/tools/validate-convention.d.ts +21 -0
  196. package/dist/mcp-docs-server/tools/validate-convention.d.ts.map +1 -0
  197. package/dist/mcp-docs-server/tools/validate-convention.js +48 -0
  198. package/dist/platform/config.d.ts +30 -0
  199. package/dist/platform/config.d.ts.map +1 -0
  200. package/dist/platform/config.js +85 -0
  201. package/dist/platform/correlation.d.ts +5 -0
  202. package/dist/platform/correlation.d.ts.map +1 -0
  203. package/dist/platform/correlation.js +19 -0
  204. package/dist/platform/index.d.ts +5 -0
  205. package/dist/platform/index.d.ts.map +1 -0
  206. package/dist/platform/index.js +3 -0
  207. package/dist/platform/redaction.d.ts +6 -0
  208. package/dist/platform/redaction.d.ts.map +1 -0
  209. package/dist/platform/redaction.js +40 -0
  210. package/dist/plugin/mode.d.ts +5 -0
  211. package/dist/plugin/mode.d.ts.map +1 -0
  212. package/dist/plugin/mode.js +7 -0
  213. package/dist/plugin/vitek-resolve.d.ts.map +1 -1
  214. package/dist/plugin/vitek-resolve.js +4 -3
  215. package/dist/plugin/vitek-transform.d.ts +1 -1
  216. package/dist/plugin/vitek-transform.d.ts.map +1 -1
  217. package/dist/plugin/vitek-transform.js +30 -5
  218. package/dist/public/dispatch.d.ts +3 -0
  219. package/dist/public/dispatch.d.ts.map +1 -0
  220. package/dist/public/dispatch.js +1 -0
  221. package/dist/public/doctor.d.ts +3 -0
  222. package/dist/public/doctor.d.ts.map +1 -0
  223. package/dist/public/doctor.js +1 -0
  224. package/dist/public/errors.d.ts +2 -0
  225. package/dist/public/errors.d.ts.map +1 -0
  226. package/dist/public/errors.js +1 -0
  227. package/dist/public/events.d.ts +3 -0
  228. package/dist/public/events.d.ts.map +1 -0
  229. package/dist/public/events.js +1 -0
  230. package/dist/public/generators.d.ts +3 -0
  231. package/dist/public/generators.d.ts.map +1 -0
  232. package/dist/public/generators.js +1 -0
  233. package/dist/public/introspection.d.ts +3 -0
  234. package/dist/public/introspection.d.ts.map +1 -0
  235. package/dist/public/introspection.js +1 -0
  236. package/dist/public/observability.d.ts +3 -0
  237. package/dist/public/observability.d.ts.map +1 -0
  238. package/dist/public/observability.js +1 -0
  239. package/dist/public/platform.d.ts +3 -0
  240. package/dist/public/platform.d.ts.map +1 -0
  241. package/dist/public/platform.js +1 -0
  242. package/dist/public/plugin.d.ts +3 -0
  243. package/dist/public/plugin.d.ts.map +1 -0
  244. package/dist/public/plugin.js +1 -0
  245. package/dist/public/response.d.ts +2 -0
  246. package/dist/public/response.d.ts.map +1 -0
  247. package/dist/public/response.js +1 -0
  248. package/dist/public/scheduler.d.ts +3 -0
  249. package/dist/public/scheduler.d.ts.map +1 -0
  250. package/dist/public/scheduler.js +1 -0
  251. package/dist/public/testing.d.ts +3 -0
  252. package/dist/public/testing.d.ts.map +1 -0
  253. package/dist/public/testing.js +1 -0
  254. package/dist/public/validation.d.ts +3 -0
  255. package/dist/public/validation.d.ts.map +1 -0
  256. package/dist/public/validation.js +1 -0
  257. package/dist/shared/mode.d.ts +5 -0
  258. package/dist/shared/mode.d.ts.map +1 -0
  259. package/dist/shared/mode.js +7 -0
  260. package/dist/testing/testing.d.ts +15 -0
  261. package/dist/testing/testing.d.ts.map +1 -0
  262. package/dist/testing/testing.js +51 -0
  263. package/package.json +23 -21
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare-asyncapi.d.ts","sourceRoot":"","sources":["../../../src/core/contract/compare-asyncapi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAkB7C,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,UAAU,EAAE,CA+BtF"}
@@ -0,0 +1,45 @@
1
+ import { sortKeysDeep } from './sort-json.js';
2
+ function asRecord(value) {
3
+ if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
4
+ return value;
5
+ }
6
+ return {};
7
+ }
8
+ function getChannels(spec) {
9
+ return asRecord(asRecord(spec).channels);
10
+ }
11
+ function channelFingerprint(channel) {
12
+ return JSON.stringify(sortKeysDeep(channel));
13
+ }
14
+ export function compareAsyncApiSpecs(baseline, current) {
15
+ const issues = [];
16
+ const baseCh = getChannels(baseline);
17
+ const curCh = getChannels(current);
18
+ const keys = new Set([...Object.keys(baseCh), ...Object.keys(curCh)]);
19
+ for (const k of [...keys].sort()) {
20
+ if (baseCh[k] != null && curCh[k] == null) {
21
+ issues.push({
22
+ severity: 'error',
23
+ code: 'asyncapi_missing_channel',
24
+ message: `WebSocket channel removed from contract: ${k}`,
25
+ });
26
+ }
27
+ else if (baseCh[k] == null && curCh[k] != null) {
28
+ issues.push({
29
+ severity: 'warning',
30
+ code: 'asyncapi_new_channel',
31
+ message: `WebSocket channel not in baseline: ${k}`,
32
+ });
33
+ }
34
+ else if (baseCh[k] != null && curCh[k] != null) {
35
+ if (channelFingerprint(baseCh[k]) !== channelFingerprint(curCh[k])) {
36
+ issues.push({
37
+ severity: 'error',
38
+ code: 'asyncapi_channel_mismatch',
39
+ message: `WebSocket channel definition drift: ${k}`,
40
+ });
41
+ }
42
+ }
43
+ }
44
+ return issues;
45
+ }
@@ -0,0 +1,3 @@
1
+ import type { DriftIssue } from './types.js';
2
+ export declare function compareOpenApiSpecs(baseline: unknown, current: unknown): DriftIssue[];
3
+ //# sourceMappingURL=compare-openapi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare-openapi.d.ts","sourceRoot":"","sources":["../../../src/core/contract/compare-openapi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAwC7C,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,UAAU,EAAE,CAmFrF"}
@@ -0,0 +1,116 @@
1
+ import { OPENAPI_PATH_METHODS } from './http-methods.js';
2
+ import { sortKeysDeep } from './sort-json.js';
3
+ function asRecord(value) {
4
+ if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
5
+ return value;
6
+ }
7
+ return {};
8
+ }
9
+ function getPaths(spec) {
10
+ return asRecord(asRecord(spec).paths);
11
+ }
12
+ function listOperations(paths) {
13
+ const out = [];
14
+ for (const openApiPath of Object.keys(paths).sort()) {
15
+ const item = asRecord(paths[openApiPath]);
16
+ for (const method of Object.keys(item).sort()) {
17
+ if (!OPENAPI_PATH_METHODS.has(method))
18
+ continue;
19
+ out.push({ openApiPath, method });
20
+ }
21
+ }
22
+ return out;
23
+ }
24
+ function opKey(openApiPath, method) {
25
+ return `${method.toUpperCase()} ${openApiPath}`;
26
+ }
27
+ function getResponses(operation) {
28
+ const op = asRecord(operation);
29
+ return asRecord(op.responses);
30
+ }
31
+ function responseFingerprint(response) {
32
+ return JSON.stringify(sortKeysDeep(response));
33
+ }
34
+ export function compareOpenApiSpecs(baseline, current) {
35
+ const issues = [];
36
+ const basePaths = getPaths(baseline);
37
+ const curPaths = getPaths(current);
38
+ for (const openApiPath of Object.keys(basePaths).sort()) {
39
+ if (!curPaths[openApiPath]) {
40
+ issues.push({
41
+ severity: 'error',
42
+ code: 'missing_path',
43
+ message: `Path removed from contract: ${openApiPath}`,
44
+ });
45
+ }
46
+ }
47
+ for (const openApiPath of Object.keys(basePaths).sort()) {
48
+ if (!curPaths[openApiPath])
49
+ continue;
50
+ const baseItem = asRecord(basePaths[openApiPath]);
51
+ const curItem = asRecord(curPaths[openApiPath]);
52
+ for (const method of Object.keys(baseItem).sort()) {
53
+ if (!OPENAPI_PATH_METHODS.has(method))
54
+ continue;
55
+ if (curItem[method] == null) {
56
+ issues.push({
57
+ severity: 'error',
58
+ code: 'missing_method',
59
+ message: `Operation removed from contract: ${opKey(openApiPath, method)}`,
60
+ });
61
+ }
62
+ }
63
+ }
64
+ const baseOps = listOperations(basePaths);
65
+ const curOps = listOperations(curPaths);
66
+ const baseSet = new Set(baseOps.map((o) => opKey(o.openApiPath, o.method)));
67
+ for (const { openApiPath, method } of curOps) {
68
+ const key = opKey(openApiPath, method);
69
+ if (!baseSet.has(key)) {
70
+ issues.push({
71
+ severity: 'warning',
72
+ code: 'undocumented_operation',
73
+ message: `Operation not in baseline (new or undocumented in snapshot): ${key}`,
74
+ });
75
+ }
76
+ }
77
+ for (const { openApiPath, method } of baseOps) {
78
+ if (!curPaths[openApiPath])
79
+ continue;
80
+ const baseItem = asRecord(basePaths[openApiPath]);
81
+ const curItem = asRecord(curPaths[openApiPath]);
82
+ if (curItem[method] == null)
83
+ continue;
84
+ const baseOp = baseItem[method];
85
+ const curOp = curItem[method];
86
+ const baseResp = getResponses(baseOp);
87
+ const curResp = getResponses(curOp);
88
+ const statuses = new Set([...Object.keys(baseResp), ...Object.keys(curResp)]);
89
+ for (const status of [...statuses].sort()) {
90
+ if (baseResp[status] != null && curResp[status] == null) {
91
+ issues.push({
92
+ severity: 'error',
93
+ code: 'missing_response_status',
94
+ message: `Response ${status} missing for ${opKey(openApiPath, method)}`,
95
+ });
96
+ }
97
+ else if (baseResp[status] == null && curResp[status] != null) {
98
+ issues.push({
99
+ severity: 'warning',
100
+ code: 'new_response_status',
101
+ message: `New response status ${status} for ${opKey(openApiPath, method)}`,
102
+ });
103
+ }
104
+ else if (baseResp[status] != null && curResp[status] != null) {
105
+ if (responseFingerprint(baseResp[status]) !== responseFingerprint(curResp[status])) {
106
+ issues.push({
107
+ severity: 'error',
108
+ code: 'response_schema_mismatch',
109
+ message: `Response ${status} schema mismatch for ${opKey(openApiPath, method)}`,
110
+ });
111
+ }
112
+ }
113
+ }
114
+ }
115
+ return issues;
116
+ }
@@ -0,0 +1,2 @@
1
+ export declare const OPENAPI_PATH_METHODS: Set<string>;
2
+ //# sourceMappingURL=http-methods.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-methods.d.ts","sourceRoot":"","sources":["../../../src/core/contract/http-methods.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,oBAAoB,aAAqC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { HTTP_METHODS } from '../../shared/constants.js';
2
+ export const OPENAPI_PATH_METHODS = new Set([...HTTP_METHODS]);
@@ -0,0 +1,9 @@
1
+ export type { DriftSeverity, DriftIssue } from './types.js';
2
+ export { sortKeysDeep } from './sort-json.js';
3
+ export { compareOpenApiSpecs } from './compare-openapi.js';
4
+ export { compareAsyncApiSpecs } from './compare-asyncapi.js';
5
+ export { loadProjectContractSpecs } from './project-specs.js';
6
+ export declare const CONTRACT_DIR = ".vitek/contract";
7
+ export declare const OPENAPI_SNAPSHOT_FILE = "openapi.snapshot.json";
8
+ export declare const ASYNCAPI_SNAPSHOT_FILE = "asyncapi.snapshot.json";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/contract/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,eAAO,MAAM,YAAY,oBAAoB,CAAC;AAC9C,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAC7D,eAAO,MAAM,sBAAsB,2BAA2B,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { sortKeysDeep } from './sort-json.js';
2
+ export { compareOpenApiSpecs } from './compare-openapi.js';
3
+ export { compareAsyncApiSpecs } from './compare-asyncapi.js';
4
+ export { loadProjectContractSpecs } from './project-specs.js';
5
+ export const CONTRACT_DIR = '.vitek/contract';
6
+ export const OPENAPI_SNAPSHOT_FILE = 'openapi.snapshot.json';
7
+ export const ASYNCAPI_SNAPSHOT_FILE = 'asyncapi.snapshot.json';
@@ -0,0 +1,12 @@
1
+ export interface ProjectContractSpecsOptions {
2
+ root: string;
3
+ apiDir: string;
4
+ apiBasePath: string;
5
+ socketBasePath: string;
6
+ }
7
+ export interface ProjectContractSpecs {
8
+ openApi: object;
9
+ asyncApi: object | null;
10
+ }
11
+ export declare function loadProjectContractSpecs(opts: ProjectContractSpecsOptions): ProjectContractSpecs;
12
+ //# sourceMappingURL=project-specs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-specs.d.ts","sourceRoot":"","sources":["../../../src/core/contract/project-specs.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,2BAA2B;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAeD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,2BAA2B,GAAG,oBAAoB,CAehG"}
@@ -0,0 +1,27 @@
1
+ import * as path from 'path';
2
+ import { scanApiDirectory } from '../file-system/scan-api-dir.js';
3
+ import { parsedRoutesToSchema } from '../generation/run-file-generation.js';
4
+ import { generateOpenApiSpec } from '../openapi/generate.js';
5
+ import { generateAsyncApiSpec } from '../asyncapi/generate.js';
6
+ const STABLE_ASYNCAPI_SERVER = 'ws://127.0.0.1';
7
+ function schemaToRouteForDocs(schema) {
8
+ return schema.map((s) => ({
9
+ pattern: s.pattern,
10
+ method: s.method,
11
+ params: s.params,
12
+ file: s.file,
13
+ bodyType: s.bodyType,
14
+ queryType: s.queryType,
15
+ }));
16
+ }
17
+ export function loadProjectContractSpecs(opts) {
18
+ const apiDirAbs = path.resolve(opts.root, opts.apiDir);
19
+ const scan = scanApiDirectory(apiDirAbs);
20
+ const schema = parsedRoutesToSchema(scan.routes);
21
+ const routesForDocs = schemaToRouteForDocs(schema);
22
+ const openApi = generateOpenApiSpec(routesForDocs, { apiBasePath: opts.apiBasePath });
23
+ const asyncApi = scan.sockets.length > 0
24
+ ? generateAsyncApiSpec(scan.sockets.map((s) => ({ pattern: s.pattern })), opts.socketBasePath, { serverUrl: STABLE_ASYNCAPI_SERVER })
25
+ : null;
26
+ return { openApi, asyncApi };
27
+ }
@@ -0,0 +1,2 @@
1
+ export declare function sortKeysDeep(value: unknown): unknown;
2
+ //# sourceMappingURL=sort-json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sort-json.d.ts","sourceRoot":"","sources":["../../../src/core/contract/sort-json.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAapD"}
@@ -0,0 +1,14 @@
1
+ export function sortKeysDeep(value) {
2
+ if (value === null || typeof value !== 'object') {
3
+ return value;
4
+ }
5
+ if (Array.isArray(value)) {
6
+ return value.map(sortKeysDeep);
7
+ }
8
+ const obj = value;
9
+ const sorted = {};
10
+ for (const k of Object.keys(obj).sort()) {
11
+ sorted[k] = sortKeysDeep(obj[k]);
12
+ }
13
+ return sorted;
14
+ }
@@ -0,0 +1,7 @@
1
+ export type DriftSeverity = 'error' | 'warning';
2
+ export interface DriftIssue {
3
+ severity: DriftSeverity;
4
+ code: string;
5
+ message: string;
6
+ }
7
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/contract/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,CAAC;AAEhD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,aAAa,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { IssueDispatcher } from './types.js';
2
+ export declare function createNoopIssueDispatcher(): IssueDispatcher;
3
+ export declare function createConsoleIssueDispatcher(): IssueDispatcher;
4
+ //# sourceMappingURL=dispatchers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatchers.d.ts","sourceRoot":"","sources":["../../../src/core/dispatch/dispatchers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAc,MAAM,YAAY,CAAC;AAE9D,wBAAgB,yBAAyB,IAAI,eAAe,CAI3D;AAED,wBAAgB,4BAA4B,IAAI,eAAe,CAY9D"}
@@ -0,0 +1,16 @@
1
+ export function createNoopIssueDispatcher() {
2
+ return {
3
+ dispatch(_event) { },
4
+ };
5
+ }
6
+ export function createConsoleIssueDispatcher() {
7
+ return {
8
+ dispatch(event) {
9
+ console.log(JSON.stringify({
10
+ component: 'vitek',
11
+ event: 'issue.dispatch',
12
+ ...event,
13
+ }));
14
+ },
15
+ };
16
+ }
@@ -0,0 +1,3 @@
1
+ import type { IssueDispatcher, IssueEvent } from './types.js';
2
+ export declare function emitIssueSafe(dispatcher: IssueDispatcher | undefined, event: IssueEvent, onError?: (message: string, data?: Record<string, unknown>) => void): void;
3
+ //# sourceMappingURL=emit-safe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-safe.d.ts","sourceRoot":"","sources":["../../../src/core/dispatch/emit-safe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE9D,wBAAgB,aAAa,CAC3B,UAAU,EAAE,eAAe,GAAG,SAAS,EACvC,KAAK,EAAE,UAAU,EACjB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,GAClE,IAAI,CAON"}
@@ -0,0 +1,10 @@
1
+ export function emitIssueSafe(dispatcher, event, onError) {
2
+ if (!dispatcher)
3
+ return;
4
+ Promise.resolve(dispatcher.dispatch(event)).catch((err) => {
5
+ if (!onError)
6
+ return;
7
+ const message = err instanceof Error ? err.message : String(err);
8
+ onError('Issue dispatch failed', { message });
9
+ });
10
+ }
@@ -0,0 +1,4 @@
1
+ export type { IssueSeverity, IssueSource, IssueSuggestion, IssueEvent, IssueDispatcher, } from './types.js';
2
+ export { createNoopIssueDispatcher, createConsoleIssueDispatcher } from './dispatchers.js';
3
+ export { emitIssueSafe } from './emit-safe.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/dispatch/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,aAAa,EACb,WAAW,EACX,eAAe,EACf,UAAU,EACV,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,yBAAyB,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createNoopIssueDispatcher, createConsoleIssueDispatcher } from './dispatchers.js';
2
+ export { emitIssueSafe } from './emit-safe.js';
@@ -0,0 +1,22 @@
1
+ export type IssueSeverity = 'error' | 'warning' | 'info';
2
+ export type IssueSource = 'runtime.http' | 'runtime.hook' | 'contract.check' | 'doctor' | 'manual';
3
+ export interface IssueSuggestion {
4
+ title: string;
5
+ detail?: string;
6
+ }
7
+ export interface IssueEvent {
8
+ id: string;
9
+ timestamp: string;
10
+ severity: IssueSeverity;
11
+ source: IssueSource;
12
+ title: string;
13
+ message: string;
14
+ route?: string;
15
+ requestId?: string;
16
+ metadata?: Record<string, unknown>;
17
+ suggestions?: IssueSuggestion[];
18
+ }
19
+ export interface IssueDispatcher {
20
+ dispatch(event: IssueEvent): void | Promise<void>;
21
+ }
22
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/dispatch/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEzD,MAAM,MAAM,WAAW,GACnB,cAAc,GACd,cAAc,GACd,gBAAgB,GAChB,QAAQ,GACR,QAAQ,CAAC;AAEb,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,aAAa,CAAC;IACxB,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnD"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ export type { DoctorDimensionResult, DoctorReport } from './types.js';
2
+ export { buildDoctorReport } from './report.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/doctor/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1 @@
1
+ export { buildDoctorReport } from './report.js';
@@ -0,0 +1,4 @@
1
+ import type { PlatformConfig } from '../../platform/config.js';
2
+ import type { DoctorReport } from './types.js';
3
+ export declare function buildDoctorReport(root: string, config: PlatformConfig): DoctorReport;
4
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../src/core/doctor/report.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAyB,YAAY,EAAE,MAAM,YAAY,CAAC;AAsHtE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,YAAY,CAkBpF"}
@@ -0,0 +1,166 @@
1
+ import { DEFAULT_PLATFORM_CONFIG } from '../../platform/config.js';
2
+ import { countTests, listProjectFiles } from './scan.js';
3
+ function exists(files, rel) {
4
+ return files.includes(rel);
5
+ }
6
+ function startsWithAny(files, prefix) {
7
+ return files.some((f) => f.startsWith(prefix));
8
+ }
9
+ function contractsDimension(files) {
10
+ let score = 0;
11
+ const notes = [];
12
+ if (exists(files, '.vitek/contract/openapi.snapshot.json')) {
13
+ score += 10;
14
+ }
15
+ else {
16
+ notes.push('Add contract snapshot: vitek contract snapshot');
17
+ }
18
+ if (exists(files, '.vitek/contract/asyncapi.snapshot.json')) {
19
+ score += 5;
20
+ }
21
+ else {
22
+ notes.push('Add AsyncAPI snapshot when socket routes exist');
23
+ }
24
+ if (exists(files, 'docs/guide/contract.md')) {
25
+ score += 5;
26
+ }
27
+ else {
28
+ notes.push('Document contract checks');
29
+ }
30
+ return { name: 'Contracts', score, max: 20, notes };
31
+ }
32
+ function testsDimension(files) {
33
+ const tests = countTests(files);
34
+ let score = 0;
35
+ const notes = [];
36
+ if (tests >= 40)
37
+ score += 12;
38
+ else if (tests >= 20)
39
+ score += 8;
40
+ else if (tests >= 10)
41
+ score += 5;
42
+ else
43
+ notes.push('Increase automated test coverage');
44
+ if (startsWithAny(files, 'examples/') && files.some((f) => f.startsWith('examples/') && /\.(test|spec)\./.test(f))) {
45
+ score += 8;
46
+ }
47
+ else {
48
+ notes.push('Add example-level tests');
49
+ }
50
+ return { name: 'Tests', score, max: 20, notes };
51
+ }
52
+ function securityDimension(files) {
53
+ let score = 0;
54
+ const notes = [];
55
+ if (exists(files, 'docs/guide/security.md'))
56
+ score += 6;
57
+ else
58
+ notes.push('Add security guide');
59
+ if (exists(files, 'src/platform/redaction.ts'))
60
+ score += 5;
61
+ else
62
+ notes.push('Add/redesign redaction utilities');
63
+ if (DEFAULT_PLATFORM_CONFIG.ai.redaction.stripHeaders.length > 0 &&
64
+ DEFAULT_PLATFORM_CONFIG.ai.redaction.stripFields.length > 0) {
65
+ score += 4;
66
+ }
67
+ else {
68
+ notes.push('Define default redaction policy');
69
+ }
70
+ return { name: 'Security', score, max: 15, notes };
71
+ }
72
+ function observabilityDimension(files, config) {
73
+ let score = 0;
74
+ const notes = [];
75
+ if (exists(files, 'src/platform/correlation.ts'))
76
+ score += 4;
77
+ else
78
+ notes.push('Add request correlation layer');
79
+ if (exists(files, 'src/adapters/vite/logger.ts'))
80
+ score += 3;
81
+ else
82
+ notes.push('Add structured request logging');
83
+ if (config.features.observability)
84
+ score += 3;
85
+ else
86
+ notes.push('Enable features.observability when ready');
87
+ return { name: 'Observability', score, max: 10, notes };
88
+ }
89
+ function reliabilityDimension(files, config) {
90
+ let score = 0;
91
+ const notes = [];
92
+ if (exists(files, 'src/core/dispatch/types.ts'))
93
+ score += 4;
94
+ else
95
+ notes.push('Add issue/event dispatch contracts');
96
+ if (exists(files, 'src/core/events/event-bus.ts'))
97
+ score += 4;
98
+ else
99
+ notes.push('Add event bus');
100
+ if (exists(files, 'src/core/scheduler/runner.ts'))
101
+ score += 4;
102
+ else
103
+ notes.push('Add scheduler runner');
104
+ if (config.features.issueDispatch)
105
+ score += 3;
106
+ else
107
+ notes.push('Enable features.issueDispatch when sink is ready');
108
+ return { name: 'Reliability', score, max: 15, notes };
109
+ }
110
+ function docsDimension(files) {
111
+ let score = 0;
112
+ const notes = [];
113
+ if (exists(files, 'docs/ROADMAP-AI-PLATFORM.md'))
114
+ score += 4;
115
+ else
116
+ notes.push('Keep roadmap updated');
117
+ if (exists(files, 'docs/guide/ai-platform-config.md'))
118
+ score += 3;
119
+ else
120
+ notes.push('Document platform config');
121
+ if (exists(files, 'docs/guide/mcp-project.md'))
122
+ score += 3;
123
+ else
124
+ notes.push('Document MCP project flows');
125
+ return { name: 'Docs', score, max: 10, notes };
126
+ }
127
+ function architectureDimension(files) {
128
+ let score = 0;
129
+ const notes = [];
130
+ if (startsWithAny(files, 'src/core/contract/'))
131
+ score += 3;
132
+ else
133
+ notes.push('Missing contract module split');
134
+ if (startsWithAny(files, 'src/core/dispatch/'))
135
+ score += 3;
136
+ else
137
+ notes.push('Missing dispatch module split');
138
+ if (startsWithAny(files, 'src/core/events/'))
139
+ score += 2;
140
+ else
141
+ notes.push('Missing events module split');
142
+ if (startsWithAny(files, 'src/core/scheduler/'))
143
+ score += 2;
144
+ else
145
+ notes.push('Missing scheduler module split');
146
+ return { name: 'Architecture', score, max: 10, notes };
147
+ }
148
+ export function buildDoctorReport(root, config) {
149
+ const files = listProjectFiles(root);
150
+ const dimensions = [
151
+ contractsDimension(files),
152
+ testsDimension(files),
153
+ securityDimension(files),
154
+ observabilityDimension(files, config),
155
+ reliabilityDimension(files, config),
156
+ docsDimension(files),
157
+ architectureDimension(files),
158
+ ];
159
+ const score = dimensions.reduce((sum, d) => sum + d.score, 0);
160
+ const topActions = dimensions
161
+ .filter((d) => d.score < d.max)
162
+ .sort((a, b) => a.score / a.max - b.score / b.max)
163
+ .flatMap((d) => d.notes.map((n) => `${d.name}: ${n}`))
164
+ .slice(0, 5);
165
+ return { score, dimensions, topActions };
166
+ }
@@ -0,0 +1,3 @@
1
+ export declare function listProjectFiles(root: string): string[];
2
+ export declare function countTests(files: string[]): number;
3
+ //# sourceMappingURL=scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../../src/core/doctor/scan.ts"],"names":[],"mappings":"AAeA,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAIvD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAElD"}
@@ -0,0 +1,23 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ function walk(dir, out) {
4
+ if (!fs.existsSync(dir))
5
+ return;
6
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
7
+ const full = path.join(dir, entry.name);
8
+ if (entry.isDirectory()) {
9
+ walk(full, out);
10
+ }
11
+ else if (entry.isFile()) {
12
+ out.push(full);
13
+ }
14
+ }
15
+ }
16
+ export function listProjectFiles(root) {
17
+ const out = [];
18
+ walk(root, out);
19
+ return out.map((f) => path.relative(root, f).replace(/\\/g, '/'));
20
+ }
21
+ export function countTests(files) {
22
+ return files.filter((f) => /\.(test|spec)\.(ts|js|tsx|jsx|mjs|cjs)$/.test(f)).length;
23
+ }
@@ -0,0 +1,12 @@
1
+ export interface DoctorDimensionResult {
2
+ name: string;
3
+ score: number;
4
+ max: number;
5
+ notes: string[];
6
+ }
7
+ export interface DoctorReport {
8
+ score: number;
9
+ dimensions: DoctorDimensionResult[];
10
+ topActions: string[];
11
+ }
12
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/doctor/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,qBAAqB,EAAE,CAAC;IACpC,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ export type EventMap = Record<string, unknown>;
2
+ export type EventHandler<TPayload> = (payload: TPayload) => void | Promise<void>;
3
+ export interface EventBus<TEvents extends EventMap> {
4
+ on<TKey extends keyof TEvents>(event: TKey, handler: EventHandler<TEvents[TKey]>): () => void;
5
+ emit<TKey extends keyof TEvents>(event: TKey, payload: TEvents[TKey]): Promise<void>;
6
+ }
7
+ export declare function createEventBus<TEvents extends EventMap>(): EventBus<TEvents>;
8
+ //# sourceMappingURL=event-bus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../../../src/core/events/event-bus.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/C,MAAM,MAAM,YAAY,CAAC,QAAQ,IAAI,CAAC,OAAO,EAAE,QAAQ,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEjF,MAAM,WAAW,QAAQ,CAAC,OAAO,SAAS,QAAQ;IAChD,EAAE,CAAC,IAAI,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC;IAC9F,IAAI,CAAC,IAAI,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtF;AAED,wBAAgB,cAAc,CAAC,OAAO,SAAS,QAAQ,KAAK,QAAQ,CAAC,OAAO,CAAC,CAuB5E"}