@bonesofspring/ai-rules 0.2.22 → 0.2.23

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 (213) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +6 -2
  3. package/bin/cli.js +32 -8
  4. package/bin/mavis-install.js +441 -0
  5. package/package.json +9 -2
  6. package/presets/_shared/core/meta/preset-pr-checklist.md +1 -0
  7. package/presets/_shared/core/meta/preset-twin-sync.md +16 -0
  8. package/presets/claude/android-kotlin/rules/tooling-and-review/preset-pr-checklist.md +1 -0
  9. package/presets/claude/android-kotlin/rules/tooling-and-review/preset-twin-sync.md +16 -0
  10. package/presets/claude/go/rules/tooling-and-review/preset-pr-checklist.md +1 -0
  11. package/presets/claude/go/rules/tooling-and-review/preset-twin-sync.md +16 -0
  12. package/presets/claude/ios-swift/rules/tooling-and-review/preset-pr-checklist.md +1 -0
  13. package/presets/claude/ios-swift/rules/tooling-and-review/preset-twin-sync.md +16 -0
  14. package/presets/claude/java/rules/tooling-and-review/preset-pr-checklist.md +1 -0
  15. package/presets/claude/java/rules/tooling-and-review/preset-twin-sync.md +16 -0
  16. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-pr-checklist.md +1 -0
  17. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-twin-sync.md +16 -0
  18. package/presets/claude/next/rules/tooling-and-review/preset-pr-checklist.md +1 -0
  19. package/presets/claude/next/rules/tooling-and-review/preset-twin-sync.md +16 -0
  20. package/presets/claude/nuxt/rules/tooling-and-review/preset-pr-checklist.md +1 -0
  21. package/presets/claude/nuxt/rules/tooling-and-review/preset-twin-sync.md +16 -0
  22. package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-pr-checklist.md +1 -0
  23. package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-twin-sync.md +16 -0
  24. package/presets/claude/php-laravel/rules/tooling-and-review/preset-pr-checklist.md +1 -0
  25. package/presets/claude/php-laravel/rules/tooling-and-review/preset-twin-sync.md +16 -0
  26. package/presets/claude/svelte/rules/tooling-and-review/preset-pr-checklist.md +1 -0
  27. package/presets/claude/svelte/rules/tooling-and-review/preset-twin-sync.md +16 -0
  28. package/presets/cursor/android-kotlin/rules/preset-pr-checklist.mdc +1 -0
  29. package/presets/cursor/android-kotlin/rules/preset-twin-sync.mdc +16 -0
  30. package/presets/cursor/go/rules/preset-pr-checklist.mdc +1 -0
  31. package/presets/cursor/go/rules/preset-twin-sync.mdc +16 -0
  32. package/presets/cursor/ios-swift/rules/preset-pr-checklist.mdc +1 -0
  33. package/presets/cursor/ios-swift/rules/preset-twin-sync.mdc +16 -0
  34. package/presets/cursor/java/rules/preset-pr-checklist.mdc +1 -0
  35. package/presets/cursor/java/rules/preset-twin-sync.mdc +16 -0
  36. package/presets/cursor/mcp-ts/rules/preset-pr-checklist.mdc +1 -0
  37. package/presets/cursor/mcp-ts/rules/preset-twin-sync.mdc +16 -0
  38. package/presets/cursor/next/rules/preset-pr-checklist.mdc +1 -0
  39. package/presets/cursor/next/rules/preset-twin-sync.mdc +16 -0
  40. package/presets/cursor/nuxt/rules/preset-pr-checklist.mdc +1 -0
  41. package/presets/cursor/nuxt/rules/preset-twin-sync.mdc +16 -0
  42. package/presets/cursor/php-hexagonal/rules/preset-pr-checklist.mdc +1 -0
  43. package/presets/cursor/php-hexagonal/rules/preset-twin-sync.mdc +16 -0
  44. package/presets/cursor/php-laravel/rules/preset-pr-checklist.mdc +1 -0
  45. package/presets/cursor/php-laravel/rules/preset-twin-sync.mdc +16 -0
  46. package/presets/cursor/svelte/rules/preset-pr-checklist.mdc +1 -0
  47. package/presets/cursor/svelte/rules/preset-twin-sync.mdc +16 -0
  48. package/presets/mavis/README.md +60 -0
  49. package/presets/mavis/next/MAVIS.md +67 -0
  50. package/presets/mavis/next/MCP.md +36 -0
  51. package/presets/mavis/next/README.md +15 -0
  52. package/presets/mavis/next/REPO_AGENTS.md +94 -0
  53. package/presets/mavis/next/adapter-map.json +959 -0
  54. package/presets/mavis/next/agents/README.md +206 -0
  55. package/presets/mavis/next/agents/accessibility-reviewer.md +61 -0
  56. package/presets/mavis/next/agents/api-contract-reviewer.md +57 -0
  57. package/presets/mavis/next/agents/build-verifier.md +110 -0
  58. package/presets/mavis/next/agents/ci-investigator.md +63 -0
  59. package/presets/mavis/next/agents/code-reviewer.md +61 -0
  60. package/presets/mavis/next/agents/codebase-analyzer.md +21 -0
  61. package/presets/mavis/next/agents/debugger.md +80 -0
  62. package/presets/mavis/next/agents/feature-developer.md +101 -0
  63. package/presets/mavis/next/agents/migration-specialist.md +67 -0
  64. package/presets/mavis/next/agents/mockup-reviewer.md +53 -0
  65. package/presets/mavis/next/agents/openspec-author.md +157 -0
  66. package/presets/mavis/next/agents/performance-auditor.md +68 -0
  67. package/presets/mavis/next/agents/playwright-test-generator.md +28 -0
  68. package/presets/mavis/next/agents/playwright-test-healer.md +28 -0
  69. package/presets/mavis/next/agents/playwright-test-planner.md +21 -0
  70. package/presets/mavis/next/agents/qa-tester.md +52 -0
  71. package/presets/mavis/next/agents/security-reviewer.md +54 -0
  72. package/presets/mavis/next/agents/solution-architect.md +68 -0
  73. package/presets/mavis/next/agents/task-analyst.md +166 -0
  74. package/presets/mavis/next/agents/task-router.md +178 -0
  75. package/presets/mavis/next/agents/tech-writer.md +57 -0
  76. package/presets/mavis/next/agents/unit-test-generator.md +31 -0
  77. package/presets/mavis/next/agents/unit-test-healer.md +32 -0
  78. package/presets/mavis/next/agents/unit-test-planner.md +54 -0
  79. package/presets/mavis/next/commands/README.md +49 -0
  80. package/presets/mavis/next/commands/spec-start.md +24 -0
  81. package/presets/mavis/next/commands/task-continue.md +50 -0
  82. package/presets/mavis/next/commands/task.md +50 -0
  83. package/presets/mavis/next/commands/technical-retro.md +80 -0
  84. package/presets/mavis/next/hooks/README.md +22 -0
  85. package/presets/mavis/next/hooks/chain-team-phases.sh +845 -0
  86. package/presets/mavis/next/mcp.json +19 -0
  87. package/presets/mavis/next/rules/README.md +16 -0
  88. package/presets/mavis/next/rules/agent-team-intake.md +11 -0
  89. package/presets/mavis/next/rules/agent-team-orchestrator.md +210 -0
  90. package/presets/mavis/next/rules/ai-local-overlay.md +37 -0
  91. package/presets/mavis/next/rules/anti-sycophancy-discipline.md +23 -0
  92. package/presets/mavis/next/rules/api-services.md +72 -0
  93. package/presets/mavis/next/rules/architecture-boundaries-ui.md +9 -0
  94. package/presets/mavis/next/rules/architecture-boundaries.md +86 -0
  95. package/presets/mavis/next/rules/arrow-functions.md +25 -0
  96. package/presets/mavis/next/rules/code-quality-and-refactoring.md +40 -0
  97. package/presets/mavis/next/rules/code-review-mr.md +40 -0
  98. package/presets/mavis/next/rules/css-property-order-stylelint.md +5 -0
  99. package/presets/mavis/next/rules/design-guidance.md +99 -0
  100. package/presets/mavis/next/rules/feature-delivery-workflow.md +49 -0
  101. package/presets/mavis/next/rules/http-client.md +55 -0
  102. package/presets/mavis/next/rules/layer-barrel-exports.md +68 -0
  103. package/presets/mavis/next/rules/mcp-usage.md +86 -0
  104. package/presets/mavis/next/rules/mockup-review.md +107 -0
  105. package/presets/mavis/next/rules/navigation-router-stack.md +56 -0
  106. package/presets/mavis/next/rules/navigation-router-ui.md +10 -0
  107. package/presets/mavis/next/rules/next-app-core.md +29 -0
  108. package/presets/mavis/next/rules/next-app-router.md +44 -0
  109. package/presets/mavis/next/rules/no-props-spread.md +56 -0
  110. package/presets/mavis/next/rules/no-type-assertion-as-import-export.md +51 -0
  111. package/presets/mavis/next/rules/package-manager.md +11 -0
  112. package/presets/mavis/next/rules/playwright-agents.md +67 -0
  113. package/presets/mavis/next/rules/post-change-lint.md +35 -0
  114. package/presets/mavis/next/rules/preset-layering.md +27 -0
  115. package/presets/mavis/next/rules/preset-no-cross-stack-leakage.md +90 -0
  116. package/presets/mavis/next/rules/preset-pr-checklist.md +35 -0
  117. package/presets/mavis/next/rules/preset-token-budget.md +36 -0
  118. package/presets/mavis/next/rules/preset-twin-sync.md +65 -0
  119. package/presets/mavis/next/rules/product-specs-authoring.md +112 -0
  120. package/presets/mavis/next/rules/product-specs.md +56 -0
  121. package/presets/mavis/next/rules/public-imports.md +50 -0
  122. package/presets/mavis/next/rules/react-a11y-coding.md +31 -0
  123. package/presets/mavis/next/rules/react-next-anti-hallucination.md +60 -0
  124. package/presets/mavis/next/rules/react-ui.md +105 -0
  125. package/presets/mavis/next/rules/reference-features.md +45 -0
  126. package/presets/mavis/next/rules/security-next.md +45 -0
  127. package/presets/mavis/next/rules/store-rtk.md +78 -0
  128. package/presets/mavis/next/rules/technical-retro.md +11 -0
  129. package/presets/mavis/next/rules/tests-e2e-structure.md +72 -0
  130. package/presets/mavis/next/rules/tests-unit.md +72 -0
  131. package/presets/mavis/next/rules/types-jsdoc.md +43 -0
  132. package/presets/mavis/next/rules/ux-design.md +99 -0
  133. package/presets/mavis/next/skills/README.md +21 -0
  134. package/presets/mavis/next/skills/ci-investigation/SKILL.md +39 -0
  135. package/presets/mavis/next/skills/code-review/SKILL.md +39 -0
  136. package/presets/mavis/next/skills/debug-investigation/SKILL.md +26 -0
  137. package/presets/mavis/next/skills/feature-delivery/SKILL.md +34 -0
  138. package/presets/mavis/next/skills/mockup-review/SKILL.md +24 -0
  139. package/presets/mavis/next/skills/playwright-e2e/SKILL.md +28 -0
  140. package/presets/mavis/next/skills/react-performance/SKILL.md +39 -0
  141. package/presets/mavis/next/skills/spec-authoring/SKILL.md +21 -0
  142. package/presets/mavis/next/skills/spec-discovery/SKILL.md +53 -0
  143. package/presets/mavis/next/skills/technical-retro/SKILL.md +49 -0
  144. package/presets/mavis/next/skills/unit-testing/SKILL.md +29 -0
  145. package/presets/mavis/next/skills/ux-design/SKILL.md +31 -0
  146. package/presets/mavis/next/skills/write-adr/SKILL.md +36 -0
  147. package/presets/mavis/next/team/README.md +148 -0
  148. package/presets/mavis/next/team/conventions.md +21 -0
  149. package/presets/mavis/next/team/fixtures/artifact-manifest.example.json +79 -0
  150. package/presets/mavis/next/team/fixtures/bugfix-standard.json +25 -0
  151. package/presets/mavis/next/team/fixtures/feature-full.json +29 -0
  152. package/presets/mavis/next/team/fixtures/feature-light.json +27 -0
  153. package/presets/mavis/next/team/fixtures/feature-with-figma-url.json +17 -0
  154. package/presets/mavis/next/team/fixtures/feature-with-ux-no-figma.json +17 -0
  155. package/presets/mavis/next/team/fixtures/memlog.example.md +9 -0
  156. package/presets/mavis/next/team/fixtures/metrics-scenarios/tasks/human-gate/metrics.json +69 -0
  157. package/presets/mavis/next/team/fixtures/metrics-scenarios/tasks/missing-ledger/status.json +5 -0
  158. package/presets/mavis/next/team/fixtures/metrics-scenarios/tasks/parallel-receipts/metrics.json +79 -0
  159. package/presets/mavis/next/team/fixtures/metrics-scenarios/tasks/serial-retry/metrics.json +124 -0
  160. package/presets/mavis/next/team/fixtures/metrics-scenarios/tasks/validation-failed/metrics.json +124 -0
  161. package/presets/mavis/next/team/fixtures/metrics.example.json +54 -0
  162. package/presets/mavis/next/team/fixtures/mockup-review-fail-embedded-status.json +8 -0
  163. package/presets/mavis/next/team/fixtures/mockup-review-standalone.json +14 -0
  164. package/presets/mavis/next/team/fixtures/ux-design-standalone.json +15 -0
  165. package/presets/mavis/next/team/tasks/.gitkeep +0 -0
  166. package/presets/mavis/platform-contract.json +131 -0
  167. package/scripts/capture-cli-golden.mjs +44 -0
  168. package/scripts/check-chain-hook-coverage.sh +1 -0
  169. package/scripts/check-mavis-adapter-map.mjs +294 -0
  170. package/scripts/check-mavis-local-overlay.mjs +56 -0
  171. package/scripts/check-mavis-platform-contract.mjs +388 -0
  172. package/scripts/check-mavis-token-budget.mjs +48 -0
  173. package/scripts/check-preset-leakage.sh +35 -3
  174. package/scripts/check-preset-structure.sh +63 -0
  175. package/scripts/check-shared-core-drift.sh +18 -0
  176. package/scripts/check-task-router-intents.sh +15 -2
  177. package/scripts/fixtures/cli-golden/claude/next.json +130 -0
  178. package/scripts/fixtures/cli-golden/cursor/next.json +132 -0
  179. package/scripts/fixtures/cli-golden/mavis/next.json +125 -0
  180. package/scripts/fixtures/mavis-adapter-map/invalid-unmapped/cursor/AGENTS.md +1 -0
  181. package/scripts/fixtures/mavis-adapter-map/invalid-unmapped/cursor/rules/extra.mdc +1 -0
  182. package/scripts/fixtures/mavis-adapter-map/invalid-unmapped/cursor/rules/sample.mdc +2 -0
  183. package/scripts/fixtures/mavis-adapter-map/invalid-unmapped/mavis/MAVIS.md +1 -0
  184. package/scripts/fixtures/mavis-adapter-map/invalid-unmapped/mavis/adapter-map.json +26 -0
  185. package/scripts/fixtures/mavis-adapter-map/invalid-unmapped/mavis/rules/sample.md +2 -0
  186. package/scripts/fixtures/mavis-adapter-map/valid/cursor/AGENTS.md +1 -0
  187. package/scripts/fixtures/mavis-adapter-map/valid/cursor/rules/sample.mdc +2 -0
  188. package/scripts/fixtures/mavis-adapter-map/valid/mavis/MAVIS.md +1 -0
  189. package/scripts/fixtures/mavis-adapter-map/valid/mavis/adapter-map.json +26 -0
  190. package/scripts/fixtures/mavis-adapter-map/valid/mavis/rules/sample.md +2 -0
  191. package/scripts/fixtures/mavis-platform-contract/invalid-minimax-destination.json +131 -0
  192. package/scripts/fixtures/mavis-platform-contract/invalid-missing-capability.json +126 -0
  193. package/scripts/fixtures/mavis-platform-contract/invalid-released-unknown-stack.json +133 -0
  194. package/scripts/fixtures/mavis-platform-contract/invalid-unknown-native-path.json +131 -0
  195. package/scripts/fixtures/mavis-platform-contract/invalid-version-pin.json +132 -0
  196. package/scripts/fixtures/mavis-platform-contract/valid.json +131 -0
  197. package/scripts/fixtures/mavis-probe/AGENTS.md +6 -0
  198. package/scripts/fixtures/mavis-probe/agents/probe-agent.md +6 -0
  199. package/scripts/fixtures/mavis-probe/fake-mcode.mjs +98 -0
  200. package/scripts/fixtures/mavis-probe/output.schema.json +28 -0
  201. package/scripts/fixtures/mavis-probe/rules/probe.md +5 -0
  202. package/scripts/fixtures/mavis-probe/skills/probe/SKILL.md +11 -0
  203. package/scripts/generate-mavis-next.mjs +704 -0
  204. package/scripts/lib/cli-golden.mjs +50 -0
  205. package/scripts/lib/discover-hooks.mjs +72 -0
  206. package/scripts/probe-mavis-capabilities.mjs +480 -0
  207. package/scripts/test-agent-task-metrics-hooks.mjs +22 -16
  208. package/scripts/test-chain-team-phases-coverage.mjs +10 -7
  209. package/scripts/test-cli-init-clean.mjs +256 -0
  210. package/scripts/test-cli-mcp-merge.mjs +23 -0
  211. package/scripts/test-mavis-context-budget.mjs +55 -0
  212. package/scripts/test-mavis-orchestration.mjs +649 -0
  213. package/scripts/test-probe-mavis-capabilities.mjs +205 -0
