crewhaus 0.1.8 → 0.2.1

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 (138) hide show
  1. package/README.md +10 -3
  2. package/dist/advice-apply.d.ts +182 -0
  3. package/dist/advice-apply.js +286 -0
  4. package/dist/advise-rules.d.ts +348 -0
  5. package/dist/advise-rules.js +905 -0
  6. package/dist/alert-sink.d.ts +48 -0
  7. package/dist/alert-sink.js +86 -0
  8. package/dist/approval-gate.d.ts +127 -0
  9. package/dist/approval-gate.js +254 -0
  10. package/dist/audit-verify.d.ts +69 -0
  11. package/dist/audit-verify.js +97 -0
  12. package/dist/autodistill.d.ts +113 -0
  13. package/dist/autodistill.js +256 -0
  14. package/dist/channel-provision.d.ts +360 -0
  15. package/dist/channel-provision.js +881 -0
  16. package/dist/ci-scaffold.d.ts +31 -0
  17. package/dist/ci-scaffold.js +343 -0
  18. package/dist/compile-check.d.ts +90 -0
  19. package/dist/compile-check.js +285 -0
  20. package/dist/compliance-schedule.d.ts +35 -0
  21. package/dist/compliance-schedule.js +36 -0
  22. package/dist/context-pressure.d.ts +80 -0
  23. package/dist/context-pressure.js +166 -0
  24. package/dist/dataset-mine.d.ts +173 -0
  25. package/dist/dataset-mine.js +404 -0
  26. package/dist/datasets.d.ts +124 -0
  27. package/dist/datasets.js +260 -0
  28. package/dist/deploy-canary.d.ts +83 -0
  29. package/dist/deploy-canary.js +87 -0
  30. package/dist/doctor-checks.d.ts +33 -0
  31. package/dist/doctor-checks.js +92 -0
  32. package/dist/doctor-detect.d.ts +108 -0
  33. package/dist/doctor-detect.js +214 -0
  34. package/dist/doctor-fix.d.ts +81 -0
  35. package/dist/doctor-fix.js +164 -0
  36. package/dist/egress-triage.d.ts +121 -0
  37. package/dist/egress-triage.js +261 -0
  38. package/dist/eval-bridge.d.ts +114 -0
  39. package/dist/eval-bridge.js +158 -0
  40. package/dist/eval-coverage.d.ts +140 -0
  41. package/dist/eval-coverage.js +428 -0
  42. package/dist/eval-history.d.ts +48 -0
  43. package/dist/eval-history.js +157 -0
  44. package/dist/eval-matrix.d.ts +80 -0
  45. package/dist/eval-matrix.js +182 -0
  46. package/dist/eval-sentinel.d.ts +65 -0
  47. package/dist/eval-sentinel.js +132 -0
  48. package/dist/faq.d.ts +68 -0
  49. package/dist/faq.js +168 -0
  50. package/dist/feedback.d.ts +9 -2
  51. package/dist/feedback.js +17 -7
  52. package/dist/fewshot.d.ts +83 -0
  53. package/dist/fewshot.js +158 -0
  54. package/dist/fleet.d.ts +207 -0
  55. package/dist/fleet.js +488 -0
  56. package/dist/flywheel.d.ts +193 -0
  57. package/dist/flywheel.js +519 -0
  58. package/dist/graders-suggest.d.ts +186 -0
  59. package/dist/graders-suggest.js +658 -0
  60. package/dist/incident.d.ts +99 -0
  61. package/dist/incident.js +217 -0
  62. package/dist/index.d.ts +9 -1
  63. package/dist/index.js +11664 -963
  64. package/dist/init-interactive.d.ts +105 -0
  65. package/dist/init-interactive.js +208 -0
  66. package/dist/intents.d.ts +105 -0
  67. package/dist/intents.js +292 -0
  68. package/dist/judge-calibrate.d.ts +137 -0
  69. package/dist/judge-calibrate.js +247 -0
  70. package/dist/justification-calibrate.d.ts +150 -0
  71. package/dist/justification-calibrate.js +262 -0
  72. package/dist/justification-gate.d.ts +27 -6
  73. package/dist/justification-gate.js +30 -6
  74. package/dist/knowledge-sync.d.ts +179 -0
  75. package/dist/knowledge-sync.js +551 -0
  76. package/dist/lessons.d.ts +87 -0
  77. package/dist/lessons.js +207 -0
  78. package/dist/lint.d.ts +127 -0
  79. package/dist/lint.js +226 -0
  80. package/dist/loadtest.d.ts +114 -0
  81. package/dist/loadtest.js +196 -0
  82. package/dist/marketplace-cli.d.ts +110 -0
  83. package/dist/marketplace-cli.js +250 -0
  84. package/dist/mcp-doctor.d.ts +121 -0
  85. package/dist/mcp-doctor.js +249 -0
  86. package/dist/model-scan.d.ts +116 -0
  87. package/dist/model-scan.js +226 -0
  88. package/dist/onchain-tune.d.ts +164 -0
  89. package/dist/onchain-tune.js +346 -0
  90. package/dist/permissions-suggest.d.ts +126 -0
  91. package/dist/permissions-suggest.js +333 -0
  92. package/dist/pii-tune.d.ts +107 -0
  93. package/dist/pii-tune.js +122 -0
  94. package/dist/propose.d.ts +117 -0
  95. package/dist/propose.js +184 -0
  96. package/dist/refresh-goldens.d.ts +82 -0
  97. package/dist/refresh-goldens.js +221 -0
  98. package/dist/regression-pin.d.ts +160 -0
  99. package/dist/regression-pin.js +281 -0
  100. package/dist/retention.d.ts +193 -0
  101. package/dist/retention.js +607 -0
  102. package/dist/retire.d.ts +118 -0
  103. package/dist/retire.js +291 -0
  104. package/dist/right-size.d.ts +100 -0
  105. package/dist/right-size.js +123 -0
  106. package/dist/route.d.ts +19 -0
  107. package/dist/route.js +90 -0
  108. package/dist/scaffold-evals.d.ts +138 -0
  109. package/dist/scaffold-evals.js +410 -0
  110. package/dist/scope-audit-drift.d.ts +139 -0
  111. package/dist/scope-audit-drift.js +260 -0
  112. package/dist/security-corpus.d.ts +237 -0
  113. package/dist/security-corpus.js +516 -0
  114. package/dist/security-digest.d.ts +174 -0
  115. package/dist/security-digest.js +656 -0
  116. package/dist/sessions-index.d.ts +27 -0
  117. package/dist/sessions-index.js +51 -0
  118. package/dist/slo-doctor.d.ts +67 -0
  119. package/dist/slo-doctor.js +119 -0
  120. package/dist/slo-sink.d.ts +96 -0
  121. package/dist/slo-sink.js +107 -0
  122. package/dist/spec-changelog.d.ts +102 -0
  123. package/dist/spec-changelog.js +237 -0
  124. package/dist/state-backup.d.ts +223 -0
  125. package/dist/state-backup.js +648 -0
  126. package/dist/tools-cli.d.ts +170 -0
  127. package/dist/tools-cli.js +300 -0
  128. package/dist/triage.d.ts +202 -0
  129. package/dist/triage.js +403 -0
  130. package/dist/upgrade.d.ts +57 -0
  131. package/dist/upgrade.js +113 -0
  132. package/dist/version.d.ts +6 -0
  133. package/dist/version.js +27 -0
  134. package/dist/voice-eval.d.ts +138 -0
  135. package/dist/voice-eval.js +309 -0
  136. package/dist/watch.d.ts +58 -0
  137. package/dist/watch.js +97 -0
  138. package/package.json +90 -65
