@mozole/cli 1.2.3 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -4
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +23 -5
- package/dist/cli.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +9 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/new.d.ts +1 -0
- package/dist/commands/new.d.ts.map +1 -1
- package/dist/commands/new.js +1 -1
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/qa.d.ts +1 -0
- package/dist/commands/qa.d.ts.map +1 -1
- package/dist/commands/qa.js +2 -1
- package/dist/commands/qa.js.map +1 -1
- package/dist/config/project.d.ts +6 -0
- package/dist/config/project.d.ts.map +1 -1
- package/dist/config/project.js +9 -0
- package/dist/config/project.js.map +1 -1
- package/dist/governor/fingerprint.d.ts.map +1 -1
- package/dist/governor/fingerprint.js +3 -0
- package/dist/governor/fingerprint.js.map +1 -1
- package/dist/governor/hook.d.ts +2 -1
- package/dist/governor/hook.d.ts.map +1 -1
- package/dist/governor/hook.js +83 -24
- package/dist/governor/hook.js.map +1 -1
- package/dist/governor/state.d.ts +1 -0
- package/dist/governor/state.d.ts.map +1 -1
- package/dist/governor/state.js.map +1 -1
- package/dist/platform/process.d.ts.map +1 -1
- package/dist/platform/process.js +14 -4
- package/dist/platform/process.js.map +1 -1
- package/dist/qa/diff.d.ts +10 -0
- package/dist/qa/diff.d.ts.map +1 -0
- package/dist/qa/diff.js +79 -0
- package/dist/qa/diff.js.map +1 -0
- package/dist/qa/runner.d.ts +11 -0
- package/dist/qa/runner.d.ts.map +1 -1
- package/dist/qa/runner.js +30 -7
- package/dist/qa/runner.js.map +1 -1
- package/dist/scaffold/admin.d.ts +8 -0
- package/dist/scaffold/admin.d.ts.map +1 -0
- package/dist/scaffold/admin.js +45 -0
- package/dist/scaffold/admin.js.map +1 -0
- package/dist/scaffold/templates.d.ts +5 -2
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +43 -12
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/verify/runner.d.ts.map +1 -1
- package/dist/verify/runner.js +19 -3
- package/dist/verify/runner.js.map +1 -1
- package/dist/version.d.ts +2 -2
- package/dist/version.js +1 -1
- package/package.json +5 -2
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
export async function inspectAdminScaffold(root, config) {
|
|
4
|
+
if (!config.admin?.enabled)
|
|
5
|
+
return { enabled: false, healthy: true, detail: "static-only project" };
|
|
6
|
+
const requiredFiles = [
|
|
7
|
+
"app/admin/session.server.ts",
|
|
8
|
+
"app/admin/layout.tsx",
|
|
9
|
+
"app/admin/login.tsx",
|
|
10
|
+
"app/admin/dashboard.tsx",
|
|
11
|
+
];
|
|
12
|
+
try {
|
|
13
|
+
const [routerConfig, routes, packageText, ...adminFiles] = await Promise.all([
|
|
14
|
+
readFile(path.join(root, "react-router.config.ts"), "utf8"),
|
|
15
|
+
readFile(path.join(root, "app", "routes.ts"), "utf8"),
|
|
16
|
+
readFile(path.join(root, "package.json"), "utf8"),
|
|
17
|
+
...requiredFiles.map((relative) => readFile(path.join(root, ...relative.split("/")), "utf8")),
|
|
18
|
+
]);
|
|
19
|
+
const pkg = JSON.parse(packageText);
|
|
20
|
+
const prerendered = ["/", "/about", "/contact"].every((route) => routerConfig.includes(`"${route}"`));
|
|
21
|
+
const healthy = /ssr:\s*true/.test(routerConfig) &&
|
|
22
|
+
prerendered &&
|
|
23
|
+
!routerConfig.includes('"/admin"') &&
|
|
24
|
+
routes.includes('route("admin"') &&
|
|
25
|
+
routes.includes('route("admin/login"') &&
|
|
26
|
+
adminFiles.every((contents) => contents.length > 0) &&
|
|
27
|
+
Boolean(pkg.dependencies?.["@react-router/serve"]) &&
|
|
28
|
+
pkg.scripts?.start === "react-router-serve build/server/index.js";
|
|
29
|
+
return {
|
|
30
|
+
enabled: true,
|
|
31
|
+
healthy,
|
|
32
|
+
detail: healthy
|
|
33
|
+
? "Node runtime required; /admin excluded from prerender"
|
|
34
|
+
: "admin runtime files or hybrid rendering config are incomplete",
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
return {
|
|
39
|
+
enabled: true,
|
|
40
|
+
healthy: false,
|
|
41
|
+
detail: `admin runtime files missing: ${error instanceof Error ? error.message : String(error)}`,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=admin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/scaffold/admin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAS7B,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAY,EACZ,MAAoB;IAEpB,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO;QACxB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC;IAE1E,MAAM,aAAa,GAAG;QACpB,6BAA6B;QAC7B,sBAAsB;QACtB,qBAAqB;QACrB,yBAAyB;KAC1B,CAAC;IACF,IAAI,CAAC;QACH,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,UAAU,CAAC,GACtD,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,wBAAwB,CAAC,EAAE,MAAM,CAAC;YAC3D,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC;YACrD,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC;YACjD,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAChC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAC1D;SACF,CAAC,CAAC;QACL,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAGjC,CAAC;QACF,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAC9D,YAAY,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG,CAAC,CACpC,CAAC;QACF,MAAM,OAAO,GACX,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC;YAChC,WAAW;YACX,CAAC,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC;YAClC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC;YAChC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAC;YACtC,UAAU,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;YACnD,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,qBAAqB,CAAC,CAAC;YAClD,GAAG,CAAC,OAAO,EAAE,KAAK,KAAK,0CAA0C,CAAC;QACpE,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO;YACP,MAAM,EAAE,OAAO;gBACb,CAAC,CAAC,uDAAuD;gBACzD,CAAC,CAAC,+DAA+D;SACpE,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,gCAAgC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;SACjG,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { MozoleConfig } from "../config/project.js";
|
|
2
|
-
export
|
|
3
|
-
|
|
2
|
+
export interface ProjectTemplateOptions {
|
|
3
|
+
withAdmin?: boolean | undefined;
|
|
4
|
+
}
|
|
5
|
+
export declare function projectConfig(name: string, options?: ProjectTemplateOptions): MozoleConfig;
|
|
6
|
+
export declare function projectTemplates(name: string, options?: ProjectTemplateOptions): Record<string, string>;
|
|
4
7
|
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAIzD,wBAAgB,aAAa,
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAIzD,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACjC;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,sBAA2B,GACnC,YAAY,CAsCd;AAID,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,sBAA2B,GACnC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAwMxB"}
|
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
import { cceMcpServer } from "../integrations/antigravity.js";
|
|
2
2
|
import { TOOLCHAIN } from "../version.js";
|
|
3
|
-
export function projectConfig(name) {
|
|
3
|
+
export function projectConfig(name, options = {}) {
|
|
4
4
|
return {
|
|
5
5
|
schemaVersion: 1,
|
|
6
6
|
name,
|
|
7
7
|
framework: "react-router",
|
|
8
8
|
routes: ["/", "/about", "/contact"],
|
|
9
|
+
...(options.withAdmin
|
|
10
|
+
? {
|
|
11
|
+
admin: {
|
|
12
|
+
enabled: true,
|
|
13
|
+
routePrefix: "/admin",
|
|
14
|
+
runtime: "node",
|
|
15
|
+
},
|
|
16
|
+
}
|
|
17
|
+
: {}),
|
|
9
18
|
qa: {
|
|
19
|
+
visualDiffThreshold: 0.001,
|
|
10
20
|
viewports: [
|
|
11
21
|
{ width: 375, height: 812 },
|
|
12
22
|
{ width: 768, height: 1024 },
|
|
@@ -30,7 +40,7 @@ export function projectConfig(name) {
|
|
|
30
40
|
};
|
|
31
41
|
}
|
|
32
42
|
const json = (value) => `${JSON.stringify(value, null, 2)}\n`;
|
|
33
|
-
export function projectTemplates(name) {
|
|
43
|
+
export function projectTemplates(name, options = {}) {
|
|
34
44
|
const cliSpec = process.env.MOZOLE_CLI_SPEC ?? TOOLCHAIN.mozoleCli;
|
|
35
45
|
const packageJson = {
|
|
36
46
|
name,
|
|
@@ -41,6 +51,9 @@ export function projectTemplates(name) {
|
|
|
41
51
|
scripts: {
|
|
42
52
|
dev: "react-router dev",
|
|
43
53
|
build: "react-router build",
|
|
54
|
+
...(options.withAdmin
|
|
55
|
+
? { start: "react-router-serve build/server/index.js" }
|
|
56
|
+
: {}),
|
|
44
57
|
preview: "vite preview --host 127.0.0.1",
|
|
45
58
|
lint: "biome check .",
|
|
46
59
|
format: "biome format --write .",
|
|
@@ -55,6 +68,9 @@ export function projectTemplates(name) {
|
|
|
55
68
|
"qa:visual": "mozole qa --visual",
|
|
56
69
|
},
|
|
57
70
|
dependencies: {
|
|
71
|
+
...(options.withAdmin
|
|
72
|
+
? { "@react-router/serve": TOOLCHAIN.reactRouter }
|
|
73
|
+
: {}),
|
|
58
74
|
"@react-router/node": TOOLCHAIN.reactRouter,
|
|
59
75
|
isbot: TOOLCHAIN.isbot,
|
|
60
76
|
react: TOOLCHAIN.react,
|
|
@@ -79,16 +95,16 @@ export function projectTemplates(name) {
|
|
|
79
95
|
vitest: TOOLCHAIN.vitest,
|
|
80
96
|
},
|
|
81
97
|
};
|
|
82
|
-
|
|
98
|
+
const files = {
|
|
83
99
|
"package.json": json(packageJson),
|
|
84
|
-
".mozole/project.json": json(projectConfig(name)),
|
|
100
|
+
".mozole/project.json": json(projectConfig(name, options)),
|
|
85
101
|
".mozole/toolchain.json": json(TOOLCHAIN),
|
|
86
102
|
".gitignore": "node_modules/\nbuild/\ndist/\n.react-router/\ncoverage/\n.mozole/logs/\n.mozole/qa/\n.mozole/state/\n.mozole/telemetry.json\n.cce/\n.DS_Store\n*.log\n",
|
|
87
103
|
".context-engine.yaml": "retrieval:\n top_k: 20\n confidence_threshold: 0.5\ncompression:\n level: standard\n output: standard\n",
|
|
88
104
|
".agents/mcp_config.json": json({
|
|
89
105
|
mcpServers: { "mozole-cce": cceMcpServer() },
|
|
90
106
|
}),
|
|
91
|
-
".agents/rules/mozole.md": "Follow the shared project contract in `AGENTS.md`. Repository reads are forbidden by default. Required order: CCE search → additional CCE search → bounded line-range read only when CCE output is insufficient → full-file read only after explicit escalation. Editing a file is NOT sufficient justification for reading it in full. If CCE is unavailable, report the blocker; do not fall back to repository reads. Routine browser validation uses screenshot-free `mozole qa`; visual QA requires an explicit request or confirmed deterministic failure. Stop after requested work, `mozole verify`, and relevant routine QA pass.\n",
|
|
107
|
+
".agents/rules/mozole.md": "Follow the shared project contract in `AGENTS.md`. Repository reads are forbidden by default. Required order: CCE search → additional CCE search → bounded line-range read only when CCE output is insufficient → full-file read only after explicit escalation. Editing a file is NOT sufficient justification for reading it in full. If CCE is unavailable, report the blocker; do not fall back to repository reads. Before UI work, follow the Design contract and complete `docs/design-tokens.md`. Routine browser validation uses screenshot-free `mozole qa`; visual QA requires an explicit request or confirmed deterministic failure. Stop after requested work, `mozole verify`, and relevant routine QA pass.\n",
|
|
92
108
|
".agents/workflows/mozole-verify.md": "Run `mozole verify`. If it passes or is current, report the concise result and stop. If it fails, use the actionable summary; retrieve a raw log with `mozole logs <name>` only when the summary is insufficient. Rerun only after a relevant change, unless fresh evidence was explicitly requested with `--force`.\n",
|
|
93
109
|
".agents/workflows/mozole-qa.md": "Run `mozole qa`. Use its deterministic evidence and do not capture or request screenshots. If QA passes or is current, report concisely and stop. If it fails and fixing is in scope, address confirmed evidence and rerun only after a relevant change.\n",
|
|
94
110
|
".agents/workflows/mozole-qa-interactive.md": "Run `mozole qa --interactive`. Use deterministic interaction evidence without screenshots. Fix confirmed in-scope failures, then rerun only after a relevant change. Stop when QA passes or is current.\n",
|
|
@@ -128,7 +144,9 @@ export function projectTemplates(name) {
|
|
|
128
144
|
],
|
|
129
145
|
},
|
|
130
146
|
}),
|
|
131
|
-
"react-router.config.ts":
|
|
147
|
+
"react-router.config.ts": options.withAdmin
|
|
148
|
+
? 'import type { Config } from "@react-router/dev/config";\n\nexport default {\n ssr: true,\n prerender: ["/", "/about", "/contact"],\n} satisfies Config;\n'
|
|
149
|
+
: 'import type { Config } from "@react-router/dev/config";\n\nexport default {\n ssr: false,\n prerender: true,\n} satisfies Config;\n',
|
|
132
150
|
"vite.config.ts": 'import { reactRouter } from "@react-router/dev/vite";\nimport { defineConfig } from "vite";\n\nexport default defineConfig({ plugins: [reactRouter()] });\n',
|
|
133
151
|
"tsconfig.json": json({
|
|
134
152
|
include: ["**/*", ".react-router/types/**/*"],
|
|
@@ -174,18 +192,31 @@ export function projectTemplates(name) {
|
|
|
174
192
|
json: { formatter: { expand: "always" } },
|
|
175
193
|
}),
|
|
176
194
|
"vitest.config.ts": 'import react from "@vitejs/plugin-react";\nimport { defineConfig } from "vitest/config";\n\nexport default defineConfig({\n plugins: [react()],\n test: {\n environment: "jsdom",\n setupFiles: ["./tests/setup.ts"],\n exclude: ["node_modules/**", "build/**", ".react-router/**"],\n },\n});\n',
|
|
177
|
-
"app/routes.ts":
|
|
195
|
+
"app/routes.ts": options.withAdmin
|
|
196
|
+
? 'import { index, type RouteConfig, route } from "@react-router/dev/routes";\n\nexport default [\n index("routes/home.tsx"),\n route("about", "routes/about.tsx"),\n route("contact", "routes/contact.tsx"),\n route("admin/login", "admin/login.tsx"),\n route("admin", "admin/layout.tsx", [index("admin/dashboard.tsx")]),\n] satisfies RouteConfig;\n'
|
|
197
|
+
: 'import { index, type RouteConfig, route } from "@react-router/dev/routes";\n\nexport default [\n index("routes/home.tsx"),\n route("about", "routes/about.tsx"),\n route("contact", "routes/contact.tsx"),\n] satisfies RouteConfig;\n',
|
|
178
198
|
"app/root.tsx": 'import {\n Links,\n Meta,\n NavLink,\n Outlet,\n Scripts,\n ScrollRestoration,\n} from "react-router";\nimport type { Route } from "./+types/root";\nimport "./styles/global.css";\n\nexport const links: Route.LinksFunction = () => [];\n\nexport function Layout({ children }: { children: React.ReactNode }) {\n return (\n <html lang="en">\n <head>\n <meta charSet="utf-8" />\n <meta name="viewport" content="width=device-width, initial-scale=1" />\n <Meta />\n <Links />\n </head>\n <body>\n <header>\n <nav aria-label="Main navigation">\n <NavLink to="/">Home</NavLink>\n <NavLink to="/about">About</NavLink>\n <NavLink to="/contact">Contact</NavLink>\n </nav>\n </header>\n {children}\n <ScrollRestoration />\n <Scripts />\n </body>\n </html>\n );\n}\n\nexport default function App() {\n return <Outlet />;\n}\n\nexport function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {\n const message = error instanceof Error ? error.message : "Unexpected error";\n return (\n <main>\n <h1>Something went wrong</h1>\n <p>{message}</p>\n </main>\n );\n}\n',
|
|
179
|
-
"app/routes/home.tsx": 'export function meta() {\n return [\n { title: "Home" },\n { name: "description", content: "A static-first web project." },\n ];\n}\n\nexport default function Home() {\n return (\n <main>\n <p
|
|
199
|
+
"app/routes/home.tsx": 'export function meta() {\n return [\n { title: "Home" },\n { name: "description", content: "A static-first web project." },\n ];\n}\n\nexport default function Home() {\n return (\n <main>\n <p>Static-first</p>\n <h1>Build the site this project needs.</h1>\n <p>\n React Router Framework Mode, deterministic verification, and browser QA\n are ready.\n </p>\n </main>\n );\n}\n',
|
|
180
200
|
"app/routes/about.tsx": 'export function meta() {\n return [\n { title: "About" },\n { name: "description", content: "About this project." },\n ];\n}\n\nexport default function About() {\n return (\n <main>\n <h1>About</h1>\n <p>Replace this neutral starting point with project-specific content.</p>\n </main>\n );\n}\n',
|
|
181
201
|
"app/routes/contact.tsx": 'export function meta() {\n return [\n { title: "Contact" },\n { name: "description", content: "Contact information." },\n ];\n}\n\nexport default function Contact() {\n return (\n <main>\n <h1>Contact</h1>\n <p>Add the project contact workflow here.</p>\n </main>\n );\n}\n',
|
|
182
|
-
"app/styles/global.css": ":root {\n color-
|
|
202
|
+
"app/styles/global.css": ":root {\n --color-bg: /* TODO: set per-project */;\n --color-fg: /* TODO: set per-project */;\n --color-accent: /* TODO: set per-project */;\n --font-display: /* TODO: set per-project */;\n --font-body: /* TODO: set per-project */;\n color: var(--color-fg);\n background: var(--color-bg);\n font-family: var(--font-body);\n}\n* {\n box-sizing: border-box;\n}\nbody {\n margin: 0;\n min-width: 320px;\n}\na {\n color: var(--color-accent);\n text-underline-offset: 0.2em;\n}\nnav {\n max-width: 70rem;\n margin: auto;\n padding: 1rem 1.5rem;\n display: flex;\n gap: 1.25rem;\n}\nnav a.active {\n font-weight: 700;\n}\nmain {\n width: min(70rem, 100%);\n margin: 0 auto;\n padding: clamp(3rem, 8vw, 8rem) 1.5rem;\n}\nh1 {\n max-width: 18ch;\n font-family: var(--font-display);\n font-size: clamp(2.25rem, 7vw, 5rem);\n line-height: 1.02;\n letter-spacing: -0.04em;\n margin: 0.15em 0 0.4em;\n}\np {\n max-width: 65ch;\n line-height: 1.65;\n}\n",
|
|
183
203
|
"tests/setup.ts": 'import "@testing-library/jest-dom/vitest";\n',
|
|
184
204
|
"tests/smoke.test.tsx": 'import { render, screen } from "@testing-library/react";\nimport { describe, expect, it } from "vitest";\nimport Home from "../app/routes/home";\n\ndescribe("Home", () => {\n it("renders the starting point", () => {\n render(<Home />);\n expect(\n screen.getByRole("heading", { name: /build the site/i }),\n ).toBeVisible();\n });\n});\n',
|
|
185
|
-
"AGENTS.md": "# Project guide\n\n## Commands\n\n- `npm run dev` — local app\n- `npm run verify` — lint, typecheck, tests, production build\n- `npm run qa` — deterministic browser QA (no screenshots)\n- `npm run qa:interactive` — adds safe interaction probes\n- `npm run qa:visual` — explicit screenshot review\n- `mozole cce install` — install persistent CCE and required uv runtime\n- `mozole ui` — full-screen terminal dashboard\n\n## Architecture\n\nReact Router Framework Mode lives in `app/`; routes are in `app/routes.ts`; static output is `build/client/`. Mozole settings are in `.mozole/`; Antigravity integration is in `.agents/`; deeper decisions belong in `docs/`.\n\n## Mandatory CCE contract\n\nRepository reads are forbidden by default. Allowed retrieval order:\n\n1. CCE `context_search`\n2. additional CCE search, `expand_chunk`, or `related_context`\n3. bounded line-range read only when CCE output is insufficient\n4. full-file read only after explicit escalation\n\nEditing a file is NOT sufficient justification for reading it in full. If CCE is unavailable, stop and report the blocker instead of falling back to repository reads. Prefer localized patches and inspect `git diff`. Keep narration and successful logs concise. Routine browser validation uses screenshot-free `mozole qa`; visual QA requires an explicit user request or confirmed deterministic failure. Stop after requested work, `mozole verify`, and relevant routine QA pass.\n",
|
|
186
|
-
"CLAUDE.md": "@AGENTS.md\n\n## Claude Code CCE contract\n\nRepository reads are forbidden by default. Use `context_search`, then additional CCE retrieval. Read may use a bounded line range only when CCE is insufficient; a full-file Read requires explicit escalation. Editing is not justification. If CCE is unavailable, report the blocker; do not fall back.\n",
|
|
187
|
-
"docs/
|
|
205
|
+
"AGENTS.md": "# Project guide\n\n## Commands\n\n- `npm run dev` — local app\n- `npm run verify` — lint, typecheck, tests, production build\n- `npm run qa` — deterministic browser QA (no screenshots)\n- `npm run qa:interactive` — adds safe interaction probes\n- `npm run qa:visual` — explicit screenshot review\n- `mozole cce install` — install persistent CCE and required uv runtime\n- `mozole ui` — full-screen terminal dashboard\n\n## Architecture\n\nReact Router Framework Mode lives in `app/`; routes are in `app/routes.ts`; static output is `build/client/`. Mozole settings are in `.mozole/`; Antigravity integration is in `.agents/`; deeper decisions belong in `docs/`.\n\n## Design contract\n\nBefore writing UI code, complete `docs/design-tokens.md` and set its CSS custom properties. Avoid every banned default pattern listed there. Before generating markup for a new page, write a one-paragraph design rationale covering visual direction, typography, palette, and layout.\n\n## Mandatory CCE contract\n\nRepository reads are forbidden by default. Allowed retrieval order:\n\n1. CCE `context_search`\n2. additional CCE search, `expand_chunk`, or `related_context`\n3. bounded line-range read only when CCE output is insufficient\n4. full-file read only after explicit escalation\n\nEditing a file is NOT sufficient justification for reading it in full. If CCE is unavailable, stop and report the blocker instead of falling back to repository reads. Prefer localized patches and inspect `git diff`. Keep narration and successful logs concise. Routine browser validation uses screenshot-free `mozole qa`; visual QA requires an explicit user request or confirmed deterministic failure. Stop after requested work, `mozole verify`, and relevant routine QA pass.\n",
|
|
206
|
+
"CLAUDE.md": "@AGENTS.md\n\n## Design contract\n\nComplete `docs/design-tokens.md`, avoid its banned defaults, and write a one-paragraph design rationale before generating markup for a new page.\n\n## Claude Code CCE contract\n\nRepository reads are forbidden by default. Use `context_search`, then additional CCE retrieval. Read may use a bounded line range only when CCE is insufficient; a full-file Read requires explicit escalation. Editing is not justification. If CCE is unavailable, report the blocker; do not fall back.\n",
|
|
207
|
+
"docs/design-tokens.md": "# Design tokens\n\nComplete this contract before writing UI code. Replace every TODO custom-property value in `app/styles/global.css` with a deliberate project-specific choice.\n\n## Required decisions\n\n- `--color-bg`: primary page background.\n- `--color-fg`: primary text and foreground.\n- `--color-accent`: interactive and emphasis color.\n- `--font-display`: heading/display family and fallbacks.\n- `--font-body`: body/interface family and fallbacks.\n- Record one paragraph explaining visual direction, typography, palette, spacing, and layout before generating markup for each new page.\n\n## Banned default patterns\n\nDo not use these as automatic defaults:\n\n- Warm cream background with terracotta accent palette.\n- Identical border-radius and soft grey box-shadow on every card.\n- Uppercase, tracked-out eyebrow labels.\n- En- or em-dash-joined meta labels.\n- Arrow glyphs appended to button text.\n",
|
|
208
|
+
"docs/architecture.md": options.withAdmin
|
|
209
|
+
? "# Architecture\n\nThe app uses React Router Framework Mode with Vite. Public routes `/`, `/about`, and `/contact` are prerendered into `build/client/` and can still be served as static HTML. The opt-in `/admin` area is deliberately excluded from prerendering and uses React Router loaders/actions for a login gate, so the complete application requires a Node runtime serving `build/server/index.js` via `npm start`. It cannot deploy to pure static hosting when the admin route must work. Configure `MOZOLE_ADMIN_PASSWORD` and `MOZOLE_ADMIN_SESSION_SECRET` in the runtime environment; replace the example authentication seam before production use. Mozole fingerprints relevant inputs under `.mozole/state/`; unchanged successful verification and QA are reused, while `--force` requests fresh evidence.\n"
|
|
210
|
+
: "# Architecture\n\nThe app uses React Router Framework Mode with Vite. `ssr: false` and `prerender: true` emit real HTML for every statically declared route. Static files in `build/client/` can be served beside a future PHP backend without a production Node process. Mozole fingerprints relevant inputs under `.mozole/state/`; unchanged successful verification and QA are reused, while `--force` requests fresh evidence. Codex and Claude Code use the shared root instructions; Antigravity workspace MCP, rules, and workflows live under `.agents/` and share the same CCE index.\n",
|
|
188
211
|
"README.md": `# ${name}\n\nStatic-first React Router Framework Mode project generated by Mozole for Codex, Claude Code, and Google Antigravity.\n\n## Start\n\n\`\`\`sh\nnpm install\nnpm run dev\n\`\`\`\n\nRun \`npm run verify\` before handoff and \`npm run qa\` for screenshot-free browser checks. Unchanged successful checks are reused; use \`--force\` for intentionally fresh evidence. Visual QA is explicit only. Antigravity workspace integration is under \`.agents/\`. Production files are emitted to \`build/client/\`.\n`,
|
|
189
212
|
};
|
|
213
|
+
if (options.withAdmin)
|
|
214
|
+
Object.assign(files, {
|
|
215
|
+
"app/admin/session.server.ts": 'import { createCookie } from "react-router";\n\nfunction adminCookie() {\n const secret = process.env.MOZOLE_ADMIN_SESSION_SECRET;\n if (!secret) return undefined;\n return createCookie("mozole_admin_session", {\n httpOnly: true,\n maxAge: 60 * 60 * 8,\n path: "/",\n sameSite: "lax",\n secrets: [secret],\n secure: process.env.NODE_ENV === "production",\n });\n}\n\nexport async function isAdminAuthenticated(request: Request) {\n const cookie = adminCookie();\n if (!cookie) return false;\n return (\n (await cookie.parse(request.headers.get("Cookie"))) === "authenticated"\n );\n}\n\nexport async function createAdminSession() {\n const cookie = adminCookie();\n if (!cookie) return undefined;\n return cookie.serialize("authenticated");\n}\n',
|
|
216
|
+
"app/admin/layout.tsx": 'import { Outlet, redirect } from "react-router";\nimport type { Route } from "./+types/layout";\nimport { isAdminAuthenticated } from "./session.server";\n\nexport async function loader({ request }: Route.LoaderArgs) {\n if (!(await isAdminAuthenticated(request))) throw redirect("/admin/login");\n return null;\n}\n\nexport default function AdminLayout() {\n return (\n <main>\n <h1>Admin</h1>\n <Outlet />\n </main>\n );\n}\n',
|
|
217
|
+
"app/admin/login.tsx": 'import { data, Form, redirect, useActionData } from "react-router";\nimport type { Route } from "./+types/login";\nimport { createAdminSession } from "./session.server";\n\nexport async function action({ request }: Route.ActionArgs) {\n const form = await request.formData();\n const expected = process.env.MOZOLE_ADMIN_PASSWORD;\n const session = await createAdminSession();\n if (!expected || !session)\n return data(\n { error: "Admin runtime credentials are not configured." },\n { status: 503 },\n );\n if (form.get("password") !== expected)\n return data({ error: "Invalid credentials." }, { status: 401 });\n return redirect("/admin", { headers: { "Set-Cookie": session } });\n}\n\nexport default function AdminLogin() {\n const result = useActionData<typeof action>();\n return (\n <main>\n <h1>Admin login</h1>\n <Form method="post">\n <label>\n Password\n <input name="password" type="password" required />\n </label>\n <button type="submit">Sign in</button>\n </Form>\n {result?.error ? <p role="alert">{result.error}</p> : null}\n </main>\n );\n}\n',
|
|
218
|
+
"app/admin/dashboard.tsx": "export default function AdminDashboard() {\n return (\n <section>\n <h2>Protected dashboard</h2>\n <p>Replace this example route with the project-specific admin surface.</p>\n </section>\n );\n}\n",
|
|
219
|
+
});
|
|
220
|
+
return files;
|
|
190
221
|
}
|
|
191
222
|
//# sourceMappingURL=templates.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/verify/runner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/verify/runner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAMzD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,SAAS,UAAW,MAAM,KAAG,MAAiC,CAAC;AAE5E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,MAAM,CAoBpE;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,YAAY,EACpB,MAAM,CAAC,EAAE,WAAW,EACpB,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACjE,OAAO,CAAC;IAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC,CAyFtE"}
|
package/dist/verify/runner.js
CHANGED
|
@@ -2,6 +2,7 @@ import { access } from "node:fs/promises";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { npmExecutable, resolveExecutable } from "../platform/executable.js";
|
|
4
4
|
import { run } from "../platform/process.js";
|
|
5
|
+
import { inspectAdminScaffold } from "../scaffold/admin.js";
|
|
5
6
|
import { updateTelemetry } from "../telemetry/store.js";
|
|
6
7
|
const ansi = new RegExp(`${String.fromCharCode(27)}\\[[0-?]*[ -/]*[@-~]`, "g");
|
|
7
8
|
export const stripAnsi = (value) => value.replace(ansi, "");
|
|
@@ -41,11 +42,27 @@ export async function runVerification(root, config, signal, onStep) {
|
|
|
41
42
|
...config.verifiers,
|
|
42
43
|
];
|
|
43
44
|
const results = [];
|
|
45
|
+
const adminOffset = config.admin?.enabled ? 1 : 0;
|
|
46
|
+
const total = checks.length + adminOffset;
|
|
47
|
+
if (config.admin?.enabled) {
|
|
48
|
+
onStep?.("admin", 1, total);
|
|
49
|
+
const admin = await inspectAdminScaffold(root, config);
|
|
50
|
+
results.push({
|
|
51
|
+
name: "admin",
|
|
52
|
+
passed: admin.healthy,
|
|
53
|
+
detail: admin.healthy ? undefined : admin.detail,
|
|
54
|
+
rawChars: admin.detail.length,
|
|
55
|
+
});
|
|
56
|
+
if (!admin.healthy) {
|
|
57
|
+
const body = `VERIFY FAIL\n\nadmin ✗\n\n${admin.detail}`;
|
|
58
|
+
return { results, output: body, passed: false };
|
|
59
|
+
}
|
|
60
|
+
}
|
|
44
61
|
for (let i = 0; i < checks.length; i++) {
|
|
45
62
|
const check = checks[i];
|
|
46
63
|
if (!check)
|
|
47
64
|
continue;
|
|
48
|
-
onStep?.(check.name, i + 1,
|
|
65
|
+
onStep?.(check.name, i + 1 + adminOffset, total);
|
|
49
66
|
let result;
|
|
50
67
|
try {
|
|
51
68
|
result = await run(check.command, check.args, {
|
|
@@ -78,8 +95,7 @@ export async function runVerification(root, config, signal, onStep) {
|
|
|
78
95
|
if (result.exitCode !== 0)
|
|
79
96
|
break;
|
|
80
97
|
}
|
|
81
|
-
const passed = results.length ===
|
|
82
|
-
results.every((result) => result.passed);
|
|
98
|
+
const passed = results.length === total && results.every((result) => result.passed);
|
|
83
99
|
const body = passed
|
|
84
100
|
? `VERIFY PASS\n\n${results.map((result) => `${result.name.padEnd(10)} ✓`).join("\n")}`
|
|
85
101
|
: `VERIFY FAIL\n\n${results.map((result) => `${result.name.padEnd(10)} ${result.passed ? "✓" : "✗"}`).join("\n")}\n\n${results.find((result) => !result.passed)?.detail ?? "Unknown failure"}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/verify/runner.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/verify/runner.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mozole/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Static-first React Router bootstrap and agent harness",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -27,11 +27,14 @@
|
|
|
27
27
|
"verify": "npm run lint && npm run typecheck && npm run test:run && npm run build"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"
|
|
30
|
+
"pixelmatch": "^7.2.0",
|
|
31
|
+
"playwright": "1.62.1",
|
|
32
|
+
"pngjs": "^7.0.0"
|
|
31
33
|
},
|
|
32
34
|
"devDependencies": {
|
|
33
35
|
"@biomejs/biome": "2.5.11",
|
|
34
36
|
"@types/node": "26.4.0",
|
|
37
|
+
"@types/pngjs": "^6.0.5",
|
|
35
38
|
"cross-env": "10.1.0",
|
|
36
39
|
"tsx": "4.20.6",
|
|
37
40
|
"typescript": "7.0.2",
|