@defrex/autobuild 0.8.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 +201 -0
- package/README.md +192 -0
- package/SPEC.md +2269 -0
- package/bin/ab-build-runner.ts +47 -0
- package/bin/ab-dev.ts +27 -0
- package/bin/ab-dispatch-kernel.ts +92 -0
- package/bin/ab-harvest-runner.ts +29 -0
- package/bin/ab-init-probe.ts +19 -0
- package/bin/ab-process-group-reaper.ts +32 -0
- package/bin/ab.ts +6 -0
- package/bin/agent/ab +3 -0
- package/docs/answering-blocked-builds.md +89 -0
- package/docs/architecture.md +726 -0
- package/docs/assets/headline-wide.png +0 -0
- package/docs/configuration.md +1623 -0
- package/docs/hosted-dispatcher-cutover-validation.md +178 -0
- package/docs/hosted-dispatcher.md +204 -0
- package/docs/mcp.md +119 -0
- package/docs/operator-api.md +186 -0
- package/docs/remote-store-protocol.md +972 -0
- package/docs/remote-ticket-protocol.md +79 -0
- package/docs/setup.md +289 -0
- package/docs/spec-standard.md +63 -0
- package/docs/ticket-dependencies.md +59 -0
- package/docs/vercel-sandbox-rollout-probe.md +7 -0
- package/package.json +135 -0
- package/packages/core/src/cli/args.ts +74 -0
- package/packages/core/src/cli/artifact.ts +182 -0
- package/packages/core/src/cli/binary.ts +198 -0
- package/packages/core/src/cli/build-control.ts +789 -0
- package/packages/core/src/cli/build-progress.ts +55 -0
- package/packages/core/src/cli/bulk-control.ts +385 -0
- package/packages/core/src/cli/context.ts +470 -0
- package/packages/core/src/cli/dashboard/actions.ts +59 -0
- package/packages/core/src/cli/dashboard/cells.ts +92 -0
- package/packages/core/src/cli/dashboard/composer.ts +230 -0
- package/packages/core/src/cli/dashboard/detail.ts +100 -0
- package/packages/core/src/cli/dashboard/frame-image.ts +373 -0
- package/packages/core/src/cli/dashboard/live.ts +152 -0
- package/packages/core/src/cli/dashboard/model.ts +1173 -0
- package/packages/core/src/cli/dashboard/poll.ts +196 -0
- package/packages/core/src/cli/dashboard/render.ts +1568 -0
- package/packages/core/src/cli/dashboard/selection.ts +66 -0
- package/packages/core/src/cli/dashboard/session-feed.ts +244 -0
- package/packages/core/src/cli/dashboard/session-view.ts +506 -0
- package/packages/core/src/cli/dashboard/transcript.ts +108 -0
- package/packages/core/src/cli/dev.ts +46 -0
- package/packages/core/src/cli/dispatch-frontend.ts +1045 -0
- package/packages/core/src/cli/dispatch-process.ts +259 -0
- package/packages/core/src/cli/dispatch.ts +3692 -0
- package/packages/core/src/cli/dotenv.ts +48 -0
- package/packages/core/src/cli/env.ts +206 -0
- package/packages/core/src/cli/harvest.ts +698 -0
- package/packages/core/src/cli/help.ts +713 -0
- package/packages/core/src/cli/init-agent.ts +106 -0
- package/packages/core/src/cli/init-validation.ts +583 -0
- package/packages/core/src/cli/init.ts +756 -0
- package/packages/core/src/cli/installation.ts +333 -0
- package/packages/core/src/cli/keyboard.ts +261 -0
- package/packages/core/src/cli/main.ts +1399 -0
- package/packages/core/src/cli/mcp.ts +279 -0
- package/packages/core/src/cli/models.ts +65 -0
- package/packages/core/src/cli/observe.ts +55 -0
- package/packages/core/src/cli/plugin.ts +227 -0
- package/packages/core/src/cli/pr-attachments.ts +138 -0
- package/packages/core/src/cli/pr-summary.ts +124 -0
- package/packages/core/src/cli/publication-settlement.ts +188 -0
- package/packages/core/src/cli/repo-state.ts +213 -0
- package/packages/core/src/cli/repository-status.ts +80 -0
- package/packages/core/src/cli/self-update.ts +443 -0
- package/packages/core/src/cli/status.ts +895 -0
- package/packages/core/src/cli/store-opening.contract.ts +289 -0
- package/packages/core/src/cli/store-opening.ts +167 -0
- package/packages/core/src/cli/store-ref.ts +33 -0
- package/packages/core/src/cli/terminal-restore.ts +174 -0
- package/packages/core/src/cli/terminal.ts +361 -0
- package/packages/core/src/cli/terminals.ts +995 -0
- package/packages/core/src/cli/testkit.ts +194 -0
- package/packages/core/src/cli/ticket.ts +484 -0
- package/packages/core/src/cli/upgrade-agent.ts +180 -0
- package/packages/core/src/cli/upgrade-commit.ts +468 -0
- package/packages/core/src/cli/upgrade-notice.ts +91 -0
- package/packages/core/src/cli/upgrade-progress.ts +110 -0
- package/packages/core/src/cli/upgrade.ts +888 -0
- package/packages/core/src/cli/wait.ts +587 -0
- package/packages/core/src/cli/watch.ts +932 -0
- package/packages/core/src/config/live.ts +255 -0
- package/packages/core/src/config/load.ts +98 -0
- package/packages/core/src/config/roles.ts +438 -0
- package/packages/core/src/config/schema.ts +774 -0
- package/packages/core/src/distribution.ts +24 -0
- package/packages/core/src/events/catalog.ts +201 -0
- package/packages/core/src/events/envelope.ts +59 -0
- package/packages/core/src/events/payloads.ts +618 -0
- package/packages/core/src/events/repository.ts +559 -0
- package/packages/core/src/events/sessions.ts +180 -0
- package/packages/core/src/harvest/schema.ts +147 -0
- package/packages/core/src/ids.ts +45 -0
- package/packages/core/src/integration/harness.ts +681 -0
- package/packages/core/src/kernel/auto-merge.ts +259 -0
- package/packages/core/src/kernel/converge.ts +117 -0
- package/packages/core/src/kernel/dispatch-settings.ts +60 -0
- package/packages/core/src/kernel/dispatch-status.ts +141 -0
- package/packages/core/src/kernel/engine.ts +1047 -0
- package/packages/core/src/kernel/harvest.ts +823 -0
- package/packages/core/src/kernel/origin.ts +69 -0
- package/packages/core/src/kernel/phases.ts +196 -0
- package/packages/core/src/kernel/plan-verify-selection.ts +105 -0
- package/packages/core/src/kernel/pr-attachments.ts +82 -0
- package/packages/core/src/kernel/reducer.ts +752 -0
- package/packages/core/src/kernel/stall.ts +155 -0
- package/packages/core/src/kernel/verify-applicability.ts +52 -0
- package/packages/core/src/markdown.ts +67 -0
- package/packages/core/src/ontology.ts +288 -0
- package/packages/core/src/open-map.ts +203 -0
- package/packages/core/src/operator/annotations.ts +187 -0
- package/packages/core/src/operator/client.ts +311 -0
- package/packages/core/src/operator/control.ts +117 -0
- package/packages/core/src/operator/index.ts +62 -0
- package/packages/core/src/operator/presentation.ts +22 -0
- package/packages/core/src/operator/protocol.ts +98 -0
- package/packages/core/src/operator/query.ts +201 -0
- package/packages/core/src/operator/registry.ts +1043 -0
- package/packages/core/src/operator/requests.ts +138 -0
- package/packages/core/src/operator/sandbox.ts +458 -0
- package/packages/core/src/operator/server.ts +616 -0
- package/packages/core/src/operator/sessions.ts +223 -0
- package/packages/core/src/operator/tickets.ts +177 -0
- package/packages/core/src/plugin-sdk/index.ts +174 -0
- package/packages/core/src/plugins/contract-entry.ts +74 -0
- package/packages/core/src/plugins/contract-env.ts +3 -0
- package/packages/core/src/plugins/load.ts +259 -0
- package/packages/core/src/plugins/manifest.ts +236 -0
- package/packages/core/src/plugins/registry.ts +274 -0
- package/packages/core/src/plugins/runtimes.ts +75 -0
- package/packages/core/src/ports/forge/contract.ts +258 -0
- package/packages/core/src/ports/forge/create.ts +74 -0
- package/packages/core/src/ports/forge/fake.ts +488 -0
- package/packages/core/src/ports/forge/github-pr-attachments.ts +351 -0
- package/packages/core/src/ports/forge/github-transport.ts +352 -0
- package/packages/core/src/ports/forge/github.ts +1162 -0
- package/packages/core/src/ports/forge/local-git.ts +568 -0
- package/packages/core/src/ports/runner/claude.ts +873 -0
- package/packages/core/src/ports/runner/cli-stream.ts +90 -0
- package/packages/core/src/ports/runner/codex.ts +873 -0
- package/packages/core/src/ports/runner/contract.ts +492 -0
- package/packages/core/src/ports/runner/fake.ts +213 -0
- package/packages/core/src/ports/runner/json-record.ts +2 -0
- package/packages/core/src/ports/runner/live-contract-fixture.ts +176 -0
- package/packages/core/src/ports/runner/one-shot.ts +29 -0
- package/packages/core/src/ports/runner/pi-bridge-core.ts +136 -0
- package/packages/core/src/ports/runner/pi-bridge.js +6 -0
- package/packages/core/src/ports/runner/pi-rpc.ts +454 -0
- package/packages/core/src/ports/runner/pi.ts +617 -0
- package/packages/core/src/ports/runner/production.ts +74 -0
- package/packages/core/src/ports/runner/provider-error.ts +121 -0
- package/packages/core/src/ports/runner/routing.ts +234 -0
- package/packages/core/src/ports/runner/runtime.ts +214 -0
- package/packages/core/src/ports/runner/session-env.ts +34 -0
- package/packages/core/src/ports/runner/stream-parts.ts +103 -0
- package/packages/core/src/ports/tickets/contract.ts +570 -0
- package/packages/core/src/ports/tickets/create.ts +135 -0
- package/packages/core/src/ports/tickets/fake.ts +215 -0
- package/packages/core/src/ports/tickets/file.ts +559 -0
- package/packages/core/src/ports/tickets/linear.ts +811 -0
- package/packages/core/src/ports/tickets/operations.ts +161 -0
- package/packages/core/src/ports/tickets/remote-index.ts +13 -0
- package/packages/core/src/ports/tickets/remote-protocol.ts +80 -0
- package/packages/core/src/ports/tickets/remote-server.ts +185 -0
- package/packages/core/src/ports/tickets/remote.ts +130 -0
- package/packages/core/src/ports/tickets/update.ts +51 -0
- package/packages/core/src/ports/types.ts +528 -0
- package/packages/core/src/ports/workspace/build-execution.ts +123 -0
- package/packages/core/src/ports/workspace/contract.ts +136 -0
- package/packages/core/src/ports/workspace/create.ts +132 -0
- package/packages/core/src/ports/workspace/distribution-archive.ts +317 -0
- package/packages/core/src/ports/workspace/fake.ts +432 -0
- package/packages/core/src/ports/workspace/git-worktree.ts +848 -0
- package/packages/core/src/ports/workspace/harvest-execution.ts +111 -0
- package/packages/core/src/ports/workspace/in-process-build-execution.ts +30 -0
- package/packages/core/src/ports/workspace/local-build-execution.ts +88 -0
- package/packages/core/src/ports/workspace/operator-sandbox.ts +142 -0
- package/packages/core/src/ports/workspace/phase-scratch.ts +156 -0
- package/packages/core/src/ports/workspace/vercel-sandbox.ts +2541 -0
- package/packages/core/src/processes/build-child-exit.ts +78 -0
- package/packages/core/src/processes/build-child.ts +119 -0
- package/packages/core/src/processes/build-execution-state.ts +95 -0
- package/packages/core/src/processes/build-parent-watch.ts +35 -0
- package/packages/core/src/processes/build-runner.ts +2614 -0
- package/packages/core/src/processes/dispatcher.ts +2825 -0
- package/packages/core/src/processes/execution-settlement.ts +171 -0
- package/packages/core/src/processes/harvest-child.ts +115 -0
- package/packages/core/src/processes/harvest-execution-state.ts +121 -0
- package/packages/core/src/processes/harvest-runner.ts +1656 -0
- package/packages/core/src/processes/harvest.ts +595 -0
- package/packages/core/src/processes/infrastructure-failure-budget.ts +146 -0
- package/packages/core/src/processes/phase-failure-budget.ts +52 -0
- package/packages/core/src/processes/process-group-reaper.ts +35 -0
- package/packages/core/src/processes/process-group.ts +65 -0
- package/packages/core/src/processes/publication-loss.ts +62 -0
- package/packages/core/src/processes/publication-state.ts +93 -0
- package/packages/core/src/processes/sandbox-state.ts +101 -0
- package/packages/core/src/registry.ts +24 -0
- package/packages/core/src/sessions/reducer.ts +185 -0
- package/packages/core/src/skills.ts +7 -0
- package/packages/core/src/spec-standard.ts +47 -0
- package/packages/core/src/store/adapter.ts +80 -0
- package/packages/core/src/store/build-scope.ts +272 -0
- package/packages/core/src/store/contract.ts +2581 -0
- package/packages/core/src/store/local/blobs.ts +38 -0
- package/packages/core/src/store/local/schema.ts +180 -0
- package/packages/core/src/store/local/store.ts +1713 -0
- package/packages/core/src/store/memory.ts +1138 -0
- package/packages/core/src/store/phase-session.ts +425 -0
- package/packages/core/src/store/remote/client.ts +780 -0
- package/packages/core/src/store/remote/index.ts +12 -0
- package/packages/core/src/store/remote/protocol.ts +348 -0
- package/packages/core/src/store/remote/server.ts +923 -0
- package/packages/core/src/store/remote/token.ts +137 -0
- package/packages/core/src/store/remote/version.ts +10 -0
- package/packages/core/src/store/retention.ts +91 -0
- package/packages/core/src/store/session-handle.ts +265 -0
- package/packages/core/src/store/streams/assemble.ts +79 -0
- package/packages/core/src/store/streams/lock.ts +42 -0
- package/packages/core/src/store/streams/session-writer.ts +306 -0
- package/packages/core/src/store/streams/types.ts +171 -0
- package/packages/core/src/store/streams/wait.ts +127 -0
- package/packages/core/src/store/subscribe.ts +105 -0
- package/packages/core/src/store/types.ts +466 -0
- package/packages/core/src/testing/fixed.ts +44 -0
- package/packages/core/src/testing/store-failures.ts +32 -0
- package/packages/core/src/zod-issues.ts +91 -0
- package/skills/code-review/SKILL.md +100 -0
- package/skills/finalize/SKILL.md +44 -0
- package/skills/guide/SKILL.md +1781 -0
- package/skills/guide/references/operator-api.md +164 -0
- package/skills/guide/references/plugin-authoring.md +354 -0
- package/skills/guide/references/remote-store-protocol.md +972 -0
- package/skills/guide/references/remote-ticket-protocol.md +79 -0
- package/skills/guide/references/setup.md +289 -0
- package/skills/guide/references/spec-standard.md +63 -0
- package/skills/guide/references/ticket-dependencies.md +59 -0
- package/skills/harvest/SKILL.md +66 -0
- package/skills/harvest-review/SKILL.md +63 -0
- package/skills/implement/SKILL.md +82 -0
- package/skills/plan/SKILL.md +123 -0
- package/skills/plan-review/SKILL.md +121 -0
- package/skills/reconcile/SKILL.md +65 -0
- package/skills/spec/SKILL.md +132 -0
- package/skills/tickets/SKILL.md +139 -0
- package/templates/autobuild.toml +36 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Operator API v1
|
|
2
|
+
|
|
3
|
+
The hosted service exposes the polling-oriented operator surface at
|
|
4
|
+
`/operator/v1/repos/{repo}`. It is versioned with remote store protocol **2**.
|
|
5
|
+
Every request must send `X-Autobuild-Version`,
|
|
6
|
+
`X-Autobuild-Protocol-Version: 2`, and `Authorization: Bearer …`. Identity is
|
|
7
|
+
checked before authentication or resource lookup.
|
|
8
|
+
|
|
9
|
+
Mint a token offline; the signed user is used as the human actor on every write:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
AB_STORE_SECRET='…' bun packages/hosted-store-service/src/bin.ts mint operator \
|
|
13
|
+
--user 'Ada Lovelace' --ttl-seconds 3600
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Admin, build, repository, and deployment (`{ "operator": true, … }`) tokens
|
|
17
|
+
have no attributed operator authority. Human-operator tokens have no raw
|
|
18
|
+
`/builds`, `/repos`, `/sessions`, or `/tickets` authority. Encode repository,
|
|
19
|
+
build, session, and artifact kind as separate URL path segments.
|
|
20
|
+
|
|
21
|
+
## Operator sessions
|
|
22
|
+
|
|
23
|
+
Operator sessions are the signed-in operator's durable orchestrator
|
|
24
|
+
conversations: a hosted-only third store resource. A session
|
|
25
|
+
belongs to the operator who created it; other operators of the same repository
|
|
26
|
+
can read it and cannot write to it (`403 auth` on non-owner writes). Every
|
|
27
|
+
write is attributed to the token's signed user — never a client-supplied
|
|
28
|
+
identity — and carries no `via` marker: session events are the delegate's own
|
|
29
|
+
log. Writes of any kind to an archived session are `409 refusal`, and the
|
|
30
|
+
archived status is terminal.
|
|
31
|
+
|
|
32
|
+
| Method and path | Result |
|
|
33
|
+
|---|---|
|
|
34
|
+
| `GET …/sessions` | The repository's session records, newest update first. Readable by any operator of the repository. |
|
|
35
|
+
| `POST …/sessions` | `{"title"?:"…"}` → `201` + the created `SessionRecord`; the signed-in operator owns it. |
|
|
36
|
+
| `GET …/sessions/{sid}` | `{session, state, turns}` where `state` is the reducer's derived state (`status`, `openTurn`, `pendingApproval`, `wakeGlobs`, `wakeCursors`, `turns`) and `turns` the ordered turn list. Readable by any operator of the repository. |
|
|
37
|
+
| `POST …/sessions/{sid}/messages` | `{"text":"…"}` → appends `message.posted`. Owner only. |
|
|
38
|
+
| `PUT …/sessions/{sid}/wake` | `{"globs":["…"]}` (possibly empty) → appends `session.wake-set`. Owner only. |
|
|
39
|
+
| `POST …/sessions/{sid}/approvals` | `{"turn":"…","toolCallId":"…","decision":"approve"\|"deny"}` → `approval.answered`. Owner only; `409 refusal` when the reduced state has no matching pending approval. |
|
|
40
|
+
| `POST …/sessions/{sid}/archive` | Empty body → `session.archived`. Owner only; `409 refusal` when already archived. |
|
|
41
|
+
| `GET …/sessions/{sid}/turns/{turn}/stream?since=N&wait=N` | The turn's stream read: `{chunks,status,outcome?,artifact?}` with `since` strictly greater-than and the same bounded-wait semantics as the stream protocol (whole seconds, clamped at 30). Unknown turn is `404 not-found`. Readable by any operator of the repository. |
|
|
42
|
+
|
|
43
|
+
Session state is a reduction of the session's event log, never a stored
|
|
44
|
+
column; a `GET …/sessions/{sid}` response therefore always reflects the
|
|
45
|
+
session's full history. The API never exposes raw session-event append: the
|
|
46
|
+
turn runner (a later ticket) is the only producer of turn facts.
|
|
47
|
+
|
|
48
|
+
## Reads
|
|
49
|
+
|
|
50
|
+
| Method and path | Result |
|
|
51
|
+
|---|---|
|
|
52
|
+
| `GET …/builds?scope=active\|queued\|all` | Build summaries, newest update first. `queued` means active plus queued, matching `ab builds --queued`. |
|
|
53
|
+
| `GET …/builds/{slug}` | `{detail, dashboardRow}`; `dashboardRow` remains a `CLEANING` row after `build.aborted` and becomes `null` only when the dashboard stops listing it (after cleanup's `build.completed`). |
|
|
54
|
+
| `GET …/dashboard` | `{generatedAt, model, settingsHeader}`. `model` is the dashboard's rows, steps, elapsed timing inputs, harvest row, queue/capacity and settings projection. |
|
|
55
|
+
| `GET …/status` | Repository intake, pause, and default-auto-merge projection. |
|
|
56
|
+
| `GET …/harvest/status` | Harvest gate, runs, steps, recovery, and attention projection. |
|
|
57
|
+
| `GET …/builds/{slug}/artifacts/{kind}?rev=N` | Raw bytes (`application/octet-stream`) plus content-disposition and `X-Autobuild-Artifact-*` metadata headers. Omit `rev` for latest. |
|
|
58
|
+
| `GET …/tickets?state=S&label=L` | `{states,tickets,diagnostics,criteria,triageState,readyState}`. The two lifecycle names come from effective repository configuration (including provider fallback). With no `state`, `criteria.state` is `triageState`; repeated `label` parameters narrow that state with AND filters. An explicit `state` selects that exact backend workflow state. |
|
|
59
|
+
| `GET …/tickets/{id}` | `{ticket,blockers,build}`. Blockers include native `exists`/`resolved` status; `build` prefers an active matching repository build, otherwise the most recently updated one. |
|
|
60
|
+
|
|
61
|
+
For artifact reads, an absent `rev` selects the latest revision. A supplied value
|
|
62
|
+
must match `[0-9]+` (one or more ASCII base-10 digits) and represent an integer
|
|
63
|
+
from `0` through `Number.MAX_SAFE_INTEGER` (`9007199254740991`). All other
|
|
64
|
+
supplied forms return `400 validation`.
|
|
65
|
+
|
|
66
|
+
Dashboard reads use the latest durable, run-correlated `effectiveConfig`
|
|
67
|
+
repository artifact. Missing, corrupt, or invalid configuration returns a typed
|
|
68
|
+
`409 effective-config-unavailable`; the service never guesses from a checkout.
|
|
69
|
+
Clients poll these reads; streaming is not provided. `triageState`, `readyState`,
|
|
70
|
+
and every entry in `states` are backend state names and must be sent back verbatim
|
|
71
|
+
when used with the move control.
|
|
72
|
+
|
|
73
|
+
## Controls
|
|
74
|
+
|
|
75
|
+
JSON bodies are strict: unknown fields are rejected.
|
|
76
|
+
|
|
77
|
+
| Method and path | Body |
|
|
78
|
+
|---|---|
|
|
79
|
+
| `POST …/builds/{slug}/control` | `{"action":"pause"\|"cancel-pause"\|"resume"\|"abort"\|"discard"\|"auto-merge-on"\|"auto-merge-off"}` |
|
|
80
|
+
| `POST …/builds/{slug}/answer` | One answer variant described below. |
|
|
81
|
+
| `PUT …/settings/intake` | `{"enabled":boolean}` |
|
|
82
|
+
| `POST …/settings/intake/toggle` | Empty body. |
|
|
83
|
+
| `PUT …/settings/auto-merge-default` | `{"enabled":boolean}` |
|
|
84
|
+
| `POST …/settings/auto-merge-default/toggle` | Empty body. |
|
|
85
|
+
| `POST …/bulk-control` | `{"action":"pause"\|"resume"}`. The hold fact, intake fact, then eligible build events are written in that order. |
|
|
86
|
+
| `POST …/harvest/control` | `{"action":"toggle-gate"}` or `{"action":"run","run":"…"}`. A run action is bound to that concrete projected run. |
|
|
87
|
+
| `POST …/tickets` | `{"title":"…","body":"…","labels"?:[],"state"?:"…","blockedBy"?:[]}`; omitted state preserves the backend default. |
|
|
88
|
+
| `PATCH …/tickets/{id}` | Any nonempty subset of `title`, `body`, and complete-replacement `labels`. Body bytes are not normalized. |
|
|
89
|
+
| `POST …/tickets/{id}/move` | `{"state":"backend state name"}`. |
|
|
90
|
+
| `POST …/tickets/{id}/block` | `{"blockerIds":["…"]}`. |
|
|
91
|
+
| `POST …/tickets/{id}/unblock` | `{"blockerIds":["…"]}`. |
|
|
92
|
+
|
|
93
|
+
Answer variants:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{"resolution":"guidance","text":"…"}
|
|
97
|
+
{"resolution":"retry"}
|
|
98
|
+
{"resolution":"dismiss","text":"optional audit text"}
|
|
99
|
+
{"resolution":"review-round-ceiling","ceiling":4,"text":"optional guidance"}
|
|
100
|
+
{"resolution":"revise-spec","origin":"body","body":"replacement spec","text":"optional guidance"}
|
|
101
|
+
{"resolution":"revise-spec","origin":"ticket","body":"current amended ticket body","text":"optional guidance"}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The retry object is deliberately bare: adding `text` is a `400 validation`
|
|
105
|
+
rather than silently changing the resolution to guidance. A revision object may
|
|
106
|
+
also carry `ceiling` only to receive the shared `incompatible-answer-options`
|
|
107
|
+
refusal; a ceiling and spec revision cannot be performed together.
|
|
108
|
+
|
|
109
|
+
The hosted service has no ticket-provider credentials. For ticket-origin
|
|
110
|
+
revision, a trusted caller fetches the current ticket body and supplies it; the
|
|
111
|
+
build must still have a recorded ticket. Revision conformance, lazy retry,
|
|
112
|
+
artifact metadata, event ordering, and refusal rules are the same as the CLI.
|
|
113
|
+
|
|
114
|
+
### Success results
|
|
115
|
+
|
|
116
|
+
Build control returns one of:
|
|
117
|
+
|
|
118
|
+
- `{kind:"command",slug,command,event}` after writing a pause, resume, abort,
|
|
119
|
+
discard, or per-build auto-merge command. `command` is the durable command;
|
|
120
|
+
successful cancel-pause therefore returns `command:"resume"`.
|
|
121
|
+
- `{kind:"answer-required",slug,escalationIds}` when `action:"resume"` targets
|
|
122
|
+
a blocked build. This is a successful prompt transition but **does not append
|
|
123
|
+
an event**; submit one of the answer requests next.
|
|
124
|
+
- `{kind:"answered",slug,count,resolution,resumed,...}` from the answer route.
|
|
125
|
+
`resolution` is `guidance`, `retry`, `dismiss-finding`, or `revise-spec`.
|
|
126
|
+
Depending on the operation, the result also includes `remainingOpen`,
|
|
127
|
+
`reviewRoundCeiling:{loop,value}`, `specRev`, `authorizedEarlier`, or a
|
|
128
|
+
`terminalSignal` describing a terminal status, pending abort, or ended PR.
|
|
129
|
+
|
|
130
|
+
Repository setting writes and toggles return `{enabled,event}`. Harvest gate
|
|
131
|
+
toggle returns `{command:"pause"|"resume",event}`; a concrete-run action
|
|
132
|
+
returns `{action:"resume"|"acknowledge",event}`. Bulk control returns
|
|
133
|
+
`{direction,slugs,paused,intake}`, where `slugs` is the write-ordered set of
|
|
134
|
+
builds that received a command. Every `event` is the complete durable envelope
|
|
135
|
+
including repository/build id, sequence, timestamp, actor, type, and payload.
|
|
136
|
+
|
|
137
|
+
## Errors
|
|
138
|
+
|
|
139
|
+
JSON errors have `{kind,error,code?,progress?}`. Malformed input is `400
|
|
140
|
+
validation`; missing resources/artifacts are `404 not-found`; missing/invalid
|
|
141
|
+
credentials are `401 auth`; a valid non-operator scope is `403 auth`; version
|
|
142
|
+
skew and unavailable projections are `409 conflict`. A build outside the URL's
|
|
143
|
+
repository is deliberately hidden as `404 not-found` with `unknown build`,
|
|
144
|
+
consistently for detail, control, answer, and artifact routes. Control refusals are `409
|
|
145
|
+
refusal` and preserve the shared `BuildControlError` code and exact reason text.
|
|
146
|
+
A partial bulk failure uses code `bulk-partial` and includes the durable write
|
|
147
|
+
progress and unattempted builds. Unexpected failures are `500 internal`.
|
|
148
|
+
|
|
149
|
+
## Browser gateway
|
|
150
|
+
|
|
151
|
+
The same deployment serves the web dashboard through `/api/web/repos/{repo}/…`.
|
|
152
|
+
That route is not a second public bearer-token API: it requires a current
|
|
153
|
+
Better Auth HTTP-only cookie, rechecks the deployment email and repository
|
|
154
|
+
allowlists, rejects cross-origin JSON controls, and delegates only the dashboard,
|
|
155
|
+
build, settings, and harvest operator suffixes listed above. It replaces caller-supplied authorization/version
|
|
156
|
+
headers with a server-minted token that expires after 30 seconds and carries
|
|
157
|
+
the normalized signed-in email. Consequently every durable control event has
|
|
158
|
+
the browser user's human actor while no token or signing secret reaches client
|
|
159
|
+
code. Responses are private/no-store; a 401 sends the application back to sign
|
|
160
|
+
in. Browser clients poll the visible dashboard every two seconds; live transcript
|
|
161
|
+
streaming is not provided. Delegated bearer tokens remain server-side.
|
|
162
|
+
|
|
163
|
+
The API does not expose phase-session commands, runner startup, live streaming,
|
|
164
|
+
or a generic event-append operation.
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
# Authoring Autobuild plugins
|
|
2
|
+
|
|
3
|
+
Use this reference when asked to connect Autobuild to another ticket tracker,
|
|
4
|
+
agent runtime, workspace system, or forge. A plugin is a trusted Bun module
|
|
5
|
+
loaded in-process from the consuming repository. **Definition of done for an
|
|
6
|
+
adapter: the unchanged shared contract suite for its port passes.** Interface
|
|
7
|
+
conformance or a successful `ab plugin doctor` alone is not certification.
|
|
8
|
+
|
|
9
|
+
## 1. Choose the port and preserve its semantics
|
|
10
|
+
|
|
11
|
+
Import public types only from `@defrex/autobuild/plugin-sdk`; package-internal module
|
|
12
|
+
paths are not API.
|
|
13
|
+
|
|
14
|
+
| CLI port | Manifest map | Factory result | Required semantics |
|
|
15
|
+
|---|---|---|---|
|
|
16
|
+
| `ticket-source` | `ticketSources` | `TicketSource` | Initiates a build by listing/getting/claiming tickets and receives comments/transitions/creates/updates. It owns lifecycle names, dependency completion, idempotent creation, stable external creation-key projection, and partial-list diagnostics. It is never consulted mid-build and is not artifact storage. |
|
|
17
|
+
| `agent-runtime` | `agentRuntimes` | `RuntimeRegistration` | Wrap an `AgentRunner` that supports start/continue/end, complete transcripts and usage, per-turn environment refresh and cancellation, typed failures with verbatim messages, the retry-compatible `permanent` bit, and optional `cause: availability | exhaustion | credentials | configuration` routing evidence, plus the distribution-managed `ab` launcher. A cancelled turn must retain an endable handle for transcript deposition. Declare served model prefixes/default; optional tool-free `oneShot` is a capability beside the runner interface. |
|
|
18
|
+
| `workspace-provider` | `workspaceProviders` | `WorkspaceProvider` | Provision an absolute, writable working copy for the requested branch, return durable base evidence, resume an intact branch non-destructively, rematerialize a lost copy, and make release idempotent. Never silently re-cut resumed work from a newer base. |
|
|
19
|
+
| `forge` | `forges` | `Forge` | Implement kernel-owned regular pushes, idempotent PR opening, PR-state projection, gated/ungated auto-merge behavior, head-guarded squash merge, and comments. API 1.2 adds optional idempotent `closePr` and `deleteBranch` abort-cleanup capabilities; `closePr` must preserve a racing merge. Without them abort cleanup remains visibly pending. Agents never receive forge credentials or push. `prAttachments` is an optional image-hosting capability; absence must preserve the supported text-only path. |
|
|
20
|
+
|
|
21
|
+
Plugin API 1.3 adds the optional AgentRunner failure `cause` and the
|
|
22
|
+
`exhaustion-failure` shared-contract scenario. Legacy failures without `cause`
|
|
23
|
+
remain supported: `permanent: false` is eligible for a configured alternate,
|
|
24
|
+
while `permanent: true` stops the chain. A runtime plugin that emits/depends on
|
|
25
|
+
the richer cause should declare an API range containing `^1.3.0`.
|
|
26
|
+
|
|
27
|
+
Plugin API 1.4 adds optional `Ticket.creationKey`. Ticket-source plugins should
|
|
28
|
+
project the stable external create/adoption key from `create`, `get`, and
|
|
29
|
+
`listReady`; Autobuild uses it to correlate ready tickets with durable Harvest
|
|
30
|
+
reservations while blocker recording is unfinished. Legacy tickets may omit the
|
|
31
|
+
field and continue to dispatch normally. A plugin relying on this host gate
|
|
32
|
+
should declare an API range containing `^1.4.0`.
|
|
33
|
+
|
|
34
|
+
Plugin API 1.5 makes remote workspace locations explicit. `path` is the path in
|
|
35
|
+
the workspace environment; set optional `localPath` only when that same working
|
|
36
|
+
copy is directly reachable by the dispatcher. Workspace-owned executors receive
|
|
37
|
+
the durable provider locator as `BuildExecutionStart.workspaceRef`; local PID
|
|
38
|
+
supervision remains host-owned. A workspace plugin relying on these fields
|
|
39
|
+
should declare an API range containing `^1.5.0`.
|
|
40
|
+
|
|
41
|
+
`BuildStore` and `BlobStore` contract types are exported for remote-server
|
|
42
|
+
authors, but BuildStore is **not** an in-process manifest map. Implement the
|
|
43
|
+
colocated language-neutral
|
|
44
|
+
[remote store protocol](remote-store-protocol.md) and run its conformance path
|
|
45
|
+
instead. `TelemetrySource` is a frozen port type with no plugin registration
|
|
46
|
+
surface in this release.
|
|
47
|
+
|
|
48
|
+
All four manifest maps have production selectors. Use `[tickets].source` for a
|
|
49
|
+
ticket source, the root `forge` key for a forge, `[workspace].provider` for a
|
|
50
|
+
workspace provider, and `[roles.*].runtime` for an agent runtime. Omitted forge
|
|
51
|
+
and workspace selectors retain the builtin `github` and `git-worktree` defaults;
|
|
52
|
+
role inheritance retains its normal runtime fallback.
|
|
53
|
+
|
|
54
|
+
## 2. Create a repository-local module
|
|
55
|
+
|
|
56
|
+
Start in the consuming repository, for example:
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
my-repository/
|
|
60
|
+
├── autobuild.toml
|
|
61
|
+
└── autobuild-plugin.ts
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Use erased imports in real adapter production code whenever the SDK symbols are
|
|
65
|
+
only types:
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import type {
|
|
69
|
+
AutobuildPluginManifest,
|
|
70
|
+
ForgePluginFactory,
|
|
71
|
+
} from '@defrex/autobuild/plugin-sdk'
|
|
72
|
+
import { AcmeForge } from '@acme/forge-client'
|
|
73
|
+
|
|
74
|
+
const createForge: ForgePluginFactory = ({ config, env, repoRoot }) => {
|
|
75
|
+
const token = env.ACME_FORGE_TOKEN
|
|
76
|
+
if (!token) throw new Error('ACME_FORGE_TOKEN is required')
|
|
77
|
+
return new AcmeForge({ token, config, repoRoot })
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export default {
|
|
81
|
+
name: 'acme-forge',
|
|
82
|
+
apiVersion: '^1.2.0',
|
|
83
|
+
forges: { acme: createForge },
|
|
84
|
+
} satisfies AutobuildPluginManifest
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Every module must default-export one strict `AutobuildPluginManifest`:
|
|
88
|
+
|
|
89
|
+
- `name` is a nonblank diagnostic/ownership identity; it need not equal the npm
|
|
90
|
+
package name.
|
|
91
|
+
- `apiVersion` is a semver **range accepted by the plugin**, not the plugin's
|
|
92
|
+
package version. Choose the narrowest range containing the host plugin API
|
|
93
|
+
against which you ran contracts. `ab plugin list` reports the declared range
|
|
94
|
+
and host version; invalid or incompatible ranges fail loading.
|
|
95
|
+
- The only registration keys are `ticketSources`, `agentRuntimes`,
|
|
96
|
+
`workspaceProviders`, and `forges`. Unknown manifest fields fail validation.
|
|
97
|
+
Adapter names are yours to choose: every declared name is registered
|
|
98
|
+
verbatim, including one such as `__proto__` that collides with an inherited
|
|
99
|
+
object property — declare that one computed, `{ ['__proto__']: factory }`,
|
|
100
|
+
since a plain `__proto__:` key in an object literal sets the prototype
|
|
101
|
+
instead of declaring an adapter. The parsed maps have a null prototype, so
|
|
102
|
+
reading an undeclared name answers `undefined` rather than an inherited
|
|
103
|
+
member. A blank or whitespace-only name is rejected: an adapter is selected
|
|
104
|
+
from configuration by name.
|
|
105
|
+
- A registration may be a bare adapter factory, or
|
|
106
|
+
`{ factory, contract: { factory, live? } }`. The first factory returns the
|
|
107
|
+
adapter; the contract factory returns that port suite's fixture factory.
|
|
108
|
+
Ticket-source descriptors may additionally declare a deduplicated
|
|
109
|
+
`requiredEnv` list; the host rejects missing or empty credentials before
|
|
110
|
+
invoking that selected factory.
|
|
111
|
+
- Every adapter and contract factory receives `{ config, env, repoRoot }`:
|
|
112
|
+
adapter-specific read-only `config`, the process `env`, and `repoRoot` as the
|
|
113
|
+
absolute consuming-repository root. Ticket sources receive the existing
|
|
114
|
+
`[tickets]` fields, workspace providers receive `[workspace.config]`, and
|
|
115
|
+
runtime and forge factories currently receive an empty `config` object.
|
|
116
|
+
|
|
117
|
+
Add the module specifier at the TOML root, before any table. Repository-path
|
|
118
|
+
specifiers resolve from the config-bearing root, which is the immutable build
|
|
119
|
+
worktree in scoped phases. npm package specifiers resolve from the consuming
|
|
120
|
+
main checkout's installed dependencies first, then from the Autobuild
|
|
121
|
+
installation the CLI runs from (so `bun add -g @defrex/autobuild-<extension>`
|
|
122
|
+
next to the CLI is enough); a repository copy wins over an installed one, and
|
|
123
|
+
missing packages fail and are never installed automatically:
|
|
124
|
+
|
|
125
|
+
```toml
|
|
126
|
+
plugins = ["./autobuild-plugin.ts"]
|
|
127
|
+
forge = "acme"
|
|
128
|
+
|
|
129
|
+
[tickets]
|
|
130
|
+
source = "file"
|
|
131
|
+
readyState = "ready"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Each configured specifier string must be unique. An exact repeat fails config
|
|
135
|
+
validation before Bun resolves or evaluates any plugin, identifies the repeated
|
|
136
|
+
value and both list positions, and tells the operator to remove or deduplicate
|
|
137
|
+
the entry. Distinct specifiers remain separate declarations.
|
|
138
|
+
|
|
139
|
+
Select only the adapters the repository uses. Set `forge = "acme"` for the
|
|
140
|
+
example forge above; set `[tickets].source`, `[workspace].provider`, or a
|
|
141
|
+
`[roles.*].runtime` to the matching registration name for the other ports.
|
|
142
|
+
Ticket plugins receive the existing strict `[tickets]` fields—there is no
|
|
143
|
+
untyped plugin-options table. Workspace plugins put adapter-owned settings only
|
|
144
|
+
under the open `[workspace.config]` table.
|
|
145
|
+
|
|
146
|
+
Plugin modules load in declaration order. Resolution/evaluation failure, a
|
|
147
|
+
missing or malformed default export, incompatible API range, or collision
|
|
148
|
+
fails before claims/builds. Builtin and earlier-plugin names cannot be
|
|
149
|
+
shadowed within one port; a collision between distinct plugins identifies the
|
|
150
|
+
adapter and both owners. The same adapter name may exist on different ports.
|
|
151
|
+
Registration is atomic per manifest. Plugins are trusted like configured shell
|
|
152
|
+
commands: Bun evaluates them in-process with repository authority and no
|
|
153
|
+
sandbox.
|
|
154
|
+
|
|
155
|
+
## 3. Keep secrets out of source and config
|
|
156
|
+
|
|
157
|
+
Never put credentials in `autobuild.toml`, the manifest, committed fixtures, or
|
|
158
|
+
contract output. Read them from the factory's `env` (for example
|
|
159
|
+
`env.ACME_FORGE_TOKEN`) and document the required environment variables. Keep
|
|
160
|
+
local values in ignored environment files or the process secret manager.
|
|
161
|
+
Validate missing credentials when the selected adapter or live fixture is
|
|
162
|
+
created, not at module top level, so registration remains lazy and diagnostics
|
|
163
|
+
can inspect unrelated adapters. Ticket-source descriptors should declare
|
|
164
|
+
`requiredEnv` when the host can enforce the credential names before factory
|
|
165
|
+
invocation; other ports validate their environment in their factories.
|
|
166
|
+
|
|
167
|
+
## 4. Add the contract harness first
|
|
168
|
+
|
|
169
|
+
A contract-bearing registration has this shape:
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
const manifest = {
|
|
173
|
+
name: 'acme',
|
|
174
|
+
apiVersion: '^1.2.0',
|
|
175
|
+
ticketSources: {
|
|
176
|
+
acme: {
|
|
177
|
+
factory: createAcmeTicketSource,
|
|
178
|
+
contract: { factory: createAcmeTicketContract },
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
} satisfies AutobuildPluginManifest
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
The descriptor's factory returns a `TicketSourceContractFactory`,
|
|
185
|
+
`AgentRunnerContractFactory`, `WorkspaceProviderContractFactory`, or
|
|
186
|
+
`ForgeContractFactory` as appropriate. Use the matching harness types exported
|
|
187
|
+
by `@defrex/autobuild/plugin-sdk`. The host invokes the unchanged shared suite; do not
|
|
188
|
+
copy, wrap, skip, or weaken its assertions.
|
|
189
|
+
|
|
190
|
+
Contract fixtures must isolate resources (UUID-namespaced records, branches,
|
|
191
|
+
PRs, sessions, or workspaces), expose the independent controls/probes required
|
|
192
|
+
by their harness type, clean up in `cleanup` even after assertion failure, and
|
|
193
|
+
make retries/release idempotent where the port requires it. A fixture that
|
|
194
|
+
contacts a provider or mutates external resources must declare
|
|
195
|
+
`contract: { factory, live: true }`. Autobuild refuses to launch it unless the
|
|
196
|
+
operator explicitly sets:
|
|
197
|
+
|
|
198
|
+
```sh
|
|
199
|
+
AB_RUN_LIVE_PORT_CONTRACTS=1 ab plugin test forge acme
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Run the author loop from the consuming repository:
|
|
203
|
+
|
|
204
|
+
```sh
|
|
205
|
+
ab plugin list
|
|
206
|
+
ab plugin doctor
|
|
207
|
+
ab plugin test ticket-source acme
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
- `list` shows builtins and configured registrations, provenance, module
|
|
211
|
+
resolution, plugin API compatibility, and contract availability.
|
|
212
|
+
- `doctor` attempts every configured module and exits nonzero if any fail. It
|
|
213
|
+
checks loading/registration, not adapter semantics.
|
|
214
|
+
- `test` launches Bun's unchanged suite for exactly one port/adapter, forwards
|
|
215
|
+
per-test output, and returns its exit status.
|
|
216
|
+
|
|
217
|
+
Repeat after every adapter change. The adapter is done only when that command's
|
|
218
|
+
shared suite is green (with the explicit live opt-in when applicable).
|
|
219
|
+
|
|
220
|
+
## 5. Zero-network wiring walkthrough
|
|
221
|
+
|
|
222
|
+
This executable scratch example proves module resolution, manifest spelling,
|
|
223
|
+
configuration, and the TicketSource contract bridge without network access. It
|
|
224
|
+
uses Autobuild's reference fake and is **only a wiring exercise**. Replace the
|
|
225
|
+
fake and fixture with the real provider implementation; certification means the
|
|
226
|
+
real adapter's harness passes the same unchanged suite.
|
|
227
|
+
|
|
228
|
+
Create `autobuild-plugin.ts` with the exact block below.
|
|
229
|
+
|
|
230
|
+
<!-- plugin-authoring-walkthrough-module:start -->
|
|
231
|
+
```ts
|
|
232
|
+
import { FakeTicketSource } from '@defrex/autobuild/plugin-sdk'
|
|
233
|
+
import type {
|
|
234
|
+
AutobuildPluginManifest,
|
|
235
|
+
TicketSourceContractFactory,
|
|
236
|
+
TicketSourcePluginFactory,
|
|
237
|
+
} from '@defrex/autobuild/plugin-sdk'
|
|
238
|
+
|
|
239
|
+
const createSource: TicketSourcePluginFactory = () => new FakeTicketSource()
|
|
240
|
+
|
|
241
|
+
const ticketContract: TicketSourceContractFactory = async () => ({
|
|
242
|
+
source: new FakeTicketSource([], {
|
|
243
|
+
createState: 'Triage',
|
|
244
|
+
doneState: 'Done',
|
|
245
|
+
}),
|
|
246
|
+
states: { ready: 'Ready', claimed: 'Doing', completed: 'Done' },
|
|
247
|
+
editableLabel: 'contract',
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
export default {
|
|
251
|
+
name: 'walkthrough',
|
|
252
|
+
apiVersion: '^1.2.0',
|
|
253
|
+
ticketSources: {
|
|
254
|
+
walkthrough: {
|
|
255
|
+
factory: createSource,
|
|
256
|
+
contract: { factory: () => ticketContract },
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
} satisfies AutobuildPluginManifest
|
|
260
|
+
```
|
|
261
|
+
<!-- plugin-authoring-walkthrough-module:end -->
|
|
262
|
+
|
|
263
|
+
Create `autobuild.toml`:
|
|
264
|
+
|
|
265
|
+
<!-- plugin-authoring-walkthrough-config:start -->
|
|
266
|
+
```toml
|
|
267
|
+
plugins = ["./autobuild-plugin.ts"]
|
|
268
|
+
|
|
269
|
+
[tickets]
|
|
270
|
+
source = "walkthrough"
|
|
271
|
+
readyState = "ready"
|
|
272
|
+
```
|
|
273
|
+
<!-- plugin-authoring-walkthrough-config:end -->
|
|
274
|
+
|
|
275
|
+
Then run:
|
|
276
|
+
|
|
277
|
+
```sh
|
|
278
|
+
ab init
|
|
279
|
+
ab plugin doctor
|
|
280
|
+
ab plugin list
|
|
281
|
+
ab plugin test ticket-source walkthrough
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
`ab init` preserves the existing config and vendors this guide. Doctor and list
|
|
285
|
+
must show the `walkthrough` plugin/adapter, and the final command must exit zero
|
|
286
|
+
with the TicketSource contract tests.
|
|
287
|
+
|
|
288
|
+
## 6. Package and publish when reuse warrants it
|
|
289
|
+
|
|
290
|
+
A repository-local module is the shortest path and needs no packaging. For an
|
|
291
|
+
npm plugin, keep one public module and an ordinary test/typecheck setup:
|
|
292
|
+
|
|
293
|
+
```text
|
|
294
|
+
acme-autobuild-plugin/
|
|
295
|
+
├── src/index.ts
|
|
296
|
+
├── package.json
|
|
297
|
+
├── tsconfig.json
|
|
298
|
+
└── bun.lock
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
A representative package manifest is:
|
|
302
|
+
|
|
303
|
+
```json
|
|
304
|
+
{
|
|
305
|
+
"name": "@acme/autobuild-plugin",
|
|
306
|
+
"version": "1.0.0",
|
|
307
|
+
"type": "module",
|
|
308
|
+
"exports": { ".": "./src/index.ts" },
|
|
309
|
+
"files": ["src", "README.md"],
|
|
310
|
+
"scripts": {
|
|
311
|
+
"typecheck": "tsc --noEmit",
|
|
312
|
+
"test": "bun test",
|
|
313
|
+
"prepublishOnly": "bun run typecheck && bun test"
|
|
314
|
+
},
|
|
315
|
+
"devDependencies": { "autobuild": "^2.0.0", "typescript": "^7.0.0" },
|
|
316
|
+
"peerDependencies": { "autobuild": "^2.0.0" },
|
|
317
|
+
"peerDependenciesMeta": { "autobuild": { "optional": true } }
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
When production code imports only SDK types, those imports erase: Autobuild is
|
|
322
|
+
an authoring/test dev dependency, not a runtime `dependencies` entry. An
|
|
323
|
+
optional peer declaration communicates tested host-package compatibility to
|
|
324
|
+
package consumers without making plugin execution depend on a second Autobuild
|
|
325
|
+
copy. Runtime imports (for example importing a reference fake in the scratch
|
|
326
|
+
walkthrough) are different and require a runtime dependency; do not ship the
|
|
327
|
+
fake walkthrough as a production adapter.
|
|
328
|
+
|
|
329
|
+
Keep the package's own semver independent from the manifest's `apiVersion`
|
|
330
|
+
range. On an incompatible host plugin API, update the adapter and contracts,
|
|
331
|
+
change the range only after they pass against that host, and release the
|
|
332
|
+
package version according to the user-visible compatibility change.
|
|
333
|
+
|
|
334
|
+
Before publishing:
|
|
335
|
+
|
|
336
|
+
```sh
|
|
337
|
+
bun run typecheck
|
|
338
|
+
bun test
|
|
339
|
+
npm pack --dry-run
|
|
340
|
+
npm pack
|
|
341
|
+
# inspect the tarball, then install that exact .tgz in a scratch consumer
|
|
342
|
+
npm publish --access public
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Inspect the dry-run/tarball file list for source, secrets, local fixtures, and
|
|
346
|
+
missing exports. Install the generated tarball in a scratch consuming
|
|
347
|
+
repository, configure `plugins = ["@acme/autobuild-plugin"]`, and rerun
|
|
348
|
+
`ab plugin doctor`, `ab plugin list`, and the contract command before publish.
|
|
349
|
+
Use `--access public` for a public scoped package; omit it when registry/access
|
|
350
|
+
policy says otherwise.
|
|
351
|
+
|
|
352
|
+
Official npm references: [`package.json` fields](https://docs.npmjs.com/cli/v11/configuring-npm/package-json),
|
|
353
|
+
[`npm pack`](https://docs.npmjs.com/cli/v11/commands/npm-pack), and
|
|
354
|
+
[`npm publish`](https://docs.npmjs.com/cli/v11/commands/npm-publish).
|