@agilno-tech/rivet 0.1.0-alpha.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 (283) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +6 -0
  3. package/README.md +59 -0
  4. package/bin/cli.js +42 -0
  5. package/dist/agents/backend-django-agent/SKILL.md +35 -0
  6. package/dist/agents/backend-nestjs-agent/SKILL.md +36 -0
  7. package/dist/agents/boss-agent/SKILL.md +28 -0
  8. package/dist/agents/bounded-worker/SKILL.md +28 -0
  9. package/dist/agents/data-performance-agent/SKILL.md +32 -0
  10. package/dist/agents/delivery-ticketing-agent/SKILL.md +36 -0
  11. package/dist/agents/devops-agent/SKILL.md +34 -0
  12. package/dist/agents/engineering-manager/SKILL.md +28 -0
  13. package/dist/agents/frontend-nextjs-agent/SKILL.md +34 -0
  14. package/dist/agents/frontend-web-agent/SKILL.md +31 -0
  15. package/dist/agents/incident-response-agent/SKILL.md +42 -0
  16. package/dist/agents/jest-agent/SKILL.md +77 -0
  17. package/dist/agents/mobile-agent/SKILL.md +32 -0
  18. package/dist/agents/playwright-agent/SKILL.md +54 -0
  19. package/dist/agents/product-design-manager/SKILL.md +27 -0
  20. package/dist/agents/qa-agent/SKILL.md +29 -0
  21. package/dist/agents/quality-manager/SKILL.md +28 -0
  22. package/dist/agents/vitest-agent/SKILL.md +77 -0
  23. package/dist/governance/pre-push-rules.md +75 -0
  24. package/dist/governance/prompt-hygiene.md +22 -0
  25. package/dist/governance/review-checklist.md +24 -0
  26. package/dist/governance/safety-and-data.md +27 -0
  27. package/dist/governance/usage-rules.md +21 -0
  28. package/dist/mandatory/address-pr-feedback/SKILL.md +196 -0
  29. package/dist/mandatory/agentic-goal/SKILL.md +42 -0
  30. package/dist/mandatory/agentic-status/SKILL.md +74 -0
  31. package/dist/mandatory/apply-design/SKILL.md +228 -0
  32. package/dist/mandatory/check-ac/SKILL.md +124 -0
  33. package/dist/mandatory/create-pr-and-commit/SKILL.md +304 -0
  34. package/dist/mandatory/design/SKILL.md +312 -0
  35. package/dist/mandatory/feature-workflow/SKILL.md +87 -0
  36. package/dist/mandatory/hotfix/SKILL.md +195 -0
  37. package/dist/mandatory/pre-push/SKILL.md +272 -0
  38. package/dist/mandatory/project-context/SKILL.md +180 -0
  39. package/dist/mandatory/release-docs/SKILL.md +191 -0
  40. package/dist/mandatory/review-pr/SKILL.md +323 -0
  41. package/dist/mandatory/security-review/SKILL.md +157 -0
  42. package/dist/skills/api-contract/SKILL.md +77 -0
  43. package/dist/skills/backend-django/SKILL.md +27 -0
  44. package/dist/skills/backend-nestjs/SKILL.md +65 -0
  45. package/dist/skills/bug-ticket-creation/SKILL.md +43 -0
  46. package/dist/skills/cloudwatch-troubleshooting/SKILL.md +73 -0
  47. package/dist/skills/database-migration/SKILL.md +97 -0
  48. package/dist/skills/debugging/SKILL.md +32 -0
  49. package/dist/skills/devops-infra/SKILL.md +26 -0
  50. package/dist/skills/documentation/SKILL.md +24 -0
  51. package/dist/skills/frontend-nextjs/SKILL.md +27 -0
  52. package/dist/skills/incident-postmortem/SKILL.md +38 -0
  53. package/dist/skills/kubernetes-troubleshooting/SKILL.md +71 -0
  54. package/dist/skills/mobile-react-native/SKILL.md +37 -0
  55. package/dist/skills/postgres-analytics/SKILL.md +29 -0
  56. package/dist/skills/product-jira-ticketing/SKILL.md +28 -0
  57. package/dist/skills/qa-bug-analysis/SKILL.md +27 -0
  58. package/dist/skills/refactoring/SKILL.md +32 -0
  59. package/dist/skills/sprint-planning/SKILL.md +32 -0
  60. package/dist/skills/testing-quality/SKILL.md +62 -0
  61. package/dist/v2/protocols/agent-orchestration.md +49 -0
  62. package/dist/v2/protocols/delivery.md +45 -0
  63. package/dist/v2/protocols/design-authority.md +29 -0
  64. package/dist/v2/protocols/goal-graph.md +44 -0
  65. package/dist/v2/protocols/pattern-first-development.md +29 -0
  66. package/dist/v2/protocols/qa-evidence.md +29 -0
  67. package/dist/v2/protocols/security.md +29 -0
  68. package/dist/v2/schemas/event.schema.json +86 -0
  69. package/dist/v2/schemas/evidence.schema.json +94 -0
  70. package/dist/v2/schemas/feature-decomposition.schema.json +48 -0
  71. package/dist/v2/schemas/feature-plan.schema.json +95 -0
  72. package/dist/v2/schemas/goal-graph.schema.json +61 -0
  73. package/dist/v2/schemas/integration.schema.json +119 -0
  74. package/dist/v2/schemas/orchestration.schema.json +69 -0
  75. package/dist/v2/schemas/project.schema.json +209 -0
  76. package/dist/v2/schemas/providers.schema.json +142 -0
  77. package/dist/v2/schemas/quality.schema.json +50 -0
  78. package/dist/v2/schemas/work-action.schema.json +44 -0
  79. package/dist/v2/schemas/work-request.schema.json +253 -0
  80. package/dist/v2/templates/evidence/qa-bundle.json +194 -0
  81. package/dist/v2/templates/github-actions/rivet-deploy.yml +98 -0
  82. package/dist/v2/templates/harness/SKILL.md +90 -0
  83. package/dist/v2/templates/project/.rivet/orchestration.yaml +42 -0
  84. package/dist/v2/templates/project/.rivet/project.yaml +14 -0
  85. package/dist/v2/templates/project/.rivet/providers.yaml +8 -0
  86. package/dist/v2/templates/project/.rivet/quality.yaml +16 -0
  87. package/package.json +58 -0
  88. package/protocols/agent-orchestration.md +49 -0
  89. package/protocols/delivery.md +45 -0
  90. package/protocols/design-authority.md +29 -0
  91. package/protocols/goal-graph.md +44 -0
  92. package/protocols/pattern-first-development.md +29 -0
  93. package/protocols/qa-evidence.md +29 -0
  94. package/protocols/security.md +29 -0
  95. package/schemas/event.schema.json +86 -0
  96. package/schemas/evidence.schema.json +94 -0
  97. package/schemas/feature-decomposition.schema.json +48 -0
  98. package/schemas/feature-plan.schema.json +95 -0
  99. package/schemas/goal-graph.schema.json +61 -0
  100. package/schemas/integration.schema.json +119 -0
  101. package/schemas/orchestration.schema.json +69 -0
  102. package/schemas/project.schema.json +209 -0
  103. package/schemas/providers.schema.json +142 -0
  104. package/schemas/quality.schema.json +50 -0
  105. package/schemas/work-action.schema.json +44 -0
  106. package/schemas/work-request.schema.json +253 -0
  107. package/src/adapters/confluence.js +138 -0
  108. package/src/adapters/contract.js +657 -0
  109. package/src/adapters/factory.js +122 -0
  110. package/src/adapters/figma.js +178 -0
  111. package/src/adapters/fixtures.js +183 -0
  112. package/src/adapters/github.js +314 -0
  113. package/src/adapters/http.js +704 -0
  114. package/src/adapters/jira.js +195 -0
  115. package/src/adapters/linear.js +171 -0
  116. package/src/adapters/node-transport.js +59 -0
  117. package/src/cli/integration-setup-prompt.js +32 -0
  118. package/src/cli/interrupt.js +25 -0
  119. package/src/cli/main.js +596 -0
  120. package/src/cli/output.js +174 -0
  121. package/src/cli/parse-args.js +246 -0
  122. package/src/cli/project-discovery.js +70 -0
  123. package/src/cli/task-confirmation.js +38 -0
  124. package/src/cli/task-presentation.js +22 -0
  125. package/src/clients/claude.js +214 -0
  126. package/src/clients/codex.js +180 -0
  127. package/src/clients/compatibility.js +23 -0
  128. package/src/clients/contract.js +224 -0
  129. package/src/clients/fake.js +170 -0
  130. package/src/clients/process-runner.js +657 -0
  131. package/src/clients/result-contract.js +78 -0
  132. package/src/commands/delivery-publish.js +80 -0
  133. package/src/commands/delivery-remote.js +230 -0
  134. package/src/commands/delivery-review-update.js +39 -0
  135. package/src/commands/delivery-tracker.js +94 -0
  136. package/src/commands/delivery-transition.js +79 -0
  137. package/src/commands/delivery.js +223 -0
  138. package/src/commands/dependency-approval.js +21 -0
  139. package/src/commands/doctor.js +191 -0
  140. package/src/commands/evidence.js +44 -0
  141. package/src/commands/feature.js +212 -0
  142. package/src/commands/goals.js +231 -0
  143. package/src/commands/human-run.js +208 -0
  144. package/src/commands/human-task.js +278 -0
  145. package/src/commands/init.js +848 -0
  146. package/src/commands/install.js +814 -0
  147. package/src/commands/integration-setup.js +65 -0
  148. package/src/commands/integrations.js +54 -0
  149. package/src/commands/models.js +158 -0
  150. package/src/commands/orchestrate.js +61 -0
  151. package/src/commands/preflight.js +125 -0
  152. package/src/commands/protocols.js +228 -0
  153. package/src/commands/repositories.js +77 -0
  154. package/src/commands/setup-remote.js +41 -0
  155. package/src/commands/setup.js +214 -0
  156. package/src/commands/status.js +224 -0
  157. package/src/commands/support.js +44 -0
  158. package/src/commands/task-completion.js +104 -0
  159. package/src/commands/uninstall.js +234 -0
  160. package/src/commands/verify.js +171 -0
  161. package/src/commands/work.js +220 -0
  162. package/src/commands/worktrees.js +52 -0
  163. package/src/config/command-readiness.js +218 -0
  164. package/src/config/commands.js +206 -0
  165. package/src/config/defaults.js +55 -0
  166. package/src/config/load.js +230 -0
  167. package/src/config/validate.js +560 -0
  168. package/src/delivery/bitbucket-review.js +123 -0
  169. package/src/delivery/branch-publication.js +23 -0
  170. package/src/delivery/contract.js +379 -0
  171. package/src/delivery/github-deployment.js +132 -0
  172. package/src/delivery/github-review.js +5 -0
  173. package/src/delivery/github.js +382 -0
  174. package/src/delivery/gitlab-review.js +5 -0
  175. package/src/delivery/gitlab.js +395 -0
  176. package/src/delivery/prepare.js +90 -0
  177. package/src/delivery/publication-process.js +33 -0
  178. package/src/delivery/publication-transport.js +112 -0
  179. package/src/delivery/review-request.js +184 -0
  180. package/src/delivery/review-update.js +74 -0
  181. package/src/delivery/service.js +400 -0
  182. package/src/delivery/store.js +76 -0
  183. package/src/delivery/tracker-target.js +51 -0
  184. package/src/delivery/tracker-transition.js +158 -0
  185. package/src/delivery/tracker.js +164 -0
  186. package/src/discovery/git.js +85 -0
  187. package/src/discovery/portable.js +108 -0
  188. package/src/discovery/project.js +345 -0
  189. package/src/discovery/tools.js +145 -0
  190. package/src/evaluations/approval.js +20 -0
  191. package/src/evaluations/cost-policy.js +20 -0
  192. package/src/evaluations/harness-attempt.js +113 -0
  193. package/src/evaluations/live-runner.js +55 -0
  194. package/src/evaluations/profile.js +28 -0
  195. package/src/evaluations/report.js +11 -0
  196. package/src/evaluations/text-attempt.js +18 -0
  197. package/src/evidence/checksum.js +87 -0
  198. package/src/evidence/collect.js +727 -0
  199. package/src/evidence/validate.js +354 -0
  200. package/src/feature/accepted-integration.js +46 -0
  201. package/src/feature/actions.js +37 -0
  202. package/src/feature/client-profile.js +56 -0
  203. package/src/feature/decomposition-contract.js +58 -0
  204. package/src/feature/host-execution.js +633 -0
  205. package/src/feature/host-lock-recovery.js +96 -0
  206. package/src/feature/host-run-lock.js +32 -0
  207. package/src/feature/local-approval.js +183 -0
  208. package/src/feature/plan-contract.js +215 -0
  209. package/src/feature/planner.js +253 -0
  210. package/src/feature/run-store.js +241 -0
  211. package/src/feature/runtime-bridge.js +840 -0
  212. package/src/feature/verification-report.js +168 -0
  213. package/src/feature/workflow.js +375 -0
  214. package/src/git/client.js +509 -0
  215. package/src/git/integration-worktree.js +153 -0
  216. package/src/git/reconcile.js +222 -0
  217. package/src/git/reservations.js +450 -0
  218. package/src/git/worktrees.js +478 -0
  219. package/src/graph/completion.js +189 -0
  220. package/src/graph/fixtures.js +116 -0
  221. package/src/graph/reducer.js +124 -0
  222. package/src/graph/scheduler.js +252 -0
  223. package/src/graph/validate.js +106 -0
  224. package/src/install/managed.js +579 -0
  225. package/src/install/project-reference.js +33 -0
  226. package/src/install/project-runtime.js +142 -0
  227. package/src/install/runtime-integrity.cjs +141 -0
  228. package/src/integrations/capabilities.js +69 -0
  229. package/src/integrations/host-observation.js +26 -0
  230. package/src/integrations/registry.js +56 -0
  231. package/src/models/delegate.js +102 -0
  232. package/src/models/profiles.js +53 -0
  233. package/src/models/protocols.js +208 -0
  234. package/src/models/registry.js +83 -0
  235. package/src/models/transport.js +59 -0
  236. package/src/policy/approvals.js +251 -0
  237. package/src/policy/authority.js +282 -0
  238. package/src/policy/budget.js +149 -0
  239. package/src/policy/command-bootstrap.js +219 -0
  240. package/src/policy/commands.js +803 -0
  241. package/src/prompts/launch-contract.js +43 -0
  242. package/src/prompts/planning-contract.js +92 -0
  243. package/src/protocols/presentation.js +53 -0
  244. package/src/protocols/project.js +289 -0
  245. package/src/quality/runner.js +497 -0
  246. package/src/quality/traceability.js +215 -0
  247. package/src/repositories/identity.js +59 -0
  248. package/src/repositories/index.js +2 -0
  249. package/src/repositories/provider.js +210 -0
  250. package/src/runtime/application.js +353 -0
  251. package/src/runtime/dependency-directory.js +33 -0
  252. package/src/runtime/harness-discovery.js +121 -0
  253. package/src/runtime/heartbeat.js +47 -0
  254. package/src/runtime/instance-store.js +112 -0
  255. package/src/runtime/orchestrator.js +1133 -0
  256. package/src/runtime/portable-dependencies.js +94 -0
  257. package/src/runtime/recovery.js +190 -0
  258. package/src/runtime/retry.js +54 -0
  259. package/src/runtime/supervisor.js +166 -0
  260. package/src/runtime/worktree-bootstrap.js +169 -0
  261. package/src/state/event-store.js +333 -0
  262. package/src/state/lock.js +266 -0
  263. package/src/state/paths.js +274 -0
  264. package/src/state/redact.js +106 -0
  265. package/src/state/snapshot-store.js +310 -0
  266. package/src/status/public/app.js +96 -0
  267. package/src/status/public/index.html +37 -0
  268. package/src/status/public/styles.css +50 -0
  269. package/src/status/server.js +323 -0
  270. package/src/status/view-model.js +356 -0
  271. package/src/support/bundle.js +195 -0
  272. package/src/support/failure-report.js +96 -0
  273. package/src/work-request/contract.js +250 -0
  274. package/src/work-request/host.js +78 -0
  275. package/src/work-request/local.js +163 -0
  276. package/src/work-request/tracker.js +105 -0
  277. package/templates/evidence/qa-bundle.json +194 -0
  278. package/templates/github-actions/rivet-deploy.yml +98 -0
  279. package/templates/harness/SKILL.md +90 -0
  280. package/templates/project/.rivet/orchestration.yaml +42 -0
  281. package/templates/project/.rivet/project.yaml +14 -0
  282. package/templates/project/.rivet/providers.yaml +8 -0
  283. package/templates/project/.rivet/quality.yaml +16 -0
