mewkit 1.10.2 → 1.10.4

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 (231) hide show
  1. package/README.md +49 -4
  2. package/dist/commands/budget.d.ts +13 -0
  3. package/dist/commands/budget.d.ts.map +1 -1
  4. package/dist/commands/budget.js +45 -0
  5. package/dist/commands/budget.js.map +1 -1
  6. package/dist/commands/doctor-checks.d.ts +1 -1
  7. package/dist/commands/doctor-checks.d.ts.map +1 -1
  8. package/dist/commands/doctor-checks.js +7 -1
  9. package/dist/commands/doctor-checks.js.map +1 -1
  10. package/dist/commands/doctor-hard-gates.d.ts +3 -0
  11. package/dist/commands/doctor-hard-gates.d.ts.map +1 -0
  12. package/dist/commands/doctor-hard-gates.js +170 -0
  13. package/dist/commands/doctor-hard-gates.js.map +1 -0
  14. package/dist/commands/doctor.d.ts +1 -0
  15. package/dist/commands/doctor.d.ts.map +1 -1
  16. package/dist/commands/doctor.js +77 -3
  17. package/dist/commands/doctor.js.map +1 -1
  18. package/dist/commands/evolve.d.ts +11 -0
  19. package/dist/commands/evolve.d.ts.map +1 -0
  20. package/dist/commands/evolve.js +63 -0
  21. package/dist/commands/evolve.js.map +1 -0
  22. package/dist/commands/health.d.ts +14 -0
  23. package/dist/commands/health.d.ts.map +1 -0
  24. package/dist/commands/health.js +193 -0
  25. package/dist/commands/health.js.map +1 -0
  26. package/dist/commands/init.d.ts +6 -0
  27. package/dist/commands/init.d.ts.map +1 -1
  28. package/dist/commands/init.js +64 -3
  29. package/dist/commands/init.js.map +1 -1
  30. package/dist/commands/inventory.d.ts +13 -0
  31. package/dist/commands/inventory.d.ts.map +1 -0
  32. package/dist/commands/inventory.js +85 -0
  33. package/dist/commands/inventory.js.map +1 -0
  34. package/dist/commands/pack-helpers.d.ts +37 -0
  35. package/dist/commands/pack-helpers.d.ts.map +1 -0
  36. package/dist/commands/pack-helpers.js +105 -0
  37. package/dist/commands/pack-helpers.js.map +1 -0
  38. package/dist/commands/pack.d.ts +9 -0
  39. package/dist/commands/pack.d.ts.map +1 -0
  40. package/dist/commands/pack.js +160 -0
  41. package/dist/commands/pack.js.map +1 -0
  42. package/dist/commands/policy.d.ts +8 -0
  43. package/dist/commands/policy.d.ts.map +1 -0
  44. package/dist/commands/policy.js +65 -0
  45. package/dist/commands/policy.js.map +1 -0
  46. package/dist/commands/portability.d.ts +7 -0
  47. package/dist/commands/portability.d.ts.map +1 -0
  48. package/dist/commands/portability.js +50 -0
  49. package/dist/commands/portability.js.map +1 -0
  50. package/dist/commands/providers.d.ts +6 -0
  51. package/dist/commands/providers.d.ts.map +1 -0
  52. package/dist/commands/providers.js +94 -0
  53. package/dist/commands/providers.js.map +1 -0
  54. package/dist/commands/reflect.d.ts +14 -0
  55. package/dist/commands/reflect.d.ts.map +1 -0
  56. package/dist/commands/reflect.js +135 -0
  57. package/dist/commands/reflect.js.map +1 -0
  58. package/dist/commands/simulate.d.ts +14 -0
  59. package/dist/commands/simulate.d.ts.map +1 -0
  60. package/dist/commands/simulate.js +86 -0
  61. package/dist/commands/simulate.js.map +1 -0
  62. package/dist/commands/upgrade.d.ts.map +1 -1
  63. package/dist/commands/upgrade.js +32 -6
  64. package/dist/commands/upgrade.js.map +1 -1
  65. package/dist/commands/validate.d.ts +29 -0
  66. package/dist/commands/validate.d.ts.map +1 -1
  67. package/dist/commands/validate.js +242 -94
  68. package/dist/commands/validate.js.map +1 -1
  69. package/dist/core/build-inventory.d.ts +71 -0
  70. package/dist/core/build-inventory.d.ts.map +1 -0
  71. package/dist/core/build-inventory.js +222 -0
  72. package/dist/core/build-inventory.js.map +1 -0
  73. package/dist/core/check-packs.d.ts +13 -0
  74. package/dist/core/check-packs.d.ts.map +1 -0
  75. package/dist/core/check-packs.js +131 -0
  76. package/dist/core/check-packs.js.map +1 -0
  77. package/dist/core/check-stale-index.d.ts +35 -0
  78. package/dist/core/check-stale-index.d.ts.map +1 -0
  79. package/dist/core/check-stale-index.js +132 -0
  80. package/dist/core/check-stale-index.js.map +1 -0
  81. package/dist/core/check-workflow-drift.d.ts +49 -0
  82. package/dist/core/check-workflow-drift.d.ts.map +1 -0
  83. package/dist/core/check-workflow-drift.js +226 -0
  84. package/dist/core/check-workflow-drift.js.map +1 -0
  85. package/dist/core/compute-checksums.d.ts +7 -0
  86. package/dist/core/compute-checksums.d.ts.map +1 -1
  87. package/dist/core/compute-checksums.js +12 -3
  88. package/dist/core/compute-checksums.js.map +1 -1
  89. package/dist/core/context-budget.d.ts +9 -0
  90. package/dist/core/context-budget.d.ts.map +1 -0
  91. package/dist/core/context-budget.js +46 -0
  92. package/dist/core/context-budget.js.map +1 -0
  93. package/dist/core/event-log.d.ts +44 -0
  94. package/dist/core/event-log.d.ts.map +1 -0
  95. package/dist/core/event-log.js +169 -0
  96. package/dist/core/event-log.js.map +1 -0
  97. package/dist/core/evolution/event-clusters.d.ts +4 -0
  98. package/dist/core/evolution/event-clusters.d.ts.map +1 -0
  99. package/dist/core/evolution/event-clusters.js +82 -0
  100. package/dist/core/evolution/event-clusters.js.map +1 -0
  101. package/dist/core/evolution/recommendation-renderer.d.ts +3 -0
  102. package/dist/core/evolution/recommendation-renderer.d.ts.map +1 -0
  103. package/dist/core/evolution/recommendation-renderer.js +24 -0
  104. package/dist/core/evolution/recommendation-renderer.js.map +1 -0
  105. package/dist/core/evolution/review-failure-clusters.d.ts +10 -0
  106. package/dist/core/evolution/review-failure-clusters.d.ts.map +1 -0
  107. package/dist/core/evolution/review-failure-clusters.js +30 -0
  108. package/dist/core/evolution/review-failure-clusters.js.map +1 -0
  109. package/dist/core/evolution/suggestions.d.ts +24 -0
  110. package/dist/core/evolution/suggestions.d.ts.map +1 -0
  111. package/dist/core/evolution/suggestions.js +11 -0
  112. package/dist/core/evolution/suggestions.js.map +1 -0
  113. package/dist/core/file-lock.d.ts +3 -0
  114. package/dist/core/file-lock.d.ts.map +1 -0
  115. package/dist/core/file-lock.js +84 -0
  116. package/dist/core/file-lock.js.map +1 -0
  117. package/dist/core/gate-policy.d.ts +20 -0
  118. package/dist/core/gate-policy.d.ts.map +1 -0
  119. package/dist/core/gate-policy.js +64 -0
  120. package/dist/core/gate-policy.js.map +1 -0
  121. package/dist/core/harness-scaffold.d.ts +29 -0
  122. package/dist/core/harness-scaffold.d.ts.map +1 -0
  123. package/dist/core/harness-scaffold.js +53 -0
  124. package/dist/core/harness-scaffold.js.map +1 -0
  125. package/dist/core/hook-runner.d.ts +69 -0
  126. package/dist/core/hook-runner.d.ts.map +1 -0
  127. package/dist/core/hook-runner.js +95 -0
  128. package/dist/core/hook-runner.js.map +1 -0
  129. package/dist/core/index.d.ts +6 -0
  130. package/dist/core/index.d.ts.map +1 -1
  131. package/dist/core/index.js +6 -0
  132. package/dist/core/index.js.map +1 -1
  133. package/dist/core/install-metadata-backref.d.ts +14 -0
  134. package/dist/core/install-metadata-backref.d.ts.map +1 -0
  135. package/dist/core/install-metadata-backref.js +39 -0
  136. package/dist/core/install-metadata-backref.js.map +1 -0
  137. package/dist/core/install-metadata-writer.d.ts +4 -0
  138. package/dist/core/install-metadata-writer.d.ts.map +1 -0
  139. package/dist/core/install-metadata-writer.js +31 -0
  140. package/dist/core/install-metadata-writer.js.map +1 -0
  141. package/dist/core/install-metadata.d.ts +173 -0
  142. package/dist/core/install-metadata.d.ts.map +1 -0
  143. package/dist/core/install-metadata.js +191 -0
  144. package/dist/core/install-metadata.js.map +1 -0
  145. package/dist/core/is-hook-script.d.ts +2 -0
  146. package/dist/core/is-hook-script.d.ts.map +1 -0
  147. package/dist/core/is-hook-script.js +45 -0
  148. package/dist/core/is-hook-script.js.map +1 -0
  149. package/dist/core/pack-manifest.d.ts +48 -0
  150. package/dist/core/pack-manifest.d.ts.map +1 -0
  151. package/dist/core/pack-manifest.js +126 -0
  152. package/dist/core/pack-manifest.js.map +1 -0
  153. package/dist/core/pack-resolver.d.ts +18 -0
  154. package/dist/core/pack-resolver.d.ts.map +1 -0
  155. package/dist/core/pack-resolver.js +144 -0
  156. package/dist/core/pack-resolver.js.map +1 -0
  157. package/dist/core/portability-matrix.d.ts +17 -0
  158. package/dist/core/portability-matrix.d.ts.map +1 -0
  159. package/dist/core/portability-matrix.js +31 -0
  160. package/dist/core/portability-matrix.js.map +1 -0
  161. package/dist/core/release-metadata.d.ts +80 -0
  162. package/dist/core/release-metadata.d.ts.map +1 -0
  163. package/dist/core/release-metadata.js +70 -0
  164. package/dist/core/release-metadata.js.map +1 -0
  165. package/dist/core/simulation-runner.d.ts +93 -0
  166. package/dist/core/simulation-runner.d.ts.map +1 -0
  167. package/dist/core/simulation-runner.js +161 -0
  168. package/dist/core/simulation-runner.js.map +1 -0
  169. package/dist/core/smart-update.d.ts +32 -0
  170. package/dist/core/smart-update.d.ts.map +1 -1
  171. package/dist/core/smart-update.js +239 -47
  172. package/dist/core/smart-update.js.map +1 -1
  173. package/dist/core/usage/usage-analyzer.d.ts +18 -0
  174. package/dist/core/usage/usage-analyzer.d.ts.map +1 -0
  175. package/dist/core/usage/usage-analyzer.js +41 -0
  176. package/dist/core/usage/usage-analyzer.js.map +1 -0
  177. package/dist/core/validate-install.d.ts.map +1 -1
  178. package/dist/core/validate-install.js +3 -1
  179. package/dist/core/validate-install.js.map +1 -1
  180. package/dist/index.js +91 -4
  181. package/dist/index.js.map +1 -1
  182. package/dist/memory/archive.d.ts +9 -0
  183. package/dist/memory/archive.d.ts.map +1 -0
  184. package/dist/memory/archive.js +42 -0
  185. package/dist/memory/archive.js.map +1 -0
  186. package/dist/memory/compact.d.ts +9 -0
  187. package/dist/memory/compact.d.ts.map +1 -0
  188. package/dist/memory/compact.js +33 -0
  189. package/dist/memory/compact.js.map +1 -0
  190. package/dist/memory/conflicts.d.ts +8 -0
  191. package/dist/memory/conflicts.d.ts.map +1 -0
  192. package/dist/memory/conflicts.js +28 -0
  193. package/dist/memory/conflicts.js.map +1 -0
  194. package/dist/memory/promote.d.ts +8 -0
  195. package/dist/memory/promote.d.ts.map +1 -0
  196. package/dist/memory/promote.js +10 -0
  197. package/dist/memory/promote.js.map +1 -0
  198. package/dist/memory/store-utils.d.ts +14 -0
  199. package/dist/memory/store-utils.d.ts.map +1 -0
  200. package/dist/memory/store-utils.js +44 -0
  201. package/dist/memory/store-utils.js.map +1 -0
  202. package/dist/migrate/converters/md-to-codex-rules.d.ts.map +1 -1
  203. package/dist/migrate/converters/md-to-codex-rules.js +30 -0
  204. package/dist/migrate/converters/md-to-codex-rules.js.map +1 -1
  205. package/dist/migrate/migrate-orchestrator.d.ts.map +1 -1
  206. package/dist/migrate/migrate-orchestrator.js +6 -2
  207. package/dist/migrate/migrate-orchestrator.js.map +1 -1
  208. package/dist/migrate/portability-policy.d.ts.map +1 -1
  209. package/dist/migrate/portability-policy.js +44 -23
  210. package/dist/migrate/portability-policy.js.map +1 -1
  211. package/dist/migrate/portable-installer.d.ts +3 -0
  212. package/dist/migrate/portable-installer.d.ts.map +1 -1
  213. package/dist/migrate/portable-installer.js +3 -0
  214. package/dist/migrate/portable-installer.js.map +1 -1
  215. package/dist/migrate/provider-support-summary.d.ts +49 -0
  216. package/dist/migrate/provider-support-summary.d.ts.map +1 -0
  217. package/dist/migrate/provider-support-summary.js +98 -0
  218. package/dist/migrate/provider-support-summary.js.map +1 -0
  219. package/dist/migrate/reconcile/portable-registry-lock.d.ts.map +1 -1
  220. package/dist/migrate/reconcile/portable-registry-lock.js +6 -78
  221. package/dist/migrate/reconcile/portable-registry-lock.js.map +1 -1
  222. package/dist/migrate/reconcile/portable-registry.d.ts +24 -6
  223. package/dist/migrate/reconcile/portable-registry.d.ts.map +1 -1
  224. package/dist/migrate/reconcile/portable-registry.js +7 -1
  225. package/dist/migrate/reconcile/portable-registry.js.map +1 -1
  226. package/dist/migrate/skill-directory-installer.d.ts +2 -0
  227. package/dist/migrate/skill-directory-installer.d.ts.map +1 -1
  228. package/dist/migrate/skill-directory-installer.js +3 -0
  229. package/dist/migrate/skill-directory-installer.js.map +1 -1
  230. package/dist/migrate/types.d.ts +4 -4
  231. package/package.json +1 -1
