@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.
- package/LICENSE +202 -0
- package/NOTICE +6 -0
- package/README.md +59 -0
- package/bin/cli.js +42 -0
- package/dist/agents/backend-django-agent/SKILL.md +35 -0
- package/dist/agents/backend-nestjs-agent/SKILL.md +36 -0
- package/dist/agents/boss-agent/SKILL.md +28 -0
- package/dist/agents/bounded-worker/SKILL.md +28 -0
- package/dist/agents/data-performance-agent/SKILL.md +32 -0
- package/dist/agents/delivery-ticketing-agent/SKILL.md +36 -0
- package/dist/agents/devops-agent/SKILL.md +34 -0
- package/dist/agents/engineering-manager/SKILL.md +28 -0
- package/dist/agents/frontend-nextjs-agent/SKILL.md +34 -0
- package/dist/agents/frontend-web-agent/SKILL.md +31 -0
- package/dist/agents/incident-response-agent/SKILL.md +42 -0
- package/dist/agents/jest-agent/SKILL.md +77 -0
- package/dist/agents/mobile-agent/SKILL.md +32 -0
- package/dist/agents/playwright-agent/SKILL.md +54 -0
- package/dist/agents/product-design-manager/SKILL.md +27 -0
- package/dist/agents/qa-agent/SKILL.md +29 -0
- package/dist/agents/quality-manager/SKILL.md +28 -0
- package/dist/agents/vitest-agent/SKILL.md +77 -0
- package/dist/governance/pre-push-rules.md +75 -0
- package/dist/governance/prompt-hygiene.md +22 -0
- package/dist/governance/review-checklist.md +24 -0
- package/dist/governance/safety-and-data.md +27 -0
- package/dist/governance/usage-rules.md +21 -0
- package/dist/mandatory/address-pr-feedback/SKILL.md +196 -0
- package/dist/mandatory/agentic-goal/SKILL.md +42 -0
- package/dist/mandatory/agentic-status/SKILL.md +74 -0
- package/dist/mandatory/apply-design/SKILL.md +228 -0
- package/dist/mandatory/check-ac/SKILL.md +124 -0
- package/dist/mandatory/create-pr-and-commit/SKILL.md +304 -0
- package/dist/mandatory/design/SKILL.md +312 -0
- package/dist/mandatory/feature-workflow/SKILL.md +87 -0
- package/dist/mandatory/hotfix/SKILL.md +195 -0
- package/dist/mandatory/pre-push/SKILL.md +272 -0
- package/dist/mandatory/project-context/SKILL.md +180 -0
- package/dist/mandatory/release-docs/SKILL.md +191 -0
- package/dist/mandatory/review-pr/SKILL.md +323 -0
- package/dist/mandatory/security-review/SKILL.md +157 -0
- package/dist/skills/api-contract/SKILL.md +77 -0
- package/dist/skills/backend-django/SKILL.md +27 -0
- package/dist/skills/backend-nestjs/SKILL.md +65 -0
- package/dist/skills/bug-ticket-creation/SKILL.md +43 -0
- package/dist/skills/cloudwatch-troubleshooting/SKILL.md +73 -0
- package/dist/skills/database-migration/SKILL.md +97 -0
- package/dist/skills/debugging/SKILL.md +32 -0
- package/dist/skills/devops-infra/SKILL.md +26 -0
- package/dist/skills/documentation/SKILL.md +24 -0
- package/dist/skills/frontend-nextjs/SKILL.md +27 -0
- package/dist/skills/incident-postmortem/SKILL.md +38 -0
- package/dist/skills/kubernetes-troubleshooting/SKILL.md +71 -0
- package/dist/skills/mobile-react-native/SKILL.md +37 -0
- package/dist/skills/postgres-analytics/SKILL.md +29 -0
- package/dist/skills/product-jira-ticketing/SKILL.md +28 -0
- package/dist/skills/qa-bug-analysis/SKILL.md +27 -0
- package/dist/skills/refactoring/SKILL.md +32 -0
- package/dist/skills/sprint-planning/SKILL.md +32 -0
- package/dist/skills/testing-quality/SKILL.md +62 -0
- package/dist/v2/protocols/agent-orchestration.md +49 -0
- package/dist/v2/protocols/delivery.md +45 -0
- package/dist/v2/protocols/design-authority.md +29 -0
- package/dist/v2/protocols/goal-graph.md +44 -0
- package/dist/v2/protocols/pattern-first-development.md +29 -0
- package/dist/v2/protocols/qa-evidence.md +29 -0
- package/dist/v2/protocols/security.md +29 -0
- package/dist/v2/schemas/event.schema.json +86 -0
- package/dist/v2/schemas/evidence.schema.json +94 -0
- package/dist/v2/schemas/feature-decomposition.schema.json +48 -0
- package/dist/v2/schemas/feature-plan.schema.json +95 -0
- package/dist/v2/schemas/goal-graph.schema.json +61 -0
- package/dist/v2/schemas/integration.schema.json +119 -0
- package/dist/v2/schemas/orchestration.schema.json +69 -0
- package/dist/v2/schemas/project.schema.json +209 -0
- package/dist/v2/schemas/providers.schema.json +142 -0
- package/dist/v2/schemas/quality.schema.json +50 -0
- package/dist/v2/schemas/work-action.schema.json +44 -0
- package/dist/v2/schemas/work-request.schema.json +253 -0
- package/dist/v2/templates/evidence/qa-bundle.json +194 -0
- package/dist/v2/templates/github-actions/rivet-deploy.yml +98 -0
- package/dist/v2/templates/harness/SKILL.md +90 -0
- package/dist/v2/templates/project/.rivet/orchestration.yaml +42 -0
- package/dist/v2/templates/project/.rivet/project.yaml +14 -0
- package/dist/v2/templates/project/.rivet/providers.yaml +8 -0
- package/dist/v2/templates/project/.rivet/quality.yaml +16 -0
- package/package.json +58 -0
- package/protocols/agent-orchestration.md +49 -0
- package/protocols/delivery.md +45 -0
- package/protocols/design-authority.md +29 -0
- package/protocols/goal-graph.md +44 -0
- package/protocols/pattern-first-development.md +29 -0
- package/protocols/qa-evidence.md +29 -0
- package/protocols/security.md +29 -0
- package/schemas/event.schema.json +86 -0
- package/schemas/evidence.schema.json +94 -0
- package/schemas/feature-decomposition.schema.json +48 -0
- package/schemas/feature-plan.schema.json +95 -0
- package/schemas/goal-graph.schema.json +61 -0
- package/schemas/integration.schema.json +119 -0
- package/schemas/orchestration.schema.json +69 -0
- package/schemas/project.schema.json +209 -0
- package/schemas/providers.schema.json +142 -0
- package/schemas/quality.schema.json +50 -0
- package/schemas/work-action.schema.json +44 -0
- package/schemas/work-request.schema.json +253 -0
- package/src/adapters/confluence.js +138 -0
- package/src/adapters/contract.js +657 -0
- package/src/adapters/factory.js +122 -0
- package/src/adapters/figma.js +178 -0
- package/src/adapters/fixtures.js +183 -0
- package/src/adapters/github.js +314 -0
- package/src/adapters/http.js +704 -0
- package/src/adapters/jira.js +195 -0
- package/src/adapters/linear.js +171 -0
- package/src/adapters/node-transport.js +59 -0
- package/src/cli/integration-setup-prompt.js +32 -0
- package/src/cli/interrupt.js +25 -0
- package/src/cli/main.js +596 -0
- package/src/cli/output.js +174 -0
- package/src/cli/parse-args.js +246 -0
- package/src/cli/project-discovery.js +70 -0
- package/src/cli/task-confirmation.js +38 -0
- package/src/cli/task-presentation.js +22 -0
- package/src/clients/claude.js +214 -0
- package/src/clients/codex.js +180 -0
- package/src/clients/compatibility.js +23 -0
- package/src/clients/contract.js +224 -0
- package/src/clients/fake.js +170 -0
- package/src/clients/process-runner.js +657 -0
- package/src/clients/result-contract.js +78 -0
- package/src/commands/delivery-publish.js +80 -0
- package/src/commands/delivery-remote.js +230 -0
- package/src/commands/delivery-review-update.js +39 -0
- package/src/commands/delivery-tracker.js +94 -0
- package/src/commands/delivery-transition.js +79 -0
- package/src/commands/delivery.js +223 -0
- package/src/commands/dependency-approval.js +21 -0
- package/src/commands/doctor.js +191 -0
- package/src/commands/evidence.js +44 -0
- package/src/commands/feature.js +212 -0
- package/src/commands/goals.js +231 -0
- package/src/commands/human-run.js +208 -0
- package/src/commands/human-task.js +278 -0
- package/src/commands/init.js +848 -0
- package/src/commands/install.js +814 -0
- package/src/commands/integration-setup.js +65 -0
- package/src/commands/integrations.js +54 -0
- package/src/commands/models.js +158 -0
- package/src/commands/orchestrate.js +61 -0
- package/src/commands/preflight.js +125 -0
- package/src/commands/protocols.js +228 -0
- package/src/commands/repositories.js +77 -0
- package/src/commands/setup-remote.js +41 -0
- package/src/commands/setup.js +214 -0
- package/src/commands/status.js +224 -0
- package/src/commands/support.js +44 -0
- package/src/commands/task-completion.js +104 -0
- package/src/commands/uninstall.js +234 -0
- package/src/commands/verify.js +171 -0
- package/src/commands/work.js +220 -0
- package/src/commands/worktrees.js +52 -0
- package/src/config/command-readiness.js +218 -0
- package/src/config/commands.js +206 -0
- package/src/config/defaults.js +55 -0
- package/src/config/load.js +230 -0
- package/src/config/validate.js +560 -0
- package/src/delivery/bitbucket-review.js +123 -0
- package/src/delivery/branch-publication.js +23 -0
- package/src/delivery/contract.js +379 -0
- package/src/delivery/github-deployment.js +132 -0
- package/src/delivery/github-review.js +5 -0
- package/src/delivery/github.js +382 -0
- package/src/delivery/gitlab-review.js +5 -0
- package/src/delivery/gitlab.js +395 -0
- package/src/delivery/prepare.js +90 -0
- package/src/delivery/publication-process.js +33 -0
- package/src/delivery/publication-transport.js +112 -0
- package/src/delivery/review-request.js +184 -0
- package/src/delivery/review-update.js +74 -0
- package/src/delivery/service.js +400 -0
- package/src/delivery/store.js +76 -0
- package/src/delivery/tracker-target.js +51 -0
- package/src/delivery/tracker-transition.js +158 -0
- package/src/delivery/tracker.js +164 -0
- package/src/discovery/git.js +85 -0
- package/src/discovery/portable.js +108 -0
- package/src/discovery/project.js +345 -0
- package/src/discovery/tools.js +145 -0
- package/src/evaluations/approval.js +20 -0
- package/src/evaluations/cost-policy.js +20 -0
- package/src/evaluations/harness-attempt.js +113 -0
- package/src/evaluations/live-runner.js +55 -0
- package/src/evaluations/profile.js +28 -0
- package/src/evaluations/report.js +11 -0
- package/src/evaluations/text-attempt.js +18 -0
- package/src/evidence/checksum.js +87 -0
- package/src/evidence/collect.js +727 -0
- package/src/evidence/validate.js +354 -0
- package/src/feature/accepted-integration.js +46 -0
- package/src/feature/actions.js +37 -0
- package/src/feature/client-profile.js +56 -0
- package/src/feature/decomposition-contract.js +58 -0
- package/src/feature/host-execution.js +633 -0
- package/src/feature/host-lock-recovery.js +96 -0
- package/src/feature/host-run-lock.js +32 -0
- package/src/feature/local-approval.js +183 -0
- package/src/feature/plan-contract.js +215 -0
- package/src/feature/planner.js +253 -0
- package/src/feature/run-store.js +241 -0
- package/src/feature/runtime-bridge.js +840 -0
- package/src/feature/verification-report.js +168 -0
- package/src/feature/workflow.js +375 -0
- package/src/git/client.js +509 -0
- package/src/git/integration-worktree.js +153 -0
- package/src/git/reconcile.js +222 -0
- package/src/git/reservations.js +450 -0
- package/src/git/worktrees.js +478 -0
- package/src/graph/completion.js +189 -0
- package/src/graph/fixtures.js +116 -0
- package/src/graph/reducer.js +124 -0
- package/src/graph/scheduler.js +252 -0
- package/src/graph/validate.js +106 -0
- package/src/install/managed.js +579 -0
- package/src/install/project-reference.js +33 -0
- package/src/install/project-runtime.js +142 -0
- package/src/install/runtime-integrity.cjs +141 -0
- package/src/integrations/capabilities.js +69 -0
- package/src/integrations/host-observation.js +26 -0
- package/src/integrations/registry.js +56 -0
- package/src/models/delegate.js +102 -0
- package/src/models/profiles.js +53 -0
- package/src/models/protocols.js +208 -0
- package/src/models/registry.js +83 -0
- package/src/models/transport.js +59 -0
- package/src/policy/approvals.js +251 -0
- package/src/policy/authority.js +282 -0
- package/src/policy/budget.js +149 -0
- package/src/policy/command-bootstrap.js +219 -0
- package/src/policy/commands.js +803 -0
- package/src/prompts/launch-contract.js +43 -0
- package/src/prompts/planning-contract.js +92 -0
- package/src/protocols/presentation.js +53 -0
- package/src/protocols/project.js +289 -0
- package/src/quality/runner.js +497 -0
- package/src/quality/traceability.js +215 -0
- package/src/repositories/identity.js +59 -0
- package/src/repositories/index.js +2 -0
- package/src/repositories/provider.js +210 -0
- package/src/runtime/application.js +353 -0
- package/src/runtime/dependency-directory.js +33 -0
- package/src/runtime/harness-discovery.js +121 -0
- package/src/runtime/heartbeat.js +47 -0
- package/src/runtime/instance-store.js +112 -0
- package/src/runtime/orchestrator.js +1133 -0
- package/src/runtime/portable-dependencies.js +94 -0
- package/src/runtime/recovery.js +190 -0
- package/src/runtime/retry.js +54 -0
- package/src/runtime/supervisor.js +166 -0
- package/src/runtime/worktree-bootstrap.js +169 -0
- package/src/state/event-store.js +333 -0
- package/src/state/lock.js +266 -0
- package/src/state/paths.js +274 -0
- package/src/state/redact.js +106 -0
- package/src/state/snapshot-store.js +310 -0
- package/src/status/public/app.js +96 -0
- package/src/status/public/index.html +37 -0
- package/src/status/public/styles.css +50 -0
- package/src/status/server.js +323 -0
- package/src/status/view-model.js +356 -0
- package/src/support/bundle.js +195 -0
- package/src/support/failure-report.js +96 -0
- package/src/work-request/contract.js +250 -0
- package/src/work-request/host.js +78 -0
- package/src/work-request/local.js +163 -0
- package/src/work-request/tracker.js +105 -0
- package/templates/evidence/qa-bundle.json +194 -0
- package/templates/github-actions/rivet-deploy.yml +98 -0
- package/templates/harness/SKILL.md +90 -0
- package/templates/project/.rivet/orchestration.yaml +42 -0
- package/templates/project/.rivet/project.yaml +14 -0
- package/templates/project/.rivet/providers.yaml +8 -0
- package/templates/project/.rivet/quality.yaml +16 -0
package/src/cli/main.js
ADDED
|
@@ -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
|
+
}
|