@nifrajs/cli 2.11.0 → 2.12.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 (177) hide show
  1. package/README.md +6 -0
  2. package/dist/assure-hydration.d.ts +14 -0
  3. package/dist/assure-hydration.d.ts.map +1 -0
  4. package/dist/assure-hydration.js +483 -0
  5. package/dist/assure-hydration.js.map +1 -0
  6. package/dist/assure.d.ts +35 -0
  7. package/dist/assure.d.ts.map +1 -1
  8. package/dist/assure.js +222 -1
  9. package/dist/assure.js.map +1 -1
  10. package/dist/capabilities-tool.d.ts +13 -0
  11. package/dist/capabilities-tool.d.ts.map +1 -1
  12. package/dist/capabilities-tool.js +64 -1
  13. package/dist/capabilities-tool.js.map +1 -1
  14. package/dist/check.d.ts +125 -10
  15. package/dist/check.d.ts.map +1 -1
  16. package/dist/check.js +706 -145
  17. package/dist/check.js.map +1 -1
  18. package/dist/cli.d.ts +23 -0
  19. package/dist/cli.d.ts.map +1 -1
  20. package/dist/cli.js +194 -10
  21. package/dist/cli.js.map +1 -1
  22. package/dist/contract-proof.d.ts +49 -0
  23. package/dist/contract-proof.d.ts.map +1 -0
  24. package/dist/contract-proof.js +128 -0
  25. package/dist/contract-proof.js.map +1 -0
  26. package/dist/contracts.d.ts +22 -0
  27. package/dist/contracts.d.ts.map +1 -0
  28. package/dist/contracts.js +134 -0
  29. package/dist/contracts.js.map +1 -0
  30. package/dist/diagnostics.d.ts +23 -0
  31. package/dist/diagnostics.d.ts.map +1 -0
  32. package/dist/diagnostics.js +9 -0
  33. package/dist/diagnostics.js.map +1 -0
  34. package/dist/diff-tool.d.ts +2 -0
  35. package/dist/diff-tool.d.ts.map +1 -1
  36. package/dist/diff-tool.js +1 -1
  37. package/dist/diff-tool.js.map +1 -1
  38. package/dist/docs-search.d.ts +8 -3
  39. package/dist/docs-search.d.ts.map +1 -1
  40. package/dist/docs-search.js +36 -15
  41. package/dist/docs-search.js.map +1 -1
  42. package/dist/doctor.d.ts +28 -2
  43. package/dist/doctor.d.ts.map +1 -1
  44. package/dist/doctor.js +173 -7
  45. package/dist/doctor.js.map +1 -1
  46. package/dist/examples.d.ts +1 -2
  47. package/dist/examples.d.ts.map +1 -1
  48. package/dist/examples.js +37 -16
  49. package/dist/examples.js.map +1 -1
  50. package/dist/fix-recipes.d.ts +12 -0
  51. package/dist/fix-recipes.d.ts.map +1 -0
  52. package/dist/fix-recipes.js +106 -0
  53. package/dist/fix-recipes.js.map +1 -0
  54. package/dist/init-agents.d.ts.map +1 -1
  55. package/dist/init-agents.js +60 -4
  56. package/dist/init-agents.js.map +1 -1
  57. package/dist/internal/source-facts.d.ts +15 -0
  58. package/dist/internal/source-facts.d.ts.map +1 -0
  59. package/dist/internal/source-facts.js +82 -0
  60. package/dist/internal/source-facts.js.map +1 -0
  61. package/dist/internal/typescript-import.d.ts +9 -0
  62. package/dist/internal/typescript-import.d.ts.map +1 -1
  63. package/dist/internal/typescript-import.js +38 -0
  64. package/dist/internal/typescript-import.js.map +1 -1
  65. package/dist/introspect.d.ts +6 -2
  66. package/dist/introspect.d.ts.map +1 -1
  67. package/dist/introspect.js +53 -4
  68. package/dist/introspect.js.map +1 -1
  69. package/dist/load.d.ts +6 -0
  70. package/dist/load.d.ts.map +1 -1
  71. package/dist/load.js.map +1 -1
  72. package/dist/manifest-tool.d.ts.map +1 -1
  73. package/dist/manifest-tool.js +14 -9
  74. package/dist/manifest-tool.js.map +1 -1
  75. package/dist/mcp-docs-tools.d.ts.map +1 -1
  76. package/dist/mcp-docs-tools.js +3 -0
  77. package/dist/mcp-docs-tools.js.map +1 -1
  78. package/dist/mcp-http.js +1 -1
  79. package/dist/mcp-root.d.ts +83 -0
  80. package/dist/mcp-root.d.ts.map +1 -0
  81. package/dist/mcp-root.js +221 -0
  82. package/dist/mcp-root.js.map +1 -0
  83. package/dist/mcp-run.d.ts.map +1 -1
  84. package/dist/mcp-run.js +18 -4
  85. package/dist/mcp-run.js.map +1 -1
  86. package/dist/mcp.d.ts +27 -4
  87. package/dist/mcp.d.ts.map +1 -1
  88. package/dist/mcp.js +358 -25
  89. package/dist/mcp.js.map +1 -1
  90. package/dist/project-path.d.ts +3 -0
  91. package/dist/project-path.d.ts.map +1 -0
  92. package/dist/project-path.js +36 -0
  93. package/dist/project-path.js.map +1 -0
  94. package/dist/replay.d.ts +12 -0
  95. package/dist/replay.d.ts.map +1 -0
  96. package/dist/replay.js +36 -0
  97. package/dist/replay.js.map +1 -0
  98. package/dist/rules/codes.d.ts +42 -0
  99. package/dist/rules/codes.d.ts.map +1 -0
  100. package/dist/rules/codes.js +52 -0
  101. package/dist/rules/codes.js.map +1 -0
  102. package/dist/rules/comment-markers.d.ts +10 -0
  103. package/dist/rules/comment-markers.d.ts.map +1 -0
  104. package/dist/rules/comment-markers.js +24 -0
  105. package/dist/rules/comment-markers.js.map +1 -0
  106. package/dist/rules/index.d.ts +31 -0
  107. package/dist/rules/index.d.ts.map +1 -0
  108. package/dist/rules/index.js +133 -0
  109. package/dist/rules/index.js.map +1 -0
  110. package/dist/rules/legacy.d.ts +7 -0
  111. package/dist/rules/legacy.d.ts.map +1 -0
  112. package/dist/rules/legacy.js +85 -0
  113. package/dist/rules/legacy.js.map +1 -0
  114. package/dist/rules/routes.d.ts +12 -0
  115. package/dist/rules/routes.d.ts.map +1 -0
  116. package/dist/rules/routes.js +142 -0
  117. package/dist/rules/routes.js.map +1 -0
  118. package/dist/rules/security.d.ts +10 -0
  119. package/dist/rules/security.d.ts.map +1 -0
  120. package/dist/rules/security.js +471 -0
  121. package/dist/rules/security.js.map +1 -0
  122. package/dist/search-terms.d.ts +2 -0
  123. package/dist/search-terms.d.ts.map +1 -1
  124. package/dist/search-terms.js +5 -1
  125. package/dist/search-terms.js.map +1 -1
  126. package/dist/types-search.d.ts +1 -2
  127. package/dist/types-search.d.ts.map +1 -1
  128. package/dist/types-search.js +33 -16
  129. package/dist/types-search.js.map +1 -1
  130. package/dist/verification.d.ts +9 -0
  131. package/dist/verification.d.ts.map +1 -1
  132. package/dist/verification.js +17 -1
  133. package/dist/verification.js.map +1 -1
  134. package/dist/work-graph.d.ts +123 -0
  135. package/dist/work-graph.d.ts.map +1 -0
  136. package/dist/work-graph.js +465 -0
  137. package/dist/work-graph.js.map +1 -0
  138. package/docs/examples.json +32 -2
  139. package/docs/llms-full.txt +906 -15
  140. package/docs/types.json +1682 -130
  141. package/package.json +34 -9
  142. package/src/assure-hydration.ts +606 -0
  143. package/src/assure.ts +316 -2
  144. package/src/capabilities-tool.ts +80 -1
  145. package/src/check.ts +873 -168
  146. package/src/cli.ts +198 -11
  147. package/src/contract-proof.ts +194 -0
  148. package/src/contracts.ts +157 -0
  149. package/src/diagnostics.ts +32 -0
  150. package/src/diff-tool.ts +1 -1
  151. package/src/docs-search.ts +45 -15
  152. package/src/doctor.ts +259 -8
  153. package/src/examples.ts +43 -15
  154. package/src/fix-recipes.ts +126 -0
  155. package/src/init-agents.ts +61 -4
  156. package/src/internal/source-facts.ts +133 -0
  157. package/src/internal/typescript-import.ts +29 -0
  158. package/src/introspect.ts +75 -6
  159. package/src/load.ts +6 -0
  160. package/src/manifest-tool.ts +16 -10
  161. package/src/mcp-docs-tools.ts +3 -0
  162. package/src/mcp-http.ts +1 -1
  163. package/src/mcp-root.ts +271 -0
  164. package/src/mcp-run.ts +19 -4
  165. package/src/mcp.ts +438 -32
  166. package/src/project-path.ts +36 -0
  167. package/src/replay.ts +44 -0
  168. package/src/rules/codes.ts +57 -0
  169. package/src/rules/comment-markers.ts +26 -0
  170. package/src/rules/index.ts +175 -0
  171. package/src/rules/legacy.ts +93 -0
  172. package/src/rules/routes.ts +157 -0
  173. package/src/rules/security.ts +505 -0
  174. package/src/search-terms.ts +9 -4
  175. package/src/types-search.ts +39 -15
  176. package/src/verification.ts +18 -1
  177. package/src/work-graph.ts +613 -0
