@nifrajs/cli 3.5.0 → 4.0.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 +42 -3
- package/dist/app-files.d.ts +11 -0
- package/dist/app-files.d.ts.map +1 -0
- package/dist/app-files.js +34 -0
- package/dist/app-files.js.map +1 -0
- package/dist/assure-hydration.d.ts +7 -1
- package/dist/assure-hydration.d.ts.map +1 -1
- package/dist/assure-hydration.js +128 -43
- package/dist/assure-hydration.js.map +1 -1
- package/dist/assure.d.ts.map +1 -1
- package/dist/assure.js +16 -2
- package/dist/assure.js.map +1 -1
- package/dist/capabilities-tool.d.ts +5 -1
- package/dist/capabilities-tool.d.ts.map +1 -1
- package/dist/capabilities-tool.js +32 -10
- package/dist/capabilities-tool.js.map +1 -1
- package/dist/cdn-check.d.ts +41 -0
- package/dist/cdn-check.d.ts.map +1 -0
- package/dist/cdn-check.js +207 -0
- package/dist/cdn-check.js.map +1 -0
- package/dist/check-diagnostics.d.ts +4 -0
- package/dist/check-diagnostics.d.ts.map +1 -1
- package/dist/check-diagnostics.js +13 -0
- package/dist/check-diagnostics.js.map +1 -1
- package/dist/check-scan.d.ts +49 -7
- package/dist/check-scan.d.ts.map +1 -1
- package/dist/check-scan.js +291 -62
- package/dist/check-scan.js.map +1 -1
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +99 -63
- package/dist/check.js.map +1 -1
- package/dist/cli.d.ts +42 -16
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +262 -82
- package/dist/cli.js.map +1 -1
- package/dist/command-catalog.d.ts +57 -5
- package/dist/command-catalog.d.ts.map +1 -1
- package/dist/command-catalog.js +270 -26
- package/dist/command-catalog.js.map +1 -1
- package/dist/config-target.d.ts +8 -0
- package/dist/config-target.d.ts.map +1 -0
- package/dist/config-target.js +45 -0
- package/dist/config-target.js.map +1 -0
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js +52 -13
- package/dist/contracts.js.map +1 -1
- package/dist/db-audit.d.ts +37 -0
- package/dist/db-audit.d.ts.map +1 -0
- package/dist/db-audit.js +99 -0
- package/dist/db-audit.js.map +1 -0
- package/dist/db-child.d.ts +64 -0
- package/dist/db-child.d.ts.map +1 -0
- package/dist/db-child.js +213 -0
- package/dist/db-child.js.map +1 -0
- package/dist/db-config.d.ts +60 -0
- package/dist/db-config.d.ts.map +1 -0
- package/dist/db-config.js +176 -0
- package/dist/db-config.js.map +1 -0
- package/dist/db-tool.d.ts +84 -0
- package/dist/db-tool.d.ts.map +1 -0
- package/dist/db-tool.js +537 -0
- package/dist/db-tool.js.map +1 -0
- package/dist/dev-bun-config.d.ts +20 -13
- package/dist/dev-bun-config.d.ts.map +1 -1
- package/dist/dev-bun-config.js +98 -41
- package/dist/dev-bun-config.js.map +1 -1
- package/dist/dev-feed-tool.d.ts +106 -0
- package/dist/dev-feed-tool.d.ts.map +1 -0
- package/dist/dev-feed-tool.js +713 -0
- package/dist/dev-feed-tool.js.map +1 -0
- package/dist/dev-server-client.d.ts +67 -0
- package/dist/dev-server-client.d.ts.map +1 -0
- package/dist/dev-server-client.js +195 -0
- package/dist/dev-server-client.js.map +1 -0
- package/dist/diff-tool.d.ts +3 -3
- package/dist/diff-tool.d.ts.map +1 -1
- package/dist/diff-tool.js +6 -5
- package/dist/diff-tool.js.map +1 -1
- package/dist/docs-search.d.ts.map +1 -1
- package/dist/docs-search.js +12 -4
- package/dist/docs-search.js.map +1 -1
- package/dist/doctor.d.ts +17 -0
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +76 -15
- package/dist/doctor.js.map +1 -1
- package/dist/env-file.d.ts +15 -0
- package/dist/env-file.d.ts.map +1 -1
- package/dist/env-file.js +73 -1
- package/dist/env-file.js.map +1 -1
- package/dist/fix-recipes.d.ts.map +1 -1
- package/dist/fix-recipes.js +41 -21
- package/dist/fix-recipes.js.map +1 -1
- package/dist/frontend-guidance.js +5 -5
- package/dist/frontend-guidance.js.map +1 -1
- package/dist/i18n-check.d.ts +16 -0
- package/dist/i18n-check.d.ts.map +1 -0
- package/dist/i18n-check.js +154 -0
- package/dist/i18n-check.js.map +1 -0
- package/dist/init-agents.d.ts +49 -13
- package/dist/init-agents.d.ts.map +1 -1
- package/dist/init-agents.js +239 -34
- package/dist/init-agents.js.map +1 -1
- package/dist/internal/code-unit-order.d.ts +4 -0
- package/dist/internal/code-unit-order.d.ts.map +1 -0
- package/dist/internal/code-unit-order.js +6 -0
- package/dist/internal/code-unit-order.js.map +1 -0
- package/dist/internal/script-kind.d.ts +7 -0
- package/dist/internal/script-kind.d.ts.map +1 -0
- package/dist/internal/script-kind.js +12 -0
- package/dist/internal/script-kind.js.map +1 -0
- package/dist/internal/source-facts.d.ts +5 -0
- package/dist/internal/source-facts.d.ts.map +1 -1
- package/dist/internal/source-facts.js +61 -5
- package/dist/internal/source-facts.js.map +1 -1
- package/dist/internal/typescript-import.d.ts +49 -24
- package/dist/internal/typescript-import.d.ts.map +1 -1
- package/dist/internal/typescript-import.js +507 -67
- package/dist/internal/typescript-import.js.map +1 -1
- package/dist/introspect.d.ts +5 -1
- package/dist/introspect.d.ts.map +1 -1
- package/dist/introspect.js +92 -27
- package/dist/introspect.js.map +1 -1
- package/dist/learn.js +3 -3
- package/dist/learn.js.map +1 -1
- package/dist/levels-tool.d.ts +10 -0
- package/dist/levels-tool.d.ts.map +1 -1
- package/dist/levels-tool.js +33 -3
- package/dist/levels-tool.js.map +1 -1
- package/dist/load.d.ts +67 -17
- package/dist/load.d.ts.map +1 -1
- package/dist/load.js +78 -18
- package/dist/load.js.map +1 -1
- package/dist/manifest-tool.d.ts.map +1 -1
- package/dist/manifest-tool.js +3 -2
- package/dist/manifest-tool.js.map +1 -1
- package/dist/mcp-app-tool.d.ts.map +1 -1
- package/dist/mcp-app-tool.js +2 -0
- package/dist/mcp-app-tool.js.map +1 -1
- package/dist/mcp-context.js +1 -1
- package/dist/mcp-context.js.map +1 -1
- package/dist/mcp-delegate.d.ts +57 -0
- package/dist/mcp-delegate.d.ts.map +1 -0
- package/dist/mcp-delegate.js +130 -0
- package/dist/mcp-delegate.js.map +1 -0
- package/dist/mcp-docs-tools.d.ts.map +1 -1
- package/dist/mcp-docs-tools.js +23 -5
- package/dist/mcp-docs-tools.js.map +1 -1
- package/dist/mcp-exec.d.ts +2 -0
- package/dist/mcp-exec.d.ts.map +1 -1
- package/dist/mcp-exec.js +132 -108
- package/dist/mcp-exec.js.map +1 -1
- package/dist/mcp-http.d.ts.map +1 -1
- package/dist/mcp-http.js +17 -5
- package/dist/mcp-http.js.map +1 -1
- package/dist/mcp-io.d.ts +14 -0
- package/dist/mcp-io.d.ts.map +1 -1
- package/dist/mcp-io.js +45 -0
- package/dist/mcp-io.js.map +1 -1
- package/dist/mcp-isolate.d.ts +48 -0
- package/dist/mcp-isolate.d.ts.map +1 -0
- package/dist/mcp-isolate.js +222 -0
- package/dist/mcp-isolate.js.map +1 -0
- package/dist/mcp-project-child.d.ts +74 -0
- package/dist/mcp-project-child.d.ts.map +1 -0
- package/dist/mcp-project-child.js +130 -0
- package/dist/mcp-project-child.js.map +1 -0
- package/dist/mcp-render.js +2 -2
- package/dist/mcp-render.js.map +1 -1
- package/dist/mcp-root.d.ts +37 -9
- package/dist/mcp-root.d.ts.map +1 -1
- package/dist/mcp-root.js +110 -23
- package/dist/mcp-root.js.map +1 -1
- package/dist/mcp-run.d.ts +18 -1
- package/dist/mcp-run.d.ts.map +1 -1
- package/dist/mcp-run.js +82 -9
- package/dist/mcp-run.js.map +1 -1
- package/dist/mcp-ws.js +4 -1
- package/dist/mcp-ws.js.map +1 -1
- package/dist/mcp.d.ts +16 -3
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +81 -53
- package/dist/mcp.js.map +1 -1
- package/dist/migrate-layout.d.ts +44 -0
- package/dist/migrate-layout.d.ts.map +1 -0
- package/dist/migrate-layout.js +982 -0
- package/dist/migrate-layout.js.map +1 -0
- package/dist/openapi-tool.d.ts +2 -2
- package/dist/openapi-tool.d.ts.map +1 -1
- package/dist/openapi-tool.js.map +1 -1
- package/dist/openapi-types.d.ts +2 -1
- package/dist/openapi-types.d.ts.map +1 -1
- package/dist/openapi-types.js +240 -12
- package/dist/openapi-types.js.map +1 -1
- package/dist/pipeline-report.d.ts +3 -2
- package/dist/pipeline-report.d.ts.map +1 -1
- package/dist/pipeline-report.js +19 -16
- package/dist/pipeline-report.js.map +1 -1
- package/dist/port.d.ts +5 -4
- package/dist/port.d.ts.map +1 -1
- package/dist/port.js +46 -29
- package/dist/port.js.map +1 -1
- package/dist/project-facts.d.ts +5 -0
- package/dist/project-facts.d.ts.map +1 -1
- package/dist/project-facts.js.map +1 -1
- package/dist/recipes/4.0.0.d.ts +9 -0
- package/dist/recipes/4.0.0.d.ts.map +1 -0
- package/dist/recipes/4.0.0.js +34 -0
- package/dist/recipes/4.0.0.js.map +1 -0
- package/dist/recipes/index.d.ts.map +1 -1
- package/dist/recipes/index.js +2 -0
- package/dist/recipes/index.js.map +1 -1
- package/dist/release-verification.d.ts +11 -1
- package/dist/release-verification.d.ts.map +1 -1
- package/dist/release-verification.js +47 -4
- package/dist/release-verification.js.map +1 -1
- package/dist/review.d.ts.map +1 -1
- package/dist/review.js +12 -8
- package/dist/review.js.map +1 -1
- package/dist/route-types.d.ts +28 -0
- package/dist/route-types.d.ts.map +1 -0
- package/dist/route-types.js +106 -0
- package/dist/route-types.js.map +1 -0
- package/dist/rules/codes.d.ts +9 -0
- package/dist/rules/codes.d.ts.map +1 -1
- package/dist/rules/codes.js +9 -0
- package/dist/rules/codes.js.map +1 -1
- package/dist/rules/data-guard.d.ts +12 -0
- package/dist/rules/data-guard.d.ts.map +1 -0
- package/dist/rules/data-guard.js +213 -0
- package/dist/rules/data-guard.js.map +1 -0
- package/dist/rules/index.d.ts +3 -0
- package/dist/rules/index.d.ts.map +1 -1
- package/dist/rules/index.js +17 -5
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/islands.d.ts.map +1 -1
- package/dist/rules/islands.js +7 -4
- package/dist/rules/islands.js.map +1 -1
- package/dist/rules/legacy.d.ts.map +1 -1
- package/dist/rules/legacy.js +71 -38
- package/dist/rules/legacy.js.map +1 -1
- package/dist/rules/nano.d.ts.map +1 -1
- package/dist/rules/nano.js +15 -6
- package/dist/rules/nano.js.map +1 -1
- package/dist/rules/pages.d.ts +15 -0
- package/dist/rules/pages.d.ts.map +1 -0
- package/dist/rules/pages.js +88 -0
- package/dist/rules/pages.js.map +1 -0
- package/dist/rules/routes.d.ts +11 -0
- package/dist/rules/routes.d.ts.map +1 -1
- package/dist/rules/routes.js +180 -2
- package/dist/rules/routes.js.map +1 -1
- package/dist/rules/secrets.d.ts +10 -0
- package/dist/rules/secrets.d.ts.map +1 -0
- package/dist/rules/secrets.js +169 -0
- package/dist/rules/secrets.js.map +1 -0
- package/dist/rules/security.d.ts +7 -0
- package/dist/rules/security.d.ts.map +1 -1
- package/dist/rules/security.js +171 -65
- package/dist/rules/security.js.map +1 -1
- package/dist/rules/typescript.d.ts +16 -0
- package/dist/rules/typescript.d.ts.map +1 -0
- package/dist/rules/typescript.js +59 -0
- package/dist/rules/typescript.js.map +1 -0
- package/dist/rules/zones.d.ts +17 -0
- package/dist/rules/zones.d.ts.map +1 -0
- package/dist/rules/zones.js +174 -0
- package/dist/rules/zones.js.map +1 -0
- package/dist/scaffold.d.ts +25 -12
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +132 -87
- package/dist/scaffold.js.map +1 -1
- package/dist/sdk.d.ts +17 -3
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +941 -153
- package/dist/sdk.js.map +1 -1
- package/dist/search-terms.d.ts +2 -0
- package/dist/search-terms.d.ts.map +1 -1
- package/dist/search-terms.js +23 -8
- package/dist/search-terms.js.map +1 -1
- package/dist/smoke.d.ts +79 -0
- package/dist/smoke.d.ts.map +1 -0
- package/dist/smoke.js +494 -0
- package/dist/smoke.js.map +1 -0
- package/dist/sync-manifest.d.ts.map +1 -1
- package/dist/sync-manifest.js +2 -1
- package/dist/sync-manifest.js.map +1 -1
- package/dist/sync-routes.d.ts +4 -3
- package/dist/sync-routes.d.ts.map +1 -1
- package/dist/sync-routes.js +4 -3
- package/dist/sync-routes.js.map +1 -1
- package/dist/test-tool.d.ts.map +1 -1
- package/dist/test-tool.js +30 -11
- package/dist/test-tool.js.map +1 -1
- package/dist/types-search.d.ts.map +1 -1
- package/dist/types-search.js +11 -5
- package/dist/types-search.js.map +1 -1
- package/dist/upgrade.d.ts +36 -6
- package/dist/upgrade.d.ts.map +1 -1
- package/dist/upgrade.js +167 -29
- package/dist/upgrade.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/verification.d.ts.map +1 -1
- package/dist/verification.js +45 -12
- package/dist/verification.js.map +1 -1
- package/dist/web-app-options.d.ts +19 -0
- package/dist/web-app-options.d.ts.map +1 -0
- package/dist/web-app-options.js +49 -0
- package/dist/web-app-options.js.map +1 -0
- package/dist/work-graph.d.ts.map +1 -1
- package/dist/work-graph.js +29 -13
- package/dist/work-graph.js.map +1 -1
- package/docs/examples.json +185 -29
- package/docs/llms-full.txt +3807 -580
- package/docs/types.json +14229 -10939
- package/package.json +19 -12
- package/src/app-files.ts +40 -0
- package/src/assure-hydration.ts +139 -46
- package/src/assure.ts +17 -2
- package/src/capabilities-tool.ts +35 -9
- package/src/cdn-check.ts +268 -0
- package/src/check-diagnostics.ts +17 -0
- package/src/check-scan.ts +358 -63
- package/src/check.ts +97 -62
- package/src/cli.ts +296 -87
- package/src/command-catalog.ts +374 -38
- package/src/config-target.ts +47 -0
- package/src/contracts.ts +54 -12
- package/src/db-audit.ts +128 -0
- package/src/db-child.ts +285 -0
- package/src/db-config.ts +224 -0
- package/src/db-tool.ts +690 -0
- package/src/dev-bun-config.ts +116 -40
- package/src/dev-feed-tool.ts +912 -0
- package/src/dev-server-client.ts +267 -0
- package/src/diff-tool.ts +6 -5
- package/src/docs-search.ts +10 -3
- package/src/doctor.ts +98 -15
- package/src/env-file.ts +78 -1
- package/src/fix-recipes.ts +44 -31
- package/src/frontend-guidance.ts +5 -5
- package/src/i18n-check.ts +179 -0
- package/src/init-agents.ts +301 -38
- package/src/internal/code-unit-order.ts +5 -0
- package/src/internal/script-kind.ts +11 -0
- package/src/internal/source-facts.ts +96 -22
- package/src/internal/typescript-import.ts +663 -68
- package/src/introspect.ts +90 -27
- package/src/learn.ts +3 -3
- package/src/levels-tool.ts +47 -2
- package/src/load.ts +140 -33
- package/src/manifest-tool.ts +3 -2
- package/src/mcp-app-tool.ts +2 -0
- package/src/mcp-context.ts +1 -1
- package/src/mcp-delegate.ts +162 -0
- package/src/mcp-docs-tools.ts +23 -5
- package/src/mcp-exec.ts +160 -132
- package/src/mcp-http.ts +19 -5
- package/src/mcp-io.ts +57 -0
- package/src/mcp-isolate.ts +287 -0
- package/src/mcp-project-child.ts +182 -0
- package/src/mcp-render.ts +2 -2
- package/src/mcp-root.ts +117 -22
- package/src/mcp-run.ts +104 -10
- package/src/mcp-ws.ts +4 -1
- package/src/mcp.ts +106 -64
- package/src/migrate-layout.ts +1121 -0
- package/src/openapi-tool.ts +7 -3
- package/src/openapi-types.ts +315 -13
- package/src/pipeline-report.ts +22 -18
- package/src/port.ts +53 -30
- package/src/project-facts.ts +5 -0
- package/src/recipes/4.0.0.ts +35 -0
- package/src/recipes/index.ts +2 -0
- package/src/release-verification.ts +74 -5
- package/src/review.ts +13 -8
- package/src/route-types.ts +133 -0
- package/src/rules/codes.ts +9 -0
- package/src/rules/data-guard.ts +230 -0
- package/src/rules/index.ts +18 -5
- package/src/rules/islands.ts +12 -4
- package/src/rules/legacy.ts +71 -39
- package/src/rules/nano.ts +18 -6
- package/src/rules/pages.ts +99 -0
- package/src/rules/routes.ts +181 -2
- package/src/rules/secrets.ts +174 -0
- package/src/rules/security.ts +198 -70
- package/src/rules/typescript.ts +77 -0
- package/src/rules/zones.ts +195 -0
- package/src/scaffold.ts +147 -95
- package/src/sdk.ts +1215 -158
- package/src/search-terms.ts +24 -7
- package/src/smoke.ts +607 -0
- package/src/sync-manifest.ts +2 -1
- package/src/sync-routes.ts +4 -3
- package/src/test-tool.ts +32 -11
- package/src/types-search.ts +11 -4
- package/src/upgrade.ts +205 -25
- package/src/verification-plan.ts +13 -0
- package/src/verification.ts +50 -12
- package/src/web-app-options.ts +57 -0
- package/src/work-graph.ts +27 -13
package/dist/command-catalog.js
CHANGED
|
@@ -7,8 +7,12 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { resolve } from "node:path";
|
|
9
9
|
import { formatAssuranceReport } from "./assure.js";
|
|
10
|
+
import { cdnCheckSpec } from "./cdn-check.js";
|
|
10
11
|
import { renderCheckReport } from "./check.js";
|
|
12
|
+
import { dbAuditSpec, dbQuerySpec, dbRoleSpec, dbSchemaSpec } from "./db-tool.js";
|
|
13
|
+
import { errorsSpec, logsSpec } from "./dev-feed-tool.js";
|
|
11
14
|
import { diagnostic, normalizeSeverity, toSarifLog } from "./diagnostics.js";
|
|
15
|
+
import { i18nCheckPassed, renderI18nCheck } from "./i18n-check.js";
|
|
12
16
|
import { collectPortResult, renderReport } from "./port.js";
|
|
13
17
|
import { reviewSpec } from "./review.js";
|
|
14
18
|
import { collectProjectWorkGraph, renderWorkGraphText, } from "./work-graph.js";
|
|
@@ -29,6 +33,17 @@ export function toCommandCatalogEntry(spec) {
|
|
|
29
33
|
outputVersion: spec.output.version,
|
|
30
34
|
transports: Object.freeze([...spec.transports]),
|
|
31
35
|
stability: spec.stability,
|
|
36
|
+
cliOnlyFields: Object.freeze([...(spec.cliOnlyFields ?? [])]),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/** The input schema a command's MCP tool advertises: its catalog schema without CLI-only fields. */
|
|
40
|
+
export function commandMcpInputSchema(entry) {
|
|
41
|
+
const properties = entry.inputSchema.properties;
|
|
42
|
+
if (entry.cliOnlyFields.length === 0 || typeof properties !== "object" || properties === null)
|
|
43
|
+
return entry.inputSchema;
|
|
44
|
+
return freezeJson({
|
|
45
|
+
...entry.inputSchema,
|
|
46
|
+
properties: Object.fromEntries(Object.entries(properties).filter(([key]) => !entry.cliOnlyFields.includes(key))),
|
|
32
47
|
});
|
|
33
48
|
}
|
|
34
49
|
function record(value) {
|
|
@@ -314,23 +329,45 @@ const FIX_SCHEMA = input(objectSchema({ code: { type: "string" }, json: { type:
|
|
|
314
329
|
};
|
|
315
330
|
});
|
|
316
331
|
const MIGRATE_SCHEMA = input(objectSchema({
|
|
332
|
+
kind: { type: "string", enum: ["layout"] },
|
|
317
333
|
from: { type: "string", enum: ["tailwind"] },
|
|
318
334
|
to: { type: "string", enum: ["stylex"] },
|
|
319
335
|
write: { type: "boolean" },
|
|
320
336
|
json: { type: "boolean" },
|
|
321
337
|
dir: { type: "string" },
|
|
322
|
-
}
|
|
338
|
+
}), (value) => {
|
|
323
339
|
const raw = withDir(record(value));
|
|
340
|
+
const flags = {
|
|
341
|
+
...parseBooleanFlags(raw, ["write", "json"]),
|
|
342
|
+
...(raw.dir === undefined ? {} : { dir: raw.dir }),
|
|
343
|
+
};
|
|
344
|
+
const kind = optionalString(raw.kind, "kind");
|
|
345
|
+
if (kind !== undefined) {
|
|
346
|
+
if (kind !== "layout")
|
|
347
|
+
throw new TypeError("the migration must be `layout` (or --from tailwind --to stylex)");
|
|
348
|
+
return { kind, ...flags };
|
|
349
|
+
}
|
|
324
350
|
const from = optionalString(raw.from, "from");
|
|
325
351
|
const to = optionalString(raw.to, "to");
|
|
326
352
|
if (from !== "tailwind")
|
|
327
353
|
throw new TypeError("from must be tailwind");
|
|
328
354
|
if (to !== "stylex")
|
|
329
355
|
throw new TypeError("to must be stylex");
|
|
356
|
+
return { from, to, ...flags };
|
|
357
|
+
});
|
|
358
|
+
const TARGET_SCHEMA = input(objectSchema({ target: { type: "string" }, json: { type: "boolean" }, dir: { type: "string" } }), (value) => {
|
|
359
|
+
const raw = withDir(record(value));
|
|
360
|
+
const target = optionalString(raw.target, "target");
|
|
330
361
|
return {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
...
|
|
362
|
+
...parseBooleanFlags(raw, ["json"]),
|
|
363
|
+
...(raw.dir === undefined ? {} : { dir: raw.dir }),
|
|
364
|
+
...(target === undefined ? {} : { target }),
|
|
365
|
+
};
|
|
366
|
+
});
|
|
367
|
+
const TYPES_SCHEMA = input(objectSchema({ check: { type: "boolean" }, json: { type: "boolean" }, dir: { type: "string" } }), (value) => {
|
|
368
|
+
const raw = withDir(record(value));
|
|
369
|
+
return {
|
|
370
|
+
...parseBooleanFlags(raw, ["check", "json"]),
|
|
334
371
|
...(raw.dir === undefined ? {} : { dir: raw.dir }),
|
|
335
372
|
};
|
|
336
373
|
});
|
|
@@ -421,6 +458,39 @@ const PORT_SCHEMA = input(objectSchema({
|
|
|
421
458
|
...(raw.dir === undefined ? {} : { dir: raw.dir }),
|
|
422
459
|
};
|
|
423
460
|
});
|
|
461
|
+
const SMOKE_SCHEMA = input(objectSchema({
|
|
462
|
+
fixture: { type: "string" },
|
|
463
|
+
inProcess: { type: "boolean" },
|
|
464
|
+
json: { type: "boolean" },
|
|
465
|
+
dir: { type: "string" },
|
|
466
|
+
}), (value) => {
|
|
467
|
+
const raw = withDir(record(value));
|
|
468
|
+
return {
|
|
469
|
+
fixture: optionalString(raw.fixture, "fixture"),
|
|
470
|
+
...parseBooleanFlags(raw, ["inProcess", "json"]),
|
|
471
|
+
...(raw.dir === undefined ? {} : { dir: raw.dir }),
|
|
472
|
+
};
|
|
473
|
+
});
|
|
474
|
+
const I18N_SCHEMA = input(objectSchema({
|
|
475
|
+
action: { type: "string", enum: ["check"] },
|
|
476
|
+
entry: { type: "string" },
|
|
477
|
+
json: { type: "boolean" },
|
|
478
|
+
strict: { type: "boolean" },
|
|
479
|
+
dir: { type: "string" },
|
|
480
|
+
}, ["action"]), (value) => {
|
|
481
|
+
const raw = withDir(record(value));
|
|
482
|
+
if (raw.action !== "check") {
|
|
483
|
+
throw new TypeError(raw.action === undefined
|
|
484
|
+
? "i18n needs an action: nifra i18n check [entry]"
|
|
485
|
+
: `unknown i18n action: ${String(raw.action)} (the one action is check)`);
|
|
486
|
+
}
|
|
487
|
+
return {
|
|
488
|
+
action: "check",
|
|
489
|
+
entry: optionalString(raw.entry, "entry"),
|
|
490
|
+
...parseBooleanFlags(raw, ["json", "strict"]),
|
|
491
|
+
...(raw.dir === undefined ? {} : { dir: raw.dir }),
|
|
492
|
+
};
|
|
493
|
+
});
|
|
424
494
|
function loadAppFor(ctx) {
|
|
425
495
|
if (ctx.loadApp !== undefined)
|
|
426
496
|
return ctx.loadApp();
|
|
@@ -600,6 +670,8 @@ const manifestSpec = {
|
|
|
600
670
|
output: output({ type: "object" }),
|
|
601
671
|
transports: ["cli", "mcp"],
|
|
602
672
|
stability: "stable",
|
|
673
|
+
// The signer is the operator's KMS/HSM callback; an agent signing its own manifest defeats it.
|
|
674
|
+
cliOnlyFields: ["sign"],
|
|
603
675
|
argv: {
|
|
604
676
|
positionals: ["action", "before", "after"],
|
|
605
677
|
flags: [
|
|
@@ -724,7 +796,9 @@ const openApiSpec = {
|
|
|
724
796
|
],
|
|
725
797
|
},
|
|
726
798
|
async run(value, ctx) {
|
|
727
|
-
const app =
|
|
799
|
+
const app = ctx.loadApp !== undefined
|
|
800
|
+
? await ctx.loadApp()
|
|
801
|
+
: await import("./load.js").then(({ loadBackendApp }) => loadBackendApp(ctx.cwd));
|
|
728
802
|
const { renderOpenApiWithTypes } = await import("./openapi-tool.js");
|
|
729
803
|
const format = value.format ?? "json";
|
|
730
804
|
return {
|
|
@@ -838,12 +912,13 @@ const fixSpec = {
|
|
|
838
912
|
};
|
|
839
913
|
const migrateSpec = {
|
|
840
914
|
name: "migrate",
|
|
841
|
-
summary: "
|
|
915
|
+
summary: "Move an app onto the frontend/backend split (`migrate layout`), or migrate static Tailwind utilities to StyleX.",
|
|
842
916
|
input: MIGRATE_SCHEMA,
|
|
843
917
|
output: output({
|
|
844
918
|
type: "object",
|
|
845
919
|
properties: {
|
|
846
920
|
ok: { type: "boolean" },
|
|
921
|
+
kind: { type: "string" },
|
|
847
922
|
from: { type: "string" },
|
|
848
923
|
to: { type: "string" },
|
|
849
924
|
write: { type: "boolean" },
|
|
@@ -852,12 +927,16 @@ const migrateSpec = {
|
|
|
852
927
|
written: { type: "array" },
|
|
853
928
|
issues: { type: "array" },
|
|
854
929
|
files: { type: "array" },
|
|
930
|
+
splits: { type: "array" },
|
|
931
|
+
moves: { type: "array" },
|
|
932
|
+
rewritten: { type: "array" },
|
|
855
933
|
},
|
|
856
|
-
required: ["ok", "
|
|
934
|
+
required: ["ok", "write", "issues"],
|
|
857
935
|
}),
|
|
858
936
|
transports: ["cli"],
|
|
859
937
|
stability: "stable",
|
|
860
938
|
argv: {
|
|
939
|
+
positionals: ["kind"],
|
|
861
940
|
flags: [
|
|
862
941
|
{ name: "from", field: "from", type: "string" },
|
|
863
942
|
{ name: "to", field: "to", type: "string" },
|
|
@@ -867,27 +946,134 @@ const migrateSpec = {
|
|
|
867
946
|
],
|
|
868
947
|
},
|
|
869
948
|
async run(value, ctx) {
|
|
949
|
+
const dir = resolve(ctx.cwd, value.dir ?? ".");
|
|
950
|
+
const write = value.write === undefined ? {} : { write: value.write };
|
|
951
|
+
if (value.kind === "layout") {
|
|
952
|
+
const { migrateLayout } = await import("./migrate-layout.js");
|
|
953
|
+
return { kind: "layout", ...(await migrateLayout(dir, write)) };
|
|
954
|
+
}
|
|
870
955
|
const { migrateTailwindToStylex } = await import("./stylex-migrate.js");
|
|
871
|
-
return migrateTailwindToStylex(
|
|
872
|
-
...(value.write === undefined ? {} : { write: value.write }),
|
|
873
|
-
});
|
|
956
|
+
return migrateTailwindToStylex(dir, write);
|
|
874
957
|
},
|
|
875
|
-
render: (out) =>
|
|
876
|
-
out.
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
958
|
+
render: (out) => {
|
|
959
|
+
if (out.kind === "layout") {
|
|
960
|
+
return [
|
|
961
|
+
out.ok
|
|
962
|
+
? `✓ ${out.splits.length} route file${out.splits.length === 1 ? "" : "s"} split, ${out.moves.length} file${out.moves.length === 1 ? "" : "s"} moved`
|
|
963
|
+
: `⚠ ${out.issues.length} issue${out.issues.length === 1 ? "" : "s"} need a decision; everything else is planned`,
|
|
964
|
+
...out.splits.map((split) => ` split ${split.file} → ${split.backend} (${split.moved.join(", ")})`),
|
|
965
|
+
...out.moves.map((move) => ` move ${move.from} → ${move.to}`),
|
|
966
|
+
...out.rewritten.map((file) => ` edit ${file} (imports)`),
|
|
967
|
+
...out.issues.map((issue) => ` ⚠ ${issue.file}: ${issue.reason}`),
|
|
968
|
+
...(out.write ? [] : [" dry run: pass --write to apply"]),
|
|
969
|
+
];
|
|
970
|
+
}
|
|
971
|
+
return [
|
|
972
|
+
out.ok
|
|
973
|
+
? `✓ migrated ${out.changed.length} file${out.changed.length === 1 ? "" : "s"}`
|
|
974
|
+
: `⚠ migrated ${out.changed.length} safe file${out.changed.length === 1 ? "" : "s"}; ${out.issues.length} manual issue${out.issues.length === 1 ? "" : "s"} remain`,
|
|
975
|
+
` scanned ${out.scanned} source file${out.scanned === 1 ? "" : "s"}`,
|
|
976
|
+
...(out.write
|
|
977
|
+
? [` wrote ${out.written.length} file${out.written.length === 1 ? "" : "s"}`]
|
|
978
|
+
: out.changed.length > 0
|
|
979
|
+
? [" dry run: pass --write to apply the safe changes"]
|
|
980
|
+
: []),
|
|
981
|
+
...out.issues
|
|
982
|
+
.slice(0, 30)
|
|
983
|
+
.map((issue) => ` ${issue.file}:${issue.line} ${issue.token} — ${issue.reason}`),
|
|
984
|
+
...(out.issues.length > 30
|
|
985
|
+
? [` … ${out.issues.length - 30} more issue${out.issues.length - 30 === 1 ? "" : "s"}`]
|
|
884
986
|
: []),
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
987
|
+
];
|
|
988
|
+
},
|
|
989
|
+
success: (out) => out.ok,
|
|
990
|
+
};
|
|
991
|
+
const targetSpec = {
|
|
992
|
+
name: "target",
|
|
993
|
+
summary: "Show the app's deploy target, or switch it (`nifra target cloudflare`): the `target` `nifra build` emits, kept in nifra.config.ts.",
|
|
994
|
+
input: TARGET_SCHEMA,
|
|
995
|
+
output: output({
|
|
996
|
+
type: "object",
|
|
997
|
+
properties: {
|
|
998
|
+
ok: { type: "boolean" },
|
|
999
|
+
target: { type: "string" },
|
|
1000
|
+
previous: { type: "string" },
|
|
1001
|
+
changed: { type: "boolean" },
|
|
1002
|
+
run: { type: "string" },
|
|
1003
|
+
},
|
|
1004
|
+
required: ["ok", "target", "changed", "run"],
|
|
1005
|
+
}),
|
|
1006
|
+
transports: ["cli"],
|
|
1007
|
+
stability: "stable",
|
|
1008
|
+
argv: {
|
|
1009
|
+
positionals: ["target"],
|
|
1010
|
+
flags: [
|
|
1011
|
+
{ name: "json", field: "json", type: "boolean" },
|
|
1012
|
+
{ name: "dir", field: "dir", type: "string" },
|
|
1013
|
+
],
|
|
1014
|
+
},
|
|
1015
|
+
async run(value, ctx) {
|
|
1016
|
+
const dir = resolve(ctx.cwd, value.dir ?? ".");
|
|
1017
|
+
const { parseBuildTarget, planBuildTarget } = await import("@nifrajs/web/build");
|
|
1018
|
+
const { readConfigTarget, writeConfigTarget } = await import("./config-target.js");
|
|
1019
|
+
const current = readConfigTarget(dir);
|
|
1020
|
+
const target = parseBuildTarget(value.target ?? current ?? "bun", value.target === undefined ? "target in nifra.config.ts" : "target");
|
|
1021
|
+
const changed = value.target !== undefined && value.target !== current;
|
|
1022
|
+
if (changed)
|
|
1023
|
+
writeConfigTarget(dir, target);
|
|
1024
|
+
return {
|
|
1025
|
+
ok: true,
|
|
1026
|
+
target,
|
|
1027
|
+
...(changed && current !== undefined ? { previous: current } : {}),
|
|
1028
|
+
changed,
|
|
1029
|
+
run: planBuildTarget(target, "dist").run,
|
|
1030
|
+
};
|
|
1031
|
+
},
|
|
1032
|
+
render: (out) => [
|
|
1033
|
+
out.changed
|
|
1034
|
+
? `✓ target: ${out.target}${out.previous === undefined ? "" : ` (was ${out.previous})`}`
|
|
1035
|
+
: `target: ${out.target}`,
|
|
1036
|
+
` nifra build → ${out.run}`,
|
|
1037
|
+
],
|
|
1038
|
+
success: (out) => out.ok,
|
|
1039
|
+
};
|
|
1040
|
+
const typesSpec = {
|
|
1041
|
+
name: "types",
|
|
1042
|
+
summary: "Generate each route's `./+types` module (params, schema-typed data, typed `api`); `--check` fails when one is stale.",
|
|
1043
|
+
input: TYPES_SCHEMA,
|
|
1044
|
+
output: output({
|
|
1045
|
+
type: "object",
|
|
1046
|
+
properties: {
|
|
1047
|
+
ok: { type: "boolean" },
|
|
1048
|
+
check: { type: "boolean" },
|
|
1049
|
+
written: { type: "array" },
|
|
1050
|
+
removed: { type: "array" },
|
|
1051
|
+
stale: { type: "array" },
|
|
1052
|
+
tsconfig: { type: "string" },
|
|
1053
|
+
},
|
|
1054
|
+
required: ["ok", "check", "written", "removed", "stale"],
|
|
1055
|
+
}),
|
|
1056
|
+
transports: ["cli"],
|
|
1057
|
+
stability: "stable",
|
|
1058
|
+
argv: {
|
|
1059
|
+
flags: [
|
|
1060
|
+
{ name: "check", field: "check", type: "boolean" },
|
|
1061
|
+
{ name: "json", field: "json", type: "boolean" },
|
|
1062
|
+
{ name: "dir", field: "dir", type: "string" },
|
|
1063
|
+
],
|
|
1064
|
+
},
|
|
1065
|
+
async run(value, ctx) {
|
|
1066
|
+
const { routeTypes } = await import("./route-types.js");
|
|
1067
|
+
return routeTypes(resolve(ctx.cwd, value.dir ?? "."), { check: value.check === true });
|
|
1068
|
+
},
|
|
1069
|
+
render: (out) => [
|
|
1070
|
+
out.check
|
|
1071
|
+
? out.ok
|
|
1072
|
+
? "✓ route types are up to date"
|
|
1073
|
+
: `✖ ${out.stale.length} route type file${out.stale.length === 1 ? " is" : "s are"} stale - run \`nifra types\``
|
|
1074
|
+
: `✓ route types: ${out.written.length} written, ${out.removed.length} removed`,
|
|
1075
|
+
...out.stale.map((file) => ` stale ${file}`),
|
|
1076
|
+
...(out.tsconfig === undefined ? [] : [` ⚠ ${out.tsconfig}`]),
|
|
891
1077
|
],
|
|
892
1078
|
success: (out) => out.ok,
|
|
893
1079
|
};
|
|
@@ -1068,6 +1254,28 @@ const replaySpec = {
|
|
|
1068
1254
|
render: (out) => [JSON.stringify(out, null, 2)],
|
|
1069
1255
|
success: (out) => out.ok,
|
|
1070
1256
|
};
|
|
1257
|
+
const smokeSpec = {
|
|
1258
|
+
name: "smoke",
|
|
1259
|
+
summary: "Run the declared production SSR, mounted-API, 404, header, auth, contract, and hydration smoke checks.",
|
|
1260
|
+
input: SMOKE_SCHEMA,
|
|
1261
|
+
output: output({ type: "object" }),
|
|
1262
|
+
transports: ["cli", "mcp"],
|
|
1263
|
+
stability: "stable",
|
|
1264
|
+
argv: {
|
|
1265
|
+
flags: [
|
|
1266
|
+
{ name: "fixture", field: "fixture", type: "string" },
|
|
1267
|
+
{ name: "in-process", field: "inProcess", type: "boolean" },
|
|
1268
|
+
{ name: "json", field: "json", type: "boolean" },
|
|
1269
|
+
],
|
|
1270
|
+
},
|
|
1271
|
+
async run(value, ctx) {
|
|
1272
|
+
const { loadSmokeFixture, runSmoke } = await import("./smoke.js");
|
|
1273
|
+
const fixture = await loadSmokeFixture(ctx.cwd, value.fixture);
|
|
1274
|
+
return runSmoke(fixture, { inProcess: value.inProcess === true });
|
|
1275
|
+
},
|
|
1276
|
+
render: (out) => out.checks.map((check) => `${check.status === "pass" ? "✓" : check.status === "skip" ? "•" : "✖"} ${check.id}${check.message === undefined ? "" : ` - ${check.message}`}`),
|
|
1277
|
+
success: (out) => out.ok,
|
|
1278
|
+
};
|
|
1071
1279
|
const portSpec = {
|
|
1072
1280
|
name: "port",
|
|
1073
1281
|
summary: "Print a feature by deploy-target portability matrix with file:line evidence and gate against an unsupported target.",
|
|
@@ -1096,7 +1304,7 @@ const portSpec = {
|
|
|
1096
1304
|
return [
|
|
1097
1305
|
report,
|
|
1098
1306
|
"",
|
|
1099
|
-
"[nifra] --ci needs a deploy target to gate against, and none was detected. Pass --target <bun|node|deno|
|
|
1307
|
+
"[nifra] --ci needs a deploy target to gate against, and none was detected. Pass --target <bun|node|deno|cloudflare|vercel>.",
|
|
1100
1308
|
];
|
|
1101
1309
|
return [report];
|
|
1102
1310
|
},
|
|
@@ -1110,6 +1318,31 @@ const portSpec = {
|
|
|
1110
1318
|
},
|
|
1111
1319
|
json: (out) => out.json,
|
|
1112
1320
|
};
|
|
1321
|
+
// CLI only: it imports app code (the catalogs), which a long-lived MCP server process would cache.
|
|
1322
|
+
const i18nSpec = {
|
|
1323
|
+
name: "i18n",
|
|
1324
|
+
summary: "Check i18n catalogs (imports the module exporting `locales` and `catalogs`): coverage, missing and unused keys, ICU syntax, placeholder and tag parity, plural cases, script purity, untranslated messages.",
|
|
1325
|
+
input: I18N_SCHEMA,
|
|
1326
|
+
output: output({ type: "object" }),
|
|
1327
|
+
transports: ["cli"],
|
|
1328
|
+
stability: "stable",
|
|
1329
|
+
argv: {
|
|
1330
|
+
positionals: ["action", "entry"],
|
|
1331
|
+
flags: [
|
|
1332
|
+
{ name: "json", field: "json", type: "boolean" },
|
|
1333
|
+
{ name: "strict", field: "strict", type: "boolean" },
|
|
1334
|
+
],
|
|
1335
|
+
},
|
|
1336
|
+
async run(value, ctx) {
|
|
1337
|
+
const { runI18nCheck } = await import("./i18n-check.js");
|
|
1338
|
+
return runI18nCheck(value.dir === undefined ? ctx.cwd : resolve(ctx.cwd, value.dir), {
|
|
1339
|
+
entry: value.entry,
|
|
1340
|
+
});
|
|
1341
|
+
},
|
|
1342
|
+
render: (out) => renderI18nCheck(out),
|
|
1343
|
+
success: (out, input) => i18nCheckPassed(out, input.strict === true),
|
|
1344
|
+
json: (out) => out,
|
|
1345
|
+
};
|
|
1113
1346
|
export const commandSpecs = Object.freeze([
|
|
1114
1347
|
checkSpec,
|
|
1115
1348
|
reviewSpec,
|
|
@@ -1123,6 +1356,8 @@ export const commandSpecs = Object.freeze([
|
|
|
1123
1356
|
doctorSpec,
|
|
1124
1357
|
fixSpec,
|
|
1125
1358
|
migrateSpec,
|
|
1359
|
+
targetSpec,
|
|
1360
|
+
typesSpec,
|
|
1126
1361
|
snapshotSpec,
|
|
1127
1362
|
diffSpec,
|
|
1128
1363
|
contractsSpec,
|
|
@@ -1130,7 +1365,16 @@ export const commandSpecs = Object.freeze([
|
|
|
1130
1365
|
syncRoutesSpec,
|
|
1131
1366
|
proveSpec,
|
|
1132
1367
|
replaySpec,
|
|
1368
|
+
smokeSpec,
|
|
1133
1369
|
portSpec,
|
|
1370
|
+
i18nSpec,
|
|
1371
|
+
errorsSpec,
|
|
1372
|
+
logsSpec,
|
|
1373
|
+
cdnCheckSpec,
|
|
1374
|
+
dbSchemaSpec,
|
|
1375
|
+
dbQuerySpec,
|
|
1376
|
+
dbRoleSpec,
|
|
1377
|
+
dbAuditSpec,
|
|
1134
1378
|
]);
|
|
1135
1379
|
const commandByName = new Map(commandSpecs.map((spec) => [spec.name, spec]));
|
|
1136
1380
|
export function findCommandSpec(name) {
|