@mozole/cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +196 -0
  3. package/dist/cli.d.ts +4 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +85 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/adopt.d.ts +4 -0
  8. package/dist/commands/adopt.d.ts.map +1 -0
  9. package/dist/commands/adopt.js +258 -0
  10. package/dist/commands/adopt.js.map +1 -0
  11. package/dist/commands/doctor.d.ts +4 -0
  12. package/dist/commands/doctor.d.ts.map +1 -0
  13. package/dist/commands/doctor.js +241 -0
  14. package/dist/commands/doctor.js.map +1 -0
  15. package/dist/commands/logs.d.ts +3 -0
  16. package/dist/commands/logs.d.ts.map +1 -0
  17. package/dist/commands/logs.js +32 -0
  18. package/dist/commands/logs.js.map +1 -0
  19. package/dist/commands/new.d.ts +3 -0
  20. package/dist/commands/new.d.ts.map +1 -0
  21. package/dist/commands/new.js +84 -0
  22. package/dist/commands/new.js.map +1 -0
  23. package/dist/commands/qa.d.ts +7 -0
  24. package/dist/commands/qa.d.ts.map +1 -0
  25. package/dist/commands/qa.js +95 -0
  26. package/dist/commands/qa.js.map +1 -0
  27. package/dist/commands/stats.d.ts +19 -0
  28. package/dist/commands/stats.d.ts.map +1 -0
  29. package/dist/commands/stats.js +100 -0
  30. package/dist/commands/stats.js.map +1 -0
  31. package/dist/commands/verify.d.ts +5 -0
  32. package/dist/commands/verify.d.ts.map +1 -0
  33. package/dist/commands/verify.js +53 -0
  34. package/dist/commands/verify.js.map +1 -0
  35. package/dist/config/project.d.ts +43 -0
  36. package/dist/config/project.d.ts.map +1 -0
  37. package/dist/config/project.js +57 -0
  38. package/dist/config/project.js.map +1 -0
  39. package/dist/context/cce.d.ts +8 -0
  40. package/dist/context/cce.d.ts.map +1 -0
  41. package/dist/context/cce.js +72 -0
  42. package/dist/context/cce.js.map +1 -0
  43. package/dist/governor/fingerprint.d.ts +7 -0
  44. package/dist/governor/fingerprint.d.ts.map +1 -0
  45. package/dist/governor/fingerprint.js +109 -0
  46. package/dist/governor/fingerprint.js.map +1 -0
  47. package/dist/governor/hook.d.ts +10 -0
  48. package/dist/governor/hook.d.ts.map +1 -0
  49. package/dist/governor/hook.js +127 -0
  50. package/dist/governor/hook.js.map +1 -0
  51. package/dist/governor/state.d.ts +35 -0
  52. package/dist/governor/state.d.ts.map +1 -0
  53. package/dist/governor/state.js +55 -0
  54. package/dist/governor/state.js.map +1 -0
  55. package/dist/integrations/antigravity.d.ts +20 -0
  56. package/dist/integrations/antigravity.d.ts.map +1 -0
  57. package/dist/integrations/antigravity.js +145 -0
  58. package/dist/integrations/antigravity.js.map +1 -0
  59. package/dist/output.d.ts +5 -0
  60. package/dist/output.d.ts.map +1 -0
  61. package/dist/output.js +2 -0
  62. package/dist/output.js.map +1 -0
  63. package/dist/platform/executable.d.ts +7 -0
  64. package/dist/platform/executable.d.ts.map +1 -0
  65. package/dist/platform/executable.js +35 -0
  66. package/dist/platform/executable.js.map +1 -0
  67. package/dist/platform/process.d.ts +24 -0
  68. package/dist/platform/process.d.ts.map +1 -0
  69. package/dist/platform/process.js +107 -0
  70. package/dist/platform/process.js.map +1 -0
  71. package/dist/qa/runner.d.ts +26 -0
  72. package/dist/qa/runner.d.ts.map +1 -0
  73. package/dist/qa/runner.js +322 -0
  74. package/dist/qa/runner.js.map +1 -0
  75. package/dist/qa/server.d.ts +10 -0
  76. package/dist/qa/server.d.ts.map +1 -0
  77. package/dist/qa/server.js +131 -0
  78. package/dist/qa/server.js.map +1 -0
  79. package/dist/scaffold/templates.d.ts +4 -0
  80. package/dist/scaffold/templates.d.ts.map +1 -0
  81. package/dist/scaffold/templates.js +186 -0
  82. package/dist/scaffold/templates.js.map +1 -0
  83. package/dist/scaffold/write.d.ts +2 -0
  84. package/dist/scaffold/write.d.ts.map +1 -0
  85. package/dist/scaffold/write.js +24 -0
  86. package/dist/scaffold/write.js.map +1 -0
  87. package/dist/telemetry/store.d.ts +27 -0
  88. package/dist/telemetry/store.d.ts.map +1 -0
  89. package/dist/telemetry/store.js +59 -0
  90. package/dist/telemetry/store.js.map +1 -0
  91. package/dist/verify/runner.d.ts +15 -0
  92. package/dist/verify/runner.d.ts.map +1 -0
  93. package/dist/verify/runner.js +91 -0
  94. package/dist/verify/runner.js.map +1 -0
  95. package/dist/version.d.ts +35 -0
  96. package/dist/version.d.ts.map +1 -0
  97. package/dist/version.js +35 -0
  98. package/dist/version.js.map +1 -0
  99. package/package.json +53 -0