@@ -0,0 +1,207 @@
1
+ import type { Manifest } from "@crewhaus/spec-registry";
2
+ /** The spec file that roots a standalone harness. */
3
+ export declare const HARNESS_SPEC_FILENAME = "crewhaus.yaml";
4
+ /** Thrown for operational failures (missing root, empty filter, disallowed
5
+ * bulk subcommand). The CLI entry file catches it and routes the message
6
+ * through `die()`; tests assert on `.message` without the process exiting. */
7
+ export declare class FleetError extends Error {
8
+ readonly name = "FleetError";
9
+ }
10
+ /** A discovered harness: its absolute directory + the spec path within it. */
11
+ export type DiscoveredHarness = {
12
+ readonly dir: string;
13
+ readonly specPath: string;
14
+ };
15
+ /**
16
+ * Walk `root` for directories carrying a `crewhaus.yaml`, bounded to
17
+ * {@link MAX_DISCOVERY_DEPTH}. Never descends into `.crewhaus`, `node_modules`,
18
+ * `.git`, `dist`, or `.worktrees`. A directory that IS a harness is still
19
+ * descended into (a harness may nest sub-harnesses in a demo tree), just not
20
+ * through its state dir. Results are sorted by directory for stable output.
21
+ */
22
+ export declare function discoverHarnesses(root: string): DiscoveredHarness[];
23
+ /** The identity fields a fleet row needs, read best-effort. */
24
+ export type SpecHeader = {
25
+ readonly name?: string;
26
+ readonly target?: string;
27
+ readonly model?: string;
28
+ };
29
+ /**
30
+ * Read `name`, `target`, and `model` from a `crewhaus.yaml` WITHOUT a full
31
+ * schema parse. A fleet scan must survive a stale/invalid spec (schema drift,
32
+ * a half-edited file), so this is a tolerant top-level-key scrape rather than
33
+ * `parseSpec`. `name`/`target` are top-level on every target shape; `model`
34
+ * lives at `agent.model` (cli/channel/voice) OR top-level `model`
35
+ * (workflow/graph/pipeline/crew) depending on the shape — the first
36
+ * `model:` at any indentation is taken. Values are unquoted and trimmed.
37
+ */
38
+ export declare function readSpecHeader(yamlText: string): SpecHeader;
39
+ /** The `.crewhaus/specs`-registered version + env pins for a harness spec. */
40
+ export type RegistryStatus = {
41
+ /** Latest registered version (`v3`), or undefined when nothing is registered. */
42
+ readonly latestVersion?: string;
43
+ /** env → version pins from the registry manifest. */
44
+ readonly pins: Readonly<Record<string, string>>;
45
+ };
46
+ /** The newest recorded eval run for a harness. */
47
+ export type LastEval = {
48
+ readonly datasetName: string;
49
+ readonly passRate: number;
50
+ readonly ts: string;
51
+ };
52
+ /** Minimal shape of an eval index entry the fleet row needs. */
53
+ export type LastEvalEntry = {
54
+ readonly datasetName: string;
55
+ readonly passRate: number;
56
+ readonly ts: string;
57
+ };
58
+ /** One harness's rolled-up inventory row. */
59
+ export type HarnessInventory = {
60
+ readonly dir: string;
61
+ readonly header: SpecHeader;
62
+ /** Best-effort spec name (header name, else the dir basename). */
63
+ readonly specName: string;
64
+ readonly registry: RegistryStatus;
65
+ readonly lastEval?: LastEval;
66
+ readonly sessionCount: number;
67
+ readonly feedbackCount: number;
68
+ /** True when the spec file did not read at all (unreadable/absent). */
69
+ readonly specUnreadable: boolean;
70
+ };
71
+ /** Count `sess_<16hex>.json` files under `.crewhaus/sessions`. */
72
+ export declare function countSessions(harnessDir: string): number;
73
+ /**
74
+ * Distinct feedback a harness carries, counted the way `crewhaus distill`
75
+ * folds it: `user_feedback` events in `sessions/*.jsonl` PLUS bare records in
76
+ * `feedback/*.jsonl` (`extractFeedbackRecords` accepts both encodings), then
77
+ * `mergeFeedback` collapses to one per (sessionId, turnNumber). The row shows
78
+ * distinct rated turns, not raw line count, so a re-rated turn counts once.
79
+ */
80
+ export declare function countFeedback(harnessDir: string): number;
81
+ /** The newest run in an eval index, or undefined. Newest by `ts` (ISO-8601
82
+ * lexical order is chronological). */
83
+ export declare function lastEvalFor(evalEntries: ReadonlyArray<LastEvalEntry>): LastEval | undefined;
84
+ /**
85
+ * Manifest reader seam — production passes a closure over
86
+ * `@crewhaus/spec-registry`; tests pass a stub. Returns undefined when the
87
+ * spec has no registry entry (never registered / compiled).
88
+ */
89
+ export type ManifestReader = (specName: string, registryRoot: string) => Promise<Manifest | undefined>;
90
+ /** Eval-index reader seam — production passes `readRunIndex`; tests stub. */
91
+ export type EvalIndexReader = (evalsDir: string) => ReadonlyArray<LastEvalEntry>;
92
+ export type BuildInventoryDeps = {
93
+ readonly readManifest: ManifestReader;
94
+ readonly readEvalIndex: EvalIndexReader;
95
+ };
96
+ /**
97
+ * Aggregate one harness directory into an inventory row. All reads are
98
+ * tolerant: a missing state dir, an unregistered spec, or an unreadable spec
99
+ * file each degrade to an empty/absent field rather than throwing, so one
100
+ * broken harness never aborts a `fleet list`.
101
+ */
102
+ export declare function buildHarnessInventory(harness: DiscoveredHarness, deps: BuildInventoryDeps): Promise<HarnessInventory>;
103
+ /** Build the full fleet inventory for a root. */
104
+ export declare function buildFleetInventory(root: string, deps: BuildInventoryDeps): Promise<HarnessInventory[]>;
105
+ /** Render the inventory as aligned columns for `fleet list`. */
106
+ export declare function formatInventory(rows: ReadonlyArray<HarnessInventory>, root: string): ReadonlyArray<string>;
107
+ export type HarnessHealth = {
108
+ readonly dir: string;
109
+ readonly specName: string;
110
+ /** True when a compiled bundle / registry entry exists (deployable). */
111
+ readonly registered: boolean;
112
+ /** env pins present. */
113
+ readonly pinnedEnvs: ReadonlyArray<string>;
114
+ /** True when a pinned eval baseline exists AND the last run met/held it. */
115
+ readonly evalHealthy: boolean;
116
+ readonly evalNote: string;
117
+ /** Open incidents from the ops-batch incidents dir, if present. */
118
+ readonly openIncidents: number;
119
+ /** Whether `.crewhaus/audit` exists (tamper-evidence available). */
120
+ readonly hasAudit: boolean;
121
+ };
122
+ /** Reader seam: newest pass-rate + whether it dropped vs the pinned baseline. */
123
+ export type EvalHealthReader = (evalsDir: string, specName: string) => {
124
+ healthy: boolean;
125
+ note: string;
126
+ };
127
+ /** Count open incidents under `.crewhaus/incidents` (files not ending
128
+ * `.resolved.json`). Absent dir → 0. The ops batch writes one JSON per
129
+ * incident; a resolved one is renamed `<id>.resolved.json`. */
130
+ export declare function countOpenIncidents(harnessDir: string): number;
131
+ export declare function buildHarnessHealth(inv: HarnessInventory, readEvalHealth: EvalHealthReader): Promise<HarnessHealth>;
132
+ /** Render the health rollup as status lines for `fleet status`. */
133
+ export declare function formatHealth(rows: ReadonlyArray<HarnessHealth>, root: string): ReadonlyArray<string>;
134
+ /** ✓ healthy / ✗ needs attention. Attention = an open incident, an eval
135
+ * regression, or an unregistered harness that nonetheless has env pins
136
+ * (a pin pointing at nothing registered). */
137
+ export declare function healthMark(r: HarnessHealth): "✓" | "✗";
138
+ /** Read-only / idempotent subcommands the bulk runner accepts without an
139
+ * explicit opt-in. Each maps to a `crewhaus <argv...>` invocation. */
140
+ export declare const READ_ONLY_BULK_COMMANDS: Readonly<Record<string, ReadonlyArray<string>>>;
141
+ /** A resolved bulk-run plan: the base argv + whether it is a mutating command. */
142
+ export type BulkCommandPlan = {
143
+ /** The base argv (e.g. ["security","digest"]). */
144
+ readonly argv: ReadonlyArray<string>;
145
+ /** True when the command is off the read-only allow-list. */
146
+ readonly mutating: boolean;
147
+ };
148
+ /**
149
+ * Resolve a `fleet run` subcommand + trailing args into a plan. Refuses
150
+ * anything off the read-only allow-list unless `allowMutating` is set. The
151
+ * longest allow-listed prefix wins, so `security digest` resolves ahead of a
152
+ * bare `security`.
153
+ */
154
+ export declare function resolveBulkCommand(subcommandTokens: ReadonlyArray<string>, allowMutating: boolean): BulkCommandPlan;
155
+ /** Match a harness against a `--filter` glob, tested against BOTH the spec
156
+ * name and the directory basename, so `--filter '*bot*'` catches either. */
157
+ export declare function matchesFilter(inv: HarnessInventory, filter: string | undefined): boolean;
158
+ /** Launch seam: run `crewhaus <argv>` in `cwd`, resolve to an exit code + the
159
+ * captured tail of output. Production wires this to `Bun.spawn`; tests inject
160
+ * a deterministic stub so no subprocess runs. */
161
+ export type FleetRunner = (opts: {
162
+ readonly cwd: string;
163
+ readonly argv: ReadonlyArray<string>;
164
+ }) => Promise<{
165
+ readonly exitCode: number;
166
+ readonly tail: string;
167
+ }>;
168
+ /** Per-harness confirm seam for `--allow-mutating` (interactive prompt in the
169
+ * CLI; a predicate in tests). Returning false skips that harness. */
170
+ export type ConfirmMutating = (inv: HarnessInventory, argv: ReadonlyArray<string>) => Promise<boolean>;
171
+ export type BulkRunResult = {
172
+ readonly inv: HarnessInventory;
173
+ readonly ran: boolean;
174
+ /** exit code when ran; undefined when skipped (filter/decline). */
175
+ readonly exitCode?: number;
176
+ readonly tail?: string;
177
+ /** Reason a harness was skipped, if it was. */
178
+ readonly skipReason?: string;
179
+ };
180
+ export type RunFleetBulkOptions = {
181
+ readonly root: string;
182
+ readonly subcommandTokens: ReadonlyArray<string>;
183
+ readonly filter?: string;
184
+ readonly allowMutating: boolean;
185
+ readonly deps: BuildInventoryDeps;
186
+ readonly runner: FleetRunner;
187
+ readonly confirm: ConfirmMutating;
188
+ };
189
+ export type RunFleetBulkReport = {
190
+ readonly plan: BulkCommandPlan;
191
+ readonly results: ReadonlyArray<BulkRunResult>;
192
+ /** Harnesses that ran and exited non-zero. */
193
+ readonly failed: number;
194
+ /** Harnesses that ran and exited zero. */
195
+ readonly passed: number;
196
+ /** Harnesses skipped (filtered out or declined). */
197
+ readonly skipped: number;
198
+ };
199
+ /**
200
+ * Run one subcommand across the filtered fleet. Read-only commands run
201
+ * unconditionally on every matched harness; a mutating command (only reachable
202
+ * with `allowMutating`) runs a harness only when `confirm` approves it. The
203
+ * runner is the sole side-effect surface, injected for testability.
204
+ */
205
+ export declare function runFleetBulk(opts: RunFleetBulkOptions): Promise<RunFleetBulkReport>;
206
+ /** Render a bulk-run report as summary lines for `fleet run`. */
207
+ export declare function formatBulkReport(report: RunFleetBulkReport): ReadonlyArray<string>;