micro-models-agent 0.55.0 → 0.56.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 (232) hide show
  1. package/README.md +358 -358
  2. package/dist/certification/certifications.json +493 -493
  3. package/dist/main.js +2301 -1213
  4. package/dist/modules/browser/bridge-server.mjs +219 -202
  5. package/dist/skills/builtin/git.md +36 -36
  6. package/dist/skills/builtin/typescript.md +35 -35
  7. package/package.json +1 -1
  8. package/dist/cli/commands.js +0 -447
  9. package/dist/cli/completer.js +0 -167
  10. package/dist/cli/index.js +0 -2
  11. package/dist/cli/main.js +0 -153
  12. package/dist/cli/plugin-commands.js +0 -36
  13. package/dist/cli/repl-commands.js +0 -761
  14. package/dist/cli/repl.js +0 -702
  15. package/dist/cli/run-result.js +0 -33
  16. package/dist/cli/security-commands.js +0 -164
  17. package/dist/cli/setup.js +0 -237
  18. package/dist/config/config.js +0 -276
  19. package/dist/config/defaults.js +0 -141
  20. package/dist/config/domains.js +0 -179
  21. package/dist/config/experts.js +0 -15
  22. package/dist/config/index.js +0 -4
  23. package/dist/config/security.js +0 -213
  24. package/dist/config/types.js +0 -1
  25. package/dist/core/agent-moe.js +0 -102
  26. package/dist/core/agent.js +0 -1018
  27. package/dist/core/bootstrap.js +0 -481
  28. package/dist/core/crash-handler.js +0 -51
  29. package/dist/core/environment.js +0 -199
  30. package/dist/core/index.js +0 -2
  31. package/dist/core/prompt-builder.js +0 -76
  32. package/dist/core/session-logger.js +0 -251
  33. package/dist/core/types.js +0 -1
  34. package/dist/core/version.js +0 -26
  35. package/dist/core/workspace.js +0 -76
  36. package/dist/i18n/en.json +0 -679
  37. package/dist/i18n/index.js +0 -46
  38. package/dist/i18n/ru.json +0 -679
  39. package/dist/index.js +0 -22
  40. package/dist/llm/image-utils.js +0 -143
  41. package/dist/llm/index.js +0 -4
  42. package/dist/llm/model-loader.js +0 -78
  43. package/dist/llm/openai-compat.js +0 -497
  44. package/dist/llm/orchestrator.js +0 -200
  45. package/dist/llm/provider.js +0 -10
  46. package/dist/llm/response.js +0 -39
  47. package/dist/llm/token-counter.js +0 -39
  48. package/dist/llm/types.js +0 -1
  49. package/dist/logger/app-logger.js +0 -189
  50. package/dist/logger/file-log.js +0 -151
  51. package/dist/logger/index.js +0 -1
  52. package/dist/migration/backup.js +0 -45
  53. package/dist/migration/detect.js +0 -50
  54. package/dist/migration/index.js +0 -2
  55. package/dist/modules/artifacts/store.js +0 -61
  56. package/dist/modules/browser/actions.js +0 -76
  57. package/dist/modules/browser/bridge-client.js +0 -199
  58. package/dist/modules/browser/bridge-path.js +0 -10
  59. package/dist/modules/browser/cookie-store.js +0 -24
  60. package/dist/modules/browser/driver.js +0 -136
  61. package/dist/modules/browser/index.js +0 -7
  62. package/dist/modules/browser/module.js +0 -29
  63. package/dist/modules/browser/session.js +0 -342
  64. package/dist/modules/browser/snapshot.js +0 -148
  65. package/dist/modules/browser/types.js +0 -12
  66. package/dist/modules/certification/cli.js +0 -213
  67. package/dist/modules/certification/fact-checker.js +0 -82
  68. package/dist/modules/certification/loader.js +0 -106
  69. package/dist/modules/certification/manifest.js +0 -58
  70. package/dist/modules/certification/runner.js +0 -245
  71. package/dist/modules/certification/scenarios.js +0 -407
  72. package/dist/modules/certification/types.js +0 -1
  73. package/dist/modules/context/chunk-query.js +0 -100
  74. package/dist/modules/context/fact-extractor.js +0 -168
  75. package/dist/modules/context/history.js +0 -15
  76. package/dist/modules/context/index.js +0 -1
  77. package/dist/modules/context/manager.js +0 -440
  78. package/dist/modules/execution/audit-runners.js +0 -206
  79. package/dist/modules/execution/auditor.js +0 -218
  80. package/dist/modules/execution/execution-plugin.js +0 -431
  81. package/dist/modules/execution/index.js +0 -8
  82. package/dist/modules/execution/module.js +0 -625
  83. package/dist/modules/execution/moe-executor.js +0 -304
  84. package/dist/modules/execution/plan-coverage.js +0 -68
  85. package/dist/modules/execution/plan-persister.js +0 -46
  86. package/dist/modules/execution/plan-store.js +0 -196
  87. package/dist/modules/execution/plan-tool.js +0 -677
  88. package/dist/modules/execution/plan-validator.js +0 -153
  89. package/dist/modules/execution/planner.js +0 -94
  90. package/dist/modules/execution/stuck-detector.js +0 -746
  91. package/dist/modules/execution/tracker.js +0 -69
  92. package/dist/modules/execution/types.js +0 -1
  93. package/dist/modules/execution/verifier.js +0 -235
  94. package/dist/modules/execution/windows-commands.js +0 -41
  95. package/dist/modules/hallucination/confidence.js +0 -66
  96. package/dist/modules/hallucination/consistency.js +0 -26
  97. package/dist/modules/hallucination/detector.js +0 -47
  98. package/dist/modules/hallucination/factual.js +0 -169
  99. package/dist/modules/hallucination/index.js +0 -5
  100. package/dist/modules/hallucination/js-identifiers.js +0 -262
  101. package/dist/modules/hallucination/llm-judge.js +0 -101
  102. package/dist/modules/index.js +0 -5
  103. package/dist/modules/indexer/cache.js +0 -40
  104. package/dist/modules/indexer/index.js +0 -3
  105. package/dist/modules/indexer/module.js +0 -246
  106. package/dist/modules/indexer/project-profile.js +0 -183
  107. package/dist/modules/indexer/walker.js +0 -101
  108. package/dist/modules/lsp/check-tool.js +0 -58
  109. package/dist/modules/lsp/client.js +0 -389
  110. package/dist/modules/lsp/command.js +0 -60
  111. package/dist/modules/lsp/config.js +0 -135
  112. package/dist/modules/lsp/index.js +0 -3
  113. package/dist/modules/lsp/module.js +0 -260
  114. package/dist/modules/lsp/probe.js +0 -86
  115. package/dist/modules/lsp/project-root.js +0 -32
  116. package/dist/modules/lsp/startup-check.js +0 -144
  117. package/dist/modules/lsp/types.js +0 -1
  118. package/dist/modules/mcp/client.js +0 -399
  119. package/dist/modules/mcp/index.js +0 -3
  120. package/dist/modules/mcp/module.js +0 -142
  121. package/dist/modules/mcp/registry.js +0 -15
  122. package/dist/modules/memory/index.js +0 -1
  123. package/dist/modules/memory/module.js +0 -96
  124. package/dist/modules/memory/search.js +0 -42
  125. package/dist/modules/memory/store.js +0 -69
  126. package/dist/modules/pipelines/engine.js +0 -60
  127. package/dist/modules/pipelines/index.js +0 -3
  128. package/dist/modules/pipelines/parser.js +0 -56
  129. package/dist/modules/pipelines/template.js +0 -14
  130. package/dist/modules/plugins/builtin/lint-on-write.js +0 -334
  131. package/dist/modules/plugins/builtin/notify.js +0 -9
  132. package/dist/modules/plugins/index.js +0 -1
  133. package/dist/modules/plugins/loader.js +0 -70
  134. package/dist/modules/plugins/manager.js +0 -261
  135. package/dist/modules/plugins/types.js +0 -1
  136. package/dist/modules/pricing/index.js +0 -61
  137. package/dist/modules/pricing/prices.js +0 -129
  138. package/dist/modules/processes/detect.js +0 -34
  139. package/dist/modules/processes/index.js +0 -2
  140. package/dist/modules/processes/registry.js +0 -327
  141. package/dist/modules/processes/runner.js +0 -23
  142. package/dist/modules/providers/create.js +0 -22
  143. package/dist/modules/providers/fallback.js +0 -79
  144. package/dist/modules/providers/health.js +0 -46
  145. package/dist/modules/providers/index.js +0 -5
  146. package/dist/modules/providers/manager.js +0 -161
  147. package/dist/modules/providers/presets.js +0 -128
  148. package/dist/modules/providers/registry.js +0 -22
  149. package/dist/modules/providers/types.js +0 -1
  150. package/dist/modules/registry.js +0 -48
  151. package/dist/modules/security/audit-log.js +0 -136
  152. package/dist/modules/security/audit-notifier.js +0 -292
  153. package/dist/modules/security/command-validator.js +0 -219
  154. package/dist/modules/security/content-scanner.js +0 -53
  155. package/dist/modules/security/data-sanitizer.js +0 -89
  156. package/dist/modules/security/encryption.js +0 -242
  157. package/dist/modules/security/index.js +0 -14
  158. package/dist/modules/security/network-validator.js +0 -88
  159. package/dist/modules/security/path-validator.js +0 -203
  160. package/dist/modules/security/rate-limiter.js +0 -119
  161. package/dist/modules/security/security-policies.js +0 -531
  162. package/dist/modules/security/session-encryption.js +0 -210
  163. package/dist/modules/security/session-isolation.js +0 -95
  164. package/dist/modules/session/index.js +0 -3
  165. package/dist/modules/session/manager.js +0 -172
  166. package/dist/modules/session/module.js +0 -24
  167. package/dist/modules/session/store.js +0 -222
  168. package/dist/modules/session/types.js +0 -1
  169. package/dist/modules/skills/index.js +0 -2
  170. package/dist/modules/skills/loader.js +0 -72
  171. package/dist/modules/skills/matcher.js +0 -27
  172. package/dist/modules/skills/module.js +0 -129
  173. package/dist/modules/types.js +0 -1
  174. package/dist/modules/updater/checker.js +0 -96
  175. package/dist/modules/updater/index.js +0 -2
  176. package/dist/modules/updater/module.js +0 -116
  177. package/dist/modules/user-profile/compressor.js +0 -16
  178. package/dist/modules/user-profile/index.js +0 -1
  179. package/dist/modules/user-profile/profile.js +0 -68
  180. package/dist/tools/approve.js +0 -33
  181. package/dist/tools/attach-image.js +0 -101
  182. package/dist/tools/bash.js +0 -519
  183. package/dist/tools/browser.js +0 -115
  184. package/dist/tools/chunk-query.js +0 -100
  185. package/dist/tools/create-dir.js +0 -56
  186. package/dist/tools/delete-file.js +0 -63
  187. package/dist/tools/download-file.js +0 -117
  188. package/dist/tools/edit-file.js +0 -80
  189. package/dist/tools/enable-tools.js +0 -59
  190. package/dist/tools/executor.js +0 -154
  191. package/dist/tools/file-info.js +0 -47
  192. package/dist/tools/filter-tools.js +0 -17
  193. package/dist/tools/glob-tool.js +0 -27
  194. package/dist/tools/grep-tool.js +0 -125
  195. package/dist/tools/hidden-tools-block.js +0 -37
  196. package/dist/tools/index.js +0 -78
  197. package/dist/tools/list-dir.js +0 -49
  198. package/dist/tools/load-skill.js +0 -43
  199. package/dist/tools/mcp-call.js +0 -69
  200. package/dist/tools/move-file.js +0 -86
  201. package/dist/tools/path-utils.js +0 -101
  202. package/dist/tools/pipeline-run.js +0 -145
  203. package/dist/tools/preview.js +0 -2
  204. package/dist/tools/process-kill.js +0 -40
  205. package/dist/tools/process-list.js +0 -37
  206. package/dist/tools/process-log.js +0 -54
  207. package/dist/tools/question.js +0 -141
  208. package/dist/tools/read-file.js +0 -179
  209. package/dist/tools/recall.js +0 -118
  210. package/dist/tools/registry.js +0 -47
  211. package/dist/tools/remember.js +0 -68
  212. package/dist/tools/scope-check.js +0 -32
  213. package/dist/tools/search-history.js +0 -85
  214. package/dist/tools/subagent.js +0 -196
  215. package/dist/tools/types.js +0 -1
  216. package/dist/tools/user-input.js +0 -123
  217. package/dist/tools/web-browse.js +0 -87
  218. package/dist/tools/web-fetch.js +0 -119
  219. package/dist/tools/web-search.js +0 -105
  220. package/dist/tools/write-file.js +0 -82
  221. package/dist/ui/box.js +0 -77
  222. package/dist/ui/colors.js +0 -4
  223. package/dist/ui/diff.js +0 -178
  224. package/dist/ui/index.js +0 -6
  225. package/dist/ui/line-editor.js +0 -822
  226. package/dist/ui/line-math.js +0 -73
  227. package/dist/ui/md-formatter.js +0 -212
  228. package/dist/ui/output.js +0 -13
  229. package/dist/ui/plan-view.js +0 -103
  230. package/dist/ui/renderer.js +0 -259
  231. package/dist/ui/spinner.js +0 -70
  232. package/dist/ui/table.js +0 -144