@@ -0,0 +1,241 @@
1
+ import { access, readFile } from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { chromium } from "playwright";
5
+ import { findProjectRoot, readConfig } from "../config/project.js";
6
+ import { cceCommand } from "../context/cce.js";
7
+ import { inspectAntigravityWorkspace } from "../integrations/antigravity.js";
8
+ import { resolveExecutable } from "../platform/executable.js";
9
+ import { run } from "../platform/process.js";
10
+ async function executable(name, args = ["--version"], required = false) {
11
+ const resolved = await resolveExecutable(name);
12
+ if (!resolved)
13
+ return { group: "", name, healthy: false, required };
14
+ const result = await run(resolved, args, {
15
+ cwd: process.cwd(),
16
+ timeoutMs: 5_000,
17
+ });
18
+ return {
19
+ group: "",
20
+ name,
21
+ healthy: result.exitCode === 0,
22
+ value: (result.stdout || result.stderr)
23
+ .trim()
24
+ .split(/\r?\n/)[0]
25
+ ?.slice(0, 50),
26
+ required,
27
+ };
28
+ }
29
+ function packageVersion(value, name) {
30
+ const pkg = value;
31
+ return pkg.dependencies?.[name] ?? pkg.devDependencies?.[name];
32
+ }
33
+ export async function detectAntigravityRuntime(resolve = resolveExecutable) {
34
+ return resolve("agy");
35
+ }
36
+ export async function doctorCommand(cwd, output = console) {
37
+ const node = await executable("node", ["--version"], true);
38
+ const nodeMajor = Number(node.value?.match(/\d+/)?.[0] ?? 0);
39
+ node.healthy = node.healthy && nodeMajor >= 22;
40
+ const antigravityPath = await detectAntigravityRuntime();
41
+ let antigravity = {
42
+ group: "Agents",
43
+ name: "Antigravity",
44
+ healthy: false,
45
+ value: "optional runtime not found",
46
+ required: false,
47
+ };
48
+ if (antigravityPath) {
49
+ const result = await run(antigravityPath, ["--version"], {
50
+ cwd,
51
+ timeoutMs: 5_000,
52
+ });
53
+ antigravity = {
54
+ group: "Agents",
55
+ name: "Antigravity",
56
+ healthy: result.exitCode === 0,
57
+ value: (result.stdout || result.stderr).trim().split(/\r?\n/)[0],
58
+ required: false,
59
+ };
60
+ }
61
+ const cceRuntime = await cceCommand();
62
+ const cceDiagnostic = {
63
+ group: "Context",
64
+ name: "CCE",
65
+ healthy: false,
66
+ required: false,
67
+ ...(cceRuntime ? {} : { value: "not installed" }),
68
+ };
69
+ if (cceRuntime) {
70
+ const result = await run(cceRuntime.command, [...cceRuntime.prefix, "--version"], { cwd, timeoutMs: 5_000 });
71
+ cceDiagnostic.healthy = result.exitCode === 0;
72
+ cceDiagnostic.value = (result.stdout || result.stderr)
73
+ .trim()
74
+ .split(/\r?\n/)[0]
75
+ ?.slice(0, 50);
76
+ }
77
+ const diagnostics = [
78
+ {
79
+ group: "Platform",
80
+ name: "OS",
81
+ healthy: true,
82
+ value: os.platform(),
83
+ required: true,
84
+ },
85
+ {
86
+ group: "Platform",
87
+ name: "Architecture",
88
+ healthy: true,
89
+ value: os.arch(),
90
+ required: true,
91
+ },
92
+ { ...node, group: "Runtime", name: "Node" },
93
+ {
94
+ ...(await executable("npm", ["--version"], true)),
95
+ group: "Runtime",
96
+ name: "npm",
97
+ },
98
+ { ...(await executable("git")), group: "Runtime", name: "Git" },
99
+ { ...(await executable("codex")), group: "Agents", name: "Codex" },
100
+ { ...(await executable("claude")), group: "Agents", name: "Claude Code" },
101
+ antigravity,
102
+ cceDiagnostic,
103
+ ];
104
+ try {
105
+ await access(chromium.executablePath());
106
+ diagnostics.push({
107
+ group: "Browser",
108
+ name: "Chromium",
109
+ healthy: true,
110
+ required: true,
111
+ });
112
+ }
113
+ catch {
114
+ diagnostics.push({
115
+ group: "Browser",
116
+ name: "Chromium",
117
+ healthy: false,
118
+ required: true,
119
+ });
120
+ }
121
+ try {
122
+ const root = await findProjectRoot(cwd);
123
+ const mozoleConfig = await readConfig(root);
124
+ const cce = diagnostics.find((item) => item.name === "CCE");
125
+ if (cce)
126
+ cce.required = mozoleConfig.cce.enabled;
127
+ let indexHealthy = !mozoleConfig.cce.enabled;
128
+ if (mozoleConfig.cce.enabled && cce?.healthy && cceRuntime) {
129
+ const status = await run(cceRuntime.command, [...cceRuntime.prefix, "status"], {
130
+ cwd: root,
131
+ timeoutMs: 15_000,
132
+ });
133
+ indexHealthy = status.exitCode === 0 && mozoleConfig.cce.initialized;
134
+ }
135
+ const ccePosition = diagnostics.findIndex((item) => item.name === "CCE");
136
+ diagnostics.splice(ccePosition + 1, 0, {
137
+ group: "Context",
138
+ name: "Index",
139
+ healthy: indexHealthy,
140
+ required: mozoleConfig.cce.enabled,
141
+ });
142
+ const pkg = JSON.parse(await readFile(path.join(root, "package.json"), "utf8"));
143
+ for (const [label, key] of [
144
+ ["React Router", "react-router"],
145
+ ["React", "react"],
146
+ ["Vite", "vite"],
147
+ ["TypeScript", "typescript"],
148
+ ["Biome", "@biomejs/biome"],
149
+ ["Vitest", "vitest"],
150
+ ])
151
+ diagnostics.push({
152
+ group: "Project",
153
+ name: label,
154
+ healthy: Boolean(packageVersion(pkg, key)),
155
+ value: packageVersion(pkg, key),
156
+ required: true,
157
+ });
158
+ diagnostics.push({
159
+ group: "Project",
160
+ name: "Mozole metadata",
161
+ healthy: true,
162
+ required: true,
163
+ });
164
+ const antigravityWorkspace = await inspectAntigravityWorkspace(root);
165
+ for (const [name, healthy] of [
166
+ ["Workspace", antigravityWorkspace.workspace],
167
+ ["CCE MCP", antigravityWorkspace.cceMcp],
168
+ ["Rule", antigravityWorkspace.rule],
169
+ ["Workflows", antigravityWorkspace.workflows],
170
+ ])
171
+ diagnostics.push({
172
+ group: "Antigravity",
173
+ name,
174
+ healthy,
175
+ value: !healthy && name === "Workspace"
176
+ ? antigravityWorkspace.detail
177
+ : undefined,
178
+ required: true,
179
+ });
180
+ diagnostics.push({
181
+ group: "Governor",
182
+ name: "State cache",
183
+ healthy: mozoleConfig.governor.enabled,
184
+ value: mozoleConfig.governor.enabled
185
+ ? mozoleConfig.governor.mode
186
+ : "disabled",
187
+ required: mozoleConfig.governor.enabled,
188
+ });
189
+ for (const [name, relative, enabled] of [
190
+ [
191
+ "Codex hook",
192
+ [".codex", "hooks.json"],
193
+ mozoleConfig.governor.hooks.codex,
194
+ ],
195
+ [
196
+ "Claude hook",
197
+ [".claude", "settings.json"],
198
+ mozoleConfig.governor.hooks.claude,
199
+ ],
200
+ ]) {
201
+ let installed = !enabled;
202
+ try {
203
+ installed = (await readFile(path.join(root, ...relative), "utf8")).includes("mozole governor hook");
204
+ }
205
+ catch { }
206
+ diagnostics.push({
207
+ group: "Governor",
208
+ name,
209
+ healthy: installed,
210
+ required: enabled,
211
+ });
212
+ }
213
+ }
214
+ catch {
215
+ diagnostics.push({
216
+ group: "Project",
217
+ name: "Mozole project",
218
+ healthy: false,
219
+ value: "not found",
220
+ required: false,
221
+ });
222
+ }
223
+ let current = "";
224
+ const lines = ["Mozole", ""];
225
+ for (const item of diagnostics) {
226
+ if (item.group !== current) {
227
+ if (current)
228
+ lines.push("");
229
+ current = item.group;
230
+ lines.push(current);
231
+ }
232
+ lines.push(` ${item.name.padEnd(14)} ${item.healthy ? "✓" : "✗"}${item.value ? ` ${item.value}` : ""}`);
233
+ }
234
+ const healthy = diagnostics
235
+ .filter((item) => item.required)
236
+ .every((item) => item.healthy);
237
+ lines.push("", `Status: ${healthy ? "HEALTHY" : "NEEDS ATTENTION"}`);
238
+ output.log(lines.join("\n"));
239
+ return healthy ? 0 : 1;
240
+ }
241
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Output } from "../output.js";
2
+ export declare function logsCommand(cwd: string, name: string | undefined, raw: boolean, output?: Output): Promise<number>;
3
+ //# sourceMappingURL=logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,GAAG,EAAE,OAAO,EACZ,MAAM,GAAE,MAAgB,GACvB,OAAO,CAAC,MAAM,CAAC,CA4BjB"}
@@ -0,0 +1,32 @@
1
+ import { readdir, readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { findProjectRoot } from "../config/project.js";
4
+ export async function logsCommand(cwd, name, raw, output = console) {
5
+ try {
6
+ const root = await findProjectRoot(cwd);
7
+ const directory = path.join(root, ".mozole", "logs");
8
+ const names = (await readdir(directory))
9
+ .filter((entry) => entry.endsWith(".log"))
10
+ .sort();
11
+ if (!name) {
12
+ output.log(names.length ? names.join("\n") : "No diagnostic logs.");
13
+ return 0;
14
+ }
15
+ const filename = name.endsWith(".log") ? name : `${name}.log`;
16
+ if (path.basename(filename) !== filename || !names.includes(filename)) {
17
+ output.error(`Unknown log: ${name}`);
18
+ return 2;
19
+ }
20
+ const contents = await readFile(path.join(directory, filename), "utf8");
21
+ const delivered = raw
22
+ ? contents
23
+ : contents.split(/\r?\n/).slice(-81).join("\n");
24
+ output.log(delivered.trimEnd());
25
+ return 0;
26
+ }
27
+ catch (error) {
28
+ output.error(`LOGS FAIL\n\n${error instanceof Error ? error.message : String(error)}`);
29
+ return 2;
30
+ }
31
+ }
32
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,GAAW,EACX,IAAwB,EACxB,GAAY,EACZ,MAAM,GAAW,OAAO;IAExB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;aACrC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;aACzC,IAAI,EAAE,CAAC;QACV,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC;YACpE,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,MAAM,CAAC;QAC9D,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtE,MAAM,CAAC,KAAK,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC;YACrC,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;QACxE,MAAM,SAAS,GAAG,GAAG;YACnB,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;QAChC,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CACV,gBAAgB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACzE,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Output } from "../output.js";
2
+ export declare function newCommand(name: string | undefined, cwd: string, output?: Output): Promise<number>;
3
+ //# sourceMappingURL=new.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAM3C,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,MAAgB,GACvB,OAAO,CAAC,MAAM,CAAC,CA2FjB"}
@@ -0,0 +1,84 @@
1
+ import { constants } from "node:fs";
2
+ import { access, mkdtemp, rename, rm } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { cceCommand, initializeCce } from "../context/cce.js";
5
+ import { configureAntigravityMcp } from "../integrations/antigravity.js";
6
+ import { npmExecutable } from "../platform/executable.js";
7
+ import { run } from "../platform/process.js";
8
+ import { projectTemplates } from "../scaffold/templates.js";
9
+ import { writeFiles } from "../scaffold/write.js";
10
+ export async function newCommand(name, cwd, output = console) {
11
+ if (!name ||
12
+ name === "." ||
13
+ path.isAbsolute(name) ||
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 access(target, constants.F_OK);
23
+ output.error(`Cannot create ${target}: path already exists.`);
24
+ return 2;
25
+ }
26
+ catch { }
27
+ const staging = await mkdtemp(path.join(cwd, `.mozole-${name}-`));
28
+ const controller = new AbortController();
29
+ const abort = () => controller.abort();
30
+ process.once("SIGINT", abort);
31
+ process.once("SIGTERM", abort);
32
+ let moved = false;
33
+ try {
34
+ await writeFiles(staging, projectTemplates(name));
35
+ if (process.env.MOZOLE_SKIP_INSTALL !== "1") {
36
+ const installed = await run(npmExecutable(), ["install", "--no-fund", "--no-audit"], {
37
+ cwd: staging,
38
+ timeoutMs: 600_000,
39
+ signal: controller.signal,
40
+ logFile: path.join(staging, ".mozole", "logs", "npm-install.log"),
41
+ });
42
+ if (installed.exitCode !== 0)
43
+ throw new Error(`npm install failed. See .mozole/logs/npm-install.log`);
44
+ if (process.env.MOZOLE_SKIP_BROWSER !== "1") {
45
+ const browser = await run(npmExecutable(), ["exec", "--", "playwright", "install", "chromium"], {
46
+ cwd: staging,
47
+ timeoutMs: 600_000,
48
+ signal: controller.signal,
49
+ logFile: path.join(staging, ".mozole", "logs", "playwright-install.log"),
50
+ });
51
+ if (browser.exitCode !== 0)
52
+ throw new Error("Chromium installation failed. See .mozole/logs/playwright-install.log");
53
+ }
54
+ }
55
+ await rename(staging, target);
56
+ moved = true;
57
+ let cceMessage = "CCE not initialized (install uv or cce, then run `cce init --agent all`).";
58
+ if (process.env.MOZOLE_SKIP_CCE !== "1") {
59
+ const cce = await initializeCce(target, controller.signal);
60
+ if (controller.signal.aborted)
61
+ throw new Error("Creation cancelled.");
62
+ if (cce?.exitCode === 0)
63
+ cceMessage = "CCE indexed and configured.";
64
+ else if (cce)
65
+ cceMessage =
66
+ "CCE setup needs attention; see .mozole/logs/cce-init.log.";
67
+ }
68
+ const cce = await cceCommand();
69
+ await configureAntigravityMcp(target, cce?.prefix.length ? "uvx" : "cce");
70
+ output.log(`\nCreated ${name}\n${cceMessage}\n\nNext: cd ${name} && npm run verify`);
71
+ return 0;
72
+ }
73
+ catch (error) {
74
+ if (!moved)
75
+ await rm(staging, { recursive: true, force: true });
76
+ output.error(`CREATE FAIL\n\n${error instanceof Error ? error.message : String(error)}\nCleanup: ${moved ? `project remains at ${target}` : "incomplete staging directory removed"}`);
77
+ return controller.signal.aborted ? 130 : 1;
78
+ }
79
+ finally {
80
+ process.removeListener("SIGINT", abort);
81
+ process.removeListener("SIGTERM", abort);
82
+ }
83
+ }
84
+ //# sourceMappingURL=new.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new.js","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { Output } from "../output.js";
2
+ export declare function qaCommand(cwd: string, mode: {
3
+ interactive: boolean;
4
+ visual: boolean;
5
+ force?: boolean;
6
+ }, output?: Output): Promise<number>;
7
+ //# sourceMappingURL=qa.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qa.d.ts","sourceRoot":"","sources":["../../src/commands/qa.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAoC3C,wBAAsB,SAAS,CAC7B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,WAAW,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EAChE,MAAM,GAAE,MAAgB,GACvB,OAAO,CAAC,MAAM,CAAC,CA+DjB"}
@@ -0,0 +1,95 @@
1
+ import { access, readdir } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { findProjectRoot, readConfig } from "../config/project.js";
4
+ import { fileFingerprint, projectFingerprint, } from "../governor/fingerprint.js";
5
+ import { qaStateKey, readGovernorState, writeGovernorState, } from "../governor/state.js";
6
+ import { runQa } from "../qa/runner.js";
7
+ import { updateTelemetry } from "../telemetry/store.js";
8
+ async function visualArtifactsCurrent(root, artifacts) {
9
+ if (!artifacts?.length)
10
+ return false;
11
+ try {
12
+ for (const artifact of artifacts) {
13
+ const absolute = path.resolve(root, artifact.path);
14
+ if (!absolute.startsWith(`${path.resolve(root)}${path.sep}`))
15
+ return false;
16
+ await access(absolute);
17
+ if ((await fileFingerprint(absolute)) !== artifact.sha256)
18
+ return false;
19
+ }
20
+ return true;
21
+ }
22
+ catch {
23
+ return false;
24
+ }
25
+ }
26
+ async function captureArtifactState(root) {
27
+ const directory = path.join(root, ".mozole", "qa");
28
+ const names = (await readdir(directory)).filter((name) => name.endsWith(".png"));
29
+ return Promise.all(names.sort().map(async (name) => ({
30
+ path: path.posix.join(".mozole", "qa", name),
31
+ sha256: await fileFingerprint(path.join(directory, name)),
32
+ })));
33
+ }
34
+ export async function qaCommand(cwd, mode, output = console) {
35
+ const controller = new AbortController();
36
+ const abort = () => controller.abort();
37
+ process.once("SIGINT", abort);
38
+ process.once("SIGTERM", abort);
39
+ try {
40
+ const root = await findProjectRoot(cwd);
41
+ const config = await readConfig(root);
42
+ const key = qaStateKey(mode);
43
+ const profile = mode.visual ? "visual" : "qa";
44
+ const fingerprint = await projectFingerprint(root, config, profile);
45
+ const state = await readGovernorState(root);
46
+ const cached = state.qa[key];
47
+ const artifactsCurrent = mode.visual
48
+ ? await visualArtifactsCurrent(root, cached?.artifacts)
49
+ : true;
50
+ if (config.governor.enabled &&
51
+ !mode.force &&
52
+ cached?.fingerprint === fingerprint &&
53
+ artifactsCurrent) {
54
+ const reused = mode.visual ? (cached.artifacts?.length ?? 0) : 0;
55
+ const message = mode.visual
56
+ ? `VISUAL QA CURRENT\n\nReused ${reused} screenshot artifacts.`
57
+ : "QA CURRENT\n\nNo relevant changes since the last successful QA run.";
58
+ output.log(message);
59
+ if (config.telemetry.enabled)
60
+ await updateTelemetry(root, (telemetry) => {
61
+ telemetry.qa.avoidedRuns++;
62
+ telemetry.qa.browserLaunchesAvoided++;
63
+ telemetry.qa.reusedVisualArtifacts += reused;
64
+ telemetry.governor.modelFacingDiagnosticChars += message.length;
65
+ });
66
+ return 0;
67
+ }
68
+ const result = await runQa(root, config, mode, controller.signal);
69
+ (result.passed ? output.log : output.error)(result.output);
70
+ if (result.passed) {
71
+ state.qa[key] = {
72
+ fingerprint: await projectFingerprint(root, config, profile),
73
+ passedAt: new Date().toISOString(),
74
+ routes: [...config.routes],
75
+ viewports: config.qa.viewports.map((viewport) => `${viewport.width}x${viewport.height}`),
76
+ ...(mode.visual ? { artifacts: await captureArtifactState(root) } : {}),
77
+ };
78
+ await writeGovernorState(root, state);
79
+ }
80
+ else if (cached?.fingerprint === fingerprint) {
81
+ delete state.qa[key];
82
+ await writeGovernorState(root, state);
83
+ }
84
+ return result.passed ? 0 : 1;
85
+ }
86
+ catch (error) {
87
+ output.error(`QA FAIL\n\n${error instanceof Error ? error.message : String(error)}\n\nIf Chromium is missing, run: npx playwright install chromium`);
88
+ return controller.signal.aborted ? 130 : 2;
89
+ }
90
+ finally {
91
+ process.removeListener("SIGINT", abort);
92
+ process.removeListener("SIGTERM", abort);
93
+ }
94
+ }
95
+ //# sourceMappingURL=qa.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qa.js","sourceRoot":"","sources":["../../src/commands/qa.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { Output } from "../output.js";
2
+ interface CceSavings {
3
+ queries: number;
4
+ served_tokens: number;
5
+ full_file_tokens: number;
6
+ tokens_saved: number;
7
+ savings_pct: number;
8
+ }
9
+ export declare function parseCceSavings(output: string): CceSavings | undefined;
10
+ export declare function cceSavingsInvocation(cce: {
11
+ command: string;
12
+ prefix: string[];
13
+ }): {
14
+ command: string;
15
+ args: string[];
16
+ };
17
+ export declare function statsCommand(cwd: string, output?: Output): Promise<number>;
18
+ export {};
19
+ //# sourceMappingURL=stats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/commands/stats.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAW3C,UAAU,UAAU;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAsBtE;AACD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAEtC;AACD,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,MAAgB,GACvB,OAAO,CAAC,MAAM,CAAC,CAqEjB"}
@@ -0,0 +1,100 @@
1
+ import { findProjectRoot } from "../config/project.js";
2
+ import { cceCommand } from "../context/cce.js";
3
+ import { run } from "../platform/process.js";
4
+ import { readTelemetry } from "../telemetry/store.js";
5
+ function number(value) {
6
+ return new Intl.NumberFormat("en-US", {
7
+ notation: value >= 10_000 ? "compact" : "standard",
8
+ maximumFractionDigits: 1,
9
+ }).format(value);
10
+ }
11
+ export function parseCceSavings(output) {
12
+ const start = output.indexOf("{");
13
+ const end = output.lastIndexOf("}");
14
+ if (start < 0 || end < start)
15
+ return undefined;
16
+ try {
17
+ const value = JSON.parse(output.slice(start, end + 1));
18
+ if (![
19
+ value.queries,
20
+ value.served_tokens,
21
+ value.full_file_tokens,
22
+ value.tokens_saved,
23
+ value.savings_pct,
24
+ ].every((item) => typeof item === "number" && Number.isFinite(item)))
25
+ return undefined;
26
+ return value;
27
+ }
28
+ catch {
29
+ return undefined;
30
+ }
31
+ }
32
+ export function cceSavingsInvocation(cce) {
33
+ return { command: cce.command, args: [...cce.prefix, "savings", "--json"] };
34
+ }
35
+ export async function statsCommand(cwd, output = console) {
36
+ try {
37
+ const root = await findProjectRoot(cwd);
38
+ const telemetry = await readTelemetry(root);
39
+ const cce = await cceCommand();
40
+ let cceLines = [];
41
+ if (cce) {
42
+ const invocation = cceSavingsInvocation(cce);
43
+ const result = await run(invocation.command, invocation.args, {
44
+ cwd: root,
45
+ timeoutMs: 15_000,
46
+ });
47
+ const savings = result.exitCode === 0 ? parseCceSavings(result.stdout) : undefined;
48
+ if (savings)
49
+ cceLines = [
50
+ ` potential full-file context ${number(savings.full_file_tokens)} tokens`,
51
+ ` delivered context ${number(savings.served_tokens)} tokens`,
52
+ ` avoided context ${number(savings.tokens_saved)} tokens`,
53
+ ` queries ${number(savings.queries)}`,
54
+ ` measured reduction ${savings.savings_pct.toFixed(1)}%`,
55
+ ];
56
+ }
57
+ const suppressed = telemetry.verification.rawChars - telemetry.verification.deliveredChars;
58
+ const reduction = telemetry.verification.rawChars
59
+ ? (suppressed / telemetry.verification.rawChars) * 100
60
+ : 0;
61
+ output.log([
62
+ "Mozole Agent Efficiency",
63
+ "",
64
+ "Context (CCE measured)",
65
+ ...(cceLines.length
66
+ ? cceLines
67
+ : [" unavailable — run CCE queries to collect measurements"]),
68
+ "",
69
+ "Verification (measured)",
70
+ ` runs ${telemetry.verification.runs}`,
71
+ ` raw output ${number(telemetry.verification.rawChars)} chars`,
72
+ ` delivered output ${number(telemetry.verification.deliveredChars)} chars`,
73
+ ` suppressed output ${number(Math.max(0, suppressed))} chars`,
74
+ ` reruns avoided ${telemetry.verification.avoidedRuns}`,
75
+ ` output reduction ${reduction.toFixed(1)}%`,
76
+ "",
77
+ "QA (measured)",
78
+ ` runs ${telemetry.qa.runs}`,
79
+ ` probes ${telemetry.qa.probes}`,
80
+ ` screenshots ${telemetry.qa.screenshots}`,
81
+ ` non-visual runs ${telemetry.qa.runs - telemetry.qa.visualRuns}`,
82
+ ` reruns avoided ${telemetry.qa.avoidedRuns}`,
83
+ ` browser launches saved ${telemetry.qa.browserLaunchesAvoided}`,
84
+ ` visual artifacts reused ${telemetry.qa.reusedVisualArtifacts}`,
85
+ "",
86
+ "Governor (measured)",
87
+ ` repeated-read warnings ${telemetry.governor.repeatedReadWarnings}`,
88
+ ` repeated-work warnings ${telemetry.governor.repeatedWorkWarnings}`,
89
+ ` diagnostic payload ${number(telemetry.governor.modelFacingDiagnosticChars)} chars`,
90
+ "",
91
+ "No billing or model-token savings are inferred from character counts.",
92
+ ].join("\n"));
93
+ return 0;
94
+ }
95
+ catch (error) {
96
+ output.error(`STATS FAIL\n\n${error instanceof Error ? error.message : String(error)}`);
97
+ return 2;
98
+ }
99
+ }
100
+ //# sourceMappingURL=stats.js.map