@@ -0,0 +1,128 @@
1
+ import { existsSync, realpathSync } from "node:fs";
2
+ import { resolve, sep } from "node:path";
3
+ import { diffRouteSnapshots } from "@nifrajs/core/diff";
4
+ import { DEFAULT_SNAPSHOT_FILE, parseSnapshotFile, snapshotBackend } from "./diff-tool.js";
5
+ import { collectProjectVerification } from "./verification.js";
6
+ const routeKey = (method, path) => `${method.toUpperCase()}\n${path}`;
7
+ function safeBaselinePath(cwd, baselinePath) {
8
+ const root = resolve(cwd);
9
+ const target = resolve(root, baselinePath);
10
+ if (target !== root && !target.startsWith(`${root}${sep}`)) {
11
+ throw new Error("contract proof baseline must stay inside the project directory");
12
+ }
13
+ return target;
14
+ }
15
+ function errorMessage(error) {
16
+ return error instanceof Error ? error.message : String(error);
17
+ }
18
+ function changedRoutes(diff, assurance, capability) {
19
+ const changes = new Map();
20
+ for (const change of diff.changes) {
21
+ const key = routeKey(change.method, change.path);
22
+ const current = changes.get(key);
23
+ if (current === undefined)
24
+ changes.set(key, [change]);
25
+ else
26
+ current.push(change);
27
+ }
28
+ const assured = new Map((assurance?.routes ?? []).map((route) => [routeKey(route.method, route.path), route]));
29
+ const assuranceFindings = new Map();
30
+ for (const finding of assurance?.findings ?? []) {
31
+ const key = routeKey(finding.method, finding.path);
32
+ const current = assuranceFindings.get(key);
33
+ if (current === undefined)
34
+ assuranceFindings.set(key, [finding]);
35
+ else
36
+ current.push(finding);
37
+ }
38
+ const capable = new Map((capability?.routes ?? []).map((route) => [routeKey(route.method, route.path), route]));
39
+ const capabilityFindings = new Map();
40
+ for (const finding of capability?.findings ?? []) {
41
+ const key = routeKey(finding.method, finding.path);
42
+ const current = capabilityFindings.get(key);
43
+ if (current === undefined)
44
+ capabilityFindings.set(key, [finding]);
45
+ else
46
+ current.push(finding);
47
+ }
48
+ return Object.freeze([...changes].map(([key, routeChanges]) => {
49
+ const first = routeChanges[0];
50
+ if (first === undefined)
51
+ throw new Error("contract proof: missing route change");
52
+ const assuredRoute = assured.get(key);
53
+ const capableRoute = capable.get(key);
54
+ return {
55
+ method: first.method,
56
+ path: first.path,
57
+ changes: Object.freeze([...routeChanges]),
58
+ ...(assurance === undefined
59
+ ? {}
60
+ : {
61
+ assurance: {
62
+ ...(assuredRoute === undefined ? {} : { route: assuredRoute }),
63
+ findings: Object.freeze([...(assuranceFindings.get(key) ?? [])]),
64
+ },
65
+ }),
66
+ ...(capability === undefined
67
+ ? {}
68
+ : {
69
+ capability: {
70
+ ...(capableRoute === undefined ? {} : { route: capableRoute }),
71
+ findings: Object.freeze([...(capabilityFindings.get(key) ?? [])]),
72
+ },
73
+ }),
74
+ };
75
+ }));
76
+ }
77
+ /** Compose route diff, route assurance, capability evidence, and an optional check result. */
78
+ export async function collectContractProof(cwd, options = {}) {
79
+ const baselinePath = options.baselinePath ?? DEFAULT_SNAPSHOT_FILE;
80
+ const resolvedBaseline = safeBaselinePath(cwd, baselinePath);
81
+ if (!existsSync(resolvedBaseline)) {
82
+ throw new Error(`contract proof baseline not found: ${resolvedBaseline}`);
83
+ }
84
+ const realRoot = realpathSync(resolve(cwd));
85
+ const realBaseline = realpathSync(resolvedBaseline);
86
+ if (realBaseline !== realRoot && !realBaseline.startsWith(`${realRoot}${sep}`)) {
87
+ throw new Error("contract proof baseline must stay inside the project directory");
88
+ }
89
+ const baseline = parseSnapshotFile(await Bun.file(resolvedBaseline).text(), baselinePath);
90
+ const current = await snapshotBackend(cwd);
91
+ const diff = diffRouteSnapshots(baseline.routes, current);
92
+ const verification = await collectProjectVerification(cwd, {
93
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
94
+ });
95
+ const proof = {
96
+ assuranceConfigPresent: verification.assuranceConfigPresent,
97
+ ...(verification.configError === undefined
98
+ ? {}
99
+ : { configError: errorMessage(verification.configError) }),
100
+ ...(verification.routeAssurance === undefined
101
+ ? {}
102
+ : {
103
+ assurance: {
104
+ ok: verification.routeAssurance.ok,
105
+ routeCount: verification.routeAssurance.routes.length,
106
+ findings: verification.routeAssurance.findings,
107
+ },
108
+ }),
109
+ ...(verification.capability === undefined
110
+ ? {}
111
+ : {
112
+ capability: {
113
+ ok: verification.capability.report.ok,
114
+ routeCount: verification.capability.report.routes.length,
115
+ findings: verification.capability.report.findings,
116
+ },
117
+ }),
118
+ ...(options.check === true ? { check: await verification.check() } : {}),
119
+ };
120
+ return Object.freeze({
121
+ baseline: baselinePath,
122
+ hasBreaking: diff.hasBreaking,
123
+ changes: diff.changes,
124
+ routes: changedRoutes(diff, verification.routeAssurance, verification.capability?.report),
125
+ verification: proof,
126
+ });
127
+ }
128
+ //# sourceMappingURL=contract-proof.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-proof.js","sourceRoot":"","sources":["../src/contract-proof.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { type ReflectedRoute } from "@nifrajs/core/reflection";
2
+ export interface ContractDigest {
3
+ readonly request: string;
4
+ readonly response: string;
5
+ }
6
+ export interface ContractsLock {
7
+ readonly version: 1;
8
+ readonly routes: Readonly<Record<string, ContractDigest>>;
9
+ }
10
+ export declare const DEFAULT_CONTRACTS_LOCK = "contracts.lock.json";
11
+ export declare function digestRoute(route: ReflectedRoute): Promise<ContractDigest>;
12
+ export declare function buildContractsLock(source: unknown): Promise<ContractsLock>;
13
+ export declare function snapshotContracts(cwd: string, out?: string): Promise<ContractsLock>;
14
+ export declare function parseContractsLock(value: unknown): ContractsLock;
15
+ export declare function checkContractsLock(cwd: string, file?: string): Promise<{
16
+ present: boolean;
17
+ diagnostics: Array<{
18
+ route?: string;
19
+ message: string;
20
+ }>;
21
+ }>;
22
+ //# sourceMappingURL=contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,cAAc,EAAiB,MAAM,0BAA0B,CAAA;AAE7E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;IACnB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAA;CAC1D;AAED,eAAO,MAAM,sBAAsB,wBAAwB,CAAA;AAmD3D,wBAAsB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAIhF;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CAYhF;AAYD,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,GAAG,SAAyB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAIxB;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAwBhE;AAED,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,IAAI,SAAyB,GAC5B,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,KAAK,CAAC;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAuBxF"}
@@ -0,0 +1,134 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
9
+ import { existsSync } from "node:fs";
10
+ import { resolve } from "node:path";
11
+ import { reflectRoutes } from "@nifrajs/core/reflection";
12
+ export const DEFAULT_CONTRACTS_LOCK = "contracts.lock.json";
13
+ const DIGEST = /^[a-f0-9]{64}$/;
14
+ function recordOf(value) {
15
+ return typeof value === "object" && value !== null && !Array.isArray(value)
16
+ ? Object.fromEntries(Object.entries(value))
17
+ : undefined;
18
+ }
19
+ function canonical(value, key) {
20
+ if (["description", "title", "default", "example", "examples"].includes(key ?? ""))
21
+ return undefined;
22
+ if (Array.isArray(value))
23
+ return value.map((item) => canonical(item));
24
+ const record = recordOf(value);
25
+ if (record === undefined)
26
+ return value;
27
+ const out = {};
28
+ for (const name of Object.keys(record).sort()) {
29
+ const item = canonical(record[name], name);
30
+ if (item !== undefined)
31
+ out[name] = item;
32
+ }
33
+ return out;
34
+ }
35
+ async function sha256(value) {
36
+ const bytes = new TextEncoder().encode(value);
37
+ const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", bytes));
38
+ return [...digest].map((item) => item.toString(16).padStart(2, "0")).join("");
39
+ }
40
+ function schemaValue(route, side) {
41
+ const schema = route.schema;
42
+ if (schema === undefined)
43
+ return {};
44
+ if (side === "request") {
45
+ return {
46
+ body: schema.body?.jsonSchema ?? schema.body?.fields ?? null,
47
+ query: schema.query?.jsonSchema ?? schema.query?.fields ?? null,
48
+ params: schema.params?.jsonSchema ?? schema.params?.fields ?? null,
49
+ };
50
+ }
51
+ return {
52
+ response: schema.response?.jsonSchema ?? schema.response?.fields ?? null,
53
+ sse: schema.sse?.jsonSchema ?? schema.sse?.fields ?? null,
54
+ errors: Object.fromEntries(Object.entries(schema.errors ?? {}).map(([status, value]) => [
55
+ status,
56
+ value.jsonSchema ?? value.fields ?? null,
57
+ ])),
58
+ };
59
+ }
60
+ export async function digestRoute(route) {
61
+ const request = JSON.stringify(canonical(schemaValue(route, "request")));
62
+ const response = JSON.stringify(canonical(schemaValue(route, "response")));
63
+ return { request: await sha256(request), response: await sha256(response) };
64
+ }
65
+ export async function buildContractsLock(source) {
66
+ const routes = Object.fromEntries(await Promise.all(reflectRoutes(source).map(async (route) => [`${route.method} ${route.path}`, await digestRoute(route)])));
67
+ return {
68
+ version: 1,
69
+ routes: Object.fromEntries(Object.entries(routes).sort(([a], [b]) => a.localeCompare(b))),
70
+ };
71
+ }
72
+ async function loadBackend(cwd) {
73
+ const backendPath = resolve(cwd, "backend.ts");
74
+ if (!existsSync(backendPath))
75
+ throw new Error(`[nifra] no backend.ts in ${cwd}`);
76
+ const loadedValue = await import(__rewriteRelativeImportExtension(backendPath));
77
+ const loaded = recordOf(loadedValue);
78
+ if (loaded?.backend === undefined)
79
+ throw new Error(`[nifra] ${backendPath} does not export backend`);
80
+ return loaded.backend;
81
+ }
82
+ export async function snapshotContracts(cwd, out = DEFAULT_CONTRACTS_LOCK) {
83
+ const lock = await buildContractsLock(await loadBackend(cwd));
84
+ await Bun.write(resolve(cwd, out), `${JSON.stringify(lock, null, 2)}\n`);
85
+ return lock;
86
+ }
87
+ export function parseContractsLock(value) {
88
+ const record = recordOf(value);
89
+ if (record === undefined)
90
+ throw new TypeError("contracts lock must be an object");
91
+ const routesValue = record.routes;
92
+ const routesRecord = recordOf(routesValue);
93
+ if (record.version !== 1 || routesRecord === undefined)
94
+ throw new TypeError("contracts lock must have version 1 and routes");
95
+ const routes = {};
96
+ for (const [key, raw] of Object.entries(routesRecord)) {
97
+ const item = recordOf(raw);
98
+ const request = item?.request;
99
+ const response = item?.response;
100
+ if (request === undefined ||
101
+ typeof request !== "string" ||
102
+ response === undefined ||
103
+ typeof response !== "string" ||
104
+ !DIGEST.test(request) ||
105
+ !DIGEST.test(response))
106
+ throw new TypeError(`invalid contract ${key}`);
107
+ routes[key] = { request, response };
108
+ }
109
+ return { version: 1, routes };
110
+ }
111
+ export async function checkContractsLock(cwd, file = DEFAULT_CONTRACTS_LOCK) {
112
+ const path = resolve(cwd, file);
113
+ if (!existsSync(path))
114
+ return { present: false, diagnostics: [] };
115
+ const parsed = parseContractsLock(JSON.parse(await Bun.file(path).text()));
116
+ const current = await buildContractsLock(await loadBackend(cwd));
117
+ const diagnostics = [];
118
+ const keys = new Set([...Object.keys(parsed.routes), ...Object.keys(current.routes)]);
119
+ for (const key of [...keys].sort()) {
120
+ const before = parsed.routes[key];
121
+ const after = current.routes[key];
122
+ if (before === undefined ||
123
+ after === undefined ||
124
+ before.request !== after.request ||
125
+ before.response !== after.response) {
126
+ diagnostics.push({
127
+ route: key,
128
+ message: `contract changed for ${key}; if intentional run \`nifra contracts snapshot\` and include the lock update in the same change.`,
129
+ });
130
+ }
131
+ }
132
+ return { present: true, diagnostics };
133
+ }
134
+ //# sourceMappingURL=contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":";;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAuB,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAY7E,MAAM,CAAC,MAAM,sBAAsB,GAAG,qBAAqB,CAAA;AAC3D,MAAM,MAAM,GAAG,gBAAgB,CAAA;AAE/B,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACzE,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC3C,CAAC,CAAC,SAAS,CAAA;AACf,CAAC;AAED,SAAS,SAAS,CAAC,KAAc,EAAE,GAAY;IAC7C,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,GAAG,IAAI,EAAE,CAAC;QAChF,OAAO,SAAS,CAAA;IAClB,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAA;IACrE,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC9B,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,KAAK,CAAA;IACtC,MAAM,GAAG,GAA4B,EAAE,CAAA;IACvC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAA;QAC1C,IAAI,IAAI,KAAK,SAAS;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC1C,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,KAAa;IACjC,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC7C,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAA;IAC3E,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AAC/E,CAAC;AAED,SAAS,WAAW,CAAC,KAAqB,EAAE,IAA4B;IACtE,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAA;IAC3B,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,EAAE,CAAA;IACnC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,UAAU,IAAI,MAAM,CAAC,IAAI,EAAE,MAAM,IAAI,IAAI;YAC5D,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,UAAU,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,IAAI,IAAI;YAC/D,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,IAAI;SACnE,CAAA;IACH,CAAC;IACD,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,UAAU,IAAI,MAAM,CAAC,QAAQ,EAAE,MAAM,IAAI,IAAI;QACxE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,UAAU,IAAI,MAAM,CAAC,GAAG,EAAE,MAAM,IAAI,IAAI;QACzD,MAAM,EAAE,MAAM,CAAC,WAAW,CACxB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;YAC3D,MAAM;YACN,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI;SACzC,CAAC,CACH;KACF,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAqB;IACrD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;IAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAA;AAC7E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAe;IACtD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAC/B,MAAM,OAAO,CAAC,GAAG,CACf,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,CACvB,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,MAAM,WAAW,CAAC,KAAK,CAAC,CAAU,CACtF,CACF,CACF,CAAA;IACD,OAAO;QACL,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;KAC1F,CAAA;AACH,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,GAAW;IACpC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,CAAA;IAC9C,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,EAAE,CAAC,CAAA;IAChF,MAAM,WAAW,GAAY,MAAM,MAAM,kCAAC,WAAW,EAAC,CAAA;IACtD,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAA;IACpC,IAAI,MAAM,EAAE,OAAO,KAAK,SAAS;QAC/B,MAAM,IAAI,KAAK,CAAC,WAAW,WAAW,0BAA0B,CAAC,CAAA;IACnE,OAAO,MAAM,CAAC,OAAO,CAAA;AACvB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAW,EACX,GAAG,GAAG,sBAAsB;IAE5B,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC,CAAA;IAC7D,MAAM,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAA;IACxE,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC9B,IAAI,MAAM,KAAK,SAAS;QAAE,MAAM,IAAI,SAAS,CAAC,kCAAkC,CAAC,CAAA;IACjF,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAA;IACjC,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAA;IAC1C,IAAI,MAAM,CAAC,OAAO,KAAK,CAAC,IAAI,YAAY,KAAK,SAAS;QACpD,MAAM,IAAI,SAAS,CAAC,+CAA+C,CAAC,CAAA;IACtE,MAAM,MAAM,GAAmC,EAAE,CAAA;IACjD,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAA;QAC1B,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,CAAA;QAC7B,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,CAAA;QAC/B,IACE,OAAO,KAAK,SAAS;YACrB,OAAO,OAAO,KAAK,QAAQ;YAC3B,QAAQ,KAAK,SAAS;YACtB,OAAO,QAAQ,KAAK,QAAQ;YAC5B,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;YACrB,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;YAEtB,MAAM,IAAI,SAAS,CAAC,oBAAoB,GAAG,EAAE,CAAC,CAAA;QAChD,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAA;IACrC,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAA;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAW,EACX,IAAI,GAAG,sBAAsB;IAE7B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,CAAA;IACjE,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IAC1E,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC,CAAA;IAChE,MAAM,WAAW,GAA+C,EAAE,CAAA;IAClE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IACrF,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QACjC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QACjC,IACE,MAAM,KAAK,SAAS;YACpB,KAAK,KAAK,SAAS;YACnB,MAAM,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO;YAChC,MAAM,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,EAClC,CAAC;YACD,WAAW,CAAC,IAAI,CAAC;gBACf,KAAK,EAAE,GAAG;gBACV,OAAO,EAAE,wBAAwB,GAAG,mGAAmG;aACxI,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAA;AACvC,CAAC"}
@@ -0,0 +1,23 @@
1
+ /** Stable, machine-actionable diagnostics shared by CLI gates and MCP renderers. */
2
+ export type Severity = "error" | "warn" | "info";
3
+ export interface DiagnosticFix {
4
+ readonly recipe: string;
5
+ readonly command?: string;
6
+ }
7
+ export interface Diagnostic {
8
+ /** Stable forever. Never renumber or reuse. */
9
+ readonly code: string;
10
+ readonly severity: Severity;
11
+ readonly message: string;
12
+ readonly file?: string;
13
+ readonly line?: number;
14
+ /** Short evidence strings that help an agent act without exposing payloads. */
15
+ readonly evidence?: readonly string[];
16
+ readonly fix?: DiagnosticFix;
17
+ /** Command that proves the fix worked. */
18
+ readonly verify?: string;
19
+ }
20
+ export declare const diagnostic: (value: Diagnostic) => Diagnostic;
21
+ export declare function severityFails(severity: Severity, strict?: boolean): boolean;
22
+ export declare function normalizeSeverity(value: "error" | "warning" | "warn" | "info"): Severity;
23
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,oFAAoF;AAEpF,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;AAEhD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACrC,QAAQ,CAAC,GAAG,CAAC,EAAE,aAAa,CAAA;IAC5B,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,eAAO,MAAM,UAAU,GAAI,OAAO,UAAU,KAAG,UAAkC,CAAA;AAEjF,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,UAAQ,GAAG,OAAO,CAEzE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAExF"}
@@ -0,0 +1,9 @@
1
+ /** Stable, machine-actionable diagnostics shared by CLI gates and MCP renderers. */
2
+ export const diagnostic = (value) => Object.freeze(value);
3
+ export function severityFails(severity, strict = false) {
4
+ return severity === "error" || (strict && severity === "warn");
5
+ }
6
+ export function normalizeSeverity(value) {
7
+ return value === "warning" ? "warn" : value;
8
+ }
9
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,oFAAoF;AAuBpF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAiB,EAAc,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAEjF,MAAM,UAAU,aAAa,CAAC,QAAkB,EAAE,MAAM,GAAG,KAAK;IAC9D,OAAO,QAAQ,KAAK,OAAO,IAAI,CAAC,MAAM,IAAI,QAAQ,KAAK,MAAM,CAAC,CAAA;AAChE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAA4C;IAC5E,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAA;AAC7C,CAAC"}
@@ -24,6 +24,8 @@ export declare const DEFAULT_SNAPSHOT_FILE = "api-snapshot.json";
24
24
  export declare function parseSnapshotFile(content: string, sourcePath: string): SnapshotFile;