@@ -1,213 +0,0 @@
1
- import { rmSync, writeFileSync } from "fs";
2
- import { join, dirname } from "path";
3
- import { fileURLToPath } from "url";
4
- import { existsSync, readFileSync } from "fs";
5
- import { t } from "../../i18n/index";
6
- import { pc } from "../../ui/colors";
7
- import { loadScenarios, filterByTags } from "./loader";
8
- import { runScenario, findMmaRoot } from "./runner";
9
- import { readManifest, upsertCertification, removeCertification, isFullyPassed } from "./manifest";
10
- const HERE = dirname(fileURLToPath(import.meta.url));
11
- const MMA_ROOT = findMmaRoot(HERE);
12
- function readVersion() {
13
- const candidates = [join(MMA_ROOT, "package.json")];
14
- for (const p of candidates) {
15
- if (existsSync(p)) {
16
- try {
17
- const raw = JSON.parse(readFileSync(p, "utf-8"));
18
- if (raw.version)
19
- return raw.version;
20
- }
21
- catch {
22
- // Broken package.json — fall back to the default version
23
- }
24
- }
25
- }
26
- return "0.0.0";
27
- }
28
- export function parseTags(s) {
29
- return s
30
- .split(",")
31
- .map((x) => x.trim())
32
- .filter(Boolean);
33
- }
34
- export async function certify(opts) {
35
- const providerUrl = opts.providerUrl || opts.config.provider.baseUrl;
36
- const { scenarios, errors } = loadScenarios(join(opts.projectDir, ".mma", "certification", "scenarios"));
37
- for (const e of errors)
38
- console.error(pc.yellow(` ${e}`));
39
- const selected = filterByTags(scenarios, opts.tags);
40
- if (selected.length === 0) {
41
- console.error(pc.red(t("cli.cert_no_scenarios", { tags: opts.tags.join(",") })));
42
- process.exitCode = 1;
43
- return;
44
- }
45
- const manifest = readManifest(opts.projectDir);
46
- const existing = manifest.certifications.find((e) => e.model === opts.name && e.providerUrl === providerUrl);
47
- if (existing && !opts.force) {
48
- console.error(pc.yellow(t("cli.cert_exists", { model: opts.name })));
49
- console.error(pc.yellow(t("cli.cert_exists_hint")));
50
- process.exitCode = 1;
51
- return;
52
- }
53
- console.log(t("cli.cert_started", { model: opts.name, provider: providerUrl }));
54
- const sandboxBase = join(process.cwd(), ".mma", "certification");
55
- const results = [];
56
- const total = selected.length;
57
- let idx = 0;
58
- for (const scenario of selected) {
59
- idx++;
60
- if (scenario.mode === "skip") {
61
- console.log(pc.dim(`[${idx}/${total}] ${scenario.id} ... skipped`));
62
- results.push({
63
- id: scenario.id,
64
- title: scenario.title,
65
- status: "skipped",
66
- passed: 0,
67
- of: 0,
68
- });
69
- continue;
70
- }
71
- const res = await runScenario(scenario, {
72
- model: opts.name,
73
- providerUrl,
74
- providerKey: opts.providerKey,
75
- contextWindow: opts.contextWindow,
76
- mmaRoot: MMA_ROOT,
77
- sandboxBase,
78
- defaultReps: opts.reps,
79
- defaultThreshold: 2,
80
- baseConfig: opts.config,
81
- onRep: (id, rep, reps, passed, failures) => {
82
- const word = passed ? pc.green(t("cli.cert_rep_pass")) : pc.red(t("cli.cert_rep_fail"));
83
- console.log(`[${idx}/${total}] ${id} (${rep}/${reps})... ${word}`);
84
- if (!passed)
85
- console.log(` ${pc.dim(failures.join("; "))}`);
86
- },
87
- });
88
- results.push(res);
89
- }
90
- if (opts.clean) {
91
- try {
92
- rmSync(sandboxBase, { recursive: true, force: true });
93
- }
94
- catch {
95
- /* ignore */
96
- }
97
- }
98
- const suite = summarize(results);
99
- const entry = {
100
- model: opts.name,
101
- providerUrl,
102
- mmaVersion: readVersion(),
103
- certifiedAt: new Date().toISOString(),
104
- suite,
105
- results,
106
- };
107
- upsertCertification(entry, opts.projectDir);
108
- console.log(t("cli.cert_done", {
109
- passed: String(suite.passed),
110
- failed: String(suite.failed),
111
- skipped: String(suite.skipped),
112
- total: String(suite.total),
113
- }));
114
- printResults(results);
115
- if (isFullyPassed(entry)) {
116
- console.log(pc.green(`\n✔ ${opts.name} is certified`));
117
- }
118
- else {
119
- console.log(pc.yellow(`\n⚠ ${opts.name} is NOT certified — all scenarios must pass`));
120
- }
121
- // Always write report file
122
- writeReport(entry, opts.projectDir);
123
- }
124
- export async function certStatus(name, config, projectDir) {
125
- const m = readManifest(projectDir);
126
- const providerUrl = config.provider.baseUrl;
127
- const entry = m.certifications.find((e) => e.model === name && e.providerUrl === providerUrl);
128
- if (!entry) {
129
- console.log(t("cli.cert_not_found", { model: name }));
130
- return;
131
- }
132
- console.log(`${t("cli.cert_provider_col")}: ${entry.providerUrl}`);
133
- console.log(`${t("cli.cert_version_col")}: ${entry.mmaVersion} ${t("cli.cert_date_col")}: ${entry.certifiedAt.slice(0, 10)}`);
134
- console.log(`${t("cli.cert_suite_col")}: ${entry.suite.passed} pass / ${entry.suite.failed} fail / ${entry.suite.skipped} skipped`);
135
- const status = isFullyPassed(entry)
136
- ? pc.green("✔ certified")
137
- : pc.yellow("⚠ NOT certified");
138
- console.log(`Status: ${status}`);
139
- printResults(entry.results);
140
- }
141
- export async function certList(projectDir) {
142
- const m = readManifest(projectDir);
143
- if (m.certifications.length === 0) {
144
- console.log(t("cli.cert_empty"));
145
- return;
146
- }
147
- for (const e of m.certifications) {
148
- const mark = isFullyPassed(e) ? pc.green("✔") : pc.red("✘");
149
- console.log(` ${mark} ${e.model} ${pc.dim(e.providerUrl)} ${e.mmaVersion} ${e.certifiedAt.slice(0, 10)} ${e.suite.passed}/${e.suite.total} pass`);
150
- }
151
- }
152
- export async function uncertify(name, config, projectDir) {
153
- const removed = removeCertification(name, config.provider.baseUrl, projectDir);
154
- if (removed)
155
- console.log(t("cli.cert_uncertified", { model: name }));
156
- else
157
- console.log(t("cli.cert_not_found", { model: name }));
158
- }
159
- function summarize(results) {
160
- return {
161
- passed: results.filter((r) => r.status === "pass").length,
162
- failed: results.filter((r) => r.status === "fail").length,
163
- skipped: results.filter((r) => r.status === "skipped").length,
164
- total: results.length,
165
- };
166
- }
167
- function printResults(results) {
168
- for (const r of results) {
169
- const icon = r.status === "pass"
170
- ? pc.green("✔")
171
- : r.status === "fail"
172
- ? pc.red("✘")
173
- : r.status === "skipped"
174
- ? pc.dim("–")
175
- : pc.yellow("!");
176
- const detail = r.status === "skipped" ? pc.dim(r.title) : `${r.passed}/${r.of}`;
177
- console.log(` ${icon} ${r.id} ${detail}`);
178
- if (r.error)
179
- console.log(` ${pc.dim(r.error)}`);
180
- if (r.diagnostics)
181
- console.log(r.diagnostics);
182
- }
183
- }
184
- function writeReport(entry, projectDir) {
185
- const reportDir = join(projectDir, "certification");
186
- const ts = entry.certifiedAt.replace(/[:.]/g, "-").slice(0, 19);
187
- const filename = `report-${entry.model.replace(/[/\\:]/g, "_")}-${ts}.json`;
188
- const reportPath = join(reportDir, filename);
189
- const report = {
190
- model: entry.model,
191
- providerUrl: entry.providerUrl,
192
- mmaVersion: entry.mmaVersion,
193
- certifiedAt: entry.certifiedAt,
194
- certified: isFullyPassed(entry),
195
- suite: entry.suite,
196
- results: entry.results.map((r) => ({
197
- id: r.id,
198
- title: r.title,
199
- status: r.status,
200
- passed: r.passed,
201
- of: r.of,
202
- error: r.error,
203
- diagnostics: r.diagnostics,
204
- })),
205
- };
206
- try {
207
- writeFileSync(reportPath, JSON.stringify(report, null, 2), "utf-8");
208
- console.log(pc.dim(`\nReport: ${reportPath}`));
209
- }
210
- catch (e) {
211
- console.error(pc.yellow(` Failed to write report: ${e.message}`));
212
- }
213
- }
@@ -1,82 +0,0 @@
1
- import { existsSync, readFileSync, statSync } from "fs";
2
- import { join } from "path";
3
- export function checkSandbox(sandboxDir, checks, exitCode, output) {
4
- const failures = [];
5
- for (const check of checks) {
6
- if (!runCheck(sandboxDir, check, exitCode, output)) {
7
- failures.push(describe(check));
8
- }
9
- }
10
- return { pass: failures.length === 0, failures };
11
- }
12
- function runCheck(sandboxDir, check, exitCode, output) {
13
- switch (check.type) {
14
- case "exitCode":
15
- return exitCode === (check.code ?? 0);
16
- case "outputContains":
17
- return output.includes(check.text);
18
- case "fileExists":
19
- return isFile(join(sandboxDir, check.path));
20
- case "fileNotExists":
21
- return !existsSync(join(sandboxDir, check.path));
22
- case "dirExists":
23
- return isDir(join(sandboxDir, check.path));
24
- case "fileContent": {
25
- const abs = join(sandboxDir, check.path);
26
- if (!isFile(abs))
27
- return false;
28
- const content = readFileSync(abs, "utf-8");
29
- if (check.contains !== undefined)
30
- return content.includes(check.contains);
31
- if (check.equals !== undefined)
32
- return content === check.equals;
33
- return false;
34
- }
35
- case "fileRegex": {
36
- const abs = join(sandboxDir, check.path);
37
- if (!isFile(abs))
38
- return false;
39
- return new RegExp(check.pattern).test(readFileSync(abs, "utf-8"));
40
- }
41
- default:
42
- return false;
43
- }
44
- }
45
- function isFile(p) {
46
- try {
47
- return existsSync(p) && statSync(p).isFile();
48
- }
49
- catch {
50
- return false;
51
- }
52
- }
53
- function isDir(p) {
54
- try {
55
- return existsSync(p) && statSync(p).isDirectory();
56
- }
57
- catch {
58
- return false;
59
- }
60
- }
61
- function describe(check) {
62
- switch (check.type) {
63
- case "exitCode":
64
- return `expected exit code ${check.code ?? 0}`;
65
- case "outputContains":
66
- return `output missing "${check.text}"`;
67
- case "fileExists":
68
- return `file missing: ${check.path}`;
69
- case "fileNotExists":
70
- return `file unexpectedly exists: ${check.path}`;
71
- case "dirExists":
72
- return `directory missing: ${check.path}`;
73
- case "fileContent": {
74
- const what = check.contains !== undefined ? `contains "${check.contains}"` : `equals "${check.equals}"`;
75
- return `${check.path} does not ${what}`;
76
- }
77
- case "fileRegex":
78
- return `${check.path} does not match ${check.pattern}`;
79
- default:
80
- return "unknown check";
81
- }
82
- }
@@ -1,106 +0,0 @@
1
- import { existsSync, readdirSync, readFileSync } from "fs";
2
- import { join } from "path";
3
- import { parse as parseYaml } from "yaml";
4
- import { BUILTIN_SCENARIOS } from "./scenarios";
5
- const TAGS = ["core", "security", "image", "network", "browser", "moe"];
6
- const CHECK_TYPES = [
7
- "fileExists",
8
- "fileNotExists",
9
- "dirExists",
10
- "fileContent",
11
- "fileRegex",
12
- "exitCode",
13
- "outputContains",
14
- ];
15
- export function validateScenario(s) {
16
- const errors = [];
17
- const isSkip = s.mode === "skip";
18
- if (!s.id || !s.title || (!isSkip && !s.prompt)) {
19
- errors.push(`[${s.id ?? "?"}] missing id, title or prompt`);
20
- }
21
- if (!Array.isArray(s.tags) || s.tags.length === 0) {
22
- errors.push(`[${s.id}] tags required`);
23
- }
24
- for (const tag of s.tags) {
25
- if (!TAGS.includes(tag))
26
- errors.push(`[${s.id}] unknown tag: ${tag}`);
27
- }
28
- if (s.mode !== "run" && s.mode !== "skip") {
29
- errors.push(`[${s.id}] mode must be run or skip`);
30
- }
31
- if (!Array.isArray(s.checks) || (!isSkip && s.checks.length === 0)) {
32
- errors.push(`[${s.id}] at least one check required`);
33
- }
34
- for (const c of s.checks) {
35
- if (!CHECK_TYPES.includes(c.type)) {
36
- errors.push(`[${s.id}] unknown check type: ${c.type}`);
37
- }
38
- if (c.type === "fileContent" && c.contains === undefined && c.equals === undefined) {
39
- errors.push(`[${s.id}] fileContent needs contains or equals`);
40
- }
41
- }
42
- if (s.reps !== undefined && (!Number.isInteger(s.reps) || s.reps < 1)) {
43
- errors.push(`[${s.id}] reps must be a positive integer`);
44
- }
45
- if (s.passThreshold !== undefined &&
46
- (!Number.isInteger(s.passThreshold) || s.passThreshold < 1)) {
47
- errors.push(`[${s.id}] passThreshold must be a positive integer`);
48
- }
49
- if (s.passThreshold !== undefined && s.reps !== undefined && s.passThreshold > s.reps) {
50
- errors.push(`[${s.id}] passThreshold > reps (must be <= reps)`);
51
- }
52
- return errors;
53
- }
54
- export function loadScenarios(userDir) {
55
- const errors = [];
56
- const scenarios = [];
57
- for (const s of BUILTIN_SCENARIOS) {
58
- const errs = validateScenario(s);
59
- if (errs.length > 0)
60
- errors.push(...errs);
61
- else
62
- scenarios.push(s);
63
- }
64
- if (userDir && existsSync(userDir)) {
65
- for (const file of readdirSync(userDir)) {
66
- if (!file.endsWith(".yaml") && !file.endsWith(".yml"))
67
- continue;
68
- try {
69
- const raw = readFileSync(join(userDir, file), "utf-8");
70
- const data = parseYaml(raw);
71
- const parsed = normalizeScenario(data, file);
72
- const errs = validateScenario(parsed);
73
- if (errs.length > 0)
74
- errors.push(...errs);
75
- else
76
- scenarios.push(parsed);
77
- }
78
- catch (e) {
79
- errors.push(`[${file}] failed to parse: ${e.message}`);
80
- }
81
- }
82
- }
83
- return { scenarios, errors };
84
- }
85
- function normalizeScenario(data, file) {
86
- const d = (data ?? {});
87
- return {
88
- id: String(d.id ?? file),
89
- title: String(d.title ?? d.id ?? file),
90
- tags: Array.isArray(d.tags) ? d.tags : [],
91
- mode: d.mode === "skip" ? "skip" : "run",
92
- prompt: String(d.prompt ?? ""),
93
- reps: typeof d.reps === "number" ? d.reps : undefined,
94
- passThreshold: typeof d.passThreshold === "number" ? d.passThreshold : undefined,
95
- fixtures: Array.isArray(d.fixtures) ? d.fixtures : undefined,
96
- checks: Array.isArray(d.checks) ? d.checks : [],
97
- skipReason: typeof d.skipReason === "string" ? d.skipReason : undefined,
98
- config: typeof d.config === "object" && d.config !== null ? d.config : undefined,
99
- };
100
- }
101
- export function filterByTags(scenarios, tags) {
102
- if (!tags || tags.length === 0) {
103
- return scenarios.filter((s) => s.tags.includes("core"));
104
- }
105
- return scenarios.filter((s) => s.tags.some((t) => tags.includes(t)));
106
- }
@@ -1,58 +0,0 @@
1
- import { existsSync, readFileSync, mkdirSync, writeFileSync } from "fs";
2
- import { join } from "path";
3
- export function manifestPath(projectDir) {
4
- return join(projectDir, "certification", "certifications.json");
5
- }
6
- export function readManifest(projectDir) {
7
- const path = manifestPath(projectDir);
8
- try {
9
- if (existsSync(path)) {
10
- const raw = JSON.parse(readFileSync(path, "utf-8"));
11
- return { version: 1, certifications: raw.certifications ?? [] };
12
- }
13
- }
14
- catch {
15
- /* corrupted manifest → start fresh */
16
- }
17
- return { version: 1, certifications: [] };
18
- }
19
- export function saveManifest(m, projectDir) {
20
- const path = manifestPath(projectDir);
21
- mkdirSync(join(projectDir, "certification"), { recursive: true });
22
- writeFileSync(path, JSON.stringify(m, null, 2), "utf-8");
23
- }
24
- export function upsertCertification(entry, projectDir) {
25
- const m = readManifest(projectDir);
26
- const idx = m.certifications.findIndex((e) => e.model === entry.model && e.providerUrl === entry.providerUrl);
27
- if (idx >= 0)
28
- m.certifications[idx] = entry;
29
- else
30
- m.certifications.push(entry);
31
- saveManifest(m, projectDir);
32
- return m;
33
- }
34
- export function removeCertification(model, providerUrl, projectDir) {
35
- const m = readManifest(projectDir);
36
- const before = m.certifications.length;
37
- m.certifications = m.certifications.filter((e) => !(e.model === model && e.providerUrl === providerUrl));
38
- if (m.certifications.length !== before) {
39
- saveManifest(m, projectDir);
40
- return true;
41
- }
42
- return false;
43
- }
44
- export function isStale(entry, currentVersion) {
45
- return entry.mmaVersion !== currentVersion;
46
- }
47
- export function isFullyPassed(entry) {
48
- return entry.suite.failed === 0 && entry.suite.passed > 0;
49
- }
50
- export function getCertMark(model, providerUrl, currentVersion, projectDir) {
51
- const m = readManifest(projectDir);
52
- const entry = m.certifications.find((e) => e.model === model && e.providerUrl === providerUrl);
53
- if (!entry)
54
- return "none";
55
- if (isStale(entry, currentVersion))
56
- return "stale";
57
- return isFullyPassed(entry) ? "certified" : "none";
58
- }