@@ -0,0 +1,596 @@
1
+ import { saveFailureReport } from '../support/failure-report.js';
2
+ import { failureGuidance } from './task-presentation.js';
3
+ import { confirmTaskAction, selectTaskOption } from './task-confirmation.js';
4
+ import * as filesystem from 'node:fs';
5
+ import { homedir } from 'node:os';
6
+ import { dirname, join } from 'node:path';
7
+ import { createInterface } from 'node:readline/promises';
8
+ import { fileURLToPath } from 'node:url';
9
+
10
+ import checkbox, { Separator } from '@inquirer/checkbox';
11
+
12
+ import {
13
+ checkForUpdate,
14
+ copyFileIntoPinnedDirectory,
15
+ createMutationGuard,
16
+ ensureContainedDirectory,
17
+ findProjectRoot,
18
+ install,
19
+ withPinnedTargetDirectory,
20
+ } from '../commands/install.js';
21
+ import { deliveryCommand } from '../commands/delivery.js';
22
+ import { repositoriesCommand } from '../commands/repositories.js';
23
+ import { defaultIntegrationSetupPrompt } from './integration-setup-prompt.js';
24
+ import { integrationsCommand } from '../commands/integrations.js';
25
+ import { doctor } from '../commands/doctor.js';
26
+ import { supportCommand } from '../commands/support.js';
27
+ import { modelsCommand } from '../commands/models.js';
28
+ import { setupCommand } from '../commands/setup.js';
29
+ import { protocolsCommand } from '../commands/protocols.js';
30
+ import { workCommand } from '../commands/work.js';
31
+ import { humanRunCommand } from '../commands/human-run.js';
32
+ import { humanTaskCommand } from '../commands/human-task.js';
33
+ import { init } from '../commands/init.js';
34
+ import { preflight } from '../commands/preflight.js';
35
+ import { uninstall } from '../commands/uninstall.js';
36
+ import { goalsCommand } from '../commands/goals.js';
37
+ import { orchestrateCommand } from '../commands/orchestrate.js';
38
+ import { evidenceCommand } from '../commands/evidence.js';
39
+ import { featureCommand } from '../commands/feature.js';
40
+ import { verifyCommand } from '../commands/verify.js';
41
+ import { statusCommand } from '../commands/status.js';
42
+ import {
43
+ CliError,
44
+ createJsonOutputBoundary,
45
+ createOutput,
46
+ emitCliError,
47
+ EXIT_CODES,
48
+ MAX_JSON_OUTPUT_BYTES,
49
+ observeOutputErrors,
50
+ } from './output.js';
51
+ import { ArgumentError, parseArgs } from './parse-args.js';
52
+
53
+ const PACKAGE_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..', '..');
54
+ const LEGACY_COMMANDS = new Set(['install', 'uninstall']);
55
+ const CONFIRMATION_TIMEOUT_MS = 30_000;
56
+ const DEPENDENCY_CONFIRMATION_TIMEOUT_MS = 120_000;
57
+ const promiseThen = Promise.prototype.then;
58
+ const reflectApply = Reflect.apply;
59
+ const abortControllerAbort = AbortController.prototype.abort;
60
+ const abortSignalAborted = Object.getOwnPropertyDescriptor(AbortSignal.prototype, 'aborted').get;
61
+ const addEventListener = EventTarget.prototype.addEventListener;
62
+ const removeEventListener = EventTarget.prototype.removeEventListener;
63
+
64
+ const BASIC_USAGE = `Usage:
65
+ Rivet: plan, build, check and review a task.
66
+
67
+ Everyday commands:
68
+ rivet setup Preview project setup
69
+ rivet setup --write Apply reviewed setup
70
+ rivet doctor Check project readiness
71
+ rivet run "task" Plan, execute and offer final review
72
+ rivet task status Inspect work and the next step
73
+ rivet task resume Continue a saved task or final review
74
+ rivet task start Reopen an unapproved plan
75
+ rivet task approve Review and finish verified work
76
+ rivet task deps Approve configured dependency setup
77
+ rivet task recover Inspect abandoned operation locks
78
+ rivet support --save Save diagnostics for a bug report
79
+
80
+ Run inside your project; use --project=<path> when elsewhere.
81
+ Choose tasks from a numbered list, or pass --run=<id> explicitly.
82
+ Use --details with run or task for full plan/state identifiers.
83
+ Use rivet --help --advanced for all harness, integration and delivery commands.
84
+ `;
85
+
86
+ const USAGE = `Advanced reference (use rivet --help for everyday commands):
87
+ Feature/work lifecycle IDs may also be passed as --run=<id> or --run <id>.
88
+ Use exactly one selector form; project/version/digest requirements remain explicit.
89
+
90
+ Usage:
91
+ rivet delivery prepare|status|refresh|reconcile|recover [--run=<id>] [--project=<path>] [--json]
92
+ rivet delivery tracker-status [--run=<id>] [--provider=<id>] [--project=<path>] [--json]
93
+ rivet delivery review-update --title=<text> --body=<text> [--run=<id>] [--provider=<id>] [--project=<path>]
94
+ rivet delivery tracker-transition [--run=<id>] [--provider=<id>] [--project=<path>]
95
+ rivet delivery tracker-update [--run=<id>] [--provider=<id>] [--project=<path>]
96
+ rivet delivery deploy [--run=<id>] [--project=<path>]
97
+ rivet delivery publish [--run=<id>] [--provider=<id>] [--project=<path>]
98
+ rivet delivery review [--project=<path>] [--run=<id>] [--provider=<id>]
99
+ rivet delivery merge [--run=<id>] [--provider=<id>] [--method=merge|squash|rebase] [--project=<path>]
100
+ rivet repositories inspect [--review=<number>] [--remote=<name>] [--provider=<id>] [--project=<path>] [--json]
101
+ rivet integrations setup [--project=<path>] Guide local read-only provider configuration
102
+ rivet integrations list|check [--project=<path>] [--host-inventory-json=<json>] [--json]
103
+ rivet models role --roles=<file> --role=<name> [--json]
104
+ rivet models delegate "prompt" --roles=<file> --role=<name> [--project=<path>]
105
+ rivet models delegate "prompt" --profile=<file> Approve one text-only model request
106
+ rivet models list [--json] List model adapters and implementation status
107
+ rivet models check --profile=<file> [--json] Validate a model profile without calling a model
108
+ rivet install Interactive — pick which skills to install (project)
109
+ rivet install --all Install all skills (project)
110
+ rivet setup [--project=<path>|--global] [--remote=<name>] [--target=claude|codex|both] [--checks-json='<json>'] [--dependencies-json='<json>'] [--write] [--json]
111
+ Project checks are exact argv arrays; unknown projects prompt with --write
112
+ rivet run "task" [--harness=claude|codex] [--project=<path>] [--details]
113
+ rivet task recover [--project=<path>] [--run=<id>]
114
+ rivet task status [--project=<path>] [--run=<id>]
115
+ rivet task start [--project=<path>] [--run=<id>]
116
+ rivet task approve [--project=<path>] [--run=<id>]
117
+ rivet task resume [--project=<path>] [--run=<id>]
118
+ rivet task deps [--project=<path>] [--run=<id>]
119
+ rivet protocols add <slug> [--from=<path>] [--project=<path>] [--json]
120
+ rivet protocols import <slug> --from=<path> [--project=<path>] [--json]
121
+ rivet protocols validate [<slug>] [--project=<path>] [--json]
122
+ rivet protocols find <query> [--include-drafts] [--include-retired] [--project=<path>] [--json]
123
+ rivet protocols show <slug> [--include-drafts] [--include-retired] [--expected-revision=<n> --expected-digest=<digest>] [--project=<path>] [--json]
124
+ rivet protocols retire <slug> --expected-revision=<n> [--project=<path>] [--json]
125
+ rivet protocols update <slug> --from=<path> --expected-revision=<n> [--publish] [--project=<path>] [--json]
126
+ rivet work propose --project=<path> (--request=<file>|--request-text=<text>|--ticket=<id>|--host-context-json=<json>) (--decomposition=<file>|--decomposition-json=<json>) [--tracker=jira|linear] [--acceptance-criteria=<text>] [--json]
127
+ rivet work prepare <run-id> --project=<path> --expected-version=<n> [--json]
128
+ rivet work next <run-id> --project=<path> --expected-runtime-version=<n> [--json]
129
+ rivet work submit <run-id> --project=<path> --expected-runtime-version=<n> (--action=<file>|--action-json=<json>) (--result=<file>|--result-json=<json>) [--json]
130
+ rivet work verify <run-id> --project=<path> --expected-version=<n> --expected-runtime-version=<n> [--json]
131
+ rivet work recover <run-id> --project=<path> [--json]
132
+ rivet work status <run-id> --project=<path> [--json]
133
+ rivet install --project-runtime [--project=<path>] [--target=both|claude|codex] [--json] Pin a private project runtime and entry skills
134
+ rivet uninstall --project-runtime [--project=<path>] [--target=both|claude|codex] [--json] Remove owned project reference/skills; retain cache
135
+ rivet install --minimal [--project=<path>|--global] [--target=claude|codex|both] [--json]
136
+ rivet uninstall --minimal [--project=<path>|--global] [--target=claude|codex|both] [--json]
137
+ rivet install --global Interactive — pick which skills to install (global)
138
+ rivet install --all --global Install all skills globally
139
+ rivet install --target=codex Install for Codex only
140
+ rivet install --target=claude Install for Claude only
141
+ rivet install --target=both Install for both
142
+ rivet install --codex Shortcut for --target=codex
143
+ rivet install --claude Shortcut for --target=claude
144
+ rivet uninstall Interactive — pick which skills to uninstall (project)
145
+ rivet uninstall --all Uninstall all skills (project)
146
+ rivet uninstall --global Interactive — pick which skills to uninstall (global)
147
+ rivet uninstall --all --global Uninstall all skills globally
148
+ rivet uninstall --target=codex Uninstall from Codex only
149
+ rivet uninstall --target=claude Uninstall from Claude only
150
+ rivet uninstall --target=both Uninstall from both
151
+ rivet init Copy governance rule templates to .claude/ in current project
152
+ rivet init --project <path> [--checks-json='<json>'] [--dependencies-json='<json>'] Preview detected project configuration
153
+ rivet init --project <path> --write [--overwrite] [--remote=<name>] [--checks-json='<json>'] [--dependencies-json='<json>']
154
+ rivet doctor [--project <path>] [--json]
155
+ rivet support [--project=<path>] [--probe-harnesses] [--save] [--json]
156
+ rivet preflight [--project <path>] [--mode=host|orchestration] [--json]
157
+ rivet verify [--json]
158
+ rivet evidence [--json]
159
+ rivet feature propose --project=<path> (--request=<file>|--request-text=<text>|--ticket=<id>) [--tracker=jira|linear] [--acceptance-criteria=<text>] [--client=claude|codex] [--json]
160
+ rivet feature start <run-id> --project=<path> --expected-version=<n> --proposal-digest=<sha256> [--json]
161
+ rivet feature run --project=<path> (--request=<file>|--request-text=<text>|--ticket=<id>) [--tracker=jira|linear] [--acceptance-criteria=<text>] [--client=claude|codex]
162
+ rivet feature status <run-id> --project=<path> [--json]
163
+ rivet feature resume <run-id> --project=<path> --expected-version=<n> [--json]
164
+ rivet feature cancel <run-id> --project=<path> --expected-version=<n> [--json]
165
+ rivet status <instance> [--fixture=<path>] [--port=<n>] [--json]
166
+ rivet goals status <instance> [--json]
167
+ rivet goals events <instance> [--limit=<n>] [--json]
168
+ rivet orchestrate run <instance> --expected-version=<n> [--json]
169
+ rivet orchestrate watch <instance> --expected-version=<n> --interval-ms=<n> --max-ticks=<n> --deadline-ms=<n> [--json]
170
+ `;
171
+
172
+ async function defaultConfirmOverwrite() {
173
+ const readline = createInterface({ input: process.stdin, output: process.stdout });
174
+ let timer;
175
+ try {
176
+ const answer = await Promise.race([
177
+ readline.question('Replace all four existing .rivet configuration files? [y/N] '),
178
+ new Promise(resolvePromise => {
179
+ timer = setTimeout(() => resolvePromise(''), CONFIRMATION_TIMEOUT_MS);
180
+ }),
181
+ ]);
182
+ return /^(?:y|yes)$/i.test(String(answer).trim());
183
+ } catch {
184
+ return false;
185
+ } finally {
186
+ clearTimeout(timer);
187
+ readline.close();
188
+ }
189
+ }
190
+
191
+ async function defaultConfirmFeatureActivation(_proposal, options = {}) {
192
+ return confirmTaskAction('Start this task? [y/N] ', {signal: options.signal});
193
+ }
194
+
195
+ async function defaultConfirmTaskApplication(_preview, options = {}) {
196
+ return confirmTaskAction('Apply this verified commit to the local branch shown above? [y/N] ', {signal: options.signal});
197
+ }
198
+
199
+ async function defaultConfirmModelDelegation(_preview, options = {}) {
200
+ if (options.signal?.aborted) return false;
201
+ const readline = createInterface({ input: process.stdin, output: process.stdout });
202
+ const abort = () => readline.close();
203
+ options.signal?.addEventListener('abort', abort, { once: true });
204
+ try {
205
+ const answer = await readline.question('Send this exact prompt to the destination above? [y/N] ', { signal: options.signal });
206
+ return /^(?:y|yes)$/i.test(String(answer).trim());
207
+ } catch { return false; }
208
+ finally { options.signal?.removeEventListener('abort', abort); readline.close(); }
209
+ }
210
+
211
+ async function defaultConfirmDependencyInstall(_plan, options = {}) {
212
+ if (options.signal?.aborted) return false;
213
+ const readline = createInterface({ input: process.stdin, output: process.stdout });
214
+ let timer;
215
+ const abort = () => readline.close();
216
+ options.signal?.addEventListener('abort', abort, { once: true });
217
+ try {
218
+ const answer = await Promise.race([
219
+ readline.question('Install these dependencies in the isolated checkout? [y/N] '),
220
+ new Promise(resolvePromise => { timer = setTimeout(() => resolvePromise(''), DEPENDENCY_CONFIRMATION_TIMEOUT_MS); }),
221
+ ]);
222
+ return /^(?:y|yes)$/i.test(String(answer).trim());
223
+ } catch { return false; }
224
+ finally { clearTimeout(timer); options.signal?.removeEventListener('abort', abort); readline.close(); }
225
+ }
226
+
227
+ async function defaultConfirmDelivery(preview) {
228
+ const readline = createInterface({ input: process.stdin, output: process.stdout });
229
+ let timer;
230
+ try {
231
+ const answer = await Promise.race([
232
+ readline.question(preview?.proposal?.action === 'branch-publish' ? 'Publish this exact commit to the new branch shown above? [y/N] ' : preview?.proposal?.action === 'review-update' ? 'Apply this exact title and body update? [y/N] ' : preview?.proposal?.action === 'review-request' ? 'Create this exact review request? [y/N] ' : preview?.proposal?.action === 'tracker-transition' ? 'Apply this exact tracker status transition? [y/N] ' : preview?.proposal?.action === 'tracker-update' ? 'Post this exact delivery summary to the ticket shown above? [y/N] ' : preview?.proposal?.action === 'deploy' ? 'Deploy this exact commit to the environment shown above? [y/N] ' : 'Merge this exact commit using the method shown above? [y/N] '),
233
+ new Promise(resolvePromise => { timer = setTimeout(() => resolvePromise(''), CONFIRMATION_TIMEOUT_MS); }),
234
+ ]);
235
+ return /^(?:y|yes)$/i.test(String(answer).trim());
236
+ } catch { return false; }
237
+ finally { clearTimeout(timer); readline.close(); }
238
+ }
239
+
240
+ async function defaultSelectTrackerDestination(choices) {
241
+ const readline = createInterface({ input: process.stdin, output: process.stdout });
242
+ let timer;
243
+ try {
244
+ const answer = String(await Promise.race([
245
+ readline.question('Choose a destination number (blank to cancel): '),
246
+ new Promise(resolve => { timer = setTimeout(() => resolve(''), CONFIRMATION_TIMEOUT_MS); }),
247
+ ])).trim();
248
+ const index = /^[1-9][0-9]*$/.test(answer) ? Number(answer)-1 : -1;
249
+ return Number.isSafeInteger(index) && index >= 0 && index < choices.length ? index : null;
250
+ } catch { return null; } finally { clearTimeout(timer); readline.close(); }
251
+ }
252
+
253
+ function resolveDependencies(overrides = {}) {
254
+ return {
255
+ reportFailure: overrides.reportFailure === false ? null : overrides.reportFailure ?? saveFailureReport,
256
+ fs: overrides.fs ?? filesystem,
257
+ prompt: overrides.prompt ?? checkbox,
258
+ separator: overrides.separator ?? (label => new Separator(label)),
259
+ env: overrides.env ?? process.env,
260
+ cwd: overrides.cwd ?? (() => process.cwd()),
261
+ home: overrides.home ?? homedir,
262
+ output: overrides.output ?? createOutput(),
263
+ fetch: overrides.fetch ?? globalThis.fetch,
264
+ models: overrides.models,
265
+ support: overrides.support,
266
+ confirmModelDelegation: overrides.confirmModelDelegation ?? defaultConfirmModelDelegation,
267
+ selectTrackerDestination: overrides.selectTrackerDestination ?? defaultSelectTrackerDestination,
268
+ confirmDelivery: overrides.confirmDelivery ?? defaultConfirmDelivery,
269
+ delivery: overrides.delivery,
270
+ confirmOverwrite: overrides.confirmOverwrite ?? defaultConfirmOverwrite,
271
+ confirmFeatureActivation: overrides.confirmFeatureActivation ?? defaultConfirmFeatureActivation,
272
+ confirmDependencyInstall: overrides.confirmDependencyInstall ?? defaultConfirmDependencyInstall,
273
+ setupRemotePrompt: overrides.setupRemotePrompt,
274
+ projectChecksPrompt: overrides.projectChecksPrompt,
275
+ harnessChoicePrompt: overrides.harnessChoicePrompt,
276
+ taskApprovalPrompt: overrides.taskApprovalPrompt ?? selectTaskOption,
277
+ taskSelectionPrompt: overrides.taskSelectionPrompt ?? selectTaskOption,
278
+ confirmTaskApplication: overrides.confirmTaskApplication ?? defaultConfirmTaskApplication,
279
+ terminalIsInteractive: overrides.terminalIsInteractive ?? (() => process.stdin.isTTY === true && process.stdout.isTTY === true),
280
+ harnesses: overrides.harnesses,
281
+ packageRoot: overrides.packageRoot ?? PACKAGE_ROOT,
282
+ maxJsonOutputBytes: overrides.maxJsonOutputBytes ?? MAX_JSON_OUTPUT_BYTES,
283
+ maxUpdateResponseBytes: overrides.maxUpdateResponseBytes,
284
+ updateCheckTimeoutMs: overrides.updateCheckTimeoutMs,
285
+ orchestration: overrides.orchestration,
286
+ evidence: overrides.evidence,
287
+ quality: overrides.quality,
288
+ feature: overrides.feature,
289
+ work: overrides.work,
290
+ status: overrides.status,
291
+ runGit: overrides.runGit,
292
+ setup: overrides.setup,
293
+ integrationHost: overrides.integrationHost,
294
+ integrationSetupPrompt: overrides.integrationSetupPrompt ?? defaultIntegrationSetupPrompt,
295
+ repositories: overrides.repositories,
296
+ resolveCommandExecutable: overrides.resolveCommandExecutable,
297
+ commands: {
298
+ doctor,
299
+ support: supportCommand,
300
+ evidence: evidenceCommand,
301
+ feature: featureCommand,
302
+ goals: goalsCommand,
303
+ init,
304
+ install,
305
+ models: modelsCommand,
306
+ integrations: integrationsCommand,
307
+ repositories: repositoriesCommand,
308
+ delivery: deliveryCommand,
309
+ setup: setupCommand,
310
+ orchestrate: orchestrateCommand,
311
+ preflight,
312
+ protocols: protocolsCommand,
313
+ run: humanRunCommand,
314
+ task: humanTaskCommand,
315
+ status: statusCommand,
316
+ uninstall,
317
+ verify: verifyCommand,
318
+ work: workCommand,
319
+ ...overrides.commands,
320
+ },
321
+ };
322
+ }
323
+
324
+ function emitBoundaryError(dependencies, error, json) {
325
+ if (!json) return emitCliError(dependencies.output, error);
326
+
327
+ const boundary = createJsonOutputBoundary(dependencies.maxJsonOutputBytes);
328
+ try {
329
+ const exitCode = emitCliError(boundary.output, error, { json: true });
330
+ boundary.commit(dependencies.output, exitCode);
331
+ return exitCode;
332
+ } catch {
333
+ const fallback = createJsonOutputBoundary(dependencies.maxJsonOutputBytes);
334
+ const exitCode = emitCliError(
335
+ fallback.output,
336
+ new CliError('Unexpected rivet failure.', 'INTERNAL_ERROR'),
337
+ { json: true },
338
+ );
339
+ fallback.commit(dependencies.output, exitCode);
340
+ return exitCode;
341
+ }
342
+ }
343
+
344
+ async function legacyInit(_parsed, dependencies) {
345
+ const { cwd, fs, output, packageRoot } = dependencies;
346
+ const root = findProjectRoot(cwd(), fs);
347
+ if (!root) {
348
+ throw new CliError('Could not find project root (no .git or package.json found).', 'INVALID_INPUT');
349
+ }
350
+
351
+ const governanceSource = join(packageRoot, 'dist', 'governance');
352
+ const governanceGuard = createMutationGuard(root, join(root, '.claude'), fs);
353
+ const claudeDirectory = governanceGuard.targetDir;
354
+ if (!fs.existsSync(governanceSource)) {
355
+ throw new CliError(
356
+ 'dist/governance/ not found. The package may be corrupted.',
357
+ 'MISSING_CONFIGURATION',
358
+ );
359
+ }
360
+
361
+ let governanceIdentity;
362
+ try {
363
+ governanceGuard.assertPath(claudeDirectory);
364
+ governanceIdentity = ensureContainedDirectory(governanceGuard, fs);
365
+ governanceGuard.assertPath(claudeDirectory);
366
+ } catch (error) {
367
+ if (error instanceof CliError) throw error;
368
+ throw new CliError('Could not create the Claude governance directory.', 'REPOSITORY_CONFLICT', {
369
+ cause: error,
370
+ });
371
+ }
372
+ let files;
373
+ try {
374
+ files = fs.readdirSync(governanceSource).filter(file => file.endsWith('.md'));
375
+ } catch (error) {
376
+ throw new CliError('Could not read governance distribution data.', 'MISSING_CONFIGURATION', {
377
+ cause: error,
378
+ });
379
+ }
380
+ const copied = [];
381
+ const skipped = [];
382
+ for (const file of files) {
383
+ const destination = join(claudeDirectory, file);
384
+ if (fs.existsSync(destination)) {
385
+ skipped.push(file);
386
+ } else {
387
+ try {
388
+ governanceGuard.assertPath(destination);
389
+ withPinnedTargetDirectory(claudeDirectory, governanceIdentity, fs, () => {
390
+ const destinationStatus = fs.lstatSync(file, { throwIfNoEntry: false });
391
+ if (destinationStatus?.isSymbolicLink()) {
392
+ throw new CliError('Target path contains a symbolic link.', 'REPOSITORY_CONFLICT');
393
+ }
394
+ if (destinationStatus) {
395
+ throw new CliError('Governance destination changed during validation.', 'REPOSITORY_CONFLICT');
396
+ }
397
+ copyFileIntoPinnedDirectory(join(governanceSource, file), file, fs);
398
+ });
399
+ governanceGuard.assertPath(destination);
400
+ } catch (error) {
401
+ if (error instanceof CliError) throw error;
402
+ throw new CliError(`Failed to copy governance template '${file}'.`, 'REPOSITORY_CONFLICT', {
403
+ cause: error,
404
+ });
405
+ }
406
+ copied.push(file);
407
+ }
408
+ }
409
+ if (copied.length > 0) {
410
+ output.log(`\nCopied to .claude/:\n${copied.map(file => ` ${file}`).join('\n')}`);
411
+ }
412
+ if (skipped.length > 0) {
413
+ output.log(`\nSkipped (already exist):\n${skipped.map(file => ` ${file}`).join('\n')}`);
414
+ }
415
+ output.log('\nCustomize these files for your project before running /pre-push.');
416
+ await checkForUpdate(dependencies);
417
+ return EXIT_CODES.SUCCESS;
418
+ }
419
+
420
+ function observeCall(callback, args) {
421
+ return new Promise(resolvePromise => {
422
+ let result;
423
+ try { result = reflectApply(callback, undefined, args); }
424
+ catch { resolvePromise(); return; }
425
+ try { reflectApply(promiseThen, result, [() => resolvePromise(), () => resolvePromise()]); }
426
+ catch { resolvePromise(); }
427
+ });
428
+ }
429
+
430
+ function followAbortSignal(signal, controller) {
431
+ if (signal == null) return () => {};
432
+ const abort = () => {
433
+ try { reflectApply(abortControllerAbort, controller, []); } catch { /* internal cancellation is best effort */ }
434
+ };
435
+ try {
436
+ if (reflectApply(abortSignalAborted, signal, [])) {
437
+ abort();
438
+ return () => {};
439
+ }
440
+ reflectApply(addEventListener, signal, ['abort', abort, { once: true }]);
441
+ } catch { return () => {}; }
442
+ let listening = true;
443
+ return () => {
444
+ if (!listening) return;
445
+ listening = false;
446
+ try { reflectApply(removeEventListener, signal, ['abort', abort]); } catch { /* cleanup is best effort */ }
447
+ };
448
+ }
449
+
450
+ function createStatusJsonLifecycle(wait, signal, close) {
451
+ if (typeof wait !== 'function' || typeof close !== 'function') throw new Error('Invalid status JSON lifecycle.');
452
+ const controller = new AbortController();
453
+ const stopFollowing = followAbortSignal(signal, controller);
454
+ const stopped = observeCall(wait, [controller.signal]);
455
+ try { reflectApply(promiseThen, stopped, [stopFollowing, stopFollowing]); } catch { stopFollowing(); }
456
+ let closing = null;
457
+ let cancelled = false;
458
+ return Object.freeze({
459
+ stopped,
460
+ cancel() {
461
+ if (cancelled) return;
462
+ cancelled = true;
463
+ stopFollowing();
464
+ try { reflectApply(abortControllerAbort, controller, []); } catch { /* internal cancellation is best effort */ }
465
+ },
466
+ close() {
467
+ if (!closing) closing = observeCall(close, []);
468
+ return closing;
469
+ },
470
+ });
471
+ }
472
+
473
+ async function publishStatusJson(jsonBoundary, output, exitCode, lifecycle) {
474
+ let signalOutputFailure;
475
+ const outputFailed = new Promise(resolvePromise => { signalOutputFailure = resolvePromise; });
476
+ const unsubscribe = observeOutputErrors(output, () => signalOutputFailure());
477
+ if (typeof unsubscribe !== 'function') {
478
+ lifecycle.cancel();
479
+ await lifecycle.close();
480
+ throw new Error('Status JSON output is not observable.');
481
+ }
482
+ let committed = false;
483
+ try {
484
+ try {
485
+ jsonBoundary.commit(output, exitCode);
486
+ committed = true;
487
+ } catch { /* the installed observer owns publication failure cleanup */ }
488
+ if (committed) await Promise.race([lifecycle.stopped, outputFailed]);
489
+ } finally {
490
+ lifecycle.cancel();
491
+ unsubscribe();
492
+ await lifecycle.close();
493
+ }
494
+ }
495
+
496
+ async function executeMain(argv, dependencies, failure) {
497
+ const json = Array.isArray(argv) && argv.includes('--json');
498
+ let statusJsonLifecycle = null;
499
+
500
+ try {
501
+ if (Array.isArray(argv) && (argv.length === 1 || (argv.length === 2 && argv[1] === '--advanced')) && ['--help', '-h', 'help'].includes(argv[0])) {
502
+ dependencies.output.log(argv.length === 2 ? USAGE : BASIC_USAGE);
503
+ return EXIT_CODES.SUCCESS;
504
+ }
505
+ const parsed = parseArgs(argv);
506
+ if (parsed.command === null) {
507
+ dependencies.output.log(BASIC_USAGE);
508
+ return EXIT_CODES.INVALID_INPUT;
509
+ }
510
+
511
+ const explicitV2Init = parsed.command === 'init' && Object.keys(parsed.flags).length > 0;
512
+ const handler = parsed.command === 'init' && !explicitV2Init
513
+ ? legacyInit
514
+ : dependencies.commands[parsed.command];
515
+ if (!handler) {
516
+ throw new CliError(`Command '${parsed.command}' is not implemented.`, 'INVALID_INPUT');
517
+ }
518
+ if (parsed.flags.json && LEGACY_COMMANDS.has(parsed.command) && parsed.flags.minimal !== true && parsed.flags['project-runtime'] !== true) {
519
+ throw new CliError(
520
+ `JSON output is not available for legacy command '${parsed.command}'.`,
521
+ 'INVALID_INPUT',
522
+ );
523
+ }
524
+
525
+ const jsonBoundary = parsed.flags.json
526
+ ? createJsonOutputBoundary(dependencies.maxJsonOutputBytes)
527
+ : null;
528
+ const builtinStatusJson = Boolean(jsonBoundary && parsed.command === 'status' && handler === statusCommand);
529
+ const commandDependencies = jsonBoundary ? {
530
+ ...dependencies,
531
+ output: jsonBoundary.output,
532
+ ...(builtinStatusJson ? {
533
+ registerStatusJsonLifecycle(wait, signal, close) {
534
+ if (statusJsonLifecycle) throw new Error('Status JSON lifecycle is already registered.');
535
+ statusJsonLifecycle = createStatusJsonLifecycle(wait, signal, close);
536
+ },
537
+ } : {}),
538
+ } : dependencies;
539
+ const exitCode = await handler(parsed, commandDependencies);
540
+ if (!Object.values(EXIT_CODES).includes(exitCode)) {
541
+ throw new Error('Command handler returned an invalid exit code');
542
+ }
543
+ if (jsonBoundary) {
544
+ if (builtinStatusJson) {
545
+ if (!statusJsonLifecycle) throw new Error('Status JSON lifecycle was not registered.');
546
+ await publishStatusJson(jsonBoundary, dependencies.output, exitCode, statusJsonLifecycle);
547
+ } else jsonBoundary.commit(dependencies.output, exitCode);
548
+ }
549
+ return exitCode;
550
+ } catch (error) {
551
+ failure.causeCode = error?.cause?.code ?? error?.code;
552
+ if (statusJsonLifecycle) {
553
+ statusJsonLifecycle.cancel();
554
+ await statusJsonLifecycle.close();
555
+ }
556
+ if (error instanceof ArgumentError) {
557
+ if (!json && error.message.startsWith('Unknown command')) {
558
+ dependencies.output.log(BASIC_USAGE);
559
+ return EXIT_CODES.INVALID_INPUT;
560
+ }
561
+ return emitBoundaryError(
562
+ dependencies,
563
+ new CliError(error.message, 'INVALID_INPUT'),
564
+ json,
565
+ );
566
+ }
567
+ return emitBoundaryError(dependencies, error, json);
568
+ }
569
+ }
570
+
571
+ /** Automatic reports are human-terminal diagnostics; JSON contracts stay unchanged. */
572
+ export async function main(argv, overrides = {}) {
573
+ const dependencies = resolveDependencies(overrides);
574
+ const failure = {};
575
+ const command = Array.isArray(argv) ? argv[0] : null;
576
+ const subcommand = ['task','feature','work','delivery','models','integrations','protocols','repositories','goals','orchestrate','worktrees'].includes(command) ? argv[1] : null;
577
+ const json = Array.isArray(argv) && argv.includes('--json');
578
+ async function report(exitCode) {
579
+ if (json || exitCode === EXIT_CODES.SUCCESS) return;
580
+ const code = Object.entries(EXIT_CODES).find(([,value])=>value===exitCode)?.[0] ?? 'INTERNAL_ERROR';
581
+ let saved = null;
582
+ try { saved = await dependencies.reportFailure?.({command,subcommand,code,exitCode,causeCode:failure.causeCode}); } catch { /* diagnostics must preserve the original failure */ }
583
+ try {
584
+ dependencies.output.error(`Next: ${failureGuidance(code, command)}`);
585
+ if (saved?.path) {
586
+ dependencies.output.error(`Diagnostic report: ${saved.path}`);
587
+ dependencies.output.error('Review the file, then attach it with reproduction steps at https://github.com/Agilno-Tech/rivet/issues/new. Nothing was uploaded.');
588
+ } else if (dependencies.reportFailure) dependencies.output.error('A diagnostic report could not be saved. You can try rivet support --save from your project.');
589
+ } catch { /* broken output does not change the command result */ }
590
+ }
591
+ let exitCode;
592
+ try { exitCode = await executeMain(argv, dependencies, failure); }
593
+ catch (error) { await report(EXIT_CODES.INTERNAL_ERROR); throw error; }
594
+ await report(exitCode);
595
+ return exitCode;
596
+ }