@mozole/cli 1.4.2 ā 2.0.0-b
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/LICENSE +16 -4
- package/README.md +85 -89
- package/dist/cli.d.ts +2 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +204 -157
- package/dist/cli.js.map +1 -1
- package/dist/commands/adopt.d.ts +5 -8
- package/dist/commands/adopt.d.ts.map +1 -1
- package/dist/commands/adopt.js +49 -812
- package/dist/commands/adopt.js.map +1 -1
- package/dist/commands/doctor.d.ts +1 -7
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +69 -377
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/new.d.ts +8 -10
- package/dist/commands/new.d.ts.map +1 -1
- package/dist/commands/new.js +32 -149
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/phase.d.ts +11 -0
- package/dist/commands/phase.d.ts.map +1 -0
- package/dist/commands/phase.js +106 -0
- package/dist/commands/phase.js.map +1 -0
- package/dist/commands/prototype.d.ts +6 -0
- package/dist/commands/prototype.d.ts.map +1 -0
- package/dist/commands/prototype.js +28 -0
- package/dist/commands/prototype.js.map +1 -0
- package/dist/commands/repomap.d.ts +6 -0
- package/dist/commands/repomap.d.ts.map +1 -0
- package/dist/commands/repomap.js +71 -0
- package/dist/commands/repomap.js.map +1 -0
- package/dist/commands/test.d.ts +6 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +115 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/ui.d.ts +1 -37
- package/dist/commands/ui.d.ts.map +1 -1
- package/dist/commands/ui.js +75 -317
- package/dist/commands/ui.js.map +1 -1
- package/dist/commands/verify.d.ts +12 -7
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +148 -65
- package/dist/commands/verify.js.map +1 -1
- package/dist/qa/a11y.d.ts +24 -0
- package/dist/qa/a11y.d.ts.map +1 -0
- package/dist/qa/a11y.js +124 -0
- package/dist/qa/a11y.js.map +1 -0
- package/dist/qa/breakpoints.d.ts +16 -0
- package/dist/qa/breakpoints.d.ts.map +1 -0
- package/dist/qa/breakpoints.js +45 -0
- package/dist/qa/breakpoints.js.map +1 -0
- package/dist/qa/contract.d.ts +21 -0
- package/dist/qa/contract.d.ts.map +1 -0
- package/dist/qa/contract.js +116 -0
- package/dist/qa/contract.js.map +1 -0
- package/dist/qa/index.d.ts +6 -0
- package/dist/qa/index.d.ts.map +1 -0
- package/dist/qa/index.js +6 -0
- package/dist/qa/index.js.map +1 -0
- package/dist/qa/probe.d.ts +48 -0
- package/dist/qa/probe.d.ts.map +1 -0
- package/dist/qa/probe.js +206 -0
- package/dist/qa/probe.js.map +1 -0
- package/dist/qa/runner.d.ts +27 -32
- package/dist/qa/runner.d.ts.map +1 -1
- package/dist/qa/runner.js +286 -336
- package/dist/qa/runner.js.map +1 -1
- package/dist/scaffold/agents.d.ts +5 -0
- package/dist/scaffold/agents.d.ts.map +1 -0
- package/dist/scaffold/agents.js +84 -0
- package/dist/scaffold/agents.js.map +1 -0
- package/dist/scaffold/backend.d.ts +6 -8
- package/dist/scaffold/backend.d.ts.map +1 -1
- package/dist/scaffold/backend.js +318 -199
- package/dist/scaffold/backend.js.map +1 -1
- package/dist/scaffold/design.d.ts +4 -3
- package/dist/scaffold/design.d.ts.map +1 -1
- package/dist/scaffold/design.js +38 -47
- package/dist/scaffold/design.js.map +1 -1
- package/dist/scaffold/flagship.d.ts +8 -0
- package/dist/scaffold/flagship.d.ts.map +1 -0
- package/dist/scaffold/flagship.js +337 -0
- package/dist/scaffold/flagship.js.map +1 -0
- package/dist/scaffold/index.d.ts +9 -0
- package/dist/scaffold/index.d.ts.map +1 -0
- package/dist/scaffold/index.js +48 -0
- package/dist/scaffold/index.js.map +1 -0
- package/dist/scaffold/phases.d.ts +10 -0
- package/dist/scaffold/phases.d.ts.map +1 -0
- package/dist/scaffold/phases.js +165 -0
- package/dist/scaffold/phases.js.map +1 -0
- package/dist/scaffold/repomap.d.ts +6 -0
- package/dist/scaffold/repomap.d.ts.map +1 -0
- package/dist/scaffold/repomap.js +89 -0
- package/dist/scaffold/repomap.js.map +1 -0
- package/dist/scaffold/standard.d.ts +13 -0
- package/dist/scaffold/standard.d.ts.map +1 -0
- package/dist/scaffold/standard.js +371 -0
- package/dist/scaffold/standard.js.map +1 -0
- package/dist/scaffold/tokens.d.ts +3 -0
- package/dist/scaffold/tokens.d.ts.map +1 -0
- package/dist/scaffold/tokens.js +126 -0
- package/dist/scaffold/tokens.js.map +1 -0
- package/dist/server/manager.d.ts +23 -0
- package/dist/server/manager.d.ts.map +1 -0
- package/dist/server/manager.js +96 -0
- package/dist/server/manager.js.map +1 -0
- package/dist/utils/ai-trace.d.ts +8 -0
- package/dist/utils/ai-trace.d.ts.map +1 -0
- package/dist/utils/ai-trace.js +69 -0
- package/dist/utils/ai-trace.js.map +1 -0
- package/dist/utils/browser.d.ts +10 -0
- package/dist/utils/browser.d.ts.map +1 -0
- package/dist/utils/browser.js +127 -0
- package/dist/utils/browser.js.map +1 -0
- package/dist/utils/fs.d.ts +11 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +166 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/git.d.ts +9 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +69 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/process.d.ts +21 -0
- package/dist/utils/process.d.ts.map +1 -0
- package/dist/utils/process.js +120 -0
- package/dist/utils/process.js.map +1 -0
- package/dist/version.d.ts +21 -36
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +21 -44
- package/dist/version.js.map +1 -1
- package/package.json +19 -38
- package/CHANGELOG.md +0 -30
- package/dist/commands/cce.d.ts +0 -7
- package/dist/commands/cce.d.ts.map +0 -1
- package/dist/commands/cce.js +0 -37
- package/dist/commands/cce.js.map +0 -1
- package/dist/commands/logs.d.ts +0 -3
- package/dist/commands/logs.d.ts.map +0 -1
- package/dist/commands/logs.js +0 -39
- package/dist/commands/logs.js.map +0 -1
- package/dist/commands/qa.d.ts +0 -12
- package/dist/commands/qa.d.ts.map +0 -1
- package/dist/commands/qa.js +0 -143
- package/dist/commands/qa.js.map +0 -1
- package/dist/commands/stats.d.ts +0 -37
- package/dist/commands/stats.d.ts.map +0 -1
- package/dist/commands/stats.js +0 -169
- package/dist/commands/stats.js.map +0 -1
- package/dist/config/project.d.ts +0 -51
- package/dist/config/project.d.ts.map +0 -1
- package/dist/config/project.js +0 -81
- package/dist/config/project.js.map +0 -1
- package/dist/context/cce.d.ts +0 -39
- package/dist/context/cce.d.ts.map +0 -1
- package/dist/context/cce.js +0 -455
- package/dist/context/cce.js.map +0 -1
- package/dist/governor/fingerprint.d.ts +0 -7
- package/dist/governor/fingerprint.d.ts.map +0 -1
- package/dist/governor/fingerprint.js +0 -129
- package/dist/governor/fingerprint.js.map +0 -1
- package/dist/governor/hook.d.ts +0 -13
- package/dist/governor/hook.d.ts.map +0 -1
- package/dist/governor/hook.js +0 -389
- package/dist/governor/hook.js.map +0 -1
- package/dist/governor/state.d.ts +0 -45
- package/dist/governor/state.d.ts.map +0 -1
- package/dist/governor/state.js +0 -60
- package/dist/governor/state.js.map +0 -1
- package/dist/integrations/antigravity.d.ts +0 -20
- package/dist/integrations/antigravity.d.ts.map +0 -1
- package/dist/integrations/antigravity.js +0 -153
- package/dist/integrations/antigravity.js.map +0 -1
- package/dist/output.d.ts +0 -5
- package/dist/output.d.ts.map +0 -1
- package/dist/output.js +0 -2
- package/dist/output.js.map +0 -1
- package/dist/platform/executable.d.ts +0 -11
- package/dist/platform/executable.d.ts.map +0 -1
- package/dist/platform/executable.js +0 -69
- package/dist/platform/executable.js.map +0 -1
- package/dist/platform/process.d.ts +0 -25
- package/dist/platform/process.d.ts.map +0 -1
- package/dist/platform/process.js +0 -179
- package/dist/platform/process.js.map +0 -1
- package/dist/progress.d.ts +0 -44
- package/dist/progress.d.ts.map +0 -1
- package/dist/progress.js +0 -123
- package/dist/progress.js.map +0 -1
- package/dist/qa/diff.d.ts +0 -10
- package/dist/qa/diff.d.ts.map +0 -1
- package/dist/qa/diff.js +0 -91
- package/dist/qa/diff.js.map +0 -1
- package/dist/qa/server.d.ts +0 -10
- package/dist/qa/server.d.ts.map +0 -1
- package/dist/qa/server.js +0 -127
- package/dist/qa/server.js.map +0 -1
- package/dist/scaffold/adoption.d.ts +0 -17
- package/dist/scaffold/adoption.d.ts.map +0 -1
- package/dist/scaffold/adoption.js +0 -279
- package/dist/scaffold/adoption.js.map +0 -1
- package/dist/scaffold/legacy.d.ts +0 -4
- package/dist/scaffold/legacy.d.ts.map +0 -1
- package/dist/scaffold/legacy.js +0 -139
- package/dist/scaffold/legacy.js.map +0 -1
- package/dist/scaffold/routes.d.ts +0 -3
- package/dist/scaffold/routes.d.ts.map +0 -1
- package/dist/scaffold/routes.js +0 -37
- package/dist/scaffold/routes.js.map +0 -1
- package/dist/scaffold/standalone.d.ts +0 -7
- package/dist/scaffold/standalone.d.ts.map +0 -1
- package/dist/scaffold/standalone.js +0 -294
- package/dist/scaffold/standalone.js.map +0 -1
- package/dist/scaffold/templates.d.ts +0 -8
- package/dist/scaffold/templates.d.ts.map +0 -1
- package/dist/scaffold/templates.js +0 -312
- package/dist/scaffold/templates.js.map +0 -1
- package/dist/scaffold/write.d.ts +0 -2
- package/dist/scaffold/write.d.ts.map +0 -1
- package/dist/scaffold/write.js +0 -38
- package/dist/scaffold/write.js.map +0 -1
- package/dist/telemetry/store.d.ts +0 -33
- package/dist/telemetry/store.d.ts.map +0 -1
- package/dist/telemetry/store.js +0 -75
- package/dist/telemetry/store.js.map +0 -1
- package/dist/verify/runner.d.ts +0 -15
- package/dist/verify/runner.d.ts.map +0 -1
- package/dist/verify/runner.js +0 -112
- package/dist/verify/runner.js.map +0 -1
- package/docs/agent-audit.md +0 -24
package/dist/commands/new.js
CHANGED
|
@@ -1,157 +1,40 @@
|
|
|
1
|
-
import { cp, lstat, mkdtemp, rename, rm } from "node:fs/promises";
|
|
2
1
|
import path from "node:path";
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
name.includes("/") ||
|
|
15
|
-
name.includes("\\") ||
|
|
16
|
-
!/^[a-z0-9][a-z0-9._-]*$/.test(name)) {
|
|
17
|
-
output.error("Usage: mozole new <name>\nName must be one safe directory segment.");
|
|
18
|
-
return 2;
|
|
19
|
-
}
|
|
20
|
-
const target = path.resolve(cwd, name);
|
|
21
|
-
try {
|
|
22
|
-
await lstat(target);
|
|
23
|
-
output.error(`Cannot create ${target}: path already exists.`);
|
|
24
|
-
return 2;
|
|
25
|
-
}
|
|
26
|
-
catch { }
|
|
27
|
-
const shouldInstallCce = Boolean((options.cceInstall || options.installCce) && !options.scaffold);
|
|
28
|
-
const isScaffold = !shouldInstallCce;
|
|
29
|
-
const totalSteps = shouldInstallCce ? 7 : 6;
|
|
30
|
-
const progress = new TaskProgress({
|
|
31
|
-
total: totalSteps,
|
|
32
|
-
title: "New Project",
|
|
33
|
-
verbose: options.verbose,
|
|
34
|
-
output,
|
|
35
|
-
onUpdate: options.onProgress,
|
|
36
|
-
});
|
|
37
|
-
const staging = await mkdtemp(path.join(cwd, `.mozole-${name}-`));
|
|
38
|
-
const controller = new AbortController();
|
|
39
|
-
const abort = () => controller.abort();
|
|
40
|
-
process.once("SIGINT", abort);
|
|
41
|
-
process.once("SIGTERM", abort);
|
|
42
|
-
let moved = false;
|
|
43
|
-
try {
|
|
44
|
-
progress.step("Scaffolding project template files and configs");
|
|
45
|
-
progress.logVerbose(`Writing template files to staging: ${staging}`);
|
|
46
|
-
await writeFiles(staging, projectTemplates(name, {
|
|
47
|
-
scaffold: isScaffold,
|
|
48
|
-
backend: options.backend,
|
|
49
|
-
}));
|
|
50
|
-
if (process.env.MOZOLE_SKIP_INSTALL !== "1") {
|
|
51
|
-
progress.step("Installing package dependencies (npm install)");
|
|
52
|
-
progress.logVerbose("Running npm install");
|
|
53
|
-
const installed = await run(npmExecutable(), ["install", "--no-fund", "--no-audit"], {
|
|
54
|
-
cwd: staging,
|
|
55
|
-
timeoutMs: 600_000,
|
|
56
|
-
signal: controller.signal,
|
|
57
|
-
logFile: path.join(staging, ".mozole", "logs", "npm-install.log"),
|
|
58
|
-
});
|
|
59
|
-
if (installed.exitCode !== 0)
|
|
60
|
-
throw new Error(`npm install failed. See .mozole/logs/npm-install.log`);
|
|
61
|
-
progress.step("Formatting generated project with Biome");
|
|
62
|
-
progress.logVerbose("Running biome format --write .");
|
|
63
|
-
const formatted = await run(npmExecutable(), ["exec", "--", "biome", "format", "--write", "."], {
|
|
64
|
-
cwd: staging,
|
|
65
|
-
timeoutMs: 600_000,
|
|
66
|
-
signal: controller.signal,
|
|
67
|
-
logFile: path.join(staging, ".mozole", "logs", "biome-format.log"),
|
|
68
|
-
});
|
|
69
|
-
if (formatted.exitCode !== 0)
|
|
70
|
-
throw new Error("Biome formatting failed. See .mozole/logs/biome-format.log");
|
|
71
|
-
if (process.env.MOZOLE_SKIP_BROWSER !== "1") {
|
|
72
|
-
progress.step("Provisioning Playwright Chromium browser");
|
|
73
|
-
progress.logVerbose("Running playwright install chromium");
|
|
74
|
-
const browser = await run(npmExecutable(), ["exec", "--", "playwright", "install", "chromium"], {
|
|
75
|
-
cwd: staging,
|
|
76
|
-
timeoutMs: 600_000,
|
|
77
|
-
signal: controller.signal,
|
|
78
|
-
logFile: path.join(staging, ".mozole", "logs", "playwright-install.log"),
|
|
79
|
-
});
|
|
80
|
-
if (browser.exitCode !== 0)
|
|
81
|
-
throw new Error("Chromium installation failed. See .mozole/logs/playwright-install.log");
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
progress.step("Skipping dependency installation (MOZOLE_SKIP_INSTALL)");
|
|
86
|
-
progress.step("Skipping formatting (MOZOLE_SKIP_INSTALL)");
|
|
87
|
-
}
|
|
88
|
-
progress.step("Moving staging workspace to target directory");
|
|
89
|
-
await rename(staging, target);
|
|
90
|
-
moved = true;
|
|
91
|
-
let cceMessage;
|
|
92
|
-
if (shouldInstallCce) {
|
|
93
|
-
const cceRuntime = await cceCommand();
|
|
94
|
-
if (!cceRuntime)
|
|
95
|
-
cceMessage =
|
|
96
|
-
"CCE runtime unavailable. Run mozole cce install, then mozole adopt . --cce-install.";
|
|
97
|
-
if (process.env.MOZOLE_SKIP_CCE !== "1") {
|
|
98
|
-
progress.step("Initializing CCE vector index & embedding model");
|
|
99
|
-
progress.logVerbose("Running CCE init");
|
|
100
|
-
const cce = await initializeCce(target, controller.signal, cceRuntime);
|
|
101
|
-
if (controller.signal.aborted)
|
|
102
|
-
throw new Error("Creation cancelled.");
|
|
103
|
-
if (cce?.exitCode === 0)
|
|
104
|
-
cceMessage = "CCE indexed and configured.";
|
|
105
|
-
else if (cce)
|
|
106
|
-
cceMessage =
|
|
107
|
-
"CCE setup needs attention; see .mozole/logs/cce-init.log.";
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
progress.step("Skipping CCE initialization (MOZOLE_SKIP_CCE)");
|
|
111
|
-
}
|
|
112
|
-
progress.step("Configuring Antigravity MCP and final workspace");
|
|
113
|
-
const cceLauncher = cceRuntime?.prefix.length
|
|
114
|
-
? "uvx"
|
|
115
|
-
: "cce";
|
|
116
|
-
await configureAntigravityMcp(target, cceLauncher, cceRuntime?.command);
|
|
2
|
+
import pc from "picocolors";
|
|
3
|
+
import { scaffoldNewProject } from "../scaffold/index.js";
|
|
4
|
+
import { exists, findPrototypeRoot } from "../utils/fs.js";
|
|
5
|
+
export async function createNewProject(options) {
|
|
6
|
+
const cwd = options.cwd ?? process.cwd();
|
|
7
|
+
const name = options.name.trim();
|
|
8
|
+
let targetDir = options.targetDir;
|
|
9
|
+
if (!targetDir) {
|
|
10
|
+
const protoRoot = await findPrototypeRoot(cwd);
|
|
11
|
+
if (protoRoot) {
|
|
12
|
+
targetDir = path.join(protoRoot, "projects", name);
|
|
117
13
|
}
|
|
118
14
|
else {
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
progress.done(`Created ${name}`);
|
|
122
|
-
let nextSteps = `Next:\n cd ${name}\n npm run dev`;
|
|
123
|
-
if (options.backend) {
|
|
124
|
-
nextSteps += `\n # In a separate terminal (PHP 8.0+):\n npm run dev:api\n # Production bundle:\n npm run build:deploy`;
|
|
15
|
+
targetDir = path.join(cwd, name);
|
|
125
16
|
}
|
|
126
|
-
nextSteps += `\n npm run verify`;
|
|
127
|
-
const summary = cceMessage
|
|
128
|
-
? `\nCreated ${name}\n${cceMessage}\n\n${nextSteps}`
|
|
129
|
-
: `\nCreated ${name} (${isScaffold ? "scaffold mode" : "optimized mode"})\n\n${nextSteps}`;
|
|
130
|
-
output.log(summary);
|
|
131
|
-
return 0;
|
|
132
17
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
let retainedLogs = "";
|
|
136
|
-
if (!moved) {
|
|
137
|
-
const logs = await mkdtemp(path.join(cwd, `.mozole-${name}-failure-`));
|
|
138
|
-
try {
|
|
139
|
-
await cp(path.join(staging, ".mozole", "logs"), path.join(logs, "logs"), { recursive: true });
|
|
140
|
-
retainedLogs = `\nRetained logs: ${path.join(logs, "logs")}`;
|
|
141
|
-
}
|
|
142
|
-
catch (logError) {
|
|
143
|
-
await rm(logs, { recursive: true, force: true });
|
|
144
|
-
if (logError.code !== "ENOENT")
|
|
145
|
-
retainedLogs = `\nCould not retain logs: ${String(logError)}`;
|
|
146
|
-
}
|
|
147
|
-
await rm(staging, { recursive: true, force: true });
|
|
148
|
-
}
|
|
149
|
-
output.error(`CREATE FAIL\n\n${error instanceof Error ? error.message : String(error)}${retainedLogs}\nCleanup: ${moved ? `project remains at ${target}` : "incomplete staging directory removed"}`);
|
|
150
|
-
return controller.signal.aborted ? 130 : 1;
|
|
151
|
-
}
|
|
152
|
-
finally {
|
|
153
|
-
process.removeListener("SIGINT", abort);
|
|
154
|
-
process.removeListener("SIGTERM", abort);
|
|
18
|
+
if (await exists(targetDir)) {
|
|
19
|
+
throw new Error(`Target directory already exists: ${targetDir}`);
|
|
155
20
|
}
|
|
21
|
+
console.log(pc.cyan(`\nā” Scaffolding Mozole project: ${pc.bold(name)}`));
|
|
22
|
+
console.log(` Profile: ${options.flagship ? pc.magenta("Flagship Creative (Wouter + Lenis + Canvas)") : pc.blue("Standard Production (React Router 7 + SSG)")}`);
|
|
23
|
+
console.log(` Backend: ${pc.yellow(options.backend ?? "php (Pure PHP 8.1+ Zero-Dependency)")}`);
|
|
24
|
+
console.log(` Destination: ${targetDir}\n`);
|
|
25
|
+
await scaffoldNewProject({
|
|
26
|
+
targetDir,
|
|
27
|
+
name,
|
|
28
|
+
flagship: options.flagship,
|
|
29
|
+
backend: options.backend,
|
|
30
|
+
initGit: options.initGit ?? true,
|
|
31
|
+
});
|
|
32
|
+
console.log(pc.green(`ā Project successfully generated at ${targetDir}`));
|
|
33
|
+
console.log("\nNext steps:");
|
|
34
|
+
console.log(` 1. ${pc.cyan(`cd ${path.relative(cwd, targetDir) || "."}`)}`);
|
|
35
|
+
console.log(` 2. ${pc.cyan("npm install")}`);
|
|
36
|
+
console.log(` 3. ${pc.cyan("mozole verify")}`);
|
|
37
|
+
console.log(` 4. ${pc.cyan("npm run dev")}\n`);
|
|
38
|
+
return targetDir;
|
|
156
39
|
}
|
|
157
40
|
//# sourceMappingURL=new.js.map
|
package/dist/commands/new.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"new.js","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"new.js","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAW3D,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAA0B;IAC/D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACzC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAEjC,IAAI,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAClC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAC/C,IAAI,SAAS,EAAE,CAAC;YACd,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED,IAAI,MAAM,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,oCAAoC,SAAS,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,mCAAmC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACzE,OAAO,CAAC,GAAG,CACT,cAAc,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,6CAA6C,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,4CAA4C,CAAC,EAAE,CACrJ,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,IAAI,qCAAqC,CAAC,EAAE,CAAC,CAAC;IACjG,OAAO,CAAC,GAAG,CAAC,kBAAkB,SAAS,IAAI,CAAC,CAAC;IAE7C,MAAM,kBAAkB,CAAC;QACvB,SAAS;QACT,IAAI;QACJ,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,IAAI;KACjC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,uCAAuC,SAAS,EAAE,CAAC,CAAC,CAAC;IAC1E,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAEhD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface PhaseCommandOptions {
|
|
2
|
+
action?: "status" | "next" | "reopen";
|
|
3
|
+
phaseId?: string;
|
|
4
|
+
cwd?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function getProjectPhaseStatus(projectRoot: string): Promise<{
|
|
7
|
+
currentPhase: string;
|
|
8
|
+
content: string;
|
|
9
|
+
}>;
|
|
10
|
+
export declare function phaseCommand(options?: PhaseCommandOptions): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=phase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phase.d.ts","sourceRoot":"","sources":["../../src/commands/phase.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAiBpD;AAED,wBAAsB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8GnF"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import pc from "picocolors";
|
|
4
|
+
import { PHASES, generatePhasesStatusMd } from "../scaffold/phases.js";
|
|
5
|
+
import { atomicWrite, exists, findProjectRoot } from "../utils/fs.js";
|
|
6
|
+
import { formatPhaseCommitMessage, isGitRepo, stageAndCommit } from "../utils/git.js";
|
|
7
|
+
export async function getProjectPhaseStatus(projectRoot) {
|
|
8
|
+
const statusPath = path.join(projectRoot, "docs", "phases", "status.md");
|
|
9
|
+
if (!(await exists(statusPath))) {
|
|
10
|
+
throw new Error(`Phase status file not found: ${statusPath}. Run 'mozole adopt' or 'mozole new'.`);
|
|
11
|
+
}
|
|
12
|
+
const content = await fs.readFile(statusPath, "utf8");
|
|
13
|
+
const match = content.match(/^\*\*Current Phase:\*\*\s*Phase\s*([^\r\n]+)$/im);
|
|
14
|
+
const phaseRaw = match?.[1]?.trim() ?? "";
|
|
15
|
+
if (!match || !PHASES.some((phase) => phase.id === phaseRaw)) {
|
|
16
|
+
throw new Error(`Invalid current phase in ${statusPath}; expected Phase 00 through 10.`);
|
|
17
|
+
}
|
|
18
|
+
const currentPhase = phaseRaw;
|
|
19
|
+
return { currentPhase, content };
|
|
20
|
+
}
|
|
21
|
+
export async function phaseCommand(options = {}) {
|
|
22
|
+
const cwd = options.cwd ?? process.cwd();
|
|
23
|
+
const projectRoot = (await findProjectRoot(cwd)) ?? cwd;
|
|
24
|
+
const { currentPhase, content } = await getProjectPhaseStatus(projectRoot);
|
|
25
|
+
const action = options.action ?? "status";
|
|
26
|
+
if (!["status", "next", "reopen"].includes(action)) {
|
|
27
|
+
throw new Error(`Invalid phase action '${action}'. Expected status, next, or reopen.`);
|
|
28
|
+
}
|
|
29
|
+
const persistPhase = async (phase, message) => {
|
|
30
|
+
const statusPath = path.join(projectRoot, "docs", "phases", "status.md");
|
|
31
|
+
await atomicWrite(statusPath, generatePhasesStatusMd(phase));
|
|
32
|
+
if (await isGitRepo(projectRoot)) {
|
|
33
|
+
try {
|
|
34
|
+
const result = await stageAndCommit(projectRoot, message);
|
|
35
|
+
if (!result.success)
|
|
36
|
+
throw new Error(result.output);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
await atomicWrite(statusPath, content);
|
|
40
|
+
throw new Error(`Phase change not committed; status restored. ${String(error)}`);
|
|
41
|
+
}
|
|
42
|
+
console.log(pc.green(` ā Git commit created: ${message}`));
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
if (action === "status") {
|
|
46
|
+
console.log(pc.cyan(`\nš Mozole 10-Step Development Phases: ${pc.bold(`Phase ${currentPhase}`)}`));
|
|
47
|
+
console.log(pc.gray("ā".repeat(65)));
|
|
48
|
+
for (const p of PHASES) {
|
|
49
|
+
const num = Number(p.id);
|
|
50
|
+
const currentNum = Number(currentPhase);
|
|
51
|
+
let badge = pc.gray("[PENDING]");
|
|
52
|
+
if (num < currentNum)
|
|
53
|
+
badge = pc.green("[COMPLETED]");
|
|
54
|
+
else if (num === currentNum)
|
|
55
|
+
badge = pc.yellow(pc.bold("[IN PROGRESS]"));
|
|
56
|
+
console.log(`\n Phase ${p.id}: ${pc.bold(p.name)} ${badge}`);
|
|
57
|
+
console.log(` ${pc.dim(p.description)}`);
|
|
58
|
+
for (const item of p.checklist) {
|
|
59
|
+
const mark = num < currentNum ? pc.green("ā") : num === currentNum ? pc.yellow("ā") : pc.gray("ā¢");
|
|
60
|
+
console.log(` ${mark} ${item}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
console.log(pc.gray(`\n${"ā".repeat(65)}`));
|
|
64
|
+
console.log(`Run ${pc.cyan("mozole phase next")} when current phase criteria are fulfilled.\n`);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (action === "next") {
|
|
68
|
+
const currentNum = Number(currentPhase);
|
|
69
|
+
if (currentNum >= 10) {
|
|
70
|
+
console.log(pc.green("\nš All 10 phases completed! Project is production launched."));
|
|
71
|
+
console.log("Routine maintenance can continue here. Reopen a phase only for architectural changes.\n");
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const currentDef = PHASES.find((p) => p.id === currentPhase);
|
|
75
|
+
const nextNum = currentNum + 1;
|
|
76
|
+
const nextPhase = String(nextNum).padStart(2, "0");
|
|
77
|
+
const nextDef = PHASES.find((p) => p.id === nextPhase);
|
|
78
|
+
console.log(pc.cyan(`\nAdvancing from Phase ${currentPhase} to Phase ${nextPhase}...`));
|
|
79
|
+
await persistPhase(nextPhase, formatPhaseCommitMessage(currentPhase, `complete ${currentDef?.name ?? "phase"} and advance to phase ${nextPhase}`));
|
|
80
|
+
console.log(pc.green(`\nā Advanced to Phase ${nextPhase}: ${nextDef?.name}`));
|
|
81
|
+
console.log(` ${nextDef?.description}`);
|
|
82
|
+
console.log(pc.cyan("\nUpcoming Checklist:"));
|
|
83
|
+
for (const item of nextDef?.checklist ?? []) {
|
|
84
|
+
console.log(` ā ${item}`);
|
|
85
|
+
}
|
|
86
|
+
console.log();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (action === "reopen") {
|
|
90
|
+
const targetPhaseId = options.phaseId ? String(options.phaseId).padStart(2, "0") : undefined;
|
|
91
|
+
if (!targetPhaseId) {
|
|
92
|
+
throw new Error("Specify a phase ID to reopen, e.g. 'mozole phase reopen 02'");
|
|
93
|
+
}
|
|
94
|
+
const targetDef = PHASES.find((p) => p.id === targetPhaseId);
|
|
95
|
+
if (!targetDef) {
|
|
96
|
+
throw new Error(`Invalid phase ID '${targetPhaseId}'. Valid phases are 00 through 10.`);
|
|
97
|
+
}
|
|
98
|
+
if (Number(targetPhaseId) >= Number(currentPhase)) {
|
|
99
|
+
throw new Error("Only a completed phase can be reopened. Use 'mozole phase next' to advance.");
|
|
100
|
+
}
|
|
101
|
+
console.log(pc.yellow(`\nReopening Phase ${targetPhaseId} for post-launch maintenance...`));
|
|
102
|
+
await persistPhase(targetPhaseId, `chore(phase-${targetPhaseId}): reopen phase for maintenance`);
|
|
103
|
+
console.log(pc.green(`ā Reopened Phase ${targetPhaseId}: ${targetDef.name}\n`));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=phase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phase.js","sourceRoot":"","sources":["../../src/commands/phase.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prototype.d.ts","sourceRoot":"","sources":["../../src/commands/prototype.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,oBAAoB;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BrF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import pc from "picocolors";
|
|
3
|
+
import { scaffoldAgentPolicies } from "../scaffold/agents.js";
|
|
4
|
+
import { atomicWrite, exists } from "../utils/fs.js";
|
|
5
|
+
import { initGit } from "../utils/git.js";
|
|
6
|
+
export async function prototypeInit(options = {}) {
|
|
7
|
+
const cwd = options.cwd ?? process.cwd();
|
|
8
|
+
const name = options.name ?? path.basename(cwd);
|
|
9
|
+
const configPath = path.join(cwd, "mozole.config.json");
|
|
10
|
+
if (await exists(configPath)) {
|
|
11
|
+
console.log(pc.yellow(`Mozole prototype repository already initialized at ${cwd}`));
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const config = {
|
|
15
|
+
version: "2.0.0",
|
|
16
|
+
name,
|
|
17
|
+
projectsDir: "projects",
|
|
18
|
+
defaultBackend: "php",
|
|
19
|
+
};
|
|
20
|
+
await atomicWrite(configPath, JSON.stringify(config, null, 2));
|
|
21
|
+
await atomicWrite(path.join(cwd, "projects", ".gitkeep"), "");
|
|
22
|
+
await atomicWrite(path.join(cwd, "shared", ".gitkeep"), "");
|
|
23
|
+
await scaffoldAgentPolicies(cwd, name);
|
|
24
|
+
await initGit(cwd, "feat: initialize mozole prototype ecosystem");
|
|
25
|
+
console.log(pc.green(`ā Initialized Mozole Prototype workspace in ${cwd}`));
|
|
26
|
+
console.log(` Run ${pc.cyan("mozole new <client-name>")} to generate a new project.`);
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=prototype.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prototype.js","sourceRoot":"","sources":["../../src/commands/prototype.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAO1C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,UAAgC,EAAE;IACpE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACzC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAEhD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC;IACxD,IAAI,MAAM,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,sDAAsD,GAAG,EAAE,CAAC,CAAC,CAAC;QACpF,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG;QACb,OAAO,EAAE,OAAO;QAChB,IAAI;QACJ,WAAW,EAAE,UAAU;QACvB,cAAc,EAAE,KAAK;KACtB,CAAC;IAEF,MAAM,WAAW,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/D,MAAM,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9D,MAAM,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;IAE5D,MAAM,qBAAqB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACvC,MAAM,OAAO,CAAC,GAAG,EAAE,6CAA6C,CAAC,CAAC;IAElE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,+CAA+C,GAAG,EAAE,CAAC,CAAC,CAAC;IAC5E,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,0BAA0B,CAAC,6BAA6B,CAAC,CAAC;AACzF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repomap.d.ts","sourceRoot":"","sources":["../../src/commands/repomap.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAwEvF"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import pc from "picocolors";
|
|
4
|
+
import { generateRepomapComponents, generateRepomapRoutes, generateRepomapTokens, } from "../scaffold/repomap.js";
|
|
5
|
+
import { atomicWrite, exists, findProjectRoot } from "../utils/fs.js";
|
|
6
|
+
export async function repomapCommand(options = {}) {
|
|
7
|
+
const cwd = options.cwd ?? process.cwd();
|
|
8
|
+
const projectRoot = (await findProjectRoot(cwd)) ?? cwd;
|
|
9
|
+
const action = options.action ?? "sync";
|
|
10
|
+
if (action !== "sync" && action !== "check") {
|
|
11
|
+
throw new Error(`Invalid repomap action '${action}'. Expected sync or check.`);
|
|
12
|
+
}
|
|
13
|
+
const repomapDir = path.join(projectRoot, "docs", "repomap");
|
|
14
|
+
if (!(await exists(repomapDir))) {
|
|
15
|
+
throw new Error(`Repomap directory not found: ${repomapDir}. Run 'mozole adopt' to initialize.`);
|
|
16
|
+
}
|
|
17
|
+
const requiredFiles = ["architecture.md", "components.md", "routes.md", "tokens.md"];
|
|
18
|
+
if (action === "check") {
|
|
19
|
+
console.log(pc.cyan(`\nš Checking docs/repomap architectural index in ${projectRoot}...`));
|
|
20
|
+
let allOk = true;
|
|
21
|
+
for (const file of requiredFiles) {
|
|
22
|
+
const filePath = path.join(repomapDir, file);
|
|
23
|
+
if (!(await exists(filePath))) {
|
|
24
|
+
console.log(pc.red(` ā Missing: docs/repomap/${file}`));
|
|
25
|
+
allOk = false;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
const stat = await fs.stat(filePath);
|
|
29
|
+
if (stat.size === 0) {
|
|
30
|
+
console.log(pc.yellow(` ! Empty: docs/repomap/${file}`));
|
|
31
|
+
allOk = false;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
console.log(pc.green(` ā Found: docs/repomap/${file} (${stat.size} bytes)`));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (!allOk) {
|
|
39
|
+
throw new Error("Repomap index validation failed. Run 'mozole repomap sync' to restore.");
|
|
40
|
+
}
|
|
41
|
+
console.log(pc.green("\nā Repomap architectural index is complete and healthy.\n"));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (action === "sync") {
|
|
45
|
+
console.log(pc.cyan(`\nš Syncing docs/repomap architectural index in ${projectRoot}...`));
|
|
46
|
+
// Components
|
|
47
|
+
const compPath = path.join(repomapDir, "components.md");
|
|
48
|
+
if (!(await exists(compPath))) {
|
|
49
|
+
await atomicWrite(compPath, generateRepomapComponents());
|
|
50
|
+
console.log(pc.green(" ā Generated docs/repomap/components.md"));
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
console.log(pc.gray(" ⢠docs/repomap/components.md up to date"));
|
|
54
|
+
}
|
|
55
|
+
// Routes
|
|
56
|
+
const routesPath = path.join(repomapDir, "routes.md");
|
|
57
|
+
if (!(await exists(routesPath))) {
|
|
58
|
+
await atomicWrite(routesPath, generateRepomapRoutes());
|
|
59
|
+
console.log(pc.green(" ā Generated docs/repomap/routes.md"));
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
console.log(pc.gray(" ⢠docs/repomap/routes.md up to date"));
|
|
63
|
+
}
|
|
64
|
+
// Tokens
|
|
65
|
+
const tokensPath = path.join(repomapDir, "tokens.md");
|
|
66
|
+
await atomicWrite(tokensPath, generateRepomapTokens());
|
|
67
|
+
console.log(pc.green(" ā Synchronized docs/repomap/tokens.md"));
|
|
68
|
+
console.log(pc.green("\nā Repomap index synchronized successfully.\n"));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=repomap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repomap.js","sourceRoot":"","sources":["../../src/commands/repomap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;CAC9C;AAED,wBAAsB,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8HjF"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import pc from "picocolors";
|
|
4
|
+
import { auditHtmlA11y } from "../qa/a11y.js";
|
|
5
|
+
import { auditCssContracts } from "../qa/contract.js";
|
|
6
|
+
import { runLiveGeometryProbe } from "../qa/runner.js";
|
|
7
|
+
import { exists, findProjectRoot } from "../utils/fs.js";
|
|
8
|
+
export async function testCommand(options = {}) {
|
|
9
|
+
const cwd = options.cwd ?? process.cwd();
|
|
10
|
+
const projectRoot = (await findProjectRoot(cwd)) ?? cwd;
|
|
11
|
+
const testType = options.type ?? "all";
|
|
12
|
+
if (!["contract", "a11y", "probe", "all"].includes(testType)) {
|
|
13
|
+
throw new Error(`Invalid test type '${testType}'. Expected contract, a11y, probe, or all.`);
|
|
14
|
+
}
|
|
15
|
+
let hasFailures = false;
|
|
16
|
+
// 1. PostCSS Design Token Contract Audit
|
|
17
|
+
if (testType === "contract" || testType === "all") {
|
|
18
|
+
console.log(pc.cyan(`\nšØ Running Mozole Design Token Contract Audit in ${projectRoot}...`));
|
|
19
|
+
const cssSources = [];
|
|
20
|
+
async function collectCss(dir) {
|
|
21
|
+
if (!(await exists(dir)))
|
|
22
|
+
return;
|
|
23
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
24
|
+
for (const e of entries) {
|
|
25
|
+
const full = path.join(dir, e.name);
|
|
26
|
+
if (e.isDirectory() && !["node_modules", ".git", "dist", "build"].includes(e.name)) {
|
|
27
|
+
await collectCss(full);
|
|
28
|
+
}
|
|
29
|
+
else if (e.isFile() && e.name.endsWith(".css")) {
|
|
30
|
+
const css = await fs.readFile(full, "utf8");
|
|
31
|
+
cssSources.push({ file: path.relative(projectRoot, full), css });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
await collectCss(path.join(projectRoot, "src"));
|
|
36
|
+
if (cssSources.length === 0) {
|
|
37
|
+
console.log(pc.yellow(" ! No CSS files found in src/"));
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
const result = auditCssContracts(cssSources);
|
|
41
|
+
for (const err of result.errors) {
|
|
42
|
+
hasFailures = true;
|
|
43
|
+
console.log(pc.red(` ā [ERROR] ${err.file}:${err.line} (${err.selector}): ${err.message}`));
|
|
44
|
+
console.log(pc.dim(` Rule: ${err.rule} | Value: ${err.value}`));
|
|
45
|
+
}
|
|
46
|
+
for (const warn of result.warnings) {
|
|
47
|
+
console.log(pc.yellow(` ! [WARN] ${warn.file}:${warn.line} (${warn.selector}): ${warn.message}`));
|
|
48
|
+
}
|
|
49
|
+
if (result.errors.length === 0) {
|
|
50
|
+
console.log(pc.green(` ā Design contracts verified across ${cssSources.length} CSS files.`));
|
|
51
|
+
if (result.warnings.length > 0) {
|
|
52
|
+
console.log(pc.yellow(` (${result.warnings.length} diagnostic warnings)`));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// 2. Static HTML & Accessibility Audit
|
|
58
|
+
if (testType === "a11y" || testType === "all") {
|
|
59
|
+
console.log(pc.cyan(`\nāæ Running Static A11y & Landmark Hierarchy Audit in ${projectRoot}...`));
|
|
60
|
+
const htmlSources = [];
|
|
61
|
+
async function collectHtml(dir) {
|
|
62
|
+
if (!(await exists(dir)))
|
|
63
|
+
return;
|
|
64
|
+
for (const entry of await fs.readdir(dir, { withFileTypes: true })) {
|
|
65
|
+
const full = path.join(dir, entry.name);
|
|
66
|
+
if (entry.isDirectory())
|
|
67
|
+
await collectHtml(full);
|
|
68
|
+
else if (entry.isFile() &&
|
|
69
|
+
entry.name.endsWith(".html") &&
|
|
70
|
+
entry.name !== "__spa-fallback.html") {
|
|
71
|
+
htmlSources.push({
|
|
72
|
+
file: path.relative(projectRoot, full),
|
|
73
|
+
html: await fs.readFile(full, "utf8"),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
await collectHtml(path.join(projectRoot, "build", "client"));
|
|
79
|
+
if (htmlSources.length === 0)
|
|
80
|
+
await collectHtml(path.join(projectRoot, "dist"));
|
|
81
|
+
const indexHtmlPath = path.join(projectRoot, "index.html");
|
|
82
|
+
if (htmlSources.length === 0 && (await exists(indexHtmlPath))) {
|
|
83
|
+
const html = await fs.readFile(indexHtmlPath, "utf8");
|
|
84
|
+
htmlSources.push({ file: "index.html", html });
|
|
85
|
+
}
|
|
86
|
+
if (htmlSources.length === 0) {
|
|
87
|
+
console.log(pc.yellow(" ! No HTML available for accessibility audit. Build the project first."));
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
const result = auditHtmlA11y(htmlSources);
|
|
91
|
+
for (const err of result.errors) {
|
|
92
|
+
hasFailures = true;
|
|
93
|
+
console.log(pc.red(` ā [ERROR] ${err.file}:${err.line} (${err.element}): ${err.message}`));
|
|
94
|
+
}
|
|
95
|
+
for (const warn of result.warnings) {
|
|
96
|
+
console.log(pc.yellow(` ! [WARN] ${warn.file}:${warn.line} (${warn.element}): ${warn.message}`));
|
|
97
|
+
}
|
|
98
|
+
if (result.errors.length === 0) {
|
|
99
|
+
console.log(pc.green(" ā Accessibility landmark hierarchy passed."));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// 3. Live Headless DOM Geometry & Trace Probe (Separate command per policy)
|
|
104
|
+
if (testType === "probe") {
|
|
105
|
+
const probeRes = await runLiveGeometryProbe({ cwd: projectRoot });
|
|
106
|
+
if (!probeRes.success) {
|
|
107
|
+
hasFailures = true;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
console.log();
|
|
111
|
+
if (hasFailures) {
|
|
112
|
+
throw new Error("Mozole quality test suite detected contract or accessibility violations.");
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"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"}
|