@mozole/cli 1.4.0 → 1.4.1
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/CHANGELOG.md +10 -1
- package/README.md +5 -1
- package/dist/commands/adopt.d.ts +1 -1
- package/dist/commands/adopt.d.ts.map +1 -1
- package/dist/commands/adopt.js +312 -102
- package/dist/commands/adopt.js.map +1 -1
- package/dist/platform/process.d.ts.map +1 -1
- package/dist/platform/process.js +4 -0
- package/dist/platform/process.js.map +1 -1
- package/dist/scaffold/adoption.d.ts +17 -0
- package/dist/scaffold/adoption.d.ts.map +1 -0
- package/dist/scaffold/adoption.js +279 -0
- package/dist/scaffold/adoption.js.map +1 -0
- package/dist/scaffold/design.d.ts +4 -0
- package/dist/scaffold/design.d.ts.map +1 -0
- package/dist/scaffold/design.js +50 -0
- package/dist/scaffold/design.js.map +1 -0
- package/dist/scaffold/legacy.d.ts +4 -0
- package/dist/scaffold/legacy.d.ts.map +1 -0
- package/dist/scaffold/legacy.js +139 -0
- package/dist/scaffold/legacy.js.map +1 -0
- package/dist/scaffold/routes.d.ts +3 -0
- package/dist/scaffold/routes.d.ts.map +1 -0
- package/dist/scaffold/routes.js +37 -0
- package/dist/scaffold/routes.js.map +1 -0
- package/dist/scaffold/standalone.d.ts +2 -1
- package/dist/scaffold/standalone.d.ts.map +1 -1
- package/dist/scaffold/standalone.js +43 -19
- package/dist/scaffold/standalone.js.map +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +9 -4
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/version.d.ts +2 -2
- package/dist/version.js +1 -1
- package/docs/agent-audit.md +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/** Exact pre-1.4 templates, used only to recognize and migrate generator-owned text. */
|
|
2
|
+
export const legacyInstructions = {
|
|
3
|
+
"AGENTS.md": "# Project guide\n\n## Commands\n\n- `npm run dev` \u2014 local app\n- `npm run verify` \u2014 lint, typecheck, tests, production build\n- `npm run qa` \u2014 deterministic browser QA (no screenshots)\n- `npm run qa:interactive` \u2014 adds safe interaction probes\n- `npm run qa:visual` \u2014 explicit screenshot review\n- `mozole cce install` \u2014 install persistent CCE and required uv runtime\n- `mozole ui` \u2014 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",
|
|
4
|
+
"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",
|
|
5
|
+
"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",
|
|
6
|
+
};
|
|
7
|
+
export function legacyBackendTemplates(name) {
|
|
8
|
+
return {
|
|
9
|
+
"api/index.php": `<?php
|
|
10
|
+
declare(strict_types=1);
|
|
11
|
+
|
|
12
|
+
require_once __DIR__ . '/config.php';
|
|
13
|
+
|
|
14
|
+
header('Content-Type: application/json; charset=utf-8');
|
|
15
|
+
header('X-Content-Type-Options: nosniff');
|
|
16
|
+
header('X-Frame-Options: DENY');
|
|
17
|
+
|
|
18
|
+
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
|
|
19
|
+
$uri = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?? '/';
|
|
20
|
+
|
|
21
|
+
// Normalize URI to match route path (handles both /api/path and direct /path on dev server)
|
|
22
|
+
$basePrefix = '/api';
|
|
23
|
+
if (str_starts_with($uri, $basePrefix)) {
|
|
24
|
+
$route = '/' . ltrim(substr($uri, strlen($basePrefix)), '/');
|
|
25
|
+
} else {
|
|
26
|
+
$route = '/' . ltrim($uri, '/');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
switch ($route) {
|
|
30
|
+
case '/':
|
|
31
|
+
case '/health':
|
|
32
|
+
echo json_encode([
|
|
33
|
+
'status' => 'ok',
|
|
34
|
+
'app' => '${name}',
|
|
35
|
+
'runtime' => 'PHP ' . PHP_VERSION,
|
|
36
|
+
'timestamp' => time(),
|
|
37
|
+
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
|
38
|
+
break;
|
|
39
|
+
|
|
40
|
+
case '/info':
|
|
41
|
+
echo json_encode([
|
|
42
|
+
'name' => '${name}',
|
|
43
|
+
'backend' => 'PHP native API',
|
|
44
|
+
'endpoints' => [
|
|
45
|
+
'GET /api/health' => 'Service status check',
|
|
46
|
+
'GET /api/info' => 'Backend metadata',
|
|
47
|
+
],
|
|
48
|
+
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
|
49
|
+
break;
|
|
50
|
+
|
|
51
|
+
default:
|
|
52
|
+
http_response_code(404);
|
|
53
|
+
echo json_encode([
|
|
54
|
+
'error' => 'Endpoint not found',
|
|
55
|
+
'path' => $uri,
|
|
56
|
+
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
`,
|
|
60
|
+
"api/config.php": `<?php
|
|
61
|
+
declare(strict_types=1);
|
|
62
|
+
|
|
63
|
+
function env(string $key, ?string $default = null): ?string {
|
|
64
|
+
$value = getenv($key);
|
|
65
|
+
return $value !== false ? $value : $default;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Environment configuration
|
|
69
|
+
define('APP_ENV', env('APP_ENV', 'development'));
|
|
70
|
+
define('APP_DEBUG', env('APP_DEBUG', 'true') === 'true');
|
|
71
|
+
|
|
72
|
+
// Optional database connection helper
|
|
73
|
+
function get_db_connection(): ?PDO {
|
|
74
|
+
static $pdo = null;
|
|
75
|
+
if ($pdo !== null) {
|
|
76
|
+
return $pdo;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
$dsn = env('DB_DSN');
|
|
80
|
+
if (!$dsn) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
$user = env('DB_USER', '');
|
|
85
|
+
$pass = env('DB_PASS', '');
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
$pdo = new PDO($dsn, $user, $pass, [
|
|
89
|
+
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
|
90
|
+
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
|
91
|
+
PDO::ATTR_EMULATE_PREPARES => false,
|
|
92
|
+
]);
|
|
93
|
+
return $pdo;
|
|
94
|
+
} catch (PDOException $e) {
|
|
95
|
+
if (APP_DEBUG) {
|
|
96
|
+
throw $e;
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
`,
|
|
102
|
+
".htaccess": `<IfModule mod_rewrite.c>
|
|
103
|
+
RewriteEngine On
|
|
104
|
+
RewriteBase /
|
|
105
|
+
|
|
106
|
+
# Route API requests to PHP front-controller
|
|
107
|
+
RewriteRule ^api(/.*)?$ api/index.php [QSA,L]
|
|
108
|
+
|
|
109
|
+
# Serve static assets directly if they exist
|
|
110
|
+
RewriteCond %{REQUEST_FILENAME} -f [OR]
|
|
111
|
+
RewriteCond %{REQUEST_FILENAME} -d
|
|
112
|
+
RewriteRule ^ - [L]
|
|
113
|
+
|
|
114
|
+
# Fallback to prerendered / client index for SPA routes
|
|
115
|
+
RewriteRule ^index\\.html$ - [L]
|
|
116
|
+
RewriteRule . /index.html [L]
|
|
117
|
+
</IfModule>
|
|
118
|
+
`,
|
|
119
|
+
"docs/backend-php.md": `# PHP Backend Architecture
|
|
120
|
+
|
|
121
|
+
This project combines a **static-first React + Vite frontend** with a lightweight, native **PHP backend API**.
|
|
122
|
+
|
|
123
|
+
## How It Works
|
|
124
|
+
|
|
125
|
+
### Local Development
|
|
126
|
+
- **Frontend (React + Vite)**: Runs via \`npm run dev\` (typically at \`http://127.0.0.1:5173\`).
|
|
127
|
+
- **Backend (PHP API)**: Runs via \`npm run dev:api\` (\`php -S 127.0.0.1:8000 -t api\`).
|
|
128
|
+
- **Proxy**: Vite's \`server.proxy\` automatically forwards all \`/api/*\` requests from the browser directly to the PHP dev server. Your React code calls \`fetch("/api/health")\` without dealing with CORS or port mismatches.
|
|
129
|
+
|
|
130
|
+
### Production Deployment (Apache / LiteSpeed / Nginx)
|
|
131
|
+
- **Zero Node.js runtime required**: Deploy the \`build/client/\` static files and the \`api/\` directory to any shared hosting or VPS.
|
|
132
|
+
- **Apache / LiteSpeed**: The provided \`.htaccess\` handles routing:
|
|
133
|
+
- All \`/api/*\` calls are routed directly to \`api/index.php\`.
|
|
134
|
+
- All static HTML, CSS, JS, and image assets are served directly by the web server at maximum speed.
|
|
135
|
+
- **Nginx**: Forward \`/api/\` to \`fastcgi_pass\` and serve \`try_files $uri $uri/ /index.html\`.
|
|
136
|
+
`,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=legacy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy.js","sourceRoot":"","sources":["../../src/scaffold/legacy.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,MAAM,CAAC,MAAM,kBAAkB,GAA2B;IACxD,WAAW,EACT,48CAA48C;IAC98C,WAAW,EACT,2VAA2V;IAC7V,uBAAuB,EACrB,w5BAAw5B;CAC35B,CAAC;AAEF,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,OAAO;QACL,eAAe,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;wBAyBG,IAAI;;;;;;;;yBAQH,IAAI;;;;;;;;;;;;;;;;;CAiB5B;QAEG,gBAAgB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCrB;QAEG,WAAW,EAAE;;;;;;;;;;;;;;;;CAgBhB;QAEG,qBAAqB,EAAE;;;;;;;;;;;;;;;;;CAiB1B;KACE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/scaffold/routes.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAqCrD"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Discover literal React Router route/prefix calls without evaluating project code. */
|
|
2
|
+
export function detectRoutes(source) {
|
|
3
|
+
const tokens = (source.match(/\/\*[\s\S]*?\*\/|\/\/[^\n]*|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|[a-zA-Z_$][\w$]*|[^\s]/g) ?? []).filter((token) => !token.startsWith("//") && !token.startsWith("/*"));
|
|
4
|
+
const routes = new Set(["/"]);
|
|
5
|
+
function scan(start, end, base) {
|
|
6
|
+
for (let i = start; i < end; i++) {
|
|
7
|
+
const name = tokens[i];
|
|
8
|
+
if (!["route", "prefix", "layout", "index"].includes(name ?? "") ||
|
|
9
|
+
tokens[i + 1] !== "(")
|
|
10
|
+
continue;
|
|
11
|
+
let depth = 1;
|
|
12
|
+
let close = i + 2;
|
|
13
|
+
for (; close < end; close++) {
|
|
14
|
+
if (tokens[close] === "(")
|
|
15
|
+
depth++;
|
|
16
|
+
if (tokens[close] === ")" && --depth === 0)
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
const literal = tokens[i + 2];
|
|
20
|
+
const value = literal && /^["']/.test(literal) ? literal.slice(1, -1) : undefined;
|
|
21
|
+
if (name === "layout")
|
|
22
|
+
scan(i + 2, close, base);
|
|
23
|
+
else if (name === "index")
|
|
24
|
+
routes.add(base || "/");
|
|
25
|
+
else if (value !== undefined && !/[:*?\\]/.test(value)) {
|
|
26
|
+
const joined = `${base}/${value}`.replace(/\/{2,}/g, "/").replace(/\/$/, "") || "/";
|
|
27
|
+
if (name === "route")
|
|
28
|
+
routes.add(joined);
|
|
29
|
+
scan(i + 3, close, joined);
|
|
30
|
+
}
|
|
31
|
+
i = close;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
scan(0, tokens.length, "");
|
|
35
|
+
return [...routes];
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/scaffold/routes.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,MAAM,MAAM,GAAG,CACb,MAAM,CAAC,KAAK,CACV,yFAAyF,CAC1F,IAAI,EAAE,CACR,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,SAAS,IAAI,CAAC,KAAa,EAAE,GAAW,EAAE,IAAY;QACpD,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACvB,IACE,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC;gBAC5D,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG;gBAErB,SAAS;YACX,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,IAAI,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;YAClB,OAAO,KAAK,GAAG,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC5B,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG;oBAAE,KAAK,EAAE,CAAC;gBACnC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,KAAK,CAAC;oBAAE,MAAM;YACpD,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9B,MAAM,KAAK,GACT,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACtE,IAAI,IAAI,KAAK,QAAQ;gBAAE,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;iBAC3C,IAAI,IAAI,KAAK,OAAO;gBAAE,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC;iBAC9C,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvD,MAAM,MAAM,GACV,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC;gBACvE,IAAI,IAAI,KAAK,OAAO;oBAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACzC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;YAC7B,CAAC;YACD,CAAC,GAAG,KAAK,CAAC;QACZ,CAAC;IACH,CAAC;IACD,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC3B,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC;AACrB,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** Standalone project tooling: no dependency on the generator at runtime. */
|
|
2
2
|
export declare const backendCheckScript = "import { spawnSync } from \"node:child_process\";\nimport { readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nfunction php(args) {\n const result = spawnSync(\"php\", args, {\n encoding: \"utf8\",\n shell: false,\n timeout: 10000,\n });\n if (result.error || result.status !== 0)\n throw new Error(result.error?.message || result.stderr || result.stdout);\n return result.stdout.trim();\n}\nasync function lint(directory) {\n for (const entry of await readdir(directory, { withFileTypes: true })) {\n const file = path.join(directory, entry.name);\n if (entry.isDirectory()) await lint(file);\n else if (entry.isFile() && entry.name.endsWith(\".php\")) php([\"-l\", file]);\n }\n}\ntry {\n const version = Number(php([\"-r\", \"echo PHP_VERSION_ID;\"]));\n if (!Number.isInteger(version) || version < 80000)\n throw new Error(\"PHP 8.0 or newer is required.\");\n await lint(\"api\");\n console.log(\"PHP PASS\");\n} catch (error) {\n console.error(`PHP FAIL\\n${error.message}`);\n process.exitCode = 1;\n}\n";
|
|
3
3
|
export declare const deployScript = "import { cp, lstat, mkdir, rename, rm } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nconst target = path.resolve(\"deploy\");\nconst staging = `${target}.${process.pid}.tmp`;\nconst backup = `${target}.${process.pid}.backup`;\nlet backedUp = false;\ntry {\n await mkdir(staging);\n await cp(\"build/client\", staging, { recursive: true, errorOnExist: true });\n await cp(\"api\", path.join(staging, \"api\"), { recursive: true });\n await cp(\".htaccess\", path.join(staging, \".htaccess\"));\n try {\n await lstat(target);\n await rename(target, backup);\n backedUp = true;\n } catch (error) {\n if (error.code !== \"ENOENT\") throw error;\n }\n try {\n await rename(staging, target);\n } catch (error) {\n if (backedUp) await rename(backup, target);\n throw error;\n }\n if (backedUp) await rm(backup, { recursive: true });\n console.log(\"DEPLOY READY: deploy/\");\n} finally {\n await rm(staging, { recursive: true, force: true });\n}\n";
|
|
4
|
-
export declare const qaScript = "import { spawn, spawnSync } from \"node:child_process\";\nimport { mkdir, readFile } from \"node:fs/promises\";\nimport net from \"node:net\";\nimport
|
|
4
|
+
export declare const qaScript = "import { spawn, spawnSync } from \"node:child_process\";\nimport { mkdir, readFile } from \"node:fs/promises\";\nimport net from \"node:net\";\nimport { chromium } from \"playwright\";\n\nconst flags = process.argv.slice(2);\nif (\n flags.some((flag) => ![\"--visual\", \"--interactive\", \"--force\"].includes(flag))\n)\n throw new Error(\"Unknown QA option\");\nconst config = JSON.parse(await readFile(\".mozole/project.json\", \"utf8\"));\nconst socket = net.createServer();\nawait new Promise((resolve, reject) => {\n socket.once(\"error\", reject);\n socket.listen(0, \"127.0.0.1\", resolve);\n});\nconst port = socket.address().port;\nawait new Promise((resolve) => socket.close(resolve));\nconst configured = config.qa.server;\nconst npmCli = process.env.npm_execpath;\nif (configured.command === \"npm\" && !npmCli) {\n throw new Error(\n \"Run QA through npm run qa so npm can be resolved without a shell.\",\n );\n}\nconst command =\n configured.command === \"npm\" ? process.execPath : configured.command;\nconst args = [\n ...(configured.command === \"npm\" ? [npmCli] : []),\n ...configured.args,\n \"--port\",\n String(port),\n \"--strictPort\",\n];\nconst child = spawn(command, args, {\n shell: false,\n detached: process.platform !== \"win32\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n});\nlet serverLog = \"\";\nfor (const stream of [child.stdout, child.stderr])\n stream.on(\"data\", (data) => {\n serverLog = (serverLog + data).slice(-4000);\n });\nlet serverError;\nchild.on(\"error\", (error) => {\n serverError = error;\n});\nlet browser;\nlet stopping = false;\nasync function cleanup() {\n if (stopping) return;\n stopping = true;\n await browser?.close().catch(() => {});\n if (child.pid) {\n if (process.platform === \"win32\")\n spawnSync(\"taskkill\", [\"/pid\", String(child.pid), \"/T\", \"/F\"], {\n shell: false,\n stdio: \"ignore\",\n });\n else {\n try {\n process.kill(-child.pid, \"SIGTERM\");\n } catch {}\n }\n }\n}\nconst interrupted = () => {\n void cleanup().finally(() => process.exit(130));\n};\nprocess.once(\"SIGINT\", interrupted);\nprocess.once(\"SIGTERM\", interrupted);\nconst deadline = setTimeout(() => {\n console.error(\"QA timed out\");\n void cleanup().finally(() => process.exit(1));\n}, 120000);\nconst base = `http://127.0.0.1:${port}`;\ntry {\n let ready = false;\n for (let attempt = 0; attempt < 300; attempt++) {\n if (serverError || child.exitCode !== null)\n throw new Error(serverError?.message || serverLog);\n try {\n ready = (\n await fetch(base + config.qa.server.readinessPath, {\n signal: AbortSignal.timeout(1000),\n })\n ).ok;\n } catch {}\n if (ready) break;\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n if (!ready)\n throw new Error(`Development server did not become ready.\\n${serverLog}`);\n browser = await chromium.launch();\n const failures = [];\n for (const viewport of config.qa.viewports) {\n const page = await browser.newPage({ viewport });\n page.on(\"pageerror\", (error) => failures.push(error.message));\n page.on(\"console\", (message) => {\n if (message.type() === \"error\") failures.push(message.text());\n });\n page.on(\"requestfailed\", (request) => {\n if (request.failure()?.errorText !== \"net::ERR_ABORTED\")\n failures.push(request.url());\n });\n page.on(\"response\", (response) => {\n if (response.status() >= 400)\n failures.push(`${response.status()} ${response.url()}`);\n });\n for (const route of config.routes) {\n const response = await page.goto(base + route, {\n waitUntil: \"networkidle\",\n });\n if (!response?.ok()) failures.push(`${route}: HTTP failure`);\n const issues = await page.evaluate(() => {\n const found = [];\n if (!document.documentElement.lang) found.push(\"missing lang\");\n if (!document.title.trim()) found.push(\"missing title\");\n if (!document.querySelector(\"h1\")) found.push(\"missing h1\");\n if (document.documentElement.scrollWidth > innerWidth + 1)\n found.push(\"horizontal overflow\");\n for (const element of document.querySelectorAll(\n \"a, button, input:not([type=hidden]), select, textarea\",\n )) {\n if (!element.getClientRects().length) continue;\n const labelled = (element.getAttribute(\"aria-labelledby\") || \"\")\n .split(/\\s+/)\n .some((id) => document.getElementById(id)?.textContent?.trim());\n if (\n !element.textContent?.trim() &&\n !element.getAttribute(\"aria-label\") &&\n !labelled &&\n !element.labels?.length &&\n !element.getAttribute(\"title\") &&\n !element.getAttribute(\"alt\") &&\n !element.querySelector(\"img[alt]\")\n )\n found.push(\"unnamed control\");\n }\n return found;\n });\n failures.push(...issues.map((issue) => `${route}: ${issue}`));\n const links = await page\n .locator(\"a[href]\")\n .evaluateAll((anchors) => anchors.map((anchor) => anchor.href));\n for (const href of new Set(links)) {\n if (\n new URL(href).origin === base &&\n !(await page.request.get(href)).ok()\n )\n failures.push(`broken link: ${href}`);\n }\n if (flags.includes(\"--interactive\")) {\n await page.keyboard.press(\"Tab\");\n if (\n !(await page.evaluate(() => document.activeElement !== document.body))\n )\n failures.push(`${route}: keyboard focus missing`);\n }\n if (flags.includes(\"--visual\")) {\n await mkdir(\".mozole/qa\", { recursive: true });\n const name = route.replace(/[^a-z0-9_-]/gi, \"-\") || \"index\";\n await page.screenshot({\n path:\n \".mozole/qa/\" +\n viewport.width +\n \"x\" +\n viewport.height +\n \"-\" +\n name +\n \".png\",\n fullPage: true,\n });\n }\n }\n await page.close();\n }\n if (failures.length) throw new Error([...new Set(failures)].join(\"\\n\"));\n console.log(\n \"QA PASS: \" +\n config.routes.length +\n \" routes, \" +\n config.qa.viewports.length +\n \" viewports\",\n );\n} catch (error) {\n console.error(`QA FAIL\\n${error.message}`);\n process.exitCode = 1;\n} finally {\n clearTimeout(deadline);\n process.removeListener(\"SIGINT\", interrupted);\n process.removeListener(\"SIGTERM\", interrupted);\n await cleanup();\n}\n";
|
|
5
5
|
export declare function basicAgentGuide(backend: boolean): string;
|
|
6
|
+
export declare const extraVerifierScript = "import { spawnSync } from \"node:child_process\";\nimport { readFile } from \"node:fs/promises\";\n\nconst config = JSON.parse(await readFile(\".mozole/project.json\", \"utf8\"));\nfor (const check of config.verifiers ?? []) {\n if (\n typeof check.command !== \"string\" ||\n !Array.isArray(check.args) ||\n !check.args.every((arg) => typeof arg === \"string\")\n )\n throw new Error(\"Invalid extra verifier\");\n const npm = check.command === \"npm\";\n if (npm && !process.env.npm_execpath)\n throw new Error(\"Run verification through npm run verify\");\n const result = spawnSync(\n npm ? process.execPath : check.command,\n npm ? [process.env.npm_execpath, ...check.args] : check.args,\n { shell: false, stdio: \"inherit\", timeout: 600000 },\n );\n if (result.error || result.status !== 0) {\n console.error(\n \"Extra verifier failed:\",\n check.name,\n result.error?.message ?? result.status,\n );\n process.exit(result.status || 1);\n }\n}\n";
|
|
6
7
|
//# sourceMappingURL=standalone.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standalone.d.ts","sourceRoot":"","sources":["../../src/scaffold/standalone.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"standalone.d.ts","sourceRoot":"","sources":["../../src/scaffold/standalone.ts"],"names":[],"mappings":"AAEA,6EAA6E;AAC7E,eAAO,MAAM,kBAAkB,ijCA+B9B,CAAC;AAEF,eAAO,MAAM,YAAY,q+BA8BxB,CAAC;AAEF,eAAO,MAAM,QAAQ,qlNAmMpB,CAAC;AAEF,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAExD;AAED,eAAO,MAAM,mBAAmB,q/BA4B/B,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { designGuardrails } from "./design.js";
|
|
1
2
|
/** Standalone project tooling: no dependency on the generator at runtime. */
|
|
2
3
|
export const backendCheckScript = `import { spawnSync } from "node:child_process";
|
|
3
4
|
import { readdir } from "node:fs/promises";
|
|
@@ -65,7 +66,6 @@ try {
|
|
|
65
66
|
export const qaScript = `import { spawn, spawnSync } from "node:child_process";
|
|
66
67
|
import { mkdir, readFile } from "node:fs/promises";
|
|
67
68
|
import net from "node:net";
|
|
68
|
-
import path from "node:path";
|
|
69
69
|
import { chromium } from "playwright";
|
|
70
70
|
|
|
71
71
|
const flags = process.argv.slice(2);
|
|
@@ -81,28 +81,23 @@ await new Promise((resolve, reject) => {
|
|
|
81
81
|
});
|
|
82
82
|
const port = socket.address().port;
|
|
83
83
|
await new Promise((resolve) => socket.close(resolve));
|
|
84
|
-
const
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
typeof metadata.bin === "string"
|
|
94
|
-
? metadata.bin
|
|
95
|
-
: Object.values(metadata.bin)[0];
|
|
84
|
+
const configured = config.qa.server;
|
|
85
|
+
const npmCli = process.env.npm_execpath;
|
|
86
|
+
if (configured.command === "npm" && !npmCli) {
|
|
87
|
+
throw new Error(
|
|
88
|
+
"Run QA through npm run qa so npm can be resolved without a shell.",
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
const command =
|
|
92
|
+
configured.command === "npm" ? process.execPath : configured.command;
|
|
96
93
|
const args = [
|
|
97
|
-
|
|
98
|
-
...
|
|
99
|
-
"--host",
|
|
100
|
-
"127.0.0.1",
|
|
94
|
+
...(configured.command === "npm" ? [npmCli] : []),
|
|
95
|
+
...configured.args,
|
|
101
96
|
"--port",
|
|
102
97
|
String(port),
|
|
103
98
|
"--strictPort",
|
|
104
99
|
];
|
|
105
|
-
const child = spawn(
|
|
100
|
+
const child = spawn(command, args, {
|
|
106
101
|
shell: false,
|
|
107
102
|
detached: process.platform !== "win32",
|
|
108
103
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -265,6 +260,35 @@ try {
|
|
|
265
260
|
}
|
|
266
261
|
`;
|
|
267
262
|
export function basicAgentGuide(backend) {
|
|
268
|
-
return `# Project guide\n\n## Commands\n\n- \`npm run dev\` — frontend development server\n- \`npm run verify\` — lint, typecheck, tests, production build\n- \`npm run qa\` — browser checks without screenshots\n- \`npm run qa:interactive\` — keyboard checks\n- \`npm run qa:visual\` — explicitly requested screenshots\n${backend ? "- `npm run dev:api` — PHP API in a separate terminal (PHP 8.0+)\n- `npm run check:php` — PHP version and syntax checks\n- `npm run build:deploy` — assemble deploy/ for Apache or LiteSpeed\n" : ""}\n## Architecture\n\nReact Router and Vite source is in \`app/\`; routes are declared in \`app/routes.ts\`. Production HTML and assets are in \`build/client/\`.${backend ? " PHP endpoints are in `api/`; the frontend uses relative `/api/` URLs through Vite's proxy. See `docs/backend-php.md`." : ""}\n\n## Working rules\n\nPreserve user changes. Inspect relevant code before editing. Run verification and relevant browser checks before handoff. Routine QA never captures screenshots; use visual QA only when requested. Report failed checks and remaining limitations.\n`;
|
|
263
|
+
return `# Project guide\n\n## Commands\n\n- \`npm run dev\` — frontend development server\n- \`npm run verify\` — lint, typecheck, tests, production build\n- \`npm run qa\` — browser checks without screenshots\n- \`npm run qa:interactive\` — keyboard checks\n- \`npm run qa:visual\` — explicitly requested screenshots\n${backend ? "- `npm run dev:api` — PHP API in a separate terminal (PHP 8.0+)\n- `npm run check:php` — PHP version and syntax checks\n- `npm run build:deploy` — assemble deploy/ for Apache or LiteSpeed\n" : ""}\n## Architecture\n\nReact Router and Vite source is in \`app/\`; routes are declared in \`app/routes.ts\`. Production HTML and assets are in \`build/client/\`.${backend ? " PHP endpoints are in `api/`; the frontend uses relative `/api/` URLs through Vite's proxy. See `docs/backend-php.md`." : ""}\n\n## Working rules\n\nPreserve user changes. Inspect relevant code before editing. Run verification and relevant browser checks before handoff. Routine QA never captures screenshots; use visual QA only when requested. Report failed checks and remaining limitations.\n\n${designGuardrails}`;
|
|
269
264
|
}
|
|
265
|
+
export const extraVerifierScript = `import { spawnSync } from "node:child_process";
|
|
266
|
+
import { readFile } from "node:fs/promises";
|
|
267
|
+
|
|
268
|
+
const config = JSON.parse(await readFile(".mozole/project.json", "utf8"));
|
|
269
|
+
for (const check of config.verifiers ?? []) {
|
|
270
|
+
if (
|
|
271
|
+
typeof check.command !== "string" ||
|
|
272
|
+
!Array.isArray(check.args) ||
|
|
273
|
+
!check.args.every((arg) => typeof arg === "string")
|
|
274
|
+
)
|
|
275
|
+
throw new Error("Invalid extra verifier");
|
|
276
|
+
const npm = check.command === "npm";
|
|
277
|
+
if (npm && !process.env.npm_execpath)
|
|
278
|
+
throw new Error("Run verification through npm run verify");
|
|
279
|
+
const result = spawnSync(
|
|
280
|
+
npm ? process.execPath : check.command,
|
|
281
|
+
npm ? [process.env.npm_execpath, ...check.args] : check.args,
|
|
282
|
+
{ shell: false, stdio: "inherit", timeout: 600000 },
|
|
283
|
+
);
|
|
284
|
+
if (result.error || result.status !== 0) {
|
|
285
|
+
console.error(
|
|
286
|
+
"Extra verifier failed:",
|
|
287
|
+
check.name,
|
|
288
|
+
result.error?.message ?? result.status,
|
|
289
|
+
);
|
|
290
|
+
process.exit(result.status || 1);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
`;
|
|
270
294
|
//# sourceMappingURL=standalone.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standalone.js","sourceRoot":"","sources":["../../src/scaffold/standalone.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BjC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8B3B,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG
|
|
1
|
+
{"version":3,"file":"standalone.js","sourceRoot":"","sources":["../../src/scaffold/standalone.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,6EAA6E;AAC7E,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BjC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8B3B,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmMvB,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,OAAO,0TAA0T,OAAO,CAAC,CAAC,CAAC,+LAA+L,CAAC,CAAC,CAAC,EAAE,mKAAmK,OAAO,CAAC,CAAC,CAAC,wHAAwH,CAAC,CAAC,CAAC,EAAE,kRAAkR,gBAAgB,EAAE,CAAC;AAChmC,CAAC;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BlC,CAAC"}
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAczD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,sBAA2B,GACnC,YAAY,CAiDd;AAID,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,sBAA2B,GACnC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA0RxB"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { cceMcpServer } from "../integrations/antigravity.js";
|
|
2
2
|
import { TOOLCHAIN } from "../version.js";
|
|
3
|
+
import { instructionBlock } from "./adoption.js";
|
|
3
4
|
import { backendTemplates } from "./backend.js";
|
|
4
|
-
import {
|
|
5
|
+
import { designGuardrails, designHandoffGuide } from "./design.js";
|
|
6
|
+
import { backendCheckScript, basicAgentGuide, deployScript, extraVerifierScript, qaScript, } from "./standalone.js";
|
|
5
7
|
export function projectConfig(name, options = {}) {
|
|
6
8
|
const isScaffold = options.scaffold !== false;
|
|
7
9
|
const config = {
|
|
@@ -106,7 +108,7 @@ export function projectTemplates(name, options = {}) {
|
|
|
106
108
|
if (isScaffold) {
|
|
107
109
|
delete packageJson.devDependencies["@mozole/cli"];
|
|
108
110
|
packageJson.devDependencies.playwright = TOOLCHAIN.playwright;
|
|
109
|
-
scripts.verify = `${options.backend ? "npm run check:php && " : ""}npm run lint && npm run typecheck && npm run test:run && npm run build`;
|
|
111
|
+
scripts.verify = `${options.backend ? "npm run check:php && " : ""}npm run lint && npm run typecheck && npm run test:run && npm run build && node scripts/verify-extra.mjs`;
|
|
110
112
|
scripts["verify:force"] = scripts.verify;
|
|
111
113
|
scripts.qa = "node scripts/qa.mjs";
|
|
112
114
|
scripts["qa:force"] = "node scripts/qa.mjs --force";
|
|
@@ -220,7 +222,7 @@ export function projectTemplates(name, options = {}) {
|
|
|
220
222
|
"app/styles/global.css": ":root {\n color-scheme: light;\n font-family: Inter, ui-sans-serif, system-ui, sans-serif;\n color: #171717;\n background: #fafafa;\n}\n* {\n box-sizing: border-box;\n}\nbody {\n margin: 0;\n min-width: 320px;\n}\na {\n color: inherit;\n text-underline-offset: 0.2em;\n}\nheader {\n border-bottom: 1px solid #ddd;\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-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.eyebrow {\n text-transform: uppercase;\n letter-spacing: 0.12em;\n font-size: 0.75rem;\n font-weight: 700;\n}\n",
|
|
221
223
|
"tests/setup.ts": 'import "@testing-library/jest-dom/vitest";\n',
|
|
222
224
|
"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',
|
|
223
|
-
"docs/design
|
|
225
|
+
"docs/design/README.md": designHandoffGuide,
|
|
224
226
|
"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",
|
|
225
227
|
"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",
|
|
226
228
|
"docs/architecture.md": "# 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",
|
|
@@ -267,13 +269,13 @@ export function projectTemplates(name, options = {}) {
|
|
|
267
269
|
".agents/workflows/mozole-qa-visual.md",
|
|
268
270
|
".codex/hooks.json",
|
|
269
271
|
".claude/settings.json",
|
|
270
|
-
"docs/design-tokens.md",
|
|
271
272
|
]) {
|
|
272
273
|
delete files[file];
|
|
273
274
|
}
|
|
274
275
|
files["AGENTS.md"] = basicAgentGuide(Boolean(options.backend));
|
|
275
276
|
files["CLAUDE.md"] = "@AGENTS.md\n";
|
|
276
277
|
files["scripts/qa.mjs"] = qaScript;
|
|
278
|
+
files["scripts/verify-extra.mjs"] = extraVerifierScript;
|
|
277
279
|
const { cce: _cce, antigravity: _antigravity, ...plainToolchain } = TOOLCHAIN;
|
|
278
280
|
files[".mozole/toolchain.json"] = json(plainToolchain);
|
|
279
281
|
files[".gitignore"] =
|
|
@@ -286,6 +288,9 @@ export function projectTemplates(name, options = {}) {
|
|
|
286
288
|
files["README.md"] =
|
|
287
289
|
`# ${name}\n\nReact + Vite project with static prerendering. Requires Node.js 22+.\n\n## Development\n\nRun \`npm run dev\`, \`npm run verify\`, and \`npm run qa\`. Browser QA uses Playwright Chromium, installed during creation; reinstall with \`npx playwright install chromium\` if needed.\n${options.backend ? "\nRequires PHP 8.0+. Start `npm run dev:api` in a separate terminal. Use `npm run build:deploy` and upload the contents of `deploy/`, including `.htaccess`. See [backend setup](docs/backend-php.md).\n" : "\nDeploy the contents of `build/client/` to your static host.\n"}`;
|
|
288
290
|
}
|
|
291
|
+
if (!isScaffold)
|
|
292
|
+
files["AGENTS.md"] += `\n${designGuardrails}`;
|
|
293
|
+
files["AGENTS.md"] = instructionBlock(files["AGENTS.md"] ?? "");
|
|
289
294
|
return files;
|
|
290
295
|
}
|
|
291
296
|
//# sourceMappingURL=templates.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/docs/agent-audit.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# Agent integration audit — 1.4.
|
|
1
|
+
# Agent integration audit — 1.4.1
|
|
2
2
|
|
|
3
3
|
## Findings and changes
|
|
4
4
|
|
|
5
5
|
1. Default scaffold removed agent files but still serialized CCE/governor/telemetry settings and CCE toolchain metadata. Its CLI dependency also installed optimization code. Plain output now contains neither that metadata nor the CLI dependency; project scripts run independently. Regression tests scan generated files and installed dependency locks.
|
|
6
6
|
2. Verification and QA loaded fingerprints and wrote governor state even when the governor was disabled. Both paths now bypass that work unless explicitly enabled. Repeated-run tests assert no state or telemetry files are created.
|
|
7
|
-
3. Default adoption installed CCE integrations without flags. Plain adoption now uses standalone scripts and basic guidance. Explicit `--cce-install` selects managed integration adoption.
|
|
7
|
+
3. Default adoption installed CCE integrations without flags. Plain adoption now uses standalone scripts and basic guidance. Explicit `--cce-install` selects managed integration adoption. Without that flag, previously optimized projects migrate to standalone mode: Mozole-owned integrations and state are archived/removed from the active system, while unrelated user integrations are preserved.
|
|
8
8
|
4. AGENTS.md was absent by default, depriving agents of useful commands and architecture. Plain projects now include concise, integration-free guidance. CLAUDE.md imports it with `@AGENTS.md`. Tests check that every documented npm command actually exists, including PHP commands.
|
|
9
9
|
5. PreToolUse matchers did not observe CCE MCP retrieval. Optional hooks now register matching PostToolUse handlers. Retrieval is recorded after execution; explicit tool-error responses are ignored. PreToolUse retains read/command enforcement.
|
|
10
10
|
6. Existing managed instruction blocks and hook groups were skipped during adoption, preserving obsolete policies. They now update idempotently while preserving unowned content and handlers. An unclosed managed block fails instead of truncating user text.
|