@@ -0,0 +1,93 @@
1
+ import { hasHarness } from "./harness-scaffold.js";
2
+ import { type HookRunResult } from "./hook-runner.js";
3
+ /**
4
+ * Declarative scenario engine that generalizes the hardcoded `doctor --hard-gates`
5
+ * probes into data-driven given→when→expect cases. Reuses the Phase-1 scaffold +
6
+ * hook-runner (the real configured-hook execution path) — independent of the event
7
+ * log. The `assertOutcome` here is THE single assertion path, also consumed by
8
+ * `doctor-hard-gates.ts`, so the two never diverge.
9
+ */
10
+ export type SimStatus = "PASS" | "FAIL" | "SKIP";
11
+ export interface ExpectSpec {
12
+ /** Whether the hook should block the tool call. */
13
+ blocked: boolean;
14
+ /** Marker string expected on the named stream when blocked. */
15
+ marker?: string;
16
+ /** Exact exit code; when omitted on a block, any non-zero passes. */
17
+ exitCode?: number;
18
+ /** Which stream carries the marker — explicit per scenario (block markers vary). */
19
+ expectStream?: "stdout" | "stderr";
20
+ }
21
+ interface WhenSpec {
22
+ /** Tool name (matched against settings.json hook matchers). */
23
+ tool: string;
24
+ /** Hook script basename to exercise (the `only` filter — keeps runs deterministic). */
25
+ hook: string;
26
+ file_path?: string;
27
+ command?: string;
28
+ /** Extra env for this step (e.g. MEOWKIT_GATE1_REQUIRE_APPROVED=1). */
29
+ env?: Record<string, string>;
30
+ }
31
+ interface GivenSpec {
32
+ /** Create an (unapproved) plan so Gate 1 existence passes. */
33
+ plan?: boolean;
34
+ /** Remove all plans (force the no-plan state). */
35
+ clearPlans?: boolean;
36
+ /** Arrange arbitrary files in the temp project. */
37
+ files?: Array<{
38
+ path: string;
39
+ content: string;
40
+ }>;
41
+ }
42
+ interface StepSpec {
43
+ given?: GivenSpec;
44
+ when: WhenSpec;
45
+ expect: ExpectSpec;
46
+ }
47
+ export interface Scenario {
48
+ name: string;
49
+ description?: string;
50
+ /** Single-step shorthand (mutually exclusive with `steps`). */
51
+ given?: GivenSpec;
52
+ when?: WhenSpec;
53
+ expect?: ExpectSpec;
54
+ /** Ordered multi-step lifecycle (e.g. full-lifecycle). */
55
+ steps?: StepSpec[];
56
+ }
57
+ export interface StepResult {
58
+ status: SimStatus;
59
+ detail: string;
60
+ expected: string;
61
+ actual: string;
62
+ }
63
+ export interface ScenarioResult {
64
+ name: string;
65
+ description?: string;
66
+ status: SimStatus;
67
+ steps: StepResult[];
68
+ }
69
+ /**
70
+ * THE shared assertion: compare a hook run result against an expectation. Returns
71
+ * PASS / FAIL / SKIP. Two honesty guards:
72
+ * - an allow-case (`blocked:false`) where NO hook ran → SKIP (never a vacuous PASS),
73
+ * - a block-case where no hook ran → FAIL (the gate was not exercised).
74
+ */
75
+ export declare function assertOutcome(result: HookRunResult | undefined, expect: ExpectSpec): {
76
+ status: SimStatus;
77
+ detail: string;
78
+ };
79
+ /** Execute one scenario against a freshly-scaffolded temp harness. Cleans up always. */
80
+ export declare function runScenario(scenario: Scenario, srcRoot: string): ScenarioResult;
81
+ /** Load + validate a scenario YAML file. Throws on a malformed/under-specified scenario. */
82
+ export declare function loadScenario(file: string): Scenario;
83
+ export interface SimulationsDir {
84
+ /** Absolute path to `<repoRoot>/.claude/simulations`. */
85
+ dir: string;
86
+ exists: boolean;
87
+ }
88
+ export declare function simulationsDir(srcRoot: string): SimulationsDir;
89
+ /** List scenario YAML basenames (without extension) in the simulations dir. */
90
+ export declare function listScenarios(srcRoot: string): string[];
91
+ export declare function loadScenarioByName(srcRoot: string, name: string): Scenario;
92
+ export { hasHarness };
93
+ //# sourceMappingURL=simulation-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simulation-runner.d.ts","sourceRoot":"","sources":["../../src/core/simulation-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,161 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import yaml from "js-yaml";
4
+ import { scaffoldHarnessProject, hasHarness } from "./harness-scaffold.js";
5
+ import { runConfiguredHook } from "./hook-runner.js";
6
+ /**
7
+ * THE shared assertion: compare a hook run result against an expectation. Returns
8
+ * PASS / FAIL / SKIP. Two honesty guards:
9
+ * - an allow-case (`blocked:false`) where NO hook ran → SKIP (never a vacuous PASS),
10
+ * - a block-case where no hook ran → FAIL (the gate was not exercised).
11
+ */
12
+ export function assertOutcome(result, expect) {
13
+ const stream = expect.expectStream ?? "stderr";
14
+ if (!result) {
15
+ if (expect.blocked === false) {
16
+ return { status: "SKIP", detail: "No hook matched the tool — allow-case not exercised (would pass vacuously)." };
17
+ }
18
+ return { status: "FAIL", detail: "Expected a block but no hook ran for this tool." };
19
+ }
20
+ const streamText = stream === "stdout" ? result.stdout : result.stderr;
21
+ if (expect.blocked) {
22
+ const markerOk = !expect.marker || streamText.includes(expect.marker);
23
+ const exitOk = expect.exitCode !== undefined ? result.status === expect.exitCode : result.status !== 0;
24
+ if (markerOk && exitOk) {
25
+ return { status: "PASS", detail: `Blocked as expected (exit ${result.status}${expect.marker ? `, ${expect.marker} on ${stream}` : ""}).` };
26
+ }
27
+ return {
28
+ status: "FAIL",
29
+ detail: `Expected block (exit ${expect.exitCode ?? "≠0"}${expect.marker ? `, ${expect.marker} on ${stream}` : ""}) but got exit ${result.status}; marker ${markerOk ? "present" : "absent"}.`,
30
+ };
31
+ }
32
+ if (result.status === 0)
33
+ return { status: "PASS", detail: "Allowed (exit 0)." };
34
+ return { status: "FAIL", detail: `Expected allow (exit 0) but got exit ${result.status}.` };
35
+ }
36
+ /** Apply a step's `given` to the scaffolded project (in-place). */
37
+ function applyGiven(project, given) {
38
+ if (!given)
39
+ return;
40
+ if (given.clearPlans)
41
+ project.clearPlans();
42
+ if (given.plan)
43
+ project.addPlan({ nested: true });
44
+ for (const f of given.files ?? []) {
45
+ const abs = path.join(project.dir, f.path);
46
+ fs.mkdirSync(path.dirname(abs), { recursive: true });
47
+ fs.writeFileSync(abs, f.content);
48
+ }
49
+ }
50
+ /** Run a single step's `when` against the project and assert against `expect`. */
51
+ function runStep(project, settings, step) {
52
+ applyGiven(project, step.given);
53
+ const results = runConfiguredHook(settings, {
54
+ projectDir: project.dir,
55
+ event: "PreToolUse",
56
+ tool: step.when.tool,
57
+ toolName: step.when.tool,
58
+ toolInput: { file_path: step.when.file_path, command: step.when.command },
59
+ only: step.when.hook,
60
+ extraEnv: step.when.env,
61
+ });
62
+ const result = results.find((r) => r.script === step.when.hook);
63
+ const outcome = assertOutcome(result, step.expect);
64
+ const stream = step.expect.expectStream ?? "stderr";
65
+ return {
66
+ status: outcome.status,
67
+ detail: outcome.detail,
68
+ expected: `${step.when.hook}: ${step.expect.blocked ? `block ${step.expect.marker ?? ""} on ${stream}` : "allow"}`.trim(),
69
+ actual: result ? `exit ${result.status}` : "no hook ran",
70
+ };
71
+ }
72
+ /** Normalize a scenario into its ordered step list (single-step shorthand → one step). */
73
+ function scenarioSteps(scenario) {
74
+ if (scenario.steps && scenario.steps.length > 0)
75
+ return scenario.steps;
76
+ if (scenario.when && scenario.expect) {
77
+ return [{ given: scenario.given, when: scenario.when, expect: scenario.expect }];
78
+ }
79
+ return [];
80
+ }
81
+ /** worst of the step statuses: FAIL > SKIP > PASS (SKIP is a soft failure for --all). */
82
+ function rollupSteps(steps) {
83
+ if (steps.length === 0)
84
+ return "FAIL";
85
+ if (steps.some((s) => s.status === "FAIL"))
86
+ return "FAIL";
87
+ if (steps.some((s) => s.status === "SKIP"))
88
+ return "SKIP";
89
+ return "PASS";
90
+ }
91
+ /** Execute one scenario against a freshly-scaffolded temp harness. Cleans up always. */
92
+ export function runScenario(scenario, srcRoot) {
93
+ const steps = scenarioSteps(scenario);
94
+ if (steps.length === 0) {
95
+ return {
96
+ name: scenario.name,
97
+ description: scenario.description,
98
+ status: "FAIL",
99
+ steps: [{ status: "FAIL", detail: "Scenario has neither a valid `when/expect` nor `steps`.", expected: "a runnable step", actual: "none" }],
100
+ };
101
+ }
102
+ const project = scaffoldHarnessProject(srcRoot);
103
+ try {
104
+ const stepResults = steps.map((step) => runStep(project, settingsOf(srcRoot), step));
105
+ return { name: scenario.name, description: scenario.description, status: rollupSteps(stepResults), steps: stepResults };
106
+ }
107
+ finally {
108
+ // try/finally so the temp dir (which may hold a synthetic .env) is removed even
109
+ // on a spawnSync timeout/throw.
110
+ project.cleanup();
111
+ }
112
+ }
113
+ let _settingsCache = null;
114
+ function settingsOf(srcRoot) {
115
+ if (_settingsCache?.root === srcRoot)
116
+ return _settingsCache.settings;
117
+ const settings = JSON.parse(fs.readFileSync(path.join(srcRoot, ".claude", "settings.json"), "utf8"));
118
+ _settingsCache = { root: srcRoot, settings };
119
+ return settings;
120
+ }
121
+ /** Load + validate a scenario YAML file. Throws on a malformed/under-specified scenario. */
122
+ export function loadScenario(file) {
123
+ const parsed = yaml.load(fs.readFileSync(file, "utf8"));
124
+ if (typeof parsed !== "object" || parsed === null)
125
+ throw new Error(`${path.basename(file)}: not a YAML object`);
126
+ const s = parsed;
127
+ if (typeof s.name !== "string" || s.name.length === 0)
128
+ throw new Error(`${path.basename(file)}: missing 'name'`);
129
+ const hasSingle = s.when !== undefined && s.expect !== undefined;
130
+ const hasSteps = Array.isArray(s.steps) && s.steps.length > 0;
131
+ if (!hasSingle && !hasSteps) {
132
+ throw new Error(`${path.basename(file)}: must define either when+expect or a non-empty steps list`);
133
+ }
134
+ return s;
135
+ }
136
+ export function simulationsDir(srcRoot) {
137
+ const dir = path.join(srcRoot, ".claude", "simulations");
138
+ return { dir, exists: fs.existsSync(dir) };
139
+ }
140
+ /** List scenario YAML basenames (without extension) in the simulations dir. */
141
+ export function listScenarios(srcRoot) {
142
+ const { dir, exists } = simulationsDir(srcRoot);
143
+ if (!exists)
144
+ return [];
145
+ return fs
146
+ .readdirSync(dir)
147
+ .filter((f) => f.endsWith(".yaml") || f.endsWith(".yml"))
148
+ .map((f) => f.replace(/\.ya?ml$/, ""))
149
+ .sort();
150
+ }
151
+ export function loadScenarioByName(srcRoot, name) {
152
+ const { dir } = simulationsDir(srcRoot);
153
+ for (const ext of [".yaml", ".yml"]) {
154
+ const file = path.join(dir, `${name}${ext}`);
155
+ if (fs.existsSync(file))
156
+ return loadScenario(file);
157
+ }
158
+ throw new Error(`Scenario '${name}' not found in ${dir}`);
159
+ }
160
+ export { hasHarness };
161
+ //# sourceMappingURL=simulation-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simulation-runner.js","sourceRoot":"","sources":["../../src/core/simulation-runner.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,20 @@ export interface UpdateStats {
6
6
  userModified: string[];