25
25
  /** Render a diff for terminals: breaking first, then info, then compatible. */
26
26
  export declare function formatDiff(diff: RoutesDiff): string;
27
+ /** Import `backend.ts` from `cwd` and snapshot its routes. */
28
+ export declare function snapshotBackend(cwd: string): Promise<readonly RouteSnapshot[]>;
27
29
  /** `nifra snapshot`: write the current contract as the CI baseline. */
28
30
  export declare function runSnapshot(cwd: string, options: {
29
31
  out?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"diff-tool.d.ts","sourceRoot":"","sources":["../src/diff-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,UAAU,EAEhB,MAAM,oBAAoB,CAAA;AAE3B,oGAAoG;AACpG,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAA;CAC1C;AAED,eAAO,MAAM,qBAAqB,sBAAsB,CAAA;AAExD,qGAAqG;AACrG,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,YAAY,CAqBnF;AAaD,+EAA+E;AAC/E,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAWnD;AAiBD,uEAAuE;AACvE,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAMvF;AAED,wGAAwG;AACxG,wBAAsB,OAAO,CAC3B,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1B,OAAO,CAAC,OAAO,CAAC,CAiBlB"}
1
+ {"version":3,"file":"diff-tool.d.ts","sourceRoot":"","sources":["../src/diff-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,UAAU,EAEhB,MAAM,oBAAoB,CAAA;AAE3B,oGAAoG;AACpG,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAA;CAC1C;AAED,eAAO,MAAM,qBAAqB,sBAAsB,CAAA;AAExD,qGAAqG;AACrG,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,YAAY,CAqBnF;AAaD,+EAA+E;AAC/E,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAWnD;AAED,8DAA8D;AAC9D,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,aAAa,EAAE,CAAC,CAYpF;AAED,uEAAuE;AACvE,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAMvF;AAED,wGAAwG;AACxG,wBAAsB,OAAO,CAC3B,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1B,OAAO,CAAC,OAAO,CAAC,CAiBlB"}
package/dist/diff-tool.js CHANGED
@@ -67,7 +67,7 @@ export function formatDiff(diff) {
67
67
  return `${lines.join("\n")}\n\n${summary}`;
68
68
  }
69
69
  /** Import `backend.ts` from `cwd` and snapshot its routes. */
70
- async function snapshotBackend(cwd) {
70
+ export async function snapshotBackend(cwd) {
71
71
  const backendPath = resolve(cwd, "backend.ts");
72
72
  if (!existsSync(backendPath)) {
73
73
  throw new Error(`[nifra] no backend.ts in ${cwd} - \`nifra snapshot\`/\`nifra diff\` compare the API contract, which lives in backend.ts.`);
@@ -1 +1 @@
1
- {"version":3,"file":"diff-tool.js","sourceRoot":"","sources":["../src/diff-tool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"diff-tool.js","sourceRoot":"","sources":["../src/diff-tool.ts"],"names":[],"mappings":"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"}
@@ -13,18 +13,23 @@ export interface DocSection {
13
13
  readonly heading: string;
14
14
  readonly body: string;
15
15
  }
16
+ export interface PreparedDocSection extends DocSection {
17
+ readonly headingTokens: ReadonlySet<string>;
18
+ readonly bodyLower: string;
19
+ }
16
20
  /** Split the generated doc into its `##` sections (the `# title` intro becomes "Overview"). */
17
21
  export declare function splitSections(markdown: string): DocSection[];
22
+ /** Return the immutable-build section parse and derived search fields from the process cache. */
23
+ export declare function getCachedDocSections(markdown: string): readonly PreparedDocSection[];
18
24
  export interface ScoredSection extends DocSection {
19
25
  readonly score: number;
20
26
  }
21
27
  /** Score sections against the query: a term in the HEADING is worth far more than body mentions
22
28
  * (headings are curated names for exactly these lookups); body occurrences cap per term so one
23
29
  * spammy section can't drown a precisely-titled one. */
24
- export declare function searchSections(sections: readonly DocSection[], query: string, limit: number): ScoredSection[];
30
+ export declare function searchSections(sections: readonly (DocSection | PreparedDocSection)[], query: string, limit: number): ScoredSection[];
25
31
  /** Render the tool result: matched sections, or the index when no query was given. */
26
32
  export declare function renderDocsResult(markdown: string, query: string | undefined, limit: number): string;
27
- /** Load the bundled corpus. Resolves relative to this module so it works from `src/` (repo dev)
28
- * and `dist/` (published) alike - `docs/llms-full.txt` sits at the package root next to both. */
33
+ /** The published corpus is immutable, so one read and one parsed-section cache are sufficient. */
29
34
  export declare function loadDocsCorpus(): Promise<string | undefined>;
30
35
  //# sourceMappingURL=docs-search.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"docs-search.d.ts","sourceRoot":"","sources":["../src/docs-search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,+FAA+F;AAC/F,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE,CAoB5D;AAED,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED;;wDAEwD;AACxD,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,SAAS,UAAU,EAAE,EAC/B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,aAAa,EAAE,CAejB;AAMD,sFAAsF;AACtF,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,KAAK,EAAE,MAAM,GACZ,MAAM,CAmBR;AAED;iGACiG;AACjG,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAQlE"}
1
+ {"version":3,"file":"docs-search.d.ts","sourceRoot":"","sources":["../src/docs-search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,kBAAmB,SAAQ,UAAU;IACpD,QAAQ,CAAC,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC3C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B;AAID,+FAA+F;AAC/F,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE,CAoB5D;AAUD,iGAAiG;AACjG,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,kBAAkB,EAAE,CAMpF;AAED,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED;;wDAEwD;AACxD,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,SAAS,CAAC,UAAU,GAAG,kBAAkB,CAAC,EAAE,EACtD,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,aAAa,EAAE,CAejB;AAMD,sFAAsF;AACtF,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,KAAK,EAAE,MAAM,GACZ,MAAM,CAmBR;AAMD,kGAAkG;AAClG,wBAAgB,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAW5D"}
@@ -10,6 +10,7 @@
10
10
  * embedding infra would be complexity without a payoff.
11
11
  */
12
12
  import { countBodyHits, queryTermGroups, tokenize, tokenSetHas } from "./search-terms.js";
13
+ const sectionCache = new Map();
13
14
  /** Split the generated doc into its `##` sections (the `# title` intro becomes "Overview"). */
14
15
  export function splitSections(markdown) {
15
16
  const out = [];
@@ -34,6 +35,22 @@ export function splitSections(markdown) {
34
35
  flush();
35
36
  return out;
36
37
  }
38
+ function prepareSection(section) {
39
+ return {
40
+ ...section,
41
+ headingTokens: new Set(tokenize(section.heading)),
42
+ bodyLower: section.body.toLowerCase(),
43
+ };
44
+ }
45
+ /** Return the immutable-build section parse and derived search fields from the process cache. */
46
+ export function getCachedDocSections(markdown) {
47
+ const cached = sectionCache.get(markdown);
48
+ if (cached !== undefined)
49
+ return cached;
50
+ const prepared = splitSections(markdown).map(prepareSection);
51
+ sectionCache.set(markdown, prepared);
52
+ return prepared;
53
+ }
37
54
  /** Score sections against the query: a term in the HEADING is worth far more than body mentions
38
55
  * (headings are curated names for exactly these lookups); body occurrences cap per term so one
39
56
  * spammy section can't drown a precisely-titled one. */
@@ -43,16 +60,15 @@ export function searchSections(sections, query, limit) {
43
60
  return [];
44
61
  const scored = [];
45
62
  for (const section of sections) {
46
- const headingTokens = new Set(tokenize(section.heading));
47
- const bodyLower = section.body.toLowerCase();
63
+ const prepared = "headingTokens" in section && "bodyLower" in section ? section : prepareSection(section);
48
64
  let score = 0;
49
65
  for (const term of terms) {
50
- if (tokenSetHas(headingTokens, term))
66
+ if (tokenSetHas(prepared.headingTokens, term))
51
67
  score += 8;
52
- score += countBodyHits(bodyLower, term, 5);
68
+ score += countBodyHits(prepared.bodyLower, term, 5);
53
69
  }
54
70
  if (score > 0)
55
- scored.push({ ...section, score });
71
+ scored.push({ heading: section.heading, body: section.body, score });
56
72
  }
57
73
  return scored.sort((a, b) => b.score - a.score).slice(0, limit);
58
74
  }
@@ -61,7 +77,7 @@ export function searchSections(sections, query, limit) {
61
77
  const MAX_SECTION_CHARS = 2800;
62
78
  /** Render the tool result: matched sections, or the index when no query was given. */
63
79
  export function renderDocsResult(markdown, query, limit) {
64
- const sections = splitSections(markdown);
80
+ const sections = getCachedDocSections(markdown);
65
81
  if (query === undefined || query.trim() === "") {
66
82
  const index = sections.map((s) => `- ${s.heading}`).join("\n");
67
83
  return `# nifra docs - section index (pass \`query\` to fetch matching sections)\n\n${index}`;
@@ -81,14 +97,19 @@ export function renderDocsResult(markdown, query, limit) {
81
97
  }
82
98
  /** Load the bundled corpus. Resolves relative to this module so it works from `src/` (repo dev)
83
99
  * and `dist/` (published) alike - `docs/llms-full.txt` sits at the package root next to both. */
84
- export async function loadDocsCorpus() {
85
- const url = new URL("../docs/llms-full.txt", import.meta.url);
86
- try {
87
- const text = await Bun.file(url).text();
88
- return text.length > 0 ? text : undefined;
89
- }
90
- catch {
91
- return undefined;
92
- }
100
+ let docsCorpusPromise;
101
+ /** The published corpus is immutable, so one read and one parsed-section cache are sufficient. */
102
+ export function loadDocsCorpus() {
103
+ docsCorpusPromise ??= (async () => {
104
+ const url = new URL("../docs/llms-full.txt", import.meta.url);
105
+ try {
106
+ const text = await Bun.file(url).text();
107
+ return text.length > 0 ? text : undefined;
108
+ }
109
+ catch {
110
+ return undefined;
111
+ }
112
+ })();
113
+ return docsCorpusPromise;
93
114
  }
94
115
  //# sourceMappingURL=docs-search.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"docs-search.js","sourceRoot":"","sources":["../src/docs-search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"docs-search.js","sourceRoot":"","sources":["../src/docs-search.ts"],"names":[],"mappings":"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"}
package/dist/doctor.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { type SourceFinding } from "./check.js";
2
2
  import { type PipelineReport } from "./pipeline-report.js";
3
+ import { type ResolvedTarget } from "./port.js";
3
4
  /**
4
5
  * Resolve an import specifier to the npm package name it would install as, or `undefined` when it isn't
5
6
  * an npm dependency at all (a relative/absolute path, a runtime builtin, or a malformed scope like the
@@ -31,6 +32,8 @@ export interface DoctorResult {
31
32
  * Advisory (never folded into `ok`): while actively editing a linked package its dist is always
32
33
  * momentarily behind - the finding matters when a dev server starts against it. */
33
34
  readonly staleDists: readonly StaleDistFinding[];
35
+ /** Static production-readiness evidence for the selected deploy target. */
36
+ readonly readiness?: DoctorReadiness;
34
37
  /**
35
38
  * Which bundler this app's `dev`/`build` phases run on, read statically, plus the config hazards
36
39
  * that exist only because there are two. Absent when the directory is not a nifra app.
@@ -45,6 +48,21 @@ export interface DoctorResult {
45
48
  /** Findings that were safe to report but not safe to write automatically. */
46
49
  readonly skippedFixes?: readonly DoctorSkippedFix[];
47
50
  }
51
+ export type DoctorReadinessStatus = "configured" | "absent" | "not-applicable";
52
+ export interface DoctorReadinessItem {
53
+ readonly id: "request-timeout" | "admission" | "request-id-tracing" | "health-route" | "log-redaction" | "graceful-lifecycle";
54
+ readonly label: string;
55
+ readonly status: DoctorReadinessStatus;
56
+ readonly evidence?: string;
57
+ }
58
+ export interface DoctorReadiness {
59
+ readonly target: string;
60
+ readonly targetSource: ResolvedTarget["source"] | null;
61
+ readonly strict: boolean;
62
+ /** True when every applicable rule has static evidence. */
63
+ readonly ok: boolean;
64
+ readonly items: readonly DoctorReadinessItem[];
65
+ }
48
66
  export interface DuplicateInstallCopy {
49
67
  /** Installed version, or `unknown` when package metadata is incomplete. */
50
68
  readonly version: string;
@@ -99,12 +117,20 @@ export interface StaleDistFinding {
99
117
  */
100
118
  export declare function collectStaleWorkspaceDists(cwd: string, rootPackage: Record<string, unknown>): Promise<StaleDistFinding[]>;
101
119
  /** Run doctor against the project at `cwd`: diff source imports vs declared deps. */
102
- export declare function collectDoctorResult(cwd: string): Promise<DoctorResult>;
120
+ export declare function collectDoctorResult(cwd: string, opts?: {
121
+ readonly target?: string;
122
+ readonly strict?: boolean;
123
+ }): Promise<DoctorResult>;
103
124
  /** Safely add undeclared imports to package.json when the version can be inferred without network I/O. */
104
- export declare function applyDoctorAutoFix(cwd: string): Promise<DoctorResult>;
125
+ export declare function applyDoctorAutoFix(cwd: string, opts?: {
126
+ readonly target?: string;
127
+ readonly strict?: boolean;
128
+ }): Promise<DoctorResult>;
105
129
  /** Run doctor; print a report (`--json` for machine output) and return whether it passed. */
106
130
  export declare function runDoctor(cwd: string, opts?: {
107
131
  readonly json?: boolean;
108
132
  readonly autoFix?: boolean;
133
+ readonly strict?: boolean;
134
+ readonly target?: string;
109
135
  }): Promise<boolean>;
110
136
  //# sourceMappingURL=doctor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}