@nifrajs/cli 2.2.0 → 2.3.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/README.md +25 -25
- package/dist/assure.d.ts +2 -2
- package/dist/assure.d.ts.map +1 -1
- package/dist/assure.js +17 -10
- package/dist/assure.js.map +1 -1
- package/dist/capabilities-tool.d.ts +7 -0
- package/dist/capabilities-tool.d.ts.map +1 -1
- package/dist/capabilities-tool.js +68 -16
- package/dist/capabilities-tool.js.map +1 -1
- package/dist/check.d.ts +61 -22
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +332 -86
- package/dist/check.js.map +1 -1
- package/dist/cli.d.ts +30 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +132 -36
- package/dist/cli.js.map +1 -1
- package/dist/diff-tool.d.ts +3 -3
- package/dist/diff-tool.js +7 -7
- package/dist/docs-search.d.ts +3 -3
- package/dist/docs-search.js +6 -6
- package/dist/doctor.d.ts +3 -3
- package/dist/doctor.js +8 -8
- package/dist/examples.d.ts +5 -5
- package/dist/examples.js +5 -5
- package/dist/init-agents.d.ts +14 -14
- package/dist/init-agents.js +14 -14
- package/dist/internal/typescript-import.d.ts +24 -0
- package/dist/internal/typescript-import.d.ts.map +1 -0
- package/dist/internal/typescript-import.js +32 -0
- package/dist/internal/typescript-import.js.map +1 -0
- package/dist/introspect.d.ts +12 -12
- package/dist/introspect.js +24 -24
- package/dist/levels-tool.d.ts +8 -8
- package/dist/levels-tool.d.ts.map +1 -1
- package/dist/levels-tool.js +33 -30
- package/dist/levels-tool.js.map +1 -1
- package/dist/load.d.ts +6 -6
- package/dist/load.d.ts.map +1 -1
- package/dist/load.js +15 -7
- package/dist/load.js.map +1 -1
- package/dist/manifest-tool.d.ts +1 -1
- package/dist/manifest-tool.d.ts.map +1 -1
- package/dist/manifest-tool.js +4 -2
- package/dist/manifest-tool.js.map +1 -1
- package/dist/mcp-docs-tools.d.ts +1 -1
- package/dist/mcp-docs-tools.js +9 -9
- package/dist/mcp-http.d.ts +5 -5
- package/dist/mcp-http.js +7 -7
- package/dist/mcp-protocol.d.ts +2 -2
- package/dist/mcp-protocol.js +2 -2
- package/dist/mcp-render.d.ts +3 -3
- package/dist/mcp-render.js +6 -6
- package/dist/mcp-run.d.ts +2 -2
- package/dist/mcp-run.js +2 -2
- package/dist/mcp.d.ts +14 -14
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +75 -45
- package/dist/mcp.js.map +1 -1
- package/dist/openapi-tool.d.ts +1 -1
- package/dist/openapi-tool.js +2 -2
- package/dist/pipeline-guard.d.ts +1 -1
- package/dist/pipeline-guard.js +1 -1
- package/dist/port.d.ts +9 -9
- package/dist/port.js +27 -27
- package/dist/recipes/1.8.0.d.ts +2 -2
- package/dist/recipes/1.8.0.js +5 -5
- package/dist/recipes/index.d.ts +2 -2
- package/dist/recipes/index.js +1 -1
- package/dist/scaffold.d.ts +3 -3
- package/dist/scaffold.js +8 -8
- package/dist/sync-routes.d.ts +28 -0
- package/dist/sync-routes.d.ts.map +1 -0
- package/dist/sync-routes.js +55 -0
- package/dist/sync-routes.js.map +1 -0
- package/dist/types-search.d.ts +5 -5
- package/dist/types-search.js +7 -7
- package/dist/upgrade.d.ts +7 -7
- package/dist/upgrade.js +12 -12
- package/dist/verification.d.ts +51 -0
- package/dist/verification.d.ts.map +1 -0
- package/dist/verification.js +80 -0
- package/dist/verification.js.map +1 -0
- package/docs/examples.json +174 -90
- package/docs/llms-full.txt +1696 -747
- package/docs/types.json +1892 -3105
- package/package.json +22 -11
- package/src/assure.ts +17 -18
- package/src/capabilities-tool.ts +82 -16
- package/src/check.ts +405 -103
- package/src/cli.ts +141 -38
- package/src/diff-tool.ts +8 -8
- package/src/docs-search.ts +6 -6
- package/src/doctor.ts +10 -10
- package/src/examples.ts +7 -7
- package/src/init-agents.ts +17 -17
- package/src/internal/typescript-import.ts +33 -0
- package/src/introspect.ts +28 -28
- package/src/levels-tool.ts +37 -31
- package/src/load.ts +21 -12
- package/src/manifest-tool.ts +4 -2
- package/src/mcp-docs-tools.ts +9 -9
- package/src/mcp-http.ts +7 -7
- package/src/mcp-protocol.ts +2 -2
- package/src/mcp-render.ts +6 -6
- package/src/mcp-run.ts +2 -2
- package/src/mcp.ts +82 -45
- package/src/openapi-tool.ts +2 -2
- package/src/pipeline-guard.ts +1 -1
- package/src/port.ts +31 -31
- package/src/recipes/1.8.0.ts +5 -5
- package/src/recipes/index.ts +2 -2
- package/src/scaffold.ts +8 -8
- package/src/sync-routes.ts +69 -0
- package/src/types-search.ts +8 -8
- package/src/upgrade.ts +12 -12
- package/src/verification.ts +123 -0
package/dist/scaffold.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `nifra_scaffold`
|
|
2
|
+
* `nifra_scaffold` - turn a URL path into the correct `routes/` file (the convention an agent most often
|
|
3
3
|
* gets wrong) + a minimal, contract-correct stub. The mapping is the inverse of @nifrajs/web's
|
|
4
4
|
* `filePathToPatterns`: `:id`/`[id]` → `[id]`, `*rest`/`[...rest]` → `[...rest]`, `[[lang]]` optional,
|
|
5
5
|
* `/` → `index`. The framework (→ file extension) comes from the project's `clientModule`.
|
|
6
6
|
*
|
|
7
|
-
* Page stubs are emitted only for the JSX family (react/preact/solid
|
|
7
|
+
* Page stubs are emitted only for the JSX family (react/preact/solid - one shared, verified shape);
|
|
8
8
|
* for vue/svelte/vanilla we return the correct PATH + the route-module contract and point at
|
|
9
9
|
* `nifra_example` for the body, rather than hand-writing an SFC we can't typecheck here.
|
|
10
10
|
*/
|
|
@@ -49,17 +49,17 @@ export function routePathToFile(urlPath, ext) {
|
|
|
49
49
|
return `routes/${segments.map(segmentToFile).join("/")}.${ext}`;
|
|
50
50
|
}
|
|
51
51
|
const ROUTE_CONTRACT = `A route module may export:
|
|
52
|
-
- \`export default function Page(props: { data: LoaderData<typeof loader> }) { … }\`
|
|
53
|
-
- \`export async function loader({ params, request, api }: LoaderArgs<typeof backend>) { … }\`
|
|
54
|
-
- \`export async function action({ request, api }: ActionArgs<typeof backend>) { … }\`
|
|
55
|
-
- \`export const meta = { title, meta:[…] }\`
|
|
52
|
+
- \`export default function Page(props: { data: LoaderData<typeof loader> }) { … }\` - the page component.
|
|
53
|
+
- \`export async function loader({ params, request, api }: LoaderArgs<typeof backend>) { … }\` - server-only; data for SSR. Reach the backend via \`api\` (typed) / DB via the backend, NEVER a top-level server-only import.
|
|
54
|
+
- \`export async function action({ request, api }: ActionArgs<typeof backend>) { … }\` - server-only; handles the form POST.
|
|
55
|
+
- \`export const meta = { title, meta:[…] }\` - head tags.
|
|
56
56
|
Path params are typed on \`params\`.`;
|
|
57
57
|
function jsxStub(file, params) {
|
|
58
58
|
const paramsNote = params.length > 0 ? `params.${params.join(", params.")}` : "no path params on this route";
|
|
59
59
|
const loaderLine = params.length > 0
|
|
60
60
|
? `// export async function loader({ params, api }: LoaderArgs<typeof backend>) { return { /* fetch by ${params[0]} */ } }`
|
|
61
61
|
: `// export async function loader({ api }: LoaderArgs<typeof backend>) { return {} }`;
|
|
62
|
-
return `// ${file}
|
|
62
|
+
return `// ${file} - server-only loader/action allowed; never top-level-import server-only code (DB/secrets).
|
|
63
63
|
// Available here: ${paramsNote}. Fetch data in a loader via the typed \`api\`; see nifra_example("loader").
|
|
64
64
|
${loaderLine}
|
|
65
65
|
export default function Page() {
|
|
@@ -125,7 +125,7 @@ export async function writeScaffoldRoute(cwd, urlPath, framework) {
|
|
|
125
125
|
}
|
|
126
126
|
return { ...result, written: true };
|
|
127
127
|
}
|
|
128
|
-
/** Render the tool result as markdown
|
|
128
|
+
/** Render the tool result as markdown - the file path, the stub (if any), and the contract note. */
|
|
129
129
|
export function renderScaffold(urlPath, framework) {
|
|
130
130
|
let r;
|
|
131
131
|
try {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `nifra sync-routes` - regenerate the route-search types (`nifra-routes.d.ts`) from the current `routes/`
|
|
3
|
+
* tree, so `navigate({ to, search })` is typed against each static route's `searchSchema`. It runs
|
|
4
|
+
* `@nifrajs/web`'s `generateRouteSearchTypes` over the discovered routes and writes the `.d.ts` at the
|
|
5
|
+
* project root; include it in your tsconfig's `include`. Because it is regenerated from the route files, a
|
|
6
|
+
* stale navigate search shape becomes a `tsc` error - run it after adding/renaming a route or changing a
|
|
7
|
+
* `searchSchema` (a pure file write, no build). A dynamic route (`:param`/catch-all) is omitted, since its
|
|
8
|
+
* pattern is not a concrete `to`; those keep the loose object form.
|
|
9
|
+
*/
|
|
10
|
+
/** The committed route-types file `sync-routes` writes, so `nifra check` can recognise + drift-check it. */
|
|
11
|
+
export declare const ROUTE_TYPES_FILE = "nifra-routes.d.ts";
|
|
12
|
+
export interface SyncRoutesResult {
|
|
13
|
+
/** The written `.d.ts` (relative to the project root). */
|
|
14
|
+
readonly file: string;
|
|
15
|
+
/** True when the file's content changed and it was rewritten. */
|
|
16
|
+
readonly changed: boolean;
|
|
17
|
+
/** How many static routes got a typed entry. */
|
|
18
|
+
readonly typedRoutes: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Generate the route-search types `.d.ts` from `<cwd>/routes` (the nifra convention). Returns `null` when
|
|
22
|
+
* there is no `routes/` directory (an API-only project - nothing to type). Never loads `framework.ts`: it
|
|
23
|
+
* needs only the route tree, so it works before a build and on a broken framework config.
|
|
24
|
+
*/
|
|
25
|
+
export declare function syncRouteTypes(cwd: string): Promise<SyncRoutesResult | null>;
|
|
26
|
+
/** CLI entry: write/refresh the route-types file and print a one-line summary + the tsconfig reminder. */
|
|
27
|
+
export declare function runSyncRoutes(cwd: string): Promise<boolean>;
|
|
28
|
+
//# sourceMappingURL=sync-routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-routes.d.ts","sourceRoot":"","sources":["../src/sync-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,4GAA4G;AAC5G,eAAO,MAAM,gBAAgB,sBAAsB,CAAA;AAEnD,MAAM,WAAW,gBAAgB;IAC/B,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,iEAAiE;IACjE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,gDAAgD;IAChD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAkBlF;AAED,0GAA0G;AAC1G,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiBjE"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `nifra sync-routes` - regenerate the route-search types (`nifra-routes.d.ts`) from the current `routes/`
|
|
3
|
+
* tree, so `navigate({ to, search })` is typed against each static route's `searchSchema`. It runs
|
|
4
|
+
* `@nifrajs/web`'s `generateRouteSearchTypes` over the discovered routes and writes the `.d.ts` at the
|
|
5
|
+
* project root; include it in your tsconfig's `include`. Because it is regenerated from the route files, a
|
|
6
|
+
* stale navigate search shape becomes a `tsc` error - run it after adding/renaming a route or changing a
|
|
7
|
+
* `searchSchema` (a pure file write, no build). A dynamic route (`:param`/catch-all) is omitted, since its
|
|
8
|
+
* pattern is not a concrete `to`; those keep the loose object form.
|
|
9
|
+
*/
|
|
10
|
+
import { existsSync } from "node:fs";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
/** The committed route-types file `sync-routes` writes, so `nifra check` can recognise + drift-check it. */
|
|
13
|
+
export const ROUTE_TYPES_FILE = "nifra-routes.d.ts";
|
|
14
|
+
/**
|
|
15
|
+
* Generate the route-search types `.d.ts` from `<cwd>/routes` (the nifra convention). Returns `null` when
|
|
16
|
+
* there is no `routes/` directory (an API-only project - nothing to type). Never loads `framework.ts`: it
|
|
17
|
+
* needs only the route tree, so it works before a build and on a broken framework config.
|
|
18
|
+
*/
|
|
19
|
+
export async function syncRouteTypes(cwd) {
|
|
20
|
+
const routesDir = join(cwd, "routes");
|
|
21
|
+
if (!existsSync(routesDir))
|
|
22
|
+
return null;
|
|
23
|
+
const { discoverRoutes } = await import("@nifrajs/web/fs");
|
|
24
|
+
const { generateRouteSearchTypes } = await import("@nifrajs/web");
|
|
25
|
+
const manifest = discoverRoutes(routesDir);
|
|
26
|
+
const code = generateRouteSearchTypes(manifest, {
|
|
27
|
+
// A route file is relative to routesDir (`reports.tsx`, `users/index.tsx`); the `.d.ts` sits at the
|
|
28
|
+
// project root, so the `typeof import(...)` specifier is `./routes/<file без extension>`.
|
|
29
|
+
resolve: (file) => `./routes/${file.replace(/\.[^./]+$/, "")}`,
|
|
30
|
+
});
|
|
31
|
+
const outFile = join(cwd, ROUTE_TYPES_FILE);
|
|
32
|
+
const existing = await Bun.file(outFile)
|
|
33
|
+
.text()
|
|
34
|
+
.catch(() => "");
|
|
35
|
+
const changed = existing !== code;
|
|
36
|
+
if (changed)
|
|
37
|
+
await Bun.write(outFile, code);
|
|
38
|
+
return { file: ROUTE_TYPES_FILE, changed, typedRoutes: (code.match(/: SearchOf</g) ?? []).length };
|
|
39
|
+
}
|
|
40
|
+
/** CLI entry: write/refresh the route-types file and print a one-line summary + the tsconfig reminder. */
|
|
41
|
+
export async function runSyncRoutes(cwd) {
|
|
42
|
+
const result = await syncRouteTypes(cwd);
|
|
43
|
+
if (result === null) {
|
|
44
|
+
console.log("nifra sync-routes: no routes/ directory found. Run from your project root.");
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
const n = result.typedRoutes;
|
|
48
|
+
const routes = `${n} typed route${n === 1 ? "" : "s"}`;
|
|
49
|
+
console.log(result.changed
|
|
50
|
+
? `✓ wrote ${result.file} (${routes})`
|
|
51
|
+
: `• ${result.file} already in sync (${routes})`);
|
|
52
|
+
console.log(" Include it in your tsconfig's `include` so `navigate({ to, search })` is typed per route.");
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=sync-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-routes.js","sourceRoot":"","sources":["../src/sync-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,4GAA4G;AAC5G,MAAM,CAAC,MAAM,gBAAgB,GAAG,mBAAmB,CAAA;AAWnD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAW;IAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;IACrC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAA;IACvC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAA;IAC1D,MAAM,EAAE,wBAAwB,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAA;IACjE,MAAM,QAAQ,GAAG,cAAc,CAAC,SAAS,CAAC,CAAA;IAC1C,MAAM,IAAI,GAAG,wBAAwB,CAAC,QAAQ,EAAE;QAC9C,oGAAoG;QACpG,0FAA0F;QAC1F,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE;KAC/D,CAAC,CAAA;IACF,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAA;IAC3C,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;SACrC,IAAI,EAAE;SACN,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;IAClB,MAAM,OAAO,GAAG,QAAQ,KAAK,IAAI,CAAA;IACjC,IAAI,OAAO;QAAE,MAAM,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;IAC3C,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAA;AACpG,CAAC;AAED,0GAA0G;AAC1G,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAW;IAC7C,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAA;IACxC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,4EAA4E,CAAC,CAAA;QACzF,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,CAAC,GAAG,MAAM,CAAC,WAAW,CAAA;IAC5B,MAAM,MAAM,GAAG,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAA;IACtD,OAAO,CAAC,GAAG,CACT,MAAM,CAAC,OAAO;QACZ,CAAC,CAAC,WAAW,MAAM,CAAC,IAAI,KAAK,MAAM,GAAG;QACtC,CAAC,CAAC,KAAK,MAAM,CAAC,IAAI,qBAAqB,MAAM,GAAG,CACnD,CAAA;IACD,OAAO,CAAC,GAAG,CACT,6FAA6F,CAC9F,CAAA;IACD,OAAO,IAAI,CAAA;AACb,CAAC"}
|
package/dist/types-search.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `nifra_types`
|
|
2
|
+
* `nifra_types` - the EXACT TypeScript of every exported `@nifrajs/*` symbol. The corpus is `types.json`
|
|
3
3
|
* (written into this package by `bun run gen:llms`): each entry's `signature` is the literal declaration
|
|
4
|
-
* parsed from the package's BUILT `.d.ts` with the TS compiler
|
|
4
|
+
* parsed from the package's BUILT `.d.ts` with the TS compiler - a clean signature, never prose, never
|
|
5
5
|
* truncated. So an agent that needs the precise shape of a type (`RateLimitStore`, `RouteSchema`, a
|
|
6
6
|
* function signature) gets the authoritative source here and never has to read a `.d.ts` file.
|
|
7
7
|
*
|
|
@@ -12,7 +12,7 @@ export interface TypeEntry {
|
|
|
12
12
|
readonly name: string;
|
|
13
13
|
readonly kind: "interface" | "type" | "class" | "function" | "enum" | "const";
|
|
14
14
|
readonly package: string;
|
|
15
|
-
/** The literal declaration text from the `.d.ts`
|
|
15
|
+
/** The literal declaration text from the `.d.ts` - a clean signature, no implementation. */
|
|
16
16
|
readonly signature: string;
|
|
17
17
|
/** The declaration's JSDoc block, if any. */
|
|
18
18
|
readonly doc?: string;
|
|
@@ -20,7 +20,7 @@ export interface TypeEntry {
|
|
|
20
20
|
export interface ScoredType extends TypeEntry {
|
|
21
21
|
readonly score: number;
|
|
22
22
|
}
|
|
23
|
-
/** Exact (case-insensitive) name lookup
|
|
23
|
+
/** Exact (case-insensitive) name lookup - returns every declaration with that name (a name can exist in
|
|
24
24
|
* more than one package). */
|
|
25
25
|
export declare function lookupType(types: readonly TypeEntry[], name: string): TypeEntry[];
|
|
26
26
|
/** Keyword-score types: a term in the name is worth far more than one in the signature/doc body. */
|
|
@@ -28,7 +28,7 @@ export declare function searchTypes(types: readonly TypeEntry[], query: string,
|
|
|
28
28
|
/**
|
|
29
29
|
* Render the tool result. `name` → the exact declaration(s); else `query` → the top matches; else a
|
|
30
30
|
* per-package index of type names. The signatures are authoritative (generated from the built `.d.ts`),
|
|
31
|
-
* so this is the complete answer
|
|
31
|
+
* so this is the complete answer - there is no need to read a `.d.ts` file.
|
|
32
32
|
*/
|
|
33
33
|
export declare function renderTypesResult(types: readonly TypeEntry[], name: string | undefined, query: string | undefined, limit: number, full?: boolean): string;
|
|
34
34
|
/** Load the bundled type corpus (`docs/types.json`), resolved relative to this module so it works from
|
package/dist/types-search.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `nifra_types`
|
|
2
|
+
* `nifra_types` - the EXACT TypeScript of every exported `@nifrajs/*` symbol. The corpus is `types.json`
|
|
3
3
|
* (written into this package by `bun run gen:llms`): each entry's `signature` is the literal declaration
|
|
4
|
-
* parsed from the package's BUILT `.d.ts` with the TS compiler
|
|
4
|
+
* parsed from the package's BUILT `.d.ts` with the TS compiler - a clean signature, never prose, never
|
|
5
5
|
* truncated. So an agent that needs the precise shape of a type (`RateLimitStore`, `RouteSchema`, a
|
|
6
6
|
* function signature) gets the authoritative source here and never has to read a `.d.ts` file.
|
|
7
7
|
*
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* signature/doc body; no args → a per-package index of the available type names.
|
|
10
10
|
*/
|
|
11
11
|
import { countBodyHits, queryTermGroups, tokenize, tokenSetHas } from "./search-terms.js";
|
|
12
|
-
/** Exact (case-insensitive) name lookup
|
|
12
|
+
/** Exact (case-insensitive) name lookup - returns every declaration with that name (a name can exist in
|
|
13
13
|
* more than one package). */
|
|
14
14
|
export function lookupType(types, name) {
|
|
15
15
|
const wanted = name.trim().toLowerCase();
|
|
@@ -36,7 +36,7 @@ export function searchTypes(types, query, limit) {
|
|
|
36
36
|
return scored.sort((a, b) => b.score - a.score || a.name.localeCompare(b.name)).slice(0, limit);
|
|
37
37
|
}
|
|
38
38
|
function renderEntry(t) {
|
|
39
|
-
const head = `## ${t.name}
|
|
39
|
+
const head = `## ${t.name} - ${t.kind}, \`${t.package}\``;
|
|
40
40
|
const doc = t.doc ? `${t.doc}\n` : "";
|
|
41
41
|
return `${head}\n\n\`\`\`ts\n${doc}${t.signature}\n\`\`\``;
|
|
42
42
|
}
|
|
@@ -76,7 +76,7 @@ function collapseSignature(signature) {
|
|
|
76
76
|
}
|
|
77
77
|
/** A search hit: enough to choose, not the whole declaration. */
|
|
78
78
|
function renderSearchHit(t) {
|
|
79
|
-
const head = `## ${t.name}
|
|
79
|
+
const head = `## ${t.name} - ${t.kind}, \`${t.package}\``;
|
|
80
80
|
const summary = summarize(t.doc);
|
|
81
81
|
const signature = t.signature.length <= SEARCH_SIGNATURE_MAX ? t.signature : collapseSignature(t.signature);
|
|
82
82
|
const note = t.signature.length <= SEARCH_SIGNATURE_MAX
|
|
@@ -87,7 +87,7 @@ function renderSearchHit(t) {
|
|
|
87
87
|
/**
|
|
88
88
|
* Render the tool result. `name` → the exact declaration(s); else `query` → the top matches; else a
|
|
89
89
|
* per-package index of type names. The signatures are authoritative (generated from the built `.d.ts`),
|
|
90
|
-
* so this is the complete answer
|
|
90
|
+
* so this is the complete answer - there is no need to read a `.d.ts` file.
|
|
91
91
|
*/
|
|
92
92
|
export function renderTypesResult(types, name, query, limit, full = false) {
|
|
93
93
|
if (name !== undefined && name.trim() !== "") {
|
|
@@ -115,7 +115,7 @@ export function renderTypesResult(types, name, query, limit, full = false) {
|
|
|
115
115
|
.sort(([a], [b]) => a.localeCompare(b))
|
|
116
116
|
.map(([pkg, names]) => `- **${pkg}**: ${names.sort().join(", ")}`)
|
|
117
117
|
.join("\n");
|
|
118
|
-
return `# nifra types
|
|
118
|
+
return `# nifra types - index (${types.length} exported symbols; pass \`name\` for the exact declaration, or \`query\` to search)\n\nSignatures are generated from the built \`.d.ts\` - authoritative + complete. Use this instead of reading any \`.d.ts\` file.\n\n${index}`;
|
|
119
119
|
}
|
|
120
120
|
/** Load the bundled type corpus (`docs/types.json`), resolved relative to this module so it works from
|
|
121
121
|
* `src/` (dev) and `dist/` (published) alike. */
|
package/dist/upgrade.d.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `nifra upgrade <version>`
|
|
2
|
+
* `nifra upgrade <version>` - an executable, per-release upgrade runner. Framework and shared-package
|
|
3
3
|
* bumps otherwise spread the same mechanical edits across every consuming app by hand; a recipe turns
|
|
4
4
|
* them into `detect → transform → verify`:
|
|
5
5
|
*
|
|
6
|
-
* 1. **pin sweep**
|
|
6
|
+
* 1. **pin sweep** - set every matching dependency to the target version across the workspace's
|
|
7
7
|
* package.json files, preserving the caret/tilde/exact style and skipping `workspace:`/`link:` specs.
|
|
8
|
-
* 2. **dependency moves**
|
|
8
|
+
* 2. **dependency moves** - replace removed packages with their supported successor without
|
|
9
9
|
* reserializing package.json or leaving duplicate dependency keys.
|
|
10
|
-
* 3. **import moves**
|
|
11
|
-
* 4. **verify**
|
|
10
|
+
* 3. **import moves** - rewrite exact import specifiers to their updated module paths.
|
|
11
|
+
* 4. **verify** - reuse the existing `nifra check` gate; no new verification surface.
|
|
12
12
|
*
|
|
13
13
|
* Dry-run by default (prints the plan, writes nothing); `--write` applies. Fail-closed on an unknown
|
|
14
14
|
* target version or a missing package.json, and deterministic (same repo + target → same edits).
|
|
15
15
|
*
|
|
16
16
|
* Deliberately NOT a codemod engine: transforms are string/specifier-level only. Structural (AST)
|
|
17
|
-
* transforms are a future addition
|
|
17
|
+
* transforms are a future addition - a recipe that needs one is the signal to add the engine, not before.
|
|
18
18
|
*/
|
|
19
19
|
import { type UpgradeRecipe } from "./recipes/index.js";
|
|
20
20
|
export interface UpgradeOptions {
|
|
@@ -64,7 +64,7 @@ export interface UpgradePlan {
|
|
|
64
64
|
*/
|
|
65
65
|
export declare function rewriteVersionSpec(spec: string, toVersion: string): string | null;
|
|
66
66
|
/**
|
|
67
|
-
* Apply pin rules to one package.json's TEXT (format-preserving
|
|
67
|
+
* Apply pin rules to one package.json's TEXT (format-preserving - targeted string replaces, never a
|
|
68
68
|
* JSON re-serialize that would reorder keys or drop comments-as-formatting). Returns the new text and
|
|
69
69
|
* the changes made.
|
|
70
70
|
*/
|
package/dist/upgrade.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `nifra upgrade <version>`
|
|
2
|
+
* `nifra upgrade <version>` - an executable, per-release upgrade runner. Framework and shared-package
|
|
3
3
|
* bumps otherwise spread the same mechanical edits across every consuming app by hand; a recipe turns
|
|
4
4
|
* them into `detect → transform → verify`:
|
|
5
5
|
*
|
|
6
|
-
* 1. **pin sweep**
|
|
6
|
+
* 1. **pin sweep** - set every matching dependency to the target version across the workspace's
|
|
7
7
|
* package.json files, preserving the caret/tilde/exact style and skipping `workspace:`/`link:` specs.
|
|
8
|
-
* 2. **dependency moves**
|
|
8
|
+
* 2. **dependency moves** - replace removed packages with their supported successor without
|
|
9
9
|
* reserializing package.json or leaving duplicate dependency keys.
|
|
10
|
-
* 3. **import moves**
|
|
11
|
-
* 4. **verify**
|
|
10
|
+
* 3. **import moves** - rewrite exact import specifiers to their updated module paths.
|
|
11
|
+
* 4. **verify** - reuse the existing `nifra check` gate; no new verification surface.
|
|
12
12
|
*
|
|
13
13
|
* Dry-run by default (prints the plan, writes nothing); `--write` applies. Fail-closed on an unknown
|
|
14
14
|
* target version or a missing package.json, and deterministic (same repo + target → same edits).
|
|
15
15
|
*
|
|
16
16
|
* Deliberately NOT a codemod engine: transforms are string/specifier-level only. Structural (AST)
|
|
17
|
-
* transforms are a future addition
|
|
17
|
+
* transforms are a future addition - a recipe that needs one is the signal to add the engine, not before.
|
|
18
18
|
*/
|
|
19
19
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
20
20
|
import { join, relative } from "node:path";
|
|
@@ -26,8 +26,8 @@ const DEP_FIELDS = [
|
|
|
26
26
|
"peerDependencies",
|
|
27
27
|
"optionalDependencies",
|
|
28
28
|
];
|
|
29
|
-
// Only a bare semver spec is rewritten. Anything else
|
|
30
|
-
// urls, "*", "latest", or a multi-part range
|
|
29
|
+
// Only a bare semver spec is rewritten. Anything else - workspace:*, link:/file:, npm: aliases, git
|
|
30
|
+
// urls, "*", "latest", or a multi-part range - is intentionally left untouched (skipped, not guessed).
|
|
31
31
|
const SEMVER_SPEC = /^([\^~]|>=|<=|>|<|=)?\s*(\d+)\.(\d+)\.(\d+)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
32
32
|
/**
|
|
33
33
|
* Rewrite a dependency version spec to `toVersion`, preserving the range operator (`^`, `~`, …).
|
|
@@ -43,7 +43,7 @@ export function rewriteVersionSpec(spec, toVersion) {
|
|
|
43
43
|
}
|
|
44
44
|
const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
45
45
|
/**
|
|
46
|
-
* Apply pin rules to one package.json's TEXT (format-preserving
|
|
46
|
+
* Apply pin rules to one package.json's TEXT (format-preserving - targeted string replaces, never a
|
|
47
47
|
* JSON re-serialize that would reorder keys or drop comments-as-formatting). Returns the new text and
|
|
48
48
|
* the changes made.
|
|
49
49
|
*/
|
|
@@ -268,7 +268,7 @@ function renderPlan(plan, write) {
|
|
|
268
268
|
if (plan.pins.length === 0 &&
|
|
269
269
|
plan.dependencyMoves.length === 0 &&
|
|
270
270
|
plan.importMoves.length === 0) {
|
|
271
|
-
lines.push("Already up to date
|
|
271
|
+
lines.push("Already up to date - no changes.");
|
|
272
272
|
return lines.join("\n");
|
|
273
273
|
}
|
|
274
274
|
if (plan.dependencyMoves.length > 0) {
|
|
@@ -325,7 +325,7 @@ export async function runUpgrade(cwd, options) {
|
|
|
325
325
|
readFileSync(join(cwd, "package.json"), "utf8");
|
|
326
326
|
}
|
|
327
327
|
catch {
|
|
328
|
-
console.error(`[nifra] no package.json in ${relative(process.cwd(), cwd) || "."}
|
|
328
|
+
console.error(`[nifra] no package.json in ${relative(process.cwd(), cwd) || "."} - run from a project root`);
|
|
329
329
|
return false;
|
|
330
330
|
}
|
|
331
331
|
const write = options.write === true;
|
|
@@ -342,7 +342,7 @@ export async function runUpgrade(cwd, options) {
|
|
|
342
342
|
const ok = await runCheck(cwd, { json: false });
|
|
343
343
|
if (!ok) {
|
|
344
344
|
if (!options.json)
|
|
345
|
-
console.error("\n[nifra] upgrade applied but `nifra check` failed
|
|
345
|
+
console.error("\n[nifra] upgrade applied but `nifra check` failed - review above.");
|
|
346
346
|
return false;
|
|
347
347
|
}
|
|
348
348
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One project verification, four commands. `nifra check`, `nifra assure`, `nifra levels`, and
|
|
3
|
+
* `nifra capabilities` are not separate audits - they are renderings of the same reflected project: the
|
|
4
|
+
* typed-contract scan, the route-assurance evaluation, and the static capability provenance. Historically
|
|
5
|
+
* each command re-derived the slice it needed, so a caller had to know which command ran which policy (and
|
|
6
|
+
* `levels` paid for the capability walk twice). `collectProjectVerification` runs each underlying policy
|
|
7
|
+
* exactly once and hands back a single value; the commands become thin formatters over subsets of it -
|
|
8
|
+
* `check`/`assure`/`levels` read their view directly, and `capabilities snapshot`/`check` read the same
|
|
9
|
+
* capability report before writing or diffing the lockfile.
|
|
10
|
+
*
|
|
11
|
+
* The typed-contract check is the one heavy pass (source walk + optional `tsc`), and `nifra assure`
|
|
12
|
+
* never needs it, so it is exposed as a lazily-invoked `check()` rather than computed up front.
|
|
13
|
+
*/
|
|
14
|
+
import { type AssuranceConfig, type AssuranceReport } from "@nifrajs/core/assurance";
|
|
15
|
+
import { type CapabilityProjectReport } from "./capabilities-tool.js";
|
|
16
|
+
import { type CheckResult } from "./check.js";
|
|
17
|
+
export interface CollectProjectVerificationOptions {
|
|
18
|
+
/** Assurance config path, default `nifra.assurance.ts`. Honored by the assurance + levels views. */
|
|
19
|
+
readonly config?: string;
|
|
20
|
+
/** Skip the `tsc` pass in the check view (the agent inner-loop mode). */
|
|
21
|
+
readonly lintsOnly?: boolean;
|
|
22
|
+
/** Cancels the check view's typecheck. */
|
|
23
|
+
readonly signal?: AbortSignal;
|
|
24
|
+
/** Cap the check view's diagnostics (the `levels` L0 and MCP paths set this). */
|
|
25
|
+
readonly maxDiagnostics?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface ProjectVerification {
|
|
28
|
+
readonly cwd: string;
|
|
29
|
+
/** Whether `nifra.assurance.ts` (or the requested `config` path) exists. */
|
|
30
|
+
readonly assuranceConfigPresent: boolean;
|
|
31
|
+
/** The loaded assurance config, when it loaded cleanly. */
|
|
32
|
+
readonly config?: AssuranceConfig;
|
|
33
|
+
/** The error from loading/evaluating the config, if any; the assurance views surface or throw it. */
|
|
34
|
+
readonly configError?: unknown;
|
|
35
|
+
/** `evaluateRouteAssurance` over the config's source + policy. Present whenever {@link config} is. */
|
|
36
|
+
readonly routeAssurance?: AssuranceReport;
|
|
37
|
+
/** Static capability provenance, when the config declares a capabilities policy. */
|
|
38
|
+
readonly capability?: CapabilityProjectReport;
|
|
39
|
+
/**
|
|
40
|
+
* The typed-contract check (scanners + typecheck + the assurance-fed capability/manifest diagnostics).
|
|
41
|
+
* Lazy and memoized: `nifra assure` never calls it, so that command pays nothing for the source walk.
|
|
42
|
+
*/
|
|
43
|
+
check(): Promise<CheckResult>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Run each verification policy once and return the unified value. The config is loaded (and reflected)
|
|
47
|
+
* a single time; the resulting route-assurance + capability evidence is both returned for the assurance
|
|
48
|
+
* views and fed into the check view, so nothing is computed twice.
|
|
49
|
+
*/
|
|
50
|
+
export declare function collectProjectVerification(cwd: string, options?: CollectProjectVerificationOptions): Promise<ProjectVerification>;
|
|
51
|
+
//# sourceMappingURL=verification.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification.d.ts","sourceRoot":"","sources":["../src/verification.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,eAAe,EAErB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,KAAK,uBAAuB,EAE7B,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAA8B,KAAK,WAAW,EAAsB,MAAM,YAAY,CAAA;AAE7F,MAAM,WAAW,iCAAiC;IAChD,oGAAoG;IACpG,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,yEAAyE;IACzE,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;IAC5B,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;IAC7B,iFAAiF;IACjF,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CACjC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,4EAA4E;IAC5E,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAA;IACxC,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAA;IACjC,qGAAqG;IACrG,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;IAC9B,sGAAsG;IACtG,QAAQ,CAAC,cAAc,CAAC,EAAE,eAAe,CAAA;IACzC,oFAAoF;IACpF,QAAQ,CAAC,UAAU,CAAC,EAAE,uBAAuB,CAAA;IAC7C;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC,CAAA;CAC9B;AAED;;;;GAIG;AACH,wBAAsB,0BAA0B,CAC9C,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,iCAAsC,GAC9C,OAAO,CAAC,mBAAmB,CAAC,CAyD9B"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One project verification, four commands. `nifra check`, `nifra assure`, `nifra levels`, and
|
|
3
|
+
* `nifra capabilities` are not separate audits - they are renderings of the same reflected project: the
|
|
4
|
+
* typed-contract scan, the route-assurance evaluation, and the static capability provenance. Historically
|
|
5
|
+
* each command re-derived the slice it needed, so a caller had to know which command ran which policy (and
|
|
6
|
+
* `levels` paid for the capability walk twice). `collectProjectVerification` runs each underlying policy
|
|
7
|
+
* exactly once and hands back a single value; the commands become thin formatters over subsets of it -
|
|
8
|
+
* `check`/`assure`/`levels` read their view directly, and `capabilities snapshot`/`check` read the same
|
|
9
|
+
* capability report before writing or diffing the lockfile.
|
|
10
|
+
*
|
|
11
|
+
* The typed-contract check is the one heavy pass (source walk + optional `tsc`), and `nifra assure`
|
|
12
|
+
* never needs it, so it is exposed as a lazily-invoked `check()` rather than computed up front.
|
|
13
|
+
*/
|
|
14
|
+
import { existsSync } from "node:fs";
|
|
15
|
+
import { resolve } from "node:path";
|
|
16
|
+
import { evaluateRouteAssurance, } from "@nifrajs/core/assurance";
|
|
17
|
+
import { collectCapabilityProjectReport, } from "./capabilities-tool.js";
|
|
18
|
+
import { collectCheckResult } from "./check.js";
|
|
19
|
+
/**
|
|
20
|
+
* Run each verification policy once and return the unified value. The config is loaded (and reflected)
|
|
21
|
+
* a single time; the resulting route-assurance + capability evidence is both returned for the assurance
|
|
22
|
+
* views and fed into the check view, so nothing is computed twice.
|
|
23
|
+
*/
|
|
24
|
+
export async function collectProjectVerification(cwd, options = {}) {
|
|
25
|
+
const { loadAssuranceConfig, DEFAULT_ASSURANCE_CONFIG } = await import("./assure.js");
|
|
26
|
+
const configPath = resolve(cwd, options.config ?? DEFAULT_ASSURANCE_CONFIG);
|
|
27
|
+
const assuranceConfigPresent = existsSync(configPath);
|
|
28
|
+
let config;
|
|
29
|
+
let configError;
|
|
30
|
+
let routeAssurance;
|
|
31
|
+
let capability;
|
|
32
|
+
// One try mirrors `check`'s single catch: any failure to load or reflect the config becomes the
|
|
33
|
+
// `configError` each view then renders in its own idiom (a diagnostic, a throw, a failed rung).
|
|
34
|
+
try {
|
|
35
|
+
config = await loadAssuranceConfig(cwd, options.config);
|
|
36
|
+
routeAssurance = evaluateRouteAssurance(config.source, config.policy, {
|
|
37
|
+
...(config.capabilities !== undefined
|
|
38
|
+
? { definitions: config.capabilities.definitions }
|
|
39
|
+
: {}),
|
|
40
|
+
});
|
|
41
|
+
if (config.capabilities !== undefined) {
|
|
42
|
+
capability = await collectCapabilityProjectReport(cwd, config.source, config.capabilities);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
configError = error;
|
|
47
|
+
config = undefined;
|
|
48
|
+
routeAssurance = undefined;
|
|
49
|
+
capability = undefined;
|
|
50
|
+
}
|
|
51
|
+
// The check view's assurance inputs. Fed to `check()` only when no custom config path was requested,
|
|
52
|
+
// so `nifra check` (which always reads the default `nifra.assurance.ts`) and `levels` L0 keep reading
|
|
53
|
+
// exactly the config they read before; a `--config` override stays a route-assurance/levels concern.
|
|
54
|
+
const checkContext = {
|
|
55
|
+
present: assuranceConfigPresent,
|
|
56
|
+
...(config !== undefined ? { config } : {}),
|
|
57
|
+
...(configError !== undefined ? { error: configError } : {}),
|
|
58
|
+
...(routeAssurance !== undefined ? { routeAssurance } : {}),
|
|
59
|
+
...(capability !== undefined ? { capability } : {}),
|
|
60
|
+
};
|
|
61
|
+
let checkResult;
|
|
62
|
+
return Object.freeze({
|
|
63
|
+
cwd,
|
|
64
|
+
assuranceConfigPresent,
|
|
65
|
+
...(config !== undefined ? { config } : {}),
|
|
66
|
+
...(configError !== undefined ? { configError } : {}),
|
|
67
|
+
...(routeAssurance !== undefined ? { routeAssurance } : {}),
|
|
68
|
+
...(capability !== undefined ? { capability } : {}),
|
|
69
|
+
check() {
|
|
70
|
+
checkResult ??= collectCheckResult(cwd, {
|
|
71
|
+
lintsOnly: options.lintsOnly ?? false,
|
|
72
|
+
...(options.signal !== undefined ? { signal: options.signal } : {}),
|
|
73
|
+
...(options.maxDiagnostics !== undefined ? { maxDiagnostics: options.maxDiagnostics } : {}),
|
|
74
|
+
...(options.config === undefined ? { assurance: checkContext } : {}),
|
|
75
|
+
});
|
|
76
|
+
return checkResult;
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=verification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification.js","sourceRoot":"","sources":["../src/verification.ts"],"names":[],"mappings":"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"}
|