@nifrajs/cli 3.3.0 → 3.5.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.
- package/dist/check-diagnostics.d.ts +3 -15
- package/dist/check-diagnostics.d.ts.map +1 -1
- package/dist/check-diagnostics.js +149 -713
- package/dist/check-diagnostics.js.map +1 -1
- package/dist/check-scan.d.ts +9 -0
- package/dist/check-scan.d.ts.map +1 -1
- package/dist/check-scan.js +32 -0
- package/dist/check-scan.js.map +1 -1
- package/dist/check.d.ts +1 -0
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +63 -8
- package/dist/check.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +46 -7
- package/dist/cli.js.map +1 -1
- package/dist/command-catalog.d.ts +4 -1
- package/dist/command-catalog.d.ts.map +1 -1
- package/dist/command-catalog.js +28 -7
- package/dist/command-catalog.js.map +1 -1
- package/dist/contracts.d.ts +3 -2
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js +4 -3
- package/dist/contracts.js.map +1 -1
- package/dist/diagnostics.d.ts +86 -0
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +85 -0
- package/dist/diagnostics.js.map +1 -1
- package/dist/introspect.d.ts +1 -3
- package/dist/introspect.d.ts.map +1 -1
- package/dist/introspect.js +1 -47
- package/dist/introspect.js.map +1 -1
- package/dist/load.d.ts +5 -0
- package/dist/load.d.ts.map +1 -1
- package/dist/load.js.map +1 -1
- package/dist/mcp-context.d.ts.map +1 -1
- package/dist/mcp-context.js +4 -5
- package/dist/mcp-context.js.map +1 -1
- package/dist/mcp-exec.d.ts +1 -0
- package/dist/mcp-exec.d.ts.map +1 -1
- package/dist/mcp-exec.js +133 -25
- package/dist/mcp-exec.js.map +1 -1
- package/dist/mcp-http.d.ts.map +1 -1
- package/dist/mcp-http.js +4 -1
- package/dist/mcp-http.js.map +1 -1
- package/dist/mcp-io.d.ts +12 -0
- package/dist/mcp-io.d.ts.map +1 -1
- package/dist/mcp-io.js +68 -0
- package/dist/mcp-io.js.map +1 -1
- package/dist/mcp-path.d.ts +10 -0
- package/dist/mcp-path.d.ts.map +1 -0
- package/dist/mcp-path.js +51 -0
- package/dist/mcp-path.js.map +1 -0
- package/dist/mcp-reflect.d.ts.map +1 -1
- package/dist/mcp-reflect.js +2 -2
- package/dist/mcp-reflect.js.map +1 -1
- package/dist/mcp-render.d.ts.map +1 -1
- package/dist/mcp-render.js +62 -43
- package/dist/mcp-render.js.map +1 -1
- package/dist/mcp-root.d.ts.map +1 -1
- package/dist/mcp-root.js +14 -2
- package/dist/mcp-root.js.map +1 -1
- package/dist/mcp-run.d.ts.map +1 -1
- package/dist/mcp-run.js +82 -51
- package/dist/mcp-run.js.map +1 -1
- package/dist/mcp.d.ts +2 -2
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +84 -29
- package/dist/mcp.js.map +1 -1
- package/dist/project-facts.d.ts +23 -4
- package/dist/project-facts.d.ts.map +1 -1
- package/dist/project-facts.js +12 -2
- package/dist/project-facts.js.map +1 -1
- package/dist/review.d.ts +21 -0
- package/dist/review.d.ts.map +1 -0
- package/dist/review.js +819 -0
- package/dist/review.js.map +1 -0
- package/dist/rules/legacy.d.ts +3 -1
- package/dist/rules/legacy.d.ts.map +1 -1
- package/dist/rules/legacy.js +796 -34
- package/dist/rules/legacy.js.map +1 -1
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +23 -4
- package/dist/scaffold.js.map +1 -1
- package/dist/verification-plan.d.ts.map +1 -1
- package/dist/verification-plan.js +4 -0
- package/dist/verification-plan.js.map +1 -1
- package/dist/work-graph.d.ts +3 -0
- package/dist/work-graph.d.ts.map +1 -1
- package/dist/work-graph.js +4 -3
- package/dist/work-graph.js.map +1 -1
- package/docs/llms-full.txt +369 -21
- package/docs/types.json +1121 -80
- package/package.json +10 -9
- package/src/check-diagnostics.ts +181 -796
- package/src/check-scan.ts +36 -0
- package/src/check.ts +65 -12
- package/src/cli.ts +53 -7
- package/src/command-catalog.ts +33 -7
- package/src/contracts.ts +12 -3
- package/src/diagnostics.ts +179 -0
- package/src/introspect.ts +3 -55
- package/src/load.ts +5 -0
- package/src/mcp-context.ts +4 -6
- package/src/mcp-exec.ts +142 -30
- package/src/mcp-http.ts +4 -1
- package/src/mcp-io.ts +73 -0
- package/src/mcp-path.ts +50 -0
- package/src/mcp-reflect.ts +3 -2
- package/src/mcp-render.ts +70 -40
- package/src/mcp-root.ts +13 -2
- package/src/mcp-run.ts +90 -50
- package/src/mcp.ts +87 -27
- package/src/project-facts.ts +37 -8
- package/src/review.ts +983 -0
- package/src/rules/legacy.ts +915 -35
- package/src/scaffold.ts +29 -4
- package/src/verification-plan.ts +14 -0
- package/src/work-graph.ts +13 -3
package/src/scaffold.ts
CHANGED
|
@@ -45,11 +45,35 @@ function segmentToFile(seg: string): string {
|
|
|
45
45
|
return seg
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
/** Reject syntax that could be interpreted by the host filesystem rather than the route mapper. */
|
|
49
|
+
function assertSafeRouteSegment(segment: string, urlPath: string): void {
|
|
50
|
+
if (segment === "." || segment === ".." || segment.includes("\0") || segment.includes("\\")) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`invalid route segment in ${JSON.stringify(urlPath)}: ${JSON.stringify(segment)}`,
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
const fileSegment = segmentToFile(segment)
|
|
56
|
+
if (
|
|
57
|
+
fileSegment === "." ||
|
|
58
|
+
fileSegment === ".." ||
|
|
59
|
+
fileSegment.includes("\0") ||
|
|
60
|
+
fileSegment.includes("/") ||
|
|
61
|
+
fileSegment.includes("\\") ||
|
|
62
|
+
fileSegment.includes(":") ||
|
|
63
|
+
/^[A-Za-z]:/.test(fileSegment)
|
|
64
|
+
) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`invalid route segment in ${JSON.stringify(urlPath)}: ${JSON.stringify(segment)}`,
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
48
71
|
/** Map a URL path to its `routes/` file path (relative to `routes/`, without extension prefix dir).
|
|
49
72
|
* `/` → `index`; `/users/:id` → `users/[id]`; `/blog/*slug` → `blog/[...slug]`. */
|
|
50
73
|
export function routePathToFile(urlPath: string, ext: string): string {
|
|
51
74
|
const segments = urlPath.split("/").filter((s) => s.length > 0)
|
|
52
75
|
if (segments.length === 0) return `routes/index.${ext}`
|
|
76
|
+
for (const segment of segments) assertSafeRouteSegment(segment, urlPath)
|
|
53
77
|
const last = segments.length - 1
|
|
54
78
|
// Catch-all must be the final segment (mirrors @nifrajs/web); flag it rather than emit an invalid file.
|
|
55
79
|
for (let i = 0; i < last; i++) {
|
|
@@ -268,11 +292,12 @@ export function scaffoldRoute(
|
|
|
268
292
|
}
|
|
269
293
|
}
|
|
270
294
|
|
|
271
|
-
function
|
|
295
|
+
function resolveInsideRoutes(cwd: string, relativeFile: string): string {
|
|
272
296
|
const root = resolve(cwd)
|
|
297
|
+
const routesRoot = resolve(root, "routes")
|
|
273
298
|
const target = resolve(root, relativeFile)
|
|
274
|
-
if (target
|
|
275
|
-
throw new Error(`refusing to write outside
|
|
299
|
+
if (target === routesRoot || !target.startsWith(`${routesRoot}${sep}`)) {
|
|
300
|
+
throw new Error(`refusing to write outside routes directory: ${relativeFile}`)
|
|
276
301
|
}
|
|
277
302
|
return target
|
|
278
303
|
}
|
|
@@ -325,7 +350,7 @@ export async function writeScaffoldRoute(
|
|
|
325
350
|
reason: "no verified ready-to-write stub for this framework; use nifra_example for the body",
|
|
326
351
|
}
|
|
327
352
|
}
|
|
328
|
-
const target =
|
|
353
|
+
const target = resolveInsideRoutes(cwd, result.file)
|
|
329
354
|
await assertNoSymlinkedAncestors(cwd, target)
|
|
330
355
|
await mkdir(dirname(target), { recursive: true })
|
|
331
356
|
await assertNoSymlinkedAncestors(cwd, target)
|
package/src/verification-plan.ts
CHANGED
|
@@ -102,6 +102,18 @@ const GATES = Object.freeze([
|
|
|
102
102
|
"Run `bun run check:core-performance` and investigate the measured performance regression.",
|
|
103
103
|
{ workflowRequired: false },
|
|
104
104
|
),
|
|
105
|
+
gate(
|
|
106
|
+
"middleware-performance",
|
|
107
|
+
[["run", "check:middleware-overhead"]],
|
|
108
|
+
"Run `bun run check:middleware-overhead` and investigate the middleware-chain regression.",
|
|
109
|
+
{ workflowRequired: false },
|
|
110
|
+
),
|
|
111
|
+
gate(
|
|
112
|
+
"edge-startup",
|
|
113
|
+
[["run", "check:edge-startup"]],
|
|
114
|
+
"Run `bun run check:edge-startup` and investigate edge/Workers import-time growth.",
|
|
115
|
+
{ workflowRequired: false },
|
|
116
|
+
),
|
|
105
117
|
gate(
|
|
106
118
|
"publish",
|
|
107
119
|
[["run", "check:publish"]],
|
|
@@ -187,6 +199,8 @@ const RELEASE_PLAN = Object.freeze([
|
|
|
187
199
|
"plugin-manifest",
|
|
188
200
|
"size",
|
|
189
201
|
"core-performance",
|
|
202
|
+
"middleware-performance",
|
|
203
|
+
"edge-startup",
|
|
190
204
|
"publish",
|
|
191
205
|
"consumer",
|
|
192
206
|
"cold-start",
|
package/src/work-graph.ts
CHANGED
|
@@ -9,7 +9,12 @@
|
|
|
9
9
|
import { existsSync } from "node:fs"
|
|
10
10
|
import { readFile, stat } from "node:fs/promises"
|
|
11
11
|
import { basename, resolve } from "node:path"
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
type ProjectEvidenceSnapshot,
|
|
14
|
+
reflectedRoutesFromEvidence,
|
|
15
|
+
snapshotProjectEvidence,
|
|
16
|
+
} from "@nifrajs/core/evidence"
|
|
17
|
+
import type { ReflectedRoute } from "@nifrajs/core/reflection"
|
|
13
18
|
import { Glob } from "bun"
|
|
14
19
|
import { digestRoute } from "./contracts.ts"
|
|
15
20
|
|
|
@@ -52,6 +57,8 @@ export interface WorkGraphSourceFile {
|
|
|
52
57
|
|
|
53
58
|
export interface WorkGraphBuildInput {
|
|
54
59
|
readonly source: unknown
|
|
60
|
+
/** Reuse a canonical route-evidence pass when the caller already has one. */
|
|
61
|
+
readonly evidence?: ProjectEvidenceSnapshot
|
|
55
62
|
readonly files?: readonly WorkGraphSourceFile[]
|
|
56
63
|
readonly freshness?: BuildFreshness
|
|
57
64
|
}
|
|
@@ -224,7 +231,8 @@ export async function buildProjectWorkGraph(
|
|
|
224
231
|
): Promise<ProjectWorkGraphResult> {
|
|
225
232
|
const freshness = input.freshness ?? { ok: true }
|
|
226
233
|
if (!freshness.ok) throw new StaleBuildError(freshness)
|
|
227
|
-
const
|
|
234
|
+
const projectEvidence = input.evidence ?? snapshotProjectEvidence(input.source)
|
|
235
|
+
const graph = await buildWorkGraph({ ...input, evidence: projectEvidence })
|
|
228
236
|
const impact = queryImpact(graph, options.changedFiles ?? [])
|
|
229
237
|
const plan = planProofs(graph, impact, options.minLevel ?? 1)
|
|
230
238
|
const evidence = createEvidenceBundle(graph, impact, plan)
|
|
@@ -232,7 +240,9 @@ export async function buildProjectWorkGraph(
|
|
|
232
240
|
}
|
|
233
241
|
|
|
234
242
|
export async function buildWorkGraph(input: WorkGraphBuildInput): Promise<WorkGraph> {
|
|
235
|
-
const routes =
|
|
243
|
+
const routes = reflectedRoutesFromEvidence(
|
|
244
|
+
input.evidence ?? snapshotProjectEvidence(input.source),
|
|
245
|
+
)
|
|
236
246
|
const files = input.files ?? []
|
|
237
247
|
const nodes = new Map<string, WorkGraphNode>()
|
|
238
248
|
const edges: WorkGraphEdge[] = []
|