@nifrajs/cli 1.5.0 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -0
- package/dist/assure.d.ts +11 -0
- package/dist/assure.d.ts.map +1 -0
- package/dist/assure.js +67 -0
- package/dist/assure.js.map +1 -0
- package/dist/capabilities-tool.d.ts +33 -0
- package/dist/capabilities-tool.d.ts.map +1 -0
- package/dist/capabilities-tool.js +320 -0
- package/dist/capabilities-tool.js.map +1 -0
- package/dist/check.d.ts +1 -1
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +117 -11
- package/dist/check.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +196 -9
- package/dist/cli.js.map +1 -1
- package/dist/levels-tool.d.ts +37 -0
- package/dist/levels-tool.d.ts.map +1 -0
- package/dist/levels-tool.js +180 -0
- package/dist/levels-tool.js.map +1 -0
- package/dist/manifest-tool.d.ts +15 -0
- package/dist/manifest-tool.d.ts.map +1 -0
- package/dist/manifest-tool.js +67 -0
- package/dist/manifest-tool.js.map +1 -0
- package/dist/mcp-http.js +1 -1
- package/dist/mcp-http.js.map +1 -1
- package/dist/mcp.d.ts +1 -0
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +31 -0
- package/dist/mcp.js.map +1 -1
- package/dist/recipes/1.8.0.d.ts +12 -0
- package/dist/recipes/1.8.0.d.ts.map +1 -0
- package/dist/recipes/1.8.0.js +20 -0
- package/dist/recipes/1.8.0.js.map +1 -0
- package/dist/recipes/index.d.ts +28 -0
- package/dist/recipes/index.d.ts.map +1 -0
- package/dist/recipes/index.js +27 -0
- package/dist/recipes/index.js.map +1 -0
- package/dist/upgrade.d.ts +82 -0
- package/dist/upgrade.d.ts.map +1 -0
- package/dist/upgrade.js +220 -0
- package/dist/upgrade.js.map +1 -0
- package/docs/examples.json +12 -0
- package/docs/llms-full.txt +419 -13
- package/docs/types.json +1924 -33
- package/package.json +8 -8
- package/src/assure.ts +88 -0
- package/src/capabilities-tool.ts +406 -0
- package/src/check.ts +135 -12
- package/src/cli.ts +203 -14
- package/src/levels-tool.ts +222 -0
- package/src/manifest-tool.ts +103 -0
- package/src/mcp-http.ts +1 -1
- package/src/mcp.ts +37 -0
- package/src/recipes/1.8.0.ts +21 -0
- package/src/recipes/index.ts +52 -0
- package/src/upgrade.ts +269 -0
package/README.md
CHANGED
|
@@ -11,9 +11,33 @@ nifra start [--port <n>] [--out <dir>] Serve the built app (client + SSR) on
|
|
|
11
11
|
nifra context Print this project's API + page routes + conventions.
|
|
12
12
|
nifra mcp MCP server (stdio) exposing this project to a coding agent.
|
|
13
13
|
nifra check [--json] Gate: typecheck + lints; --json includes fixes/suggestions.
|
|
14
|
+
nifra assure [--config <file>] [--json] Gate reflected routes against enforcement evidence.
|
|
15
|
+
nifra capabilities check [--json] Gate effect provenance + the reviewed capability lockfile.
|
|
16
|
+
nifra manifest emit [--sign <key-ref>] Emit the hash-verified route trust artifact after assurance.
|
|
17
|
+
nifra manifest diff <before> <after> Block promotion on contract/governance regressions.
|
|
14
18
|
nifra doctor [--json] [--auto-fix] Catch undeclared imported packages; auto-fix safe local versions.
|
|
15
19
|
```
|
|
16
20
|
|
|
21
|
+
## `nifra assure` — the route-enforcement gate
|
|
22
|
+
|
|
23
|
+
Create `nifra.assurance.ts` with a default `defineAssuranceConfig({ source, policy })` export, then run
|
|
24
|
+
`nifra assure` in CI. Official middleware publishes evidence at the same seam where it installs its
|
|
25
|
+
hooks; the gate classifies every reflected route with the first matching rule and exits non-zero for an
|
|
26
|
+
unclassified route, missing evidence, or forbidden evidence. Evaluation is startup/CI-only and adds no
|
|
27
|
+
request-path overhead. Use `--json` for the complete per-route report or `--config` for another file.
|
|
28
|
+
|
|
29
|
+
## `nifra manifest` — the deploy trust artifact
|
|
30
|
+
|
|
31
|
+
Add optional `manifest: { path, signer }` settings to `nifra.assurance.ts`, then run
|
|
32
|
+
`nifra manifest emit`. Emission refuses failing route or capability assurance and joins the route
|
|
33
|
+
schemas, enforcement evidence, effect tokens, and field-level response classification into one
|
|
34
|
+
deterministic SHA-256 artifact. `--sign <key-ref>` asks the configured callback to produce a detached
|
|
35
|
+
Ed25519 sidecar, so the private key can stay inside KMS/HSM infrastructure.
|
|
36
|
+
|
|
37
|
+
At promotion time, `nifra manifest diff previous.json candidate.json` hash-verifies both files and exits
|
|
38
|
+
non-zero on a breaking API change, removed assurance, expanded effect, lost provenance coverage, or
|
|
39
|
+
increased data sensitivity. This is separate from the frontend asset `dist/manifest.json`.
|
|
40
|
+
|
|
17
41
|
## `nifra check` — the drift gate (run as "done")
|
|
18
42
|
|
|
19
43
|
`nifra check` makes nifra's anti-drift guarantees actually fire instead of relying on the agent to
|
|
@@ -66,6 +90,7 @@ an agent can act on the project, not just read about it. Core tools:
|
|
|
66
90
|
- **`nifra_test`** — run bounded `bun test` with structured output.
|
|
67
91
|
- **`nifra_check`** — run the drift gate and get the structured `{ ok, typecheck, diagnostics[] }`
|
|
68
92
|
result with suggestions, so the agent verifies its own work and fixes each diagnostic before finishing.
|
|
93
|
+
- **`nifra_assure`** — evaluate `nifra.assurance.ts` and return the complete per-route evidence report.
|
|
69
94
|
- **`nifra_doctor`** — catch imported packages missing from `package.json`; with `autoFix:true`, write
|
|
70
95
|
safe dependency entries when a version can be inferred locally and return exact `bun add` commands
|
|
71
96
|
for anything that needs a package-manager decision.
|
package/dist/assure.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** `nifra assure` — evaluate a project's reflected routes against `nifra.assurance.ts`. */
|
|
2
|
+
import { type AssuranceConfig, type AssuranceReport } from "@nifrajs/core/assurance";
|
|
3
|
+
export declare const DEFAULT_ASSURANCE_CONFIG = "nifra.assurance.ts";
|
|
4
|
+
export declare function loadAssuranceConfig(cwd: string, configPath?: string): Promise<AssuranceConfig>;
|
|
5
|
+
export declare function formatAssuranceReport(report: AssuranceReport): string;
|
|
6
|
+
export declare function collectAssuranceReport(cwd: string, configPath?: string): Promise<AssuranceReport>;
|
|
7
|
+
export declare function runAssurance(cwd: string, options?: {
|
|
8
|
+
readonly json?: boolean;
|
|
9
|
+
readonly config?: string;
|
|
10
|
+
}): Promise<boolean>;
|
|
11
|
+
//# sourceMappingURL=assure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assure.d.ts","sourceRoot":"","sources":["../src/assure.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAK3F,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,eAAe,EAErB,MAAM,yBAAyB,CAAA;AAEhC,eAAO,MAAM,wBAAwB,uBAAuB,CAAA;AAY5D,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,UAAU,SAA2B,GACpC,OAAO,CAAC,eAAe,CAAC,CAgB1B;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAYrE;AAED,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,MAAM,EACX,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CAe1B;AAED,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAClE,OAAO,CAAC,OAAO,CAAC,CAMlB"}
|
package/dist/assure.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/** `nifra assure` — evaluate a project's reflected routes against `nifra.assurance.ts`. */
|
|
2
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
3
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
4
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
5
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
return path;
|
|
9
|
+
};
|
|
10
|
+
import { existsSync } from "node:fs";
|
|
11
|
+
import { resolve } from "node:path";
|
|
12
|
+
import { pathToFileURL } from "node:url";
|
|
13
|
+
import { evaluateRouteAssurance, } from "@nifrajs/core/assurance";
|
|
14
|
+
export const DEFAULT_ASSURANCE_CONFIG = "nifra.assurance.ts";
|
|
15
|
+
function isConfig(value) {
|
|
16
|
+
if (typeof value !== "object" || value === null)
|
|
17
|
+
return false;
|
|
18
|
+
const candidate = value;
|
|
19
|
+
return (candidate.source !== undefined &&
|
|
20
|
+
typeof candidate.policy === "object" &&
|
|
21
|
+
candidate.policy !== null);
|
|
22
|
+
}
|
|
23
|
+
export async function loadAssuranceConfig(cwd, configPath = DEFAULT_ASSURANCE_CONFIG) {
|
|
24
|
+
const path = resolve(cwd, configPath);
|
|
25
|
+
if (!existsSync(path)) {
|
|
26
|
+
throw new Error(`[nifra] route assurance config not found: ${path} — create ${DEFAULT_ASSURANCE_CONFIG} with a default defineAssuranceConfig({ source, policy }) export.`);
|
|
27
|
+
}
|
|
28
|
+
const specifier = pathToFileURL(path);
|
|
29
|
+
specifier.searchParams.set("nifra-assurance", String(Date.now()));
|
|
30
|
+
const loaded = (await import(__rewriteRelativeImportExtension(specifier.href)));
|
|
31
|
+
if (!isConfig(loaded.default)) {
|
|
32
|
+
throw new Error(`[nifra] ${path} must default-export defineAssuranceConfig({ source, policy }).`);
|
|
33
|
+
}
|
|
34
|
+
return loaded.default;
|
|
35
|
+
}
|
|
36
|
+
export function formatAssuranceReport(report) {
|
|
37
|
+
if (report.ok) {
|
|
38
|
+
const capability = report.capabilities
|
|
39
|
+
? ` Capability assurance covered ${report.capabilities.routes.length} route${report.capabilities.routes.length === 1 ? "" : "s"}.`
|
|
40
|
+
: "";
|
|
41
|
+
return `✓ route assurance: ${report.routes.length} route${report.routes.length === 1 ? "" : "s"} classified; all required evidence is present.${capability}`;
|
|
42
|
+
}
|
|
43
|
+
const messages = [
|
|
44
|
+
...report.findings.map((finding) => finding.message),
|
|
45
|
+
...(report.capabilities?.findings.map((finding) => finding.message) ?? []),
|
|
46
|
+
];
|
|
47
|
+
return `${messages.map((message) => `✖ ${message}`).join("\n")}\n\n${messages.length} assurance failure${messages.length === 1 ? "" : "s"} across ${report.routes.length} route${report.routes.length === 1 ? "" : "s"}.`;
|
|
48
|
+
}
|
|
49
|
+
export async function collectAssuranceReport(cwd, configPath) {
|
|
50
|
+
const config = await loadAssuranceConfig(cwd, configPath);
|
|
51
|
+
const routeReport = evaluateRouteAssurance(config.source, config.policy);
|
|
52
|
+
if (config.capabilities === undefined)
|
|
53
|
+
return routeReport;
|
|
54
|
+
const { collectCapabilityProjectReport } = await import("./capabilities-tool.js");
|
|
55
|
+
const capabilityProject = await collectCapabilityProjectReport(cwd, config.source, config.capabilities);
|
|
56
|
+
return Object.freeze({
|
|
57
|
+
...routeReport,
|
|
58
|
+
ok: routeReport.ok && capabilityProject.report.ok,
|
|
59
|
+
capabilities: capabilityProject.report,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
export async function runAssurance(cwd, options = {}) {
|
|
63
|
+
const report = await collectAssuranceReport(cwd, options.config);
|
|
64
|
+
console.log(options.json === true ? JSON.stringify(report, null, 2) : formatAssuranceReport(report));
|
|
65
|
+
return report.ok;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=assure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assure.js","sourceRoot":"","sources":["../src/assure.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** Static effect provenance, capability lockfile, and CLI commands. */
|
|
2
|
+
import { type CapabilityAssuranceReport, type CapabilityPolicy, type CapabilitySnapshot } from "@nifrajs/core/capabilities";
|
|
3
|
+
/** Value-bearing import edges relevant to effect provenance, in source order. */
|
|
4
|
+
export declare function scanEffectImports(content: string): string[];
|
|
5
|
+
export interface CapabilityImportViolation {
|
|
6
|
+
readonly method: string;
|
|
7
|
+
readonly path: string;
|
|
8
|
+
readonly module: string;
|
|
9
|
+
readonly specifier: string;
|
|
10
|
+
readonly reason: string;
|
|
11
|
+
readonly chain: readonly string[];
|
|
12
|
+
}
|
|
13
|
+
export interface CapabilityProjectReport {
|
|
14
|
+
readonly report: CapabilityAssuranceReport;
|
|
15
|
+
readonly violations: readonly CapabilityImportViolation[];
|
|
16
|
+
}
|
|
17
|
+
/** Build coverage-qualified static evidence for every reflected route. */
|
|
18
|
+
export declare function collectCapabilityProjectReport(cwd: string, source: unknown, policyInput: CapabilityPolicy): Promise<CapabilityProjectReport>;
|
|
19
|
+
export declare function parseCapabilityLockfile(content: string, sourcePath: string): CapabilitySnapshot;
|
|
20
|
+
/** Exact lockfile drift. Human approval is supplied by reviewing the checked-in lockfile change. */
|
|
21
|
+
export declare function diffCapabilitySnapshots(before: CapabilitySnapshot, after: CapabilitySnapshot): readonly string[];
|
|
22
|
+
/** Write a lockfile only from a clean, fully-covered project report. */
|
|
23
|
+
export declare function runCapabilitySnapshot(cwd: string, options?: {
|
|
24
|
+
readonly config?: string;
|
|
25
|
+
readonly out?: string;
|
|
26
|
+
}): Promise<boolean>;
|
|
27
|
+
/** Fail on assurance violations or any drift from the checked-in capability lockfile. */
|
|
28
|
+
export declare function runCapabilityCheck(cwd: string, options?: {
|
|
29
|
+
readonly config?: string;
|
|
30
|
+
readonly lockfile?: string;
|
|
31
|
+
readonly json?: boolean;
|
|
32
|
+
}): Promise<boolean>;
|
|
33
|
+
//# sourceMappingURL=capabilities-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities-tool.d.ts","sourceRoot":"","sources":["../src/capabilities-tool.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAKvE,OAAO,EACL,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EAMxB,MAAM,4BAA4B,CAAA;AASnC,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAmB3D;AAQD,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAClC;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,MAAM,EAAE,yBAAyB,CAAA;IAC1C,QAAQ,CAAC,UAAU,EAAE,SAAS,yBAAyB,EAAE,CAAA;CAC1D;AAoHD,0EAA0E;AAC1E,wBAAsB,8BAA8B,CAClD,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,OAAO,EACf,WAAW,EAAE,gBAAgB,GAC5B,OAAO,CAAC,uBAAuB,CAAC,CA8DlC;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,kBAAkB,CA6C/F;AAeD,oGAAoG;AACpG,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,kBAAkB,EAC1B,KAAK,EAAE,kBAAkB,GACxB,SAAS,MAAM,EAAE,CAsBnB;AAuBD,wEAAwE;AACxE,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAChE,OAAO,CAAC,OAAO,CAAC,CAWlB;AAED,yFAAyF;AACzF,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,GAC9F,OAAO,CAAC,OAAO,CAAC,CA2BlB"}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/** Static effect provenance, capability lockfile, and CLI commands. */
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
|
|
4
|
+
import { matchesAssuranceSelector } from "@nifrajs/core/assurance";
|
|
5
|
+
import { defineCapabilityPolicy, evaluateCapabilityAssurance, snapshotCapabilities, validCapabilityId, } from "@nifrajs/core/capabilities";
|
|
6
|
+
import { reflectRoutes } from "@nifrajs/core/reflection";
|
|
7
|
+
import { loadAssuranceConfig } from "./assure.js";
|
|
8
|
+
import { scanStaticRouteText, stripComments, walkSource } from "./check.js";
|
|
9
|
+
const EFFECT_IMPORT = /\bimport\s+(?!type\b)(?:[^'"();]*?\bfrom\s+)?["']([^"']+)["']|\bimport\s*\(\s*["']([^"']+)["']\s*\)|\brequire\s*\(\s*["']([^"']+)["']\s*\)|\bexport\s+(?!type\b)[^'";]*?\bfrom\s*["']([^"']+)["']/g;
|
|
10
|
+
const TEMPLATE_EFFECT_IMPORT = /\b(?:import|require)\s*\(\s*`([^`$]*(?:\\.[^`$]*)*)`\s*\)/g;
|
|
11
|
+
/** Value-bearing import edges relevant to effect provenance, in source order. */
|
|
12
|
+
export function scanEffectImports(content) {
|
|
13
|
+
const code = stripComments(content);
|
|
14
|
+
const found = [];
|
|
15
|
+
const re = new RegExp(EFFECT_IMPORT.source, EFFECT_IMPORT.flags);
|
|
16
|
+
for (let match = re.exec(code); match !== null; match = re.exec(code)) {
|
|
17
|
+
const specifier = match[1] ?? match[2] ?? match[3] ?? match[4];
|
|
18
|
+
if (specifier !== undefined)
|
|
19
|
+
found.push({ index: match.index, specifier });
|
|
20
|
+
}
|
|
21
|
+
// `stripComments` intentionally blanks template contents for other lints. Recover only a
|
|
22
|
+
// no-substitution template used directly as import()/require() input, and verify the keyword itself
|
|
23
|
+
// survived stripping so a commented/doc-template example cannot become provenance.
|
|
24
|
+
const templates = new RegExp(TEMPLATE_EFFECT_IMPORT.source, TEMPLATE_EFFECT_IMPORT.flags);
|
|
25
|
+
for (let match = templates.exec(content); match !== null; match = templates.exec(content)) {
|
|
26
|
+
if (code.slice(match.index, match.index + 6).trim() === "")
|
|
27
|
+
continue;
|
|
28
|
+
const specifier = match[1];
|
|
29
|
+
if (specifier !== undefined)
|
|
30
|
+
found.push({ index: match.index, specifier: specifier.replace(/\\`/g, "`") });
|
|
31
|
+
}
|
|
32
|
+
return found.sort((a, b) => a.index - b.index).map((item) => item.specifier);
|
|
33
|
+
}
|
|
34
|
+
function specifierMatches(pattern, specifier) {
|
|
35
|
+
return pattern.endsWith("/*") ? specifier.startsWith(pattern.slice(0, -1)) : specifier === pattern;
|
|
36
|
+
}
|
|
37
|
+
const routeKey = (method, path) => `${method.toUpperCase()}\n${path}`;
|
|
38
|
+
function resolveLocalModule(cwd, from, specifier, sources) {
|
|
39
|
+
if (specifier.startsWith("./") || specifier.startsWith("../")) {
|
|
40
|
+
const base = join(dirname(from), specifier).replaceAll("\\", "/");
|
|
41
|
+
const candidates = extname(base)
|
|
42
|
+
? [base]
|
|
43
|
+
: [
|
|
44
|
+
base,
|
|
45
|
+
`${base}.ts`,
|
|
46
|
+
`${base}.tsx`,
|
|
47
|
+
`${base}.mts`,
|
|
48
|
+
`${base}.cts`,
|
|
49
|
+
`${base}/index.ts`,
|
|
50
|
+
`${base}/index.tsx`,
|
|
51
|
+
];
|
|
52
|
+
const found = candidates.find((candidate) => sources.has(candidate));
|
|
53
|
+
if (found !== undefined)
|
|
54
|
+
return found;
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const fromAbsolute = join(cwd, from);
|
|
58
|
+
const resolved = Bun.resolveSync(specifier, dirname(fromAbsolute));
|
|
59
|
+
const rel = relative(cwd, resolved).replaceAll("\\", "/");
|
|
60
|
+
if (rel.startsWith("../") || isAbsolute(rel))
|
|
61
|
+
return undefined;
|
|
62
|
+
if (!sources.has(rel) && existsSync(resolved)) {
|
|
63
|
+
try {
|
|
64
|
+
sources.set(rel, readFileSync(resolved, "utf8"));
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return sources.has(rel) ? rel : undefined;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function readSources(cwd) {
|
|
77
|
+
const sources = new Map();
|
|
78
|
+
await walkSource(cwd, (rel, content) => sources.set(rel.replaceAll("\\", "/"), content));
|
|
79
|
+
return sources;
|
|
80
|
+
}
|
|
81
|
+
async function walkRouteModules(cwd, modules, method, path, policy, sources) {
|
|
82
|
+
const queue = modules.map((module) => ({ module, chain: [module] }));
|
|
83
|
+
const visited = new Set();
|
|
84
|
+
const evidence = [];
|
|
85
|
+
const violations = [];
|
|
86
|
+
let covered = false;
|
|
87
|
+
while (queue.length > 0 && visited.size < 500) {
|
|
88
|
+
const current = queue.shift();
|
|
89
|
+
if (current === undefined || visited.has(current.module) || current.chain.length > 16)
|
|
90
|
+
continue;
|
|
91
|
+
visited.add(current.module);
|
|
92
|
+
let content = sources.get(current.module);
|
|
93
|
+
if (content === undefined) {
|
|
94
|
+
try {
|
|
95
|
+
content = await Bun.file(join(cwd, current.module)).text();
|
|
96
|
+
sources.set(current.module, content);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
covered = true;
|
|
103
|
+
for (const specifier of scanEffectImports(content)) {
|
|
104
|
+
let approvedEffectBoundary = false;
|
|
105
|
+
for (const rule of policy.provenance.imports) {
|
|
106
|
+
if (!specifierMatches(rule.specifier, specifier))
|
|
107
|
+
continue;
|
|
108
|
+
approvedEffectBoundary = true;
|
|
109
|
+
for (const id of rule.capabilities) {
|
|
110
|
+
if (!evidence.some((item) => item.id === id && item.source === specifier)) {
|
|
111
|
+
evidence.push({ id, kind: "static", source: specifier });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
for (const rule of policy.provenance.forbiddenImports) {
|
|
116
|
+
if (!specifierMatches(rule.specifier, specifier))
|
|
117
|
+
continue;
|
|
118
|
+
violations.push({
|
|
119
|
+
method,
|
|
120
|
+
path,
|
|
121
|
+
module: current.module,
|
|
122
|
+
specifier,
|
|
123
|
+
reason: rule.reason,
|
|
124
|
+
chain: Object.freeze([...current.chain, specifier]),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
// An explicitly mapped import is the owned effect seam. Its implementation may legitimately
|
|
128
|
+
// import the raw provider; assurance governs whether routes can reach the seam, not its internals.
|
|
129
|
+
if (approvedEffectBoundary)
|
|
130
|
+
continue;
|
|
131
|
+
const local = resolveLocalModule(cwd, current.module, specifier, sources);
|
|
132
|
+
if (local !== undefined && !visited.has(local)) {
|
|
133
|
+
queue.push({ module: local, chain: [...current.chain, specifier] });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return { covered, evidence, violations };
|
|
138
|
+
}
|
|
139
|
+
/** Build coverage-qualified static evidence for every reflected route. */
|
|
140
|
+
export async function collectCapabilityProjectReport(cwd, source, policyInput) {
|
|
141
|
+
const policy = defineCapabilityPolicy(policyInput);
|
|
142
|
+
const sources = await readSources(cwd);
|
|
143
|
+
const automatic = new Map();
|
|
144
|
+
for (const [file, content] of sources) {
|
|
145
|
+
for (const route of scanStaticRouteText(file, content)) {
|
|
146
|
+
const modules = automatic.get(routeKey(route.method, route.path)) ?? new Set();
|
|
147
|
+
modules.add(file);
|
|
148
|
+
automatic.set(routeKey(route.method, route.path), modules);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const evidenceRoutes = [];
|
|
152
|
+
const violations = [];
|
|
153
|
+
for (const route of reflectRoutes(source)) {
|
|
154
|
+
const modules = new Set(automatic.get(routeKey(route.method, route.path)) ?? []);
|
|
155
|
+
for (const association of policy.provenance.routeModules ?? []) {
|
|
156
|
+
if (matchesAssuranceSelector(route, {
|
|
157
|
+
...(association.match.methods !== undefined
|
|
158
|
+
? { methods: association.match.methods }
|
|
159
|
+
: {}),
|
|
160
|
+
...(association.match.paths !== undefined ? { paths: association.match.paths } : {}),
|
|
161
|
+
})) {
|
|
162
|
+
for (const module of association.modules)
|
|
163
|
+
modules.add(module);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const walked = await walkRouteModules(cwd, [...modules], route.method, route.path, policy, sources);
|
|
167
|
+
evidenceRoutes.push({
|
|
168
|
+
method: route.method,
|
|
169
|
+
path: route.path,
|
|
170
|
+
covered: modules.size > 0 && walked.covered,
|
|
171
|
+
evidence: walked.evidence,
|
|
172
|
+
});
|
|
173
|
+
violations.push(...walked.violations);
|
|
174
|
+
}
|
|
175
|
+
const evaluated = evaluateCapabilityAssurance(source, policy, { routes: evidenceRoutes });
|
|
176
|
+
const report = violations.length === 0
|
|
177
|
+
? evaluated
|
|
178
|
+
: Object.freeze({
|
|
179
|
+
...evaluated,
|
|
180
|
+
ok: false,
|
|
181
|
+
findings: Object.freeze([
|
|
182
|
+
...evaluated.findings,
|
|
183
|
+
...violations.map((violation) => ({
|
|
184
|
+
code: "forbidden-effect-import",
|
|
185
|
+
method: violation.method,
|
|
186
|
+
path: violation.path,
|
|
187
|
+
message: `${violation.method} ${violation.path} reaches forbidden ${violation.specifier} via ${violation.chain.join(" → ")}: ${violation.reason}`,
|
|
188
|
+
})),
|
|
189
|
+
]),
|
|
190
|
+
});
|
|
191
|
+
return Object.freeze({ report, violations: Object.freeze(violations) });
|
|
192
|
+
}
|
|
193
|
+
export function parseCapabilityLockfile(content, sourcePath) {
|
|
194
|
+
let parsed;
|
|
195
|
+
try {
|
|
196
|
+
parsed = JSON.parse(content);
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
throw new Error(`[nifra] ${sourcePath} is not valid JSON`);
|
|
200
|
+
}
|
|
201
|
+
const candidate = parsed;
|
|
202
|
+
if (candidate === null ||
|
|
203
|
+
typeof candidate !== "object" ||
|
|
204
|
+
candidate.nifraCapabilities !== 1 ||
|
|
205
|
+
!Array.isArray(candidate.routes)) {
|
|
206
|
+
throw new Error(`[nifra] ${sourcePath} is not a nifra capability lockfile — expected { "nifraCapabilities": 1, "routes": [...] }`);
|
|
207
|
+
}
|
|
208
|
+
for (const route of candidate.routes) {
|
|
209
|
+
if (typeof route !== "object" ||
|
|
210
|
+
route === null ||
|
|
211
|
+
typeof route.method !== "string" ||
|
|
212
|
+
typeof route.path !== "string" ||
|
|
213
|
+
!Array.isArray(route.declared) ||
|
|
214
|
+
!Array.isArray(route.evidenced) ||
|
|
215
|
+
!Array.isArray(route.unproven)) {
|
|
216
|
+
throw new Error(`[nifra] ${sourcePath} contains an invalid capability route`);
|
|
217
|
+
}
|
|
218
|
+
for (const [label, values] of [
|
|
219
|
+
["declared", route.declared],
|
|
220
|
+
["evidenced", route.evidenced],
|
|
221
|
+
["unproven", route.unproven],
|
|
222
|
+
]) {
|
|
223
|
+
if (values.some((value) => typeof value !== "string" || !validCapabilityId(value)) ||
|
|
224
|
+
new Set(values).size !== values.length ||
|
|
225
|
+
[...values].sort().some((value, index) => value !== values[index])) {
|
|
226
|
+
throw new Error(`[nifra] ${sourcePath} has non-canonical ${label} capability tokens`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return candidate;
|
|
231
|
+
}
|
|
232
|
+
function routeSnapshotKey(route) {
|
|
233
|
+
return `${route.method}\n${route.path}`;
|
|
234
|
+
}
|
|
235
|
+
function listDelta(label, before, after) {
|
|
236
|
+
const added = after.filter((value) => !before.includes(value));
|
|
237
|
+
const removed = before.filter((value) => !after.includes(value));
|
|
238
|
+
return [
|
|
239
|
+
...(added.length > 0 ? [`${label} added ${added.join(", ")}`] : []),
|
|
240
|
+
...(removed.length > 0 ? [`${label} removed ${removed.join(", ")}`] : []),
|
|
241
|
+
];
|
|
242
|
+
}
|
|
243
|
+
/** Exact lockfile drift. Human approval is supplied by reviewing the checked-in lockfile change. */
|
|
244
|
+
export function diffCapabilitySnapshots(before, after) {
|
|
245
|
+
const previous = new Map(before.routes.map((route) => [routeSnapshotKey(route), route]));
|
|
246
|
+
const current = new Map(after.routes.map((route) => [routeSnapshotKey(route), route]));
|
|
247
|
+
const changes = [];
|
|
248
|
+
for (const [key, route] of current) {
|
|
249
|
+
const old = previous.get(key);
|
|
250
|
+
const prefix = `${route.method} ${route.path}`;
|
|
251
|
+
if (old === undefined) {
|
|
252
|
+
changes.push(`${prefix}: route added`);
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
for (const delta of listDelta("declared", old.declared, route.declared))
|
|
256
|
+
changes.push(`${prefix}: ${delta}`);
|
|
257
|
+
for (const delta of listDelta("evidenced", old.evidenced, route.evidenced))
|
|
258
|
+
changes.push(`${prefix}: ${delta}`);
|
|
259
|
+
for (const delta of listDelta("unproven", old.unproven, route.unproven))
|
|
260
|
+
changes.push(`${prefix}: ${delta}`);
|
|
261
|
+
}
|
|
262
|
+
for (const [key, route] of previous) {
|
|
263
|
+
if (!current.has(key))
|
|
264
|
+
changes.push(`${route.method} ${route.path}: route removed`);
|
|
265
|
+
}
|
|
266
|
+
return Object.freeze(changes);
|
|
267
|
+
}
|
|
268
|
+
async function currentProject(cwd, configPath) {
|
|
269
|
+
const config = await loadAssuranceConfig(cwd, configPath);
|
|
270
|
+
if (config.capabilities === undefined) {
|
|
271
|
+
throw new Error("[nifra] assurance config does not define capabilities");
|
|
272
|
+
}
|
|
273
|
+
return {
|
|
274
|
+
policy: config.capabilities,
|
|
275
|
+
project: await collectCapabilityProjectReport(cwd, config.source, config.capabilities),
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
function unsafeProject(project) {
|
|
279
|
+
return !project.report.ok || project.violations.length > 0;
|
|
280
|
+
}
|
|
281
|
+
/** Write a lockfile only from a clean, fully-covered project report. */
|
|
282
|
+
export async function runCapabilitySnapshot(cwd, options = {}) {
|
|
283
|
+
const { policy, project } = await currentProject(cwd, options.config);
|
|
284
|
+
if (unsafeProject(project)) {
|
|
285
|
+
console.error("[nifra] refusing to snapshot failing capability assurance");
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
const snapshot = snapshotCapabilities(project.report);
|
|
289
|
+
const path = resolve(cwd, options.out ?? policy.lockfile ?? "capabilities.lock.json");
|
|
290
|
+
await Bun.write(path, `${JSON.stringify(snapshot, null, 2)}\n`);
|
|
291
|
+
console.log(`[nifra] wrote capability lockfile to ${path}`);
|
|
292
|
+
return true;
|
|
293
|
+
}
|
|
294
|
+
/** Fail on assurance violations or any drift from the checked-in capability lockfile. */
|
|
295
|
+
export async function runCapabilityCheck(cwd, options = {}) {
|
|
296
|
+
const { policy, project } = await currentProject(cwd, options.config);
|
|
297
|
+
const path = resolve(cwd, options.lockfile ?? policy.lockfile ?? "capabilities.lock.json");
|
|
298
|
+
if (!existsSync(path))
|
|
299
|
+
throw new Error(`[nifra] capability lockfile not found: ${path}`);
|
|
300
|
+
const baseline = parseCapabilityLockfile(await Bun.file(path).text(), path);
|
|
301
|
+
const current = snapshotCapabilities(project.report);
|
|
302
|
+
const changes = diffCapabilitySnapshots(baseline, current);
|
|
303
|
+
const ok = !unsafeProject(project) && changes.length === 0;
|
|
304
|
+
if (options.json === true) {
|
|
305
|
+
console.log(JSON.stringify({ ok, report: project.report, violations: project.violations, changes }, null, 2));
|
|
306
|
+
}
|
|
307
|
+
else if (ok) {
|
|
308
|
+
console.log("✓ capability assurance and lockfile are current");
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
for (const finding of project.report.findings)
|
|
312
|
+
console.log(`✖ ${finding.message}`);
|
|
313
|
+
for (const violation of project.violations)
|
|
314
|
+
console.log(`✖ ${violation.method} ${violation.path}: ${violation.chain.join(" → ")} — ${violation.reason}`);
|
|
315
|
+
for (const change of changes)
|
|
316
|
+
console.log(`✖ capability lock drift: ${change}`);
|
|
317
|
+
}
|
|
318
|
+
return ok;
|
|
319
|
+
}
|
|
320
|
+
//# sourceMappingURL=capabilities-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities-tool.js","sourceRoot":"","sources":["../src/capabilities-tool.ts"],"names":[],"mappings":"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"}
|
package/dist/check.d.ts
CHANGED
|
@@ -121,7 +121,7 @@ export interface ManifestDriftFinding {
|
|
|
121
121
|
export declare function scanServerManifestDrift(cwd: string): Promise<ManifestDriftFinding[]>;
|
|
122
122
|
/** A single machine-readable check failure — the unit an agent (or CI) acts on. */
|
|
123
123
|
export interface CheckDiagnostic {
|
|
124
|
-
readonly rule: "typecheck" | "typed-client" | "untyped-client" | "server-only-import" | "response-route" | "undeclared-dependency" | "server-manifest-drift";
|
|
124
|
+
readonly rule: "typecheck" | "typed-client" | "untyped-client" | "server-only-import" | "response-route" | "undeclared-dependency" | "server-manifest-drift" | "manifest-drift" | "capability-assurance" | "capability-config";
|
|
125
125
|
/** `error` fails the gate (a real contract break); `warning` is advisory — surfaced to the agent but
|
|
126
126
|
* does NOT fail `nifra check`, for patterns that are sometimes intentional (a route returning a raw
|
|
127
127
|
* `Response`, which silently drops the typed client to `data: never` but is valid for files/redirects). */
|
package/dist/check.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB;AACD,0FAA0F;AAC1F,MAAM,MAAM,YAAY,GAAG,aAAa,CAAA;AAExC;6GAC6G;AAC7G,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,oGAAoG;IACpG,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B;AAiCD,MAAM,WAAW,kBAAmB,SAAQ,aAAa;IACvD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"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"}
|