7
7
  orphansDeleted: string[];
8
8
  orphansSkipped: string[];
9
+ /** Paths from release `deletions[]` removed because they were pristine kit-owned files. */
10
+ deletionsDeleted: string[];
11
+ /** Listed deletions left in place (user-modified, not kit-owned, or declined). */
12
+ deletionsSkipped: string[];
13
+ /** Listed deletions that were already absent on disk. */
14
+ deletionsAlreadyGone: string[];
15
+ /** Listed deletions a dry-run would remove. */
16
+ deletionsPreview: string[];
17
+ /** Pristine kit files removed because they fall outside the installed profile. */
18
+ profileTrimmed: string[];
19
+ /** Out-of-profile files kept (user-modified or declined). */
20
+ profileTrimSkipped: string[];
21
+ /** Out-of-profile pristine files a dry-run would trim. */
22
+ profileTrimPreview: string[];
9
23
  }
10
24
  export interface SmartUpdateOptions {
11
25
  /** Default true. Set false to disable orphan deletion (CLI: `--no-cleanup`). */
@@ -22,6 +36,24 @@ export interface SmartUpdateOptions {
22
36
  * the process hangs on stdin.
23
37
  */
24
38
  confirmOrphans?: (orphans: string[]) => Promise<boolean>;
39
+ /**
40
+ * Profile install allow-set: `.claude/`-relative paths the resolved profile
41
+ * should write. When present, the source walk skips any file NOT in this set,
42
+ * and a profile-trim pass removes previously-installed pristine kit files that
43
+ * fall outside it (the full→core downgrade). Absent ⇒ today's full install.
44
+ */
45
+ allowedPaths?: Set<string>;
46
+ /** Installed profile name to record in metadata ("full" for whole-tree). */
47
+ profile?: string;
48
+ /** Resolved pack list to record in metadata; omit for full/legacy (sentinel). */
49
+ packs?: string[];
50
+ /**
51
+ * Opt-in profile-trim: delete previously-installed pristine kit files OUTSIDE
52
+ * `allowedPaths` (the full→core downgrade). ONLY `init --profile` sets this —
53
+ * `pack add` and `upgrade` pass a narrow allow-set that filters WRITES but must
54
+ * never trigger a downgrade delete of everything else.
55
+ */
56
+ trimToProfile?: boolean;
25
57
  }
26
58
  /**
27
59
  * Smart update from a downloaded release directory.
@@ -1 +1 @@
1
- {"version":3,"file":"smart-update.d.ts","sourceRoot":"","sources":["../../src/core/smart-update.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAO/D,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IAClC,gFAAgF;IAChF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACzD;AAED;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAChC,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,OAAO,EACf,KAAK,UAAQ,EACb,OAAO,GAAE,kBAAuB,GAC9B,OAAO,CAAC,WAAW,CAAC,CAkQtB"}
1
+ {"version":3,"file":"smart-update.d.ts","sourceRoot":"","sources":["../../src/core/smart-update.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAmB/D,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,2FAA2F;IAC3F,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,kFAAkF;IAClF,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,yDAAyD;IACzD,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,+CAA+C;IAC/C,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,kFAAkF;IAClF,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,6DAA6D;IAC7D,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,0DAA0D;IAC1D,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAkB;IAClC,gFAAgF;IAChF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzD;;;;;OAKG;IACH,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAChC,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,OAAO,EACf,KAAK,UAAQ,EACb,OAAO,GAAE,kBAAuB,GAC9B,OAAO,CAAC,WAAW,CAAC,CA8ZtB"}