@@ -0,0 +1,205 @@
1
+ #!/usr/bin/env node
2
+ import assert from 'node:assert/strict';
3
+ import { execFileSync } from 'node:child_process';
4
+ import fs from 'node:fs';
5
+ import os from 'node:os';
6
+ import path from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
+
9
+ const scriptDirectory = path.dirname(fileURLToPath(import.meta.url));
10
+ const probeScript = path.join(scriptDirectory, 'probe-mavis-capabilities.mjs');
11
+ const fixtureDirectory = path.join(scriptDirectory, 'fixtures', 'mavis-probe');
12
+ const fakeMcodeSource = path.join(fixtureDirectory, 'fake-mcode.mjs');
13
+
14
+ assert.equal(fs.existsSync(probeScript), true, 'probe script must exist');
15
+
16
+ function installFakeMcode(tempRoot) {
17
+ const fakeMcode = path.join(tempRoot, 'mcode');
18
+ fs.copyFileSync(fakeMcodeSource, fakeMcode);
19
+ fs.chmodSync(fakeMcode, 0o755);
20
+ return fakeMcode;
21
+ }
22
+
23
+ function runProbe({ mcode, workdir, home, mode }) {
24
+ try {
25
+ const stdout = execFileSync(
26
+ process.execPath,
27
+ [probeScript, '--mcode', mcode, '--workdir', workdir],
28
+ {
29
+ encoding: 'utf8',
30
+ env: {
31
+ ...process.env,
32
+ HOME: home,
33
+ FAKE_MCODE_MODE: mode ?? 'supported',
34
+ },
35
+ },
36
+ );
37
+ return { exitCode: 0, evidence: JSON.parse(stdout) };
38
+ } catch (error) {
39
+ return {
40
+ exitCode: error.status ?? 1,
41
+ evidence: JSON.parse(error.stdout),
42
+ };
43
+ }
44
+ }
45
+
46
+ function assertCapabilityShape(capability) {
47
+ assert.match(capability.status, /^(confirmed|partial|unknown|no-equivalent)$/);
48
+ assert.ok(Object.hasOwn(capability, 'command'));
49
+ assert.ok(Object.hasOwn(capability, 'exitCode'));
50
+ assert.ok(Object.hasOwn(capability, 'executed'));
51
+ assert.equal(typeof capability.observation, 'string');
52
+ }
53
+
54
+ const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'mavis-probe-test-'));
55
+
56
+ try {
57
+ const home = path.join(tempRoot, 'home');
58
+ fs.mkdirSync(home);
59
+ const fakeMcode = installFakeMcode(tempRoot);
60
+
61
+ const freshWorkdir = path.join(tempRoot, 'fresh-workdir');
62
+ const fresh = runProbe({ mcode: fakeMcode, workdir: freshWorkdir, home });
63
+ assert.equal(fresh.exitCode, 0);
64
+ assert.equal(fresh.evidence.schemaVersion, 1);
65
+ assert.equal(fresh.evidence.probeStatus, 'completed');
66
+ assert.deepEqual(fresh.evidence.cli, {
67
+ executable: '<MCODE>',
68
+ version: 'mcode 9.8.7',
69
+ });
70
+ assert.ok(fresh.evidence.os.platform);
71
+ assert.ok(fresh.evidence.os.release);
72
+ assert.ok(fresh.evidence.os.arch);
73
+ assert.equal(fresh.evidence.workdir, '<WORKDIR>');
74
+
75
+ const requiredCapabilities = [
76
+ 'cliVersion',
77
+ 'cliHelp',
78
+ 'freshInit',
79
+ 'rootAgents',
80
+ 'referencedRule',
81
+ 'referencedSkill',
82
+ 'explicitAgentFile',
83
+ 'structuredOutput',
84
+ 'nativeProjectRules',
85
+ 'nativeWorkspaceSkills',
86
+ 'nativeWorkspaceAgents',
87
+ 'projectMcp',
88
+ 'projectHooks',
89
+ 'slashCommands',
90
+ 'pluginSkillMcp',
91
+ 'nativeTeam',
92
+ ];
93
+ assert.deepEqual(Object.keys(fresh.evidence.capabilities), requiredCapabilities);
94
+ for (const capability of Object.values(fresh.evidence.capabilities)) {
95
+ assertCapabilityShape(capability);
96
+ }
97
+
98
+ assert.equal(fresh.evidence.capabilities.rootAgents.status, 'confirmed');
99
+ assert.equal(fresh.evidence.capabilities.referencedRule.status, 'confirmed');
100
+ assert.equal(fresh.evidence.capabilities.referencedSkill.status, 'confirmed');
101
+ assert.equal(fresh.evidence.capabilities.explicitAgentFile.status, 'confirmed');
102
+ assert.equal(fresh.evidence.capabilities.structuredOutput.status, 'confirmed');
103
+ assert.equal(fresh.evidence.capabilities.nativeProjectRules.status, 'unknown');
104
+ assert.equal(fresh.evidence.capabilities.nativeWorkspaceSkills.status, 'unknown');
105
+ assert.equal(fresh.evidence.capabilities.nativeWorkspaceAgents.status, 'unknown');
106
+ assert.equal(fresh.evidence.capabilities.nativeProjectRules.executed, true);
107
+ assert.equal(fresh.evidence.capabilities.nativeWorkspaceSkills.executed, true);
108
+ assert.equal(fresh.evidence.capabilities.nativeWorkspaceAgents.executed, true);
109
+ assert.deepEqual(
110
+ fresh.evidence.capabilities.explicitAgentFile.command.slice(0, 3),
111
+ ['<MCODE>', 'exec', '--cwd'],
112
+ );
113
+ assert.ok(fresh.evidence.capabilities.explicitAgentFile.command.includes('--file'));
114
+ assert.ok(fresh.evidence.capabilities.structuredOutput.command.includes('--output-format'));
115
+ assert.ok(fresh.evidence.capabilities.structuredOutput.command.includes('--permission'));
116
+ assert.ok(fresh.evidence.capabilities.structuredOutput.command.includes('off'));
117
+ assert.ok(fresh.evidence.capabilities.structuredOutput.command.includes('--timeout'));
118
+ assert.deepEqual(fresh.evidence.authSeed, { seeded: false, entries: [] });
119
+ assert.equal(fresh.evidence.capabilities.projectMcp.status, 'unknown');
120
+ assert.equal(fresh.evidence.capabilities.projectMcp.exitCode, null);
121
+ assert.equal(fresh.evidence.capabilities.projectMcp.executed, false);
122
+ assert.match(fresh.evidence.capabilities.projectMcp.observation, /not executed/i);
123
+ assert.equal(fresh.evidence.capabilities.projectHooks.status, 'unknown');
124
+ assert.equal(fresh.evidence.capabilities.slashCommands.status, 'unknown');
125
+ assert.equal(fresh.evidence.capabilities.pluginSkillMcp.status, 'confirmed');
126
+ assert.equal(fresh.evidence.capabilities.pluginSkillMcp.executed, false);
127
+ assert.equal(fresh.evidence.capabilities.nativeTeam.status, 'partial');
128
+ assert.equal(fresh.evidence.capabilities.nativeTeam.executed, false);
129
+
130
+ assert.equal(fs.existsSync(path.join(freshWorkdir, 'AGENTS.md')), true);
131
+ assert.equal(fs.existsSync(path.join(freshWorkdir, 'rules', 'probe.md')), true);
132
+ assert.equal(fs.existsSync(path.join(freshWorkdir, 'agents', 'probe-agent.md')), true);
133
+ assert.equal(fs.existsSync(path.join(freshWorkdir, 'skills', 'probe', 'SKILL.md')), true);
134
+ assert.equal(fs.existsSync(path.join(freshWorkdir, 'output.schema.json')), true);
135
+ assert.equal(fs.existsSync(path.join(home, '.minimax')), false);
136
+
137
+ const serialized = JSON.stringify(fresh.evidence);
138
+ assert.doesNotMatch(serialized, /fixture-secret|fake-secret/);
139
+ assert.doesNotMatch(serialized, /\/Users\/tester/);
140
+ assert.doesNotMatch(serialized, new RegExp(tempRoot.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')));
141
+ assert.doesNotMatch(serialized, /mavis-probe-home-/);
142
+ assert.doesNotMatch(serialized, /<PROBE_HOME>/);
143
+ assert.match(serialized, /<REDACTED>|<HOME>/);
144
+
145
+ const emptyWorkdir = path.join(tempRoot, 'empty-workdir');
146
+ fs.mkdirSync(emptyWorkdir);
147
+ const empty = runProbe({ mcode: fakeMcode, workdir: emptyWorkdir, home });
148
+ assert.equal(empty.exitCode, 0);
149
+ assert.deepEqual(empty.evidence, fresh.evidence);
150
+ assert.equal(fs.existsSync(path.join(home, '.minimax')), false);
151
+
152
+ const nonemptyWorkdir = path.join(tempRoot, 'nonempty-workdir');
153
+ fs.mkdirSync(nonemptyWorkdir);
154
+ fs.writeFileSync(path.join(nonemptyWorkdir, 'keep.txt'), 'preserve-me');
155
+ const nonempty = runProbe({ mcode: fakeMcode, workdir: nonemptyWorkdir, home });
156
+ assert.equal(nonempty.exitCode, 2);
157
+ assert.equal(nonempty.evidence.probeStatus, 'blocked');
158
+ assert.equal(nonempty.evidence.capabilities.cliVersion.executed, false);
159
+ assert.match(nonempty.evidence.capabilities.freshInit.observation, /empty/i);
160
+ assert.equal(fs.readFileSync(path.join(nonemptyWorkdir, 'keep.txt'), 'utf8'), 'preserve-me');
161
+ assert.equal(fs.existsSync(path.join(home, '.minimax')), false);
162
+
163
+ const seededHome = path.join(tempRoot, 'seeded-home');
164
+ fs.mkdirSync(path.join(seededHome, '.minimax', 'cli-auth'), { recursive: true });
165
+ fs.writeFileSync(path.join(seededHome, '.minimax', 'cli-auth', 'session'), 'seed-only');
166
+ fs.writeFileSync(path.join(seededHome, '.minimax', 'config.yaml'), 'region: test\n');
167
+ const seeded = runProbe({
168
+ mcode: fakeMcode,
169
+ workdir: path.join(tempRoot, 'seeded-workdir'),
170
+ home: seededHome,
171
+ });
172
+ assert.equal(seeded.exitCode, 0);
173
+ assert.equal(seeded.evidence.authSeed.seeded, true);
174
+ assert.deepEqual(seeded.evidence.authSeed.entries, ['cli-auth', 'config.yaml']);
175
+ assert.equal(fs.existsSync(path.join(seededHome, '.minimax', 'probe-touch')), false);
176
+
177
+ const missing = runProbe({
178
+ mcode: path.join(tempRoot, 'missing-mcode'),
179
+ workdir: path.join(tempRoot, 'missing-executable-workdir'),
180
+ home,
181
+ });
182
+ assert.equal(missing.exitCode, 2);
183
+ assert.equal(missing.evidence.probeStatus, 'blocked');
184
+ assert.equal(missing.evidence.cli.version, null);
185
+ assert.equal(missing.evidence.capabilities.cliVersion.status, 'unknown');
186
+ assert.match(missing.evidence.capabilities.cliVersion.observation, /not found/i);
187
+ assert.equal(fs.existsSync(path.join(home, '.minimax')), false);
188
+
189
+ const unsupported = runProbe({
190
+ mcode: fakeMcode,
191
+ workdir: path.join(tempRoot, 'unsupported-workdir'),
192
+ home,
193
+ mode: 'unsupported',
194
+ });
195
+ assert.equal(unsupported.exitCode, 2);
196
+ assert.equal(unsupported.evidence.probeStatus, 'blocked');
197
+ assert.equal(unsupported.evidence.cli.version, null);
198
+ assert.equal(unsupported.evidence.capabilities.cliVersion.exitCode, 64);
199
+ assert.match(unsupported.evidence.capabilities.cliVersion.observation, /unsupported/i);
200
+ assert.equal(fs.existsSync(path.join(home, '.minimax')), false);
201
+
202
+ console.log('test-probe-mavis-capabilities: ok');
203
+ } finally {
204
+ fs.rmSync(tempRoot, { recursive: true, force: true });
205
+ }