@nifrajs/cli 3.5.0 → 4.0.2
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 +62 -5
- package/dist/command-catalog.d.ts.map +1 -1
- package/dist/command-catalog.js +275 -35
- 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 +48 -22
- 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 +1155 -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 +36 -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 +10 -2
- package/dist/sync-manifest.d.ts.map +1 -1
- package/dist/sync-manifest.js +44 -19
- 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 +389 -48
- 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 +53 -32
- 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 +1338 -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 +37 -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 +50 -19
- 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,10 +7,15 @@
|
|
|
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";
|
|
18
|
+
import { renderSyncManifestResults, syncManifestsOk, syncServerManifests, } from "./sync-manifest.js";
|
|
14
19
|
import { collectProjectWorkGraph, renderWorkGraphText, } from "./work-graph.js";
|
|
15
20
|
function freezeJson(value) {
|
|
16
21
|
if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
|
|
@@ -29,6 +34,17 @@ export function toCommandCatalogEntry(spec) {
|
|
|
29
34
|
outputVersion: spec.output.version,
|
|
30
35
|
transports: Object.freeze([...spec.transports]),
|
|
31
36
|
stability: spec.stability,
|
|
37
|
+
cliOnlyFields: Object.freeze([...(spec.cliOnlyFields ?? [])]),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/** The input schema a command's MCP tool advertises: its catalog schema without CLI-only fields. */
|
|
41
|
+
export function commandMcpInputSchema(entry) {
|
|
42
|
+
const properties = entry.inputSchema.properties;
|
|
43
|
+
if (entry.cliOnlyFields.length === 0 || typeof properties !== "object" || properties === null)
|
|
44
|
+
return entry.inputSchema;
|
|
45
|
+
return freezeJson({
|
|
46
|
+
...entry.inputSchema,
|
|
47
|
+
properties: Object.fromEntries(Object.entries(properties).filter(([key]) => !entry.cliOnlyFields.includes(key))),
|
|
32
48
|
});
|
|
33
49
|
}
|
|
34
50
|
function record(value) {
|
|
@@ -314,23 +330,45 @@ const FIX_SCHEMA = input(objectSchema({ code: { type: "string" }, json: { type:
|
|
|
314
330
|
};
|
|
315
331
|
});
|
|
316
332
|
const MIGRATE_SCHEMA = input(objectSchema({
|
|
333
|
+
kind: { type: "string", enum: ["layout"] },
|
|
317
334
|
from: { type: "string", enum: ["tailwind"] },
|
|
318
335
|
to: { type: "string", enum: ["stylex"] },
|
|
319
336
|
write: { type: "boolean" },
|
|
320
337
|
json: { type: "boolean" },
|
|
321
338
|
dir: { type: "string" },
|
|
322
|
-
}
|
|
339
|
+
}), (value) => {
|
|
323
340
|
const raw = withDir(record(value));
|
|
341
|
+
const flags = {
|
|
342
|
+
...parseBooleanFlags(raw, ["write", "json"]),
|
|
343
|
+
...(raw.dir === undefined ? {} : { dir: raw.dir }),
|
|
344
|
+
};
|
|
345
|
+
const kind = optionalString(raw.kind, "kind");
|
|
346
|
+
if (kind !== undefined) {
|
|
347
|
+
if (kind !== "layout")
|
|
348
|
+
throw new TypeError("the migration must be `layout` (or --from tailwind --to stylex)");
|
|
349
|
+
return { kind, ...flags };
|
|
350
|
+
}
|
|
324
351
|
const from = optionalString(raw.from, "from");
|
|
325
352
|
const to = optionalString(raw.to, "to");
|
|
326
353
|
if (from !== "tailwind")
|
|
327
354
|
throw new TypeError("from must be tailwind");
|
|
328
355
|
if (to !== "stylex")
|
|
329
356
|
throw new TypeError("to must be stylex");
|
|
357
|
+
return { from, to, ...flags };
|
|
358
|
+
});
|
|
359
|
+
const TARGET_SCHEMA = input(objectSchema({ target: { type: "string" }, json: { type: "boolean" }, dir: { type: "string" } }), (value) => {
|
|
360
|
+
const raw = withDir(record(value));
|
|
361
|
+
const target = optionalString(raw.target, "target");
|
|
330
362
|
return {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
...
|
|
363
|
+
...parseBooleanFlags(raw, ["json"]),
|
|
364
|
+
...(raw.dir === undefined ? {} : { dir: raw.dir }),
|
|
365
|
+
...(target === undefined ? {} : { target }),
|
|
366
|
+
};
|
|
367
|
+
});
|
|
368
|
+
const TYPES_SCHEMA = input(objectSchema({ check: { type: "boolean" }, json: { type: "boolean" }, dir: { type: "string" } }), (value) => {
|
|
369
|
+
const raw = withDir(record(value));
|
|
370
|
+
return {
|
|
371
|
+
...parseBooleanFlags(raw, ["check", "json"]),
|
|
334
372
|
...(raw.dir === undefined ? {} : { dir: raw.dir }),
|
|
335
373
|
};
|
|
336
374
|
});
|
|
@@ -421,6 +459,39 @@ const PORT_SCHEMA = input(objectSchema({
|
|
|
421
459
|
...(raw.dir === undefined ? {} : { dir: raw.dir }),
|
|
422
460
|
};
|
|
423
461
|
});
|
|
462
|
+
const SMOKE_SCHEMA = input(objectSchema({
|
|
463
|
+
fixture: { type: "string" },
|
|
464
|
+
inProcess: { type: "boolean" },
|
|
465
|
+
json: { type: "boolean" },
|
|
466
|
+
dir: { type: "string" },
|
|
467
|
+
}), (value) => {
|
|
468
|
+
const raw = withDir(record(value));
|
|
469
|
+
return {
|
|
470
|
+
fixture: optionalString(raw.fixture, "fixture"),
|
|
471
|
+
...parseBooleanFlags(raw, ["inProcess", "json"]),
|
|
472
|
+
...(raw.dir === undefined ? {} : { dir: raw.dir }),
|
|
473
|
+
};
|
|
474
|
+
});
|
|
475
|
+
const I18N_SCHEMA = input(objectSchema({
|
|
476
|
+
action: { type: "string", enum: ["check"] },
|
|
477
|
+
entry: { type: "string" },
|
|
478
|
+
json: { type: "boolean" },
|
|
479
|
+
strict: { type: "boolean" },
|
|
480
|
+
dir: { type: "string" },
|
|
481
|
+
}, ["action"]), (value) => {
|
|
482
|
+
const raw = withDir(record(value));
|
|
483
|
+
if (raw.action !== "check") {
|
|
484
|
+
throw new TypeError(raw.action === undefined
|
|
485
|
+
? "i18n needs an action: nifra i18n check [entry]"
|
|
486
|
+
: `unknown i18n action: ${String(raw.action)} (the one action is check)`);
|
|
487
|
+
}
|
|
488
|
+
return {
|
|
489
|
+
action: "check",
|
|
490
|
+
entry: optionalString(raw.entry, "entry"),
|
|
491
|
+
...parseBooleanFlags(raw, ["json", "strict"]),
|
|
492
|
+
...(raw.dir === undefined ? {} : { dir: raw.dir }),
|
|
493
|
+
};
|
|
494
|
+
});
|
|
424
495
|
function loadAppFor(ctx) {
|
|
425
496
|
if (ctx.loadApp !== undefined)
|
|
426
497
|
return ctx.loadApp();
|
|
@@ -600,6 +671,8 @@ const manifestSpec = {
|
|
|
600
671
|
output: output({ type: "object" }),
|
|
601
672
|
transports: ["cli", "mcp"],
|
|
602
673
|
stability: "stable",
|
|
674
|
+
// The signer is the operator's KMS/HSM callback; an agent signing its own manifest defeats it.
|
|
675
|
+
cliOnlyFields: ["sign"],
|
|
603
676
|
argv: {
|
|
604
677
|
positionals: ["action", "before", "after"],
|
|
605
678
|
flags: [
|
|
@@ -724,7 +797,9 @@ const openApiSpec = {
|
|
|
724
797
|
],
|
|
725
798
|
},
|
|
726
799
|
async run(value, ctx) {
|
|
727
|
-
const app =
|
|
800
|
+
const app = ctx.loadApp !== undefined
|
|
801
|
+
? await ctx.loadApp()
|
|
802
|
+
: await import("./load.js").then(({ loadBackendApp }) => loadBackendApp(ctx.cwd));
|
|
728
803
|
const { renderOpenApiWithTypes } = await import("./openapi-tool.js");
|
|
729
804
|
const format = value.format ?? "json";
|
|
730
805
|
return {
|
|
@@ -838,12 +913,13 @@ const fixSpec = {
|
|
|
838
913
|
};
|
|
839
914
|
const migrateSpec = {
|
|
840
915
|
name: "migrate",
|
|
841
|
-
summary: "
|
|
916
|
+
summary: "Move an app onto the frontend/backend split (`migrate layout`), or migrate static Tailwind utilities to StyleX.",
|
|
842
917
|
input: MIGRATE_SCHEMA,
|
|
843
918
|
output: output({
|
|
844
919
|
type: "object",
|
|
845
920
|
properties: {
|
|
846
921
|
ok: { type: "boolean" },
|
|
922
|
+
kind: { type: "string" },
|
|
847
923
|
from: { type: "string" },
|
|
848
924
|
to: { type: "string" },
|
|
849
925
|
write: { type: "boolean" },
|
|
@@ -852,12 +928,16 @@ const migrateSpec = {
|
|
|
852
928
|
written: { type: "array" },
|
|
853
929
|
issues: { type: "array" },
|
|
854
930
|
files: { type: "array" },
|
|
931
|
+
splits: { type: "array" },
|
|
932
|
+
moves: { type: "array" },
|
|
933
|
+
rewritten: { type: "array" },
|
|
855
934
|
},
|
|
856
|
-
required: ["ok", "
|
|
935
|
+
required: ["ok", "write", "issues"],
|
|
857
936
|
}),
|
|
858
937
|
transports: ["cli"],
|
|
859
938
|
stability: "stable",
|
|
860
939
|
argv: {
|
|
940
|
+
positionals: ["kind"],
|
|
861
941
|
flags: [
|
|
862
942
|
{ name: "from", field: "from", type: "string" },
|
|
863
943
|
{ name: "to", field: "to", type: "string" },
|
|
@@ -867,27 +947,134 @@ const migrateSpec = {
|
|
|
867
947
|
],
|
|
868
948
|
},
|
|
869
949
|
async run(value, ctx) {
|
|
950
|
+
const dir = resolve(ctx.cwd, value.dir ?? ".");
|
|
951
|
+
const write = value.write === undefined ? {} : { write: value.write };
|
|
952
|
+
if (value.kind === "layout") {
|
|
953
|
+
const { migrateLayout } = await import("./migrate-layout.js");
|
|
954
|
+
return { kind: "layout", ...(await migrateLayout(dir, write)) };
|
|
955
|
+
}
|
|
870
956
|
const { migrateTailwindToStylex } = await import("./stylex-migrate.js");
|
|
871
|
-
return migrateTailwindToStylex(
|
|
872
|
-
...(value.write === undefined ? {} : { write: value.write }),
|
|
873
|
-
});
|
|
957
|
+
return migrateTailwindToStylex(dir, write);
|
|
874
958
|
},
|
|
875
|
-
render: (out) =>
|
|
876
|
-
out.
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
959
|
+
render: (out) => {
|
|
960
|
+
if (out.kind === "layout") {
|
|
961
|
+
return [
|
|
962
|
+
out.ok
|
|
963
|
+
? `✓ ${out.splits.length} route file${out.splits.length === 1 ? "" : "s"} split, ${out.moves.length} file${out.moves.length === 1 ? "" : "s"} moved`
|
|
964
|
+
: `⚠ ${out.issues.length} issue${out.issues.length === 1 ? "" : "s"} need a decision; everything else is planned`,
|
|
965
|
+
...out.splits.map((split) => ` split ${split.file} → ${split.backend} (${split.moved.join(", ")})`),
|
|
966
|
+
...out.moves.map((move) => ` move ${move.from} → ${move.to}`),
|
|
967
|
+
...out.rewritten.map((file) => ` edit ${file} (imports)`),
|
|
968
|
+
...out.issues.map((issue) => ` ⚠ ${issue.file}: ${issue.reason}`),
|
|
969
|
+
...(out.write ? [] : [" dry run: pass --write to apply"]),
|
|
970
|
+
];
|
|
971
|
+
}
|
|
972
|
+
return [
|
|
973
|
+
out.ok
|
|
974
|
+
? `✓ migrated ${out.changed.length} file${out.changed.length === 1 ? "" : "s"}`
|
|
975
|
+
: `⚠ migrated ${out.changed.length} safe file${out.changed.length === 1 ? "" : "s"}; ${out.issues.length} manual issue${out.issues.length === 1 ? "" : "s"} remain`,
|
|
976
|
+
` scanned ${out.scanned} source file${out.scanned === 1 ? "" : "s"}`,
|
|
977
|
+
...(out.write
|
|
978
|
+
? [` wrote ${out.written.length} file${out.written.length === 1 ? "" : "s"}`]
|
|
979
|
+
: out.changed.length > 0
|
|
980
|
+
? [" dry run: pass --write to apply the safe changes"]
|
|
981
|
+
: []),
|
|
982
|
+
...out.issues
|
|
983
|
+
.slice(0, 30)
|
|
984
|
+
.map((issue) => ` ${issue.file}:${issue.line} ${issue.token} — ${issue.reason}`),
|
|
985
|
+
...(out.issues.length > 30
|
|
986
|
+
? [` … ${out.issues.length - 30} more issue${out.issues.length - 30 === 1 ? "" : "s"}`]
|
|
884
987
|
: []),
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
988
|
+
];
|
|
989
|
+
},
|
|
990
|
+
success: (out) => out.ok,
|
|
991
|
+
};
|
|
992
|
+
const targetSpec = {
|
|
993
|
+
name: "target",
|
|
994
|
+
summary: "Show the app's deploy target, or switch it (`nifra target cloudflare`): the `target` `nifra build` emits, kept in nifra.config.ts.",
|
|
995
|
+
input: TARGET_SCHEMA,
|
|
996
|
+
output: output({
|
|
997
|
+
type: "object",
|
|
998
|
+
properties: {
|
|
999
|
+
ok: { type: "boolean" },
|
|
1000
|
+
target: { type: "string" },
|
|
1001
|
+
previous: { type: "string" },
|
|
1002
|
+
changed: { type: "boolean" },
|
|
1003
|
+
run: { type: "string" },
|
|
1004
|
+
},
|
|
1005
|
+
required: ["ok", "target", "changed", "run"],
|
|
1006
|
+
}),
|
|
1007
|
+
transports: ["cli"],
|
|
1008
|
+
stability: "stable",
|
|
1009
|
+
argv: {
|
|
1010
|
+
positionals: ["target"],
|
|
1011
|
+
flags: [
|
|
1012
|
+
{ name: "json", field: "json", type: "boolean" },
|
|
1013
|
+
{ name: "dir", field: "dir", type: "string" },
|
|
1014
|
+
],
|
|
1015
|
+
},
|
|
1016
|
+
async run(value, ctx) {
|
|
1017
|
+
const dir = resolve(ctx.cwd, value.dir ?? ".");
|
|
1018
|
+
const { parseBuildTarget, planBuildTarget } = await import("@nifrajs/web/build");
|
|
1019
|
+
const { readConfigTarget, writeConfigTarget } = await import("./config-target.js");
|
|
1020
|
+
const current = readConfigTarget(dir);
|
|
1021
|
+
const target = parseBuildTarget(value.target ?? current ?? "bun", value.target === undefined ? "target in nifra.config.ts" : "target");
|
|
1022
|
+
const changed = value.target !== undefined && value.target !== current;
|
|
1023
|
+
if (changed)
|
|
1024
|
+
writeConfigTarget(dir, target);
|
|
1025
|
+
return {
|
|
1026
|
+
ok: true,
|
|
1027
|
+
target,
|
|
1028
|
+
...(changed && current !== undefined ? { previous: current } : {}),
|
|
1029
|
+
changed,
|
|
1030
|
+
run: planBuildTarget(target, "dist").run,
|
|
1031
|
+
};
|
|
1032
|
+
},
|
|
1033
|
+
render: (out) => [
|
|
1034
|
+
out.changed
|
|
1035
|
+
? `✓ target: ${out.target}${out.previous === undefined ? "" : ` (was ${out.previous})`}`
|
|
1036
|
+
: `target: ${out.target}`,
|
|
1037
|
+
` nifra build → ${out.run}`,
|
|
1038
|
+
],
|
|
1039
|
+
success: (out) => out.ok,
|
|
1040
|
+
};
|
|
1041
|
+
const typesSpec = {
|
|
1042
|
+
name: "types",
|
|
1043
|
+
summary: "Generate each route's `./+types` module (params, schema-typed data, typed `api`); `--check` fails when one is stale.",
|
|
1044
|
+
input: TYPES_SCHEMA,
|
|
1045
|
+
output: output({
|
|
1046
|
+
type: "object",
|
|
1047
|
+
properties: {
|
|
1048
|
+
ok: { type: "boolean" },
|
|
1049
|
+
check: { type: "boolean" },
|
|
1050
|
+
written: { type: "array" },
|
|
1051
|
+
removed: { type: "array" },
|
|
1052
|
+
stale: { type: "array" },
|
|
1053
|
+
tsconfig: { type: "string" },
|
|
1054
|
+
},
|
|
1055
|
+
required: ["ok", "check", "written", "removed", "stale"],
|
|
1056
|
+
}),
|
|
1057
|
+
transports: ["cli"],
|
|
1058
|
+
stability: "stable",
|
|
1059
|
+
argv: {
|
|
1060
|
+
flags: [
|
|
1061
|
+
{ name: "check", field: "check", type: "boolean" },
|
|
1062
|
+
{ name: "json", field: "json", type: "boolean" },
|
|
1063
|
+
{ name: "dir", field: "dir", type: "string" },
|
|
1064
|
+
],
|
|
1065
|
+
},
|
|
1066
|
+
async run(value, ctx) {
|
|
1067
|
+
const { routeTypes } = await import("./route-types.js");
|
|
1068
|
+
return routeTypes(resolve(ctx.cwd, value.dir ?? "."), { check: value.check === true });
|
|
1069
|
+
},
|
|
1070
|
+
render: (out) => [
|
|
1071
|
+
out.check
|
|
1072
|
+
? out.ok
|
|
1073
|
+
? "✓ route types are up to date"
|
|
1074
|
+
: `✖ ${out.stale.length} route type file${out.stale.length === 1 ? " is" : "s are"} stale - run \`nifra types\``
|
|
1075
|
+
: `✓ route types: ${out.written.length} written, ${out.removed.length} removed`,
|
|
1076
|
+
...out.stale.map((file) => ` stale ${file}`),
|
|
1077
|
+
...(out.tsconfig === undefined ? [] : [` ⚠ ${out.tsconfig}`]),
|
|
891
1078
|
],
|
|
892
1079
|
success: (out) => out.ok,
|
|
893
1080
|
};
|
|
@@ -997,16 +1184,11 @@ const syncManifestSpec = {
|
|
|
997
1184
|
stability: "stable",
|
|
998
1185
|
argv: { flags: [{ name: "json", field: "json", type: "boolean" }] },
|
|
999
1186
|
async run(_value, ctx) {
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
results: await (await import("./sync-manifest.js")).syncServerManifests(ctx.cwd),
|
|
1003
|
-
};
|
|
1187
|
+
const results = await syncServerManifests(ctx.cwd);
|
|
1188
|
+
return { ok: syncManifestsOk(results), results };
|
|
1004
1189
|
},
|
|
1005
|
-
render: (out) =>
|
|
1006
|
-
|
|
1007
|
-
? "nifra sync-manifest: no generated server-manifest.ts found under this directory."
|
|
1008
|
-
: `✓ checked ${out.results.length} generated server manifest${out.results.length === 1 ? "" : "s"}`,
|
|
1009
|
-
],
|
|
1190
|
+
render: (out) => renderSyncManifestResults(out.results),
|
|
1191
|
+
success: (out) => out.ok,
|
|
1010
1192
|
};
|
|
1011
1193
|
const syncRoutesSpec = {
|
|
1012
1194
|
name: "sync-routes",
|
|
@@ -1068,6 +1250,28 @@ const replaySpec = {
|
|
|
1068
1250
|
render: (out) => [JSON.stringify(out, null, 2)],
|
|
1069
1251
|
success: (out) => out.ok,
|
|
1070
1252
|
};
|
|
1253
|
+
const smokeSpec = {
|
|
1254
|
+
name: "smoke",
|
|
1255
|
+
summary: "Run the declared production SSR, mounted-API, 404, header, auth, contract, and hydration smoke checks.",
|
|
1256
|
+
input: SMOKE_SCHEMA,
|
|
1257
|
+
output: output({ type: "object" }),
|
|
1258
|
+
transports: ["cli", "mcp"],
|
|
1259
|
+
stability: "stable",
|
|
1260
|
+
argv: {
|
|
1261
|
+
flags: [
|
|
1262
|
+
{ name: "fixture", field: "fixture", type: "string" },
|
|
1263
|
+
{ name: "in-process", field: "inProcess", type: "boolean" },
|
|
1264
|
+
{ name: "json", field: "json", type: "boolean" },
|
|
1265
|
+
],
|
|
1266
|
+
},
|
|
1267
|
+
async run(value, ctx) {
|
|
1268
|
+
const { loadSmokeFixture, runSmoke } = await import("./smoke.js");
|
|
1269
|
+
const fixture = await loadSmokeFixture(ctx.cwd, value.fixture);
|
|
1270
|
+
return runSmoke(fixture, { inProcess: value.inProcess === true });
|
|
1271
|
+
},
|
|
1272
|
+
render: (out) => out.checks.map((check) => `${check.status === "pass" ? "✓" : check.status === "skip" ? "•" : "✖"} ${check.id}${check.message === undefined ? "" : ` - ${check.message}`}`),
|
|
1273
|
+
success: (out) => out.ok,
|
|
1274
|
+
};
|
|
1071
1275
|
const portSpec = {
|
|
1072
1276
|
name: "port",
|
|
1073
1277
|
summary: "Print a feature by deploy-target portability matrix with file:line evidence and gate against an unsupported target.",
|
|
@@ -1096,7 +1300,7 @@ const portSpec = {
|
|
|
1096
1300
|
return [
|
|
1097
1301
|
report,
|
|
1098
1302
|
"",
|
|
1099
|
-
"[nifra] --ci needs a deploy target to gate against, and none was detected. Pass --target <bun|node|deno|
|
|
1303
|
+
"[nifra] --ci needs a deploy target to gate against, and none was detected. Pass --target <bun|node|deno|cloudflare|vercel>.",
|
|
1100
1304
|
];
|
|
1101
1305
|
return [report];
|
|
1102
1306
|
},
|
|
@@ -1110,6 +1314,31 @@ const portSpec = {
|
|
|
1110
1314
|
},
|
|
1111
1315
|
json: (out) => out.json,
|
|
1112
1316
|
};
|
|
1317
|
+
// CLI only: it imports app code (the catalogs), which a long-lived MCP server process would cache.
|
|
1318
|
+
const i18nSpec = {
|
|
1319
|
+
name: "i18n",
|
|
1320
|
+
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.",
|
|
1321
|
+
input: I18N_SCHEMA,
|
|
1322
|
+
output: output({ type: "object" }),
|
|
1323
|
+
transports: ["cli"],
|
|
1324
|
+
stability: "stable",
|
|
1325
|
+
argv: {
|
|
1326
|
+
positionals: ["action", "entry"],
|
|
1327
|
+
flags: [
|
|
1328
|
+
{ name: "json", field: "json", type: "boolean" },
|
|
1329
|
+
{ name: "strict", field: "strict", type: "boolean" },
|
|
1330
|
+
],
|
|
1331
|
+
},
|
|
1332
|
+
async run(value, ctx) {
|
|
1333
|
+
const { runI18nCheck } = await import("./i18n-check.js");
|
|
1334
|
+
return runI18nCheck(value.dir === undefined ? ctx.cwd : resolve(ctx.cwd, value.dir), {
|
|
1335
|
+
entry: value.entry,
|
|
1336
|
+
});
|
|
1337
|
+
},
|
|
1338
|
+
render: (out) => renderI18nCheck(out),
|
|
1339
|
+
success: (out, input) => i18nCheckPassed(out, input.strict === true),
|
|
1340
|
+
json: (out) => out,
|
|
1341
|
+
};
|
|
1113
1342
|
export const commandSpecs = Object.freeze([
|
|
1114
1343
|
checkSpec,
|
|
1115
1344
|
reviewSpec,
|
|
@@ -1123,6 +1352,8 @@ export const commandSpecs = Object.freeze([
|
|
|
1123
1352
|
doctorSpec,
|
|
1124
1353
|
fixSpec,
|
|
1125
1354
|
migrateSpec,
|
|
1355
|
+
targetSpec,
|
|
1356
|
+
typesSpec,
|
|
1126
1357
|
snapshotSpec,
|
|
1127
1358
|
diffSpec,
|
|
1128
1359
|
contractsSpec,
|
|
@@ -1130,7 +1361,16 @@ export const commandSpecs = Object.freeze([
|
|
|
1130
1361
|
syncRoutesSpec,
|
|
1131
1362
|
proveSpec,
|
|
1132
1363
|
replaySpec,
|
|
1364
|
+
smokeSpec,
|
|
1133
1365
|
portSpec,
|
|
1366
|
+
i18nSpec,
|
|
1367
|
+
errorsSpec,
|
|
1368
|
+
logsSpec,
|
|
1369
|
+
cdnCheckSpec,
|
|
1370
|
+
dbSchemaSpec,
|
|
1371
|
+
dbQuerySpec,
|
|
1372
|
+
dbRoleSpec,
|
|
1373
|
+
dbAuditSpec,
|
|
1134
1374
|
]);
|
|
1135
1375
|
const commandByName = new Map(commandSpecs.map((spec) => [spec.name, spec]));
|
|
1136
1376
|
export function findCommandSpec(name) {
|