@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.
Files changed (251) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +192 -0
  3. package/SPEC.md +2269 -0
  4. package/bin/ab-build-runner.ts +47 -0
  5. package/bin/ab-dev.ts +27 -0
  6. package/bin/ab-dispatch-kernel.ts +92 -0
  7. package/bin/ab-harvest-runner.ts +29 -0
  8. package/bin/ab-init-probe.ts +19 -0
  9. package/bin/ab-process-group-reaper.ts +32 -0
  10. package/bin/ab.ts +6 -0
  11. package/bin/agent/ab +3 -0
  12. package/docs/answering-blocked-builds.md +89 -0
  13. package/docs/architecture.md +726 -0
  14. package/docs/assets/headline-wide.png +0 -0
  15. package/docs/configuration.md +1623 -0
  16. package/docs/hosted-dispatcher-cutover-validation.md +178 -0
  17. package/docs/hosted-dispatcher.md +204 -0
  18. package/docs/mcp.md +119 -0
  19. package/docs/operator-api.md +186 -0
  20. package/docs/remote-store-protocol.md +972 -0
  21. package/docs/remote-ticket-protocol.md +79 -0
  22. package/docs/setup.md +289 -0
  23. package/docs/spec-standard.md +63 -0
  24. package/docs/ticket-dependencies.md +59 -0
  25. package/docs/vercel-sandbox-rollout-probe.md +7 -0
  26. package/package.json +135 -0
  27. package/packages/core/src/cli/args.ts +74 -0
  28. package/packages/core/src/cli/artifact.ts +182 -0
  29. package/packages/core/src/cli/binary.ts +198 -0
  30. package/packages/core/src/cli/build-control.ts +789 -0
  31. package/packages/core/src/cli/build-progress.ts +55 -0
  32. package/packages/core/src/cli/bulk-control.ts +385 -0
  33. package/packages/core/src/cli/context.ts +470 -0
  34. package/packages/core/src/cli/dashboard/actions.ts +59 -0
  35. package/packages/core/src/cli/dashboard/cells.ts +92 -0
  36. package/packages/core/src/cli/dashboard/composer.ts +230 -0
  37. package/packages/core/src/cli/dashboard/detail.ts +100 -0
  38. package/packages/core/src/cli/dashboard/frame-image.ts +373 -0
  39. package/packages/core/src/cli/dashboard/live.ts +152 -0
  40. package/packages/core/src/cli/dashboard/model.ts +1173 -0
  41. package/packages/core/src/cli/dashboard/poll.ts +196 -0
  42. package/packages/core/src/cli/dashboard/render.ts +1568 -0
  43. package/packages/core/src/cli/dashboard/selection.ts +66 -0
  44. package/packages/core/src/cli/dashboard/session-feed.ts +244 -0
  45. package/packages/core/src/cli/dashboard/session-view.ts +506 -0
  46. package/packages/core/src/cli/dashboard/transcript.ts +108 -0
  47. package/packages/core/src/cli/dev.ts +46 -0
  48. package/packages/core/src/cli/dispatch-frontend.ts +1045 -0
  49. package/packages/core/src/cli/dispatch-process.ts +259 -0
  50. package/packages/core/src/cli/dispatch.ts +3692 -0
  51. package/packages/core/src/cli/dotenv.ts +48 -0
  52. package/packages/core/src/cli/env.ts +206 -0
  53. package/packages/core/src/cli/harvest.ts +698 -0
  54. package/packages/core/src/cli/help.ts +713 -0
  55. package/packages/core/src/cli/init-agent.ts +106 -0
  56. package/packages/core/src/cli/init-validation.ts +583 -0
  57. package/packages/core/src/cli/init.ts +756 -0
  58. package/packages/core/src/cli/installation.ts +333 -0
  59. package/packages/core/src/cli/keyboard.ts +261 -0
  60. package/packages/core/src/cli/main.ts +1399 -0
  61. package/packages/core/src/cli/mcp.ts +279 -0
  62. package/packages/core/src/cli/models.ts +65 -0
  63. package/packages/core/src/cli/observe.ts +55 -0
  64. package/packages/core/src/cli/plugin.ts +227 -0
  65. package/packages/core/src/cli/pr-attachments.ts +138 -0
  66. package/packages/core/src/cli/pr-summary.ts +124 -0
  67. package/packages/core/src/cli/publication-settlement.ts +188 -0
  68. package/packages/core/src/cli/repo-state.ts +213 -0
  69. package/packages/core/src/cli/repository-status.ts +80 -0
  70. package/packages/core/src/cli/self-update.ts +443 -0
  71. package/packages/core/src/cli/status.ts +895 -0
  72. package/packages/core/src/cli/store-opening.contract.ts +289 -0
  73. package/packages/core/src/cli/store-opening.ts +167 -0
  74. package/packages/core/src/cli/store-ref.ts +33 -0
  75. package/packages/core/src/cli/terminal-restore.ts +174 -0
  76. package/packages/core/src/cli/terminal.ts +361 -0
  77. package/packages/core/src/cli/terminals.ts +995 -0
  78. package/packages/core/src/cli/testkit.ts +194 -0
  79. package/packages/core/src/cli/ticket.ts +484 -0
  80. package/packages/core/src/cli/upgrade-agent.ts +180 -0
  81. package/packages/core/src/cli/upgrade-commit.ts +468 -0
  82. package/packages/core/src/cli/upgrade-notice.ts +91 -0
  83. package/packages/core/src/cli/upgrade-progress.ts +110 -0
  84. package/packages/core/src/cli/upgrade.ts +888 -0
  85. package/packages/core/src/cli/wait.ts +587 -0
  86. package/packages/core/src/cli/watch.ts +932 -0
  87. package/packages/core/src/config/live.ts +255 -0
  88. package/packages/core/src/config/load.ts +98 -0
  89. package/packages/core/src/config/roles.ts +438 -0
  90. package/packages/core/src/config/schema.ts +774 -0
  91. package/packages/core/src/distribution.ts +24 -0
  92. package/packages/core/src/events/catalog.ts +201 -0
  93. package/packages/core/src/events/envelope.ts +59 -0
  94. package/packages/core/src/events/payloads.ts +618 -0
  95. package/packages/core/src/events/repository.ts +559 -0
  96. package/packages/core/src/events/sessions.ts +180 -0
  97. package/packages/core/src/harvest/schema.ts +147 -0
  98. package/packages/core/src/ids.ts +45 -0
  99. package/packages/core/src/integration/harness.ts +681 -0
  100. package/packages/core/src/kernel/auto-merge.ts +259 -0
  101. package/packages/core/src/kernel/converge.ts +117 -0
  102. package/packages/core/src/kernel/dispatch-settings.ts +60 -0
  103. package/packages/core/src/kernel/dispatch-status.ts +141 -0
  104. package/packages/core/src/kernel/engine.ts +1047 -0
  105. package/packages/core/src/kernel/harvest.ts +823 -0
  106. package/packages/core/src/kernel/origin.ts +69 -0
  107. package/packages/core/src/kernel/phases.ts +196 -0
  108. package/packages/core/src/kernel/plan-verify-selection.ts +105 -0
  109. package/packages/core/src/kernel/pr-attachments.ts +82 -0
  110. package/packages/core/src/kernel/reducer.ts +752 -0
  111. package/packages/core/src/kernel/stall.ts +155 -0
  112. package/packages/core/src/kernel/verify-applicability.ts +52 -0
  113. package/packages/core/src/markdown.ts +67 -0
  114. package/packages/core/src/ontology.ts +288 -0
  115. package/packages/core/src/open-map.ts +203 -0
  116. package/packages/core/src/operator/annotations.ts +187 -0
  117. package/packages/core/src/operator/client.ts +311 -0
  118. package/packages/core/src/operator/control.ts +117 -0
  119. package/packages/core/src/operator/index.ts +62 -0
  120. package/packages/core/src/operator/presentation.ts +22 -0
  121. package/packages/core/src/operator/protocol.ts +98 -0
  122. package/packages/core/src/operator/query.ts +201 -0
  123. package/packages/core/src/operator/registry.ts +1043 -0
  124. package/packages/core/src/operator/requests.ts +138 -0
  125. package/packages/core/src/operator/sandbox.ts +458 -0
  126. package/packages/core/src/operator/server.ts +616 -0
  127. package/packages/core/src/operator/sessions.ts +223 -0
  128. package/packages/core/src/operator/tickets.ts +177 -0
  129. package/packages/core/src/plugin-sdk/index.ts +174 -0
  130. package/packages/core/src/plugins/contract-entry.ts +74 -0
  131. package/packages/core/src/plugins/contract-env.ts +3 -0
  132. package/packages/core/src/plugins/load.ts +259 -0
  133. package/packages/core/src/plugins/manifest.ts +236 -0
  134. package/packages/core/src/plugins/registry.ts +274 -0
  135. package/packages/core/src/plugins/runtimes.ts +75 -0
  136. package/packages/core/src/ports/forge/contract.ts +258 -0
  137. package/packages/core/src/ports/forge/create.ts +74 -0
  138. package/packages/core/src/ports/forge/fake.ts +488 -0
  139. package/packages/core/src/ports/forge/github-pr-attachments.ts +351 -0
  140. package/packages/core/src/ports/forge/github-transport.ts +352 -0
  141. package/packages/core/src/ports/forge/github.ts +1162 -0
  142. package/packages/core/src/ports/forge/local-git.ts +568 -0
  143. package/packages/core/src/ports/runner/claude.ts +873 -0
  144. package/packages/core/src/ports/runner/cli-stream.ts +90 -0
  145. package/packages/core/src/ports/runner/codex.ts +873 -0
  146. package/packages/core/src/ports/runner/contract.ts +492 -0
  147. package/packages/core/src/ports/runner/fake.ts +213 -0
  148. package/packages/core/src/ports/runner/json-record.ts +2 -0
  149. package/packages/core/src/ports/runner/live-contract-fixture.ts +176 -0
  150. package/packages/core/src/ports/runner/one-shot.ts +29 -0
  151. package/packages/core/src/ports/runner/pi-bridge-core.ts +136 -0
  152. package/packages/core/src/ports/runner/pi-bridge.js +6 -0
  153. package/packages/core/src/ports/runner/pi-rpc.ts +454 -0
  154. package/packages/core/src/ports/runner/pi.ts +617 -0
  155. package/packages/core/src/ports/runner/production.ts +74 -0
  156. package/packages/core/src/ports/runner/provider-error.ts +121 -0
  157. package/packages/core/src/ports/runner/routing.ts +234 -0
  158. package/packages/core/src/ports/runner/runtime.ts +214 -0
  159. package/packages/core/src/ports/runner/session-env.ts +34 -0
  160. package/packages/core/src/ports/runner/stream-parts.ts +103 -0
  161. package/packages/core/src/ports/tickets/contract.ts +570 -0
  162. package/packages/core/src/ports/tickets/create.ts +135 -0
  163. package/packages/core/src/ports/tickets/fake.ts +215 -0
  164. package/packages/core/src/ports/tickets/file.ts +559 -0
  165. package/packages/core/src/ports/tickets/linear.ts +811 -0
  166. package/packages/core/src/ports/tickets/operations.ts +161 -0
  167. package/packages/core/src/ports/tickets/remote-index.ts +13 -0
  168. package/packages/core/src/ports/tickets/remote-protocol.ts +80 -0
  169. package/packages/core/src/ports/tickets/remote-server.ts +185 -0
  170. package/packages/core/src/ports/tickets/remote.ts +130 -0
  171. package/packages/core/src/ports/tickets/update.ts +51 -0
  172. package/packages/core/src/ports/types.ts +528 -0
  173. package/packages/core/src/ports/workspace/build-execution.ts +123 -0
  174. package/packages/core/src/ports/workspace/contract.ts +136 -0
  175. package/packages/core/src/ports/workspace/create.ts +132 -0
  176. package/packages/core/src/ports/workspace/distribution-archive.ts +317 -0
  177. package/packages/core/src/ports/workspace/fake.ts +432 -0
  178. package/packages/core/src/ports/workspace/git-worktree.ts +848 -0
  179. package/packages/core/src/ports/workspace/harvest-execution.ts +111 -0
  180. package/packages/core/src/ports/workspace/in-process-build-execution.ts +30 -0
  181. package/packages/core/src/ports/workspace/local-build-execution.ts +88 -0
  182. package/packages/core/src/ports/workspace/operator-sandbox.ts +142 -0
  183. package/packages/core/src/ports/workspace/phase-scratch.ts +156 -0
  184. package/packages/core/src/ports/workspace/vercel-sandbox.ts +2541 -0
  185. package/packages/core/src/processes/build-child-exit.ts +78 -0
  186. package/packages/core/src/processes/build-child.ts +119 -0
  187. package/packages/core/src/processes/build-execution-state.ts +95 -0
  188. package/packages/core/src/processes/build-parent-watch.ts +35 -0
  189. package/packages/core/src/processes/build-runner.ts +2614 -0
  190. package/packages/core/src/processes/dispatcher.ts +2825 -0
  191. package/packages/core/src/processes/execution-settlement.ts +171 -0
  192. package/packages/core/src/processes/harvest-child.ts +115 -0
  193. package/packages/core/src/processes/harvest-execution-state.ts +121 -0
  194. package/packages/core/src/processes/harvest-runner.ts +1656 -0
  195. package/packages/core/src/processes/harvest.ts +595 -0
  196. package/packages/core/src/processes/infrastructure-failure-budget.ts +146 -0
  197. package/packages/core/src/processes/phase-failure-budget.ts +52 -0
  198. package/packages/core/src/processes/process-group-reaper.ts +35 -0
  199. package/packages/core/src/processes/process-group.ts +65 -0
  200. package/packages/core/src/processes/publication-loss.ts +62 -0
  201. package/packages/core/src/processes/publication-state.ts +93 -0
  202. package/packages/core/src/processes/sandbox-state.ts +101 -0
  203. package/packages/core/src/registry.ts +24 -0
  204. package/packages/core/src/sessions/reducer.ts +185 -0
  205. package/packages/core/src/skills.ts +7 -0
  206. package/packages/core/src/spec-standard.ts +47 -0
  207. package/packages/core/src/store/adapter.ts +80 -0
  208. package/packages/core/src/store/build-scope.ts +272 -0
  209. package/packages/core/src/store/contract.ts +2581 -0
  210. package/packages/core/src/store/local/blobs.ts +38 -0
  211. package/packages/core/src/store/local/schema.ts +180 -0
  212. package/packages/core/src/store/local/store.ts +1713 -0
  213. package/packages/core/src/store/memory.ts +1138 -0
  214. package/packages/core/src/store/phase-session.ts +425 -0
  215. package/packages/core/src/store/remote/client.ts +780 -0
  216. package/packages/core/src/store/remote/index.ts +12 -0
  217. package/packages/core/src/store/remote/protocol.ts +348 -0
  218. package/packages/core/src/store/remote/server.ts +923 -0
  219. package/packages/core/src/store/remote/token.ts +137 -0
  220. package/packages/core/src/store/remote/version.ts +10 -0
  221. package/packages/core/src/store/retention.ts +91 -0
  222. package/packages/core/src/store/session-handle.ts +265 -0
  223. package/packages/core/src/store/streams/assemble.ts +79 -0
  224. package/packages/core/src/store/streams/lock.ts +42 -0
  225. package/packages/core/src/store/streams/session-writer.ts +306 -0
  226. package/packages/core/src/store/streams/types.ts +171 -0
  227. package/packages/core/src/store/streams/wait.ts +127 -0
  228. package/packages/core/src/store/subscribe.ts +105 -0
  229. package/packages/core/src/store/types.ts +466 -0
  230. package/packages/core/src/testing/fixed.ts +44 -0
  231. package/packages/core/src/testing/store-failures.ts +32 -0
  232. package/packages/core/src/zod-issues.ts +91 -0
  233. package/skills/code-review/SKILL.md +100 -0
  234. package/skills/finalize/SKILL.md +44 -0
  235. package/skills/guide/SKILL.md +1781 -0
  236. package/skills/guide/references/operator-api.md +164 -0
  237. package/skills/guide/references/plugin-authoring.md +354 -0
  238. package/skills/guide/references/remote-store-protocol.md +972 -0
  239. package/skills/guide/references/remote-ticket-protocol.md +79 -0
  240. package/skills/guide/references/setup.md +289 -0
  241. package/skills/guide/references/spec-standard.md +63 -0
  242. package/skills/guide/references/ticket-dependencies.md +59 -0
  243. package/skills/harvest/SKILL.md +66 -0
  244. package/skills/harvest-review/SKILL.md +63 -0
  245. package/skills/implement/SKILL.md +82 -0
  246. package/skills/plan/SKILL.md +123 -0
  247. package/skills/plan-review/SKILL.md +121 -0
  248. package/skills/reconcile/SKILL.md +65 -0
  249. package/skills/spec/SKILL.md +132 -0
  250. package/skills/tickets/SKILL.md +139 -0
  251. package/templates/autobuild.toml +36 -0
@@ -0,0 +1,79 @@
1
+ # Hosted ticket protocol
2
+
3
+ The hosted ticket protocol exposes the complete `TicketSource` port without
4
+ exposing backend credentials. It shares the Autobuild and remote protocol
5
+ version headers with the remote BuildStore. Both must exactly match the service;
6
+ this release uses remote protocol version `2`.
7
+
8
+ ## Authentication and context
9
+
10
+ Every request is `POST /tickets/<operation>`, has `Content-Type:
11
+ application/json`, and requires `Authorization: Bearer <token>`. Only a signed,
12
+ unexpired **deployment operator** token (`{ "operator": true, … }`) is accepted.
13
+ Attributed human-operator, legacy admin, build, repository, and session tokens
14
+ remain valid for their own routes but are denied on `/tickets`. Mint a deployment
15
+ operator token offline with:
16
+
17
+ ```sh
18
+ AB_STORE_SECRET='…' ab-hosted-store mint operator --ttl-seconds 3600
19
+ ```
20
+
21
+ The strict request envelope is:
22
+
23
+ ```json
24
+ {
25
+ "context": {
26
+ "teamKey": "ENG",
27
+ "claimedState": "Doing",
28
+ "createState": "Triage"
29
+ },
30
+ "input": {}
31
+ }
32
+ ```
33
+
34
+ `teamKey` is required. The state overrides are optional. They come from the
35
+ requesting repository's `[tickets]` configuration and are applied only to that
36
+ request; the service does not cache a team-bound adapter. `list-ready` also
37
+ receives that repository's exact ready state and label criteria in `input`.
38
+ Backend credentials, including `LINEAR_API_KEY`, are service environment only
39
+ and never occur in this envelope or any response.
40
+
41
+ ## Operations
42
+
43
+ The operation names and `input` values are:
44
+
45
+ | Operation | Input | Successful response |
46
+ |---|---|---|
47
+ | `list-ready` | `{labels?: string[], state?: string}` | `TicketListing` |
48
+ | `get` | `{id}` | `Ticket \| null` |
49
+ | `claim` | `{id}` | `{claimed: boolean}` |
50
+ | `comment` | `{id, body}` | `{ok: true}` |
51
+ | `transition` | `{id, state}` | `{ok: true}` |
52
+ | `create` | `{draft, options?}` | `Ticket` |
53
+ | `update` | `{id, patch}` | `{ok: true}` |
54
+ | `add-blocker` | `{id, blockerId}` | `{ok: true}` |
55
+ | `remove-blocker` | `{id, blockerId}` | `{ok: true}` |
56
+ | `dependency-states` | `{ids}` | `DependencyState[]` in input order |
57
+
58
+ Requests and responses reject unknown fields. Tickets include `ref`, optional
59
+ `creationKey`, `title`, `body`, optional `state`, `labels`, and optional
60
+ `blockedBy`. The client projects every returned `ref.source` as `hosted` while
61
+ preserving backend ids, URLs, titles, lifecycle values, labels, creation keys,
62
+ and blockers.
63
+
64
+ Ticket body strings are opaque. Clients, JSON handling, the service, and the
65
+ database backend must not trim or normalize bytes, newlines, Unicode, blank
66
+ lines, or trailing whitespace.
67
+
68
+ ## Errors and conformance
69
+
70
+ Errors are JSON `{ "error": string, "kind": "validation" | "not-found" |
71
+ "auth" | "conflict" | "internal" }`. Authentication runs before body parsing
72
+ or backend construction. Responses never include exception causes, stacks,
73
+ environment values, or credentials. Client 401/403 responses become
74
+ `AuthError`; other backend messages remain actionable.
75
+
76
+ The shared `TicketSource` contract is normative for the database adapter and
77
+ the hosted client/server pair. External pass-through is tested with a fake
78
+ source behind HTTP. The existing opt-in live Linear contract remains the proof
79
+ of Linear's GraphQL behavior; the hosted service uses that adapter unchanged.
package/docs/setup.md ADDED
@@ -0,0 +1,289 @@
1
+ # Repository setup
2
+
3
+ Configure Autobuild outside the build pipeline. This conversation is not a
4
+ build or phase. Work directly in the repository and involve the maintainer in
5
+ choices that cannot be derived from source. Secrets belong in the environment
6
+ or an ignored `.env`, never in `autobuild.toml`, commits, or validation reports.
7
+
8
+ ## Choose the execution environment
9
+
10
+ Keep the default `git-worktree` provider unless the maintainer explicitly opts
11
+ into remote builds. It creates local disposable worktrees and uses the tools,
12
+ network, and credentials available to the dispatcher machine.
13
+
14
+ For remote execution, set `[workspace].provider = "vercel-sandbox"`. A Vercel
15
+ Sandbox is a fresh independent machine; a runtime that works on the setup
16
+ machine is not evidence that it works there. Confirm all of these with the
17
+ maintainer before selecting it:
18
+
19
+ - the intended Vercel team and project;
20
+ - durable dispatcher authentication with `VERCEL_TOKEN`, `VERCEL_TEAM_ID`, and
21
+ `VERCEL_PROJECT_ID`, or short-lived `VERCEL_OIDC_TOKEN` obtained from a linked
22
+ project (`vercel link` and `vercel env pull`); when validating a target other
23
+ than the current directory, export OIDC in the launcher environment because
24
+ the Vercel SDK resolves it from ambient process state. Access-token
25
+ credentials in the target's ignored `.env` are the durable choice for a
26
+ continuously running local dispatcher;
27
+ - an HTTPS `github.com/owner/repository` origin and `forge = "github"`;
28
+ - a dispatcher-side push-capable `GITHUB_TOKEN` or `GH_TOKEN`;
29
+ - for a private repository, a separate read-only clone identity named by
30
+ `gitUsernameEnv` and `gitPasswordEnv`;
31
+ - an HTTPS hosted `AB_STORE` reachable from Vercel and a scoped `AB_TOKEN`;
32
+ - each selected role and alternate's runtime/model, its pinned
33
+ `[workspace.config.runtimeProvisioning.<runtime>]` commands, and the API
34
+ credential names it needs in `[workspace.config].environmentVariables`.
35
+
36
+ Do not put `AB_STORE`, `AB_TOKEN`, Vercel credentials, Forge credentials, or
37
+ private-clone credentials in `environmentVariables`. Autobuild supplies Store
38
+ credentials separately, keeps clone credentials out of guest commands, and
39
+ performs publication from the trusted host.
40
+
41
+ ```toml
42
+ [workspace]
43
+ provider = "vercel-sandbox"
44
+
45
+ [workspace.config]
46
+ image = "vercel/sandbox/universal:latest"
47
+ vcpus = 4
48
+ timeoutSeconds = 2700
49
+ environmentVariables = ["AI_GATEWAY_API_KEY"]
50
+ # Ordered system-level steps run once in every fresh/replacement sandbox as root.
51
+ provisioning = [
52
+ { name = "system-install", command = """apt-get update
53
+ DEBIAN_FRONTEND=noninteractive apt-get install -y chromium""" },
54
+ { name = "browser-smoke", command = "CHROMIUM_BIN=/usr/bin/chromium ./scripts/browser-smoke.sh" },
55
+ ]
56
+ # Private repositories only:
57
+ # gitUsernameEnv = "AB_GIT_READ_USER"
58
+ # gitPasswordEnv = "AB_GIT_READ_TOKEN"
59
+
60
+ [workspace.config.runtimeProvisioning.pi]
61
+ install = "npm install --global --ignore-scripts @earendil-works/pi-coding-agent@0.84.4"
62
+ preflight = "test \"$(pi --version)\" = \"0.84.4\""
63
+ ```
64
+
65
+ Use a `vercel-ai-gateway/...` Pi model with `AI_GATEWAY_API_KEY` in the
66
+ dispatcher environment. Do not copy `~/.pi`, OAuth refresh tokens, or any local
67
+ runtime auth state, and do not attempt interactive login in a sandbox. Runtime
68
+ names are open: a plugin runtime uses the same strict map, for example
69
+ `[workspace.config.runtimeProvisioning.opencode]`, with its own immutable
70
+ install and exact-version preflight commands.
71
+
72
+ ## Make the environment reproducible
73
+
74
+ Inspect the repository's manifests, documentation, CI, test layout, and
75
+ conventions. Read the installed sibling `../SKILL.md` for Autobuild's complete
76
+ configuration and ticket surfaces.
77
+
78
+ Use the supported `vercel/sandbox/universal` image. Other managed images and
79
+ custom VCR images are rejected. Autobuild remains stack-neutral. For Vercel,
80
+ put repository-specific operating-system packages and machine-level tooling in
81
+ the ordered `[workspace.config].provisioning` list. Each strict `{ name,
82
+ command }` entry runs from the checkout through `sh -c` with provider root
83
+ authority after pinned Bun is verified and before dependency bootstrap,
84
+ `[commands].setup`, or an agent. It runs once per fresh environment and repeats
85
+ on every replacement. Commands are declarative TOML string data, not evaluated
86
+ configuration logic. Local git worktrees never run this list; ensure their host
87
+ already has required system tooling.
88
+
89
+ Put each selected runtime's immutable install and executable/version check in
90
+ its `runtimeProvisioning` entry. Autobuild runs install then preflight after
91
+ checkout dependencies in every fresh/replacement sandbox and before the
92
+ readiness probe, writes the marker only after success, and reruns every
93
+ preflight before each build runner. A failure names the runtime, selecting
94
+ role/alternate, and field and starts no agent. Runtime provisioning receives
95
+ only the API credentials named by `[workspace.config].environmentVariables`.
96
+
97
+ Keep package-level and checkout-level bootstrap in an idempotent
98
+ `[commands].setup`. It runs after system provisioning and must remain safe to
99
+ rerun on attachment. Do not repeatedly install OS packages there. Expose only
100
+ required runtime credentials through
101
+ `[workspace.config].environmentVariables`, keep generated caches disposable,
102
+ and lock dependencies in the repository. A browser-capable repository should
103
+ check in a dependency-free `scripts/browser-smoke.sh` that starts its dev server,
104
+ uses a repository-controlled path such as `CHROMIUM_BIN=/usr/bin/chromium` to
105
+ launch headless Chromium in the same guest, verifies the rendered page, and
106
+ exits nonzero on failure. Then:
107
+
108
+ 1. Configure real `[commands]` and ordered `[verify]` steps from the toolchain
109
+ this repository actually uses. Do not invent commands or retain placeholders.
110
+ 2. Decide the runtime and model arrangement for every pipeline role and
111
+ alternate. The runtime that launched setup and the temporary fresh-skeleton
112
+ default do not constrain the final arrangement.
113
+ 3. Choose the ticket source and workflow states. Confirm account/team facts and
114
+ required environment credentials. Configure end-to-end verification with the
115
+ repository's real lifecycle and tools. When judgment is required, author a repository-owned
116
+ agent-verify skill and select it from an agent verify step.
117
+ 4. Preserve an existing `autobuild.toml` and unrelated repository choices on a
118
+ rerun. Change only choices the maintainer approves.
119
+ 5. Commit the config, setup files, lockfiles, and installed reference changes,
120
+ then push them to `baseBranch`. A remote sandbox clones the authoritative
121
+ GitHub revision; it cannot acquire local-only edits.
122
+ 6. Run `ab init --validate`. Fix every named failure and rerun until every check
123
+ passes. Only then use the installed grooming/ticket skills to create the
124
+ first groomed Ready ticket and start `ab dispatch`.
125
+
126
+ Validation is explicit and noninteractive. It does not dispatch, claim a
127
+ ticket, or create build, phase, session, event, transcript, or artifact history.
128
+ For local execution it identifies and removes a disposable detached worktree.
129
+ For Vercel it identifies and permanently deletes a fresh unnamed sandbox, even
130
+ when system or runtime provisioning, setup, or a probe fails; cleanup failures
131
+ name the environment for manual deletion. Its `system provisioning` check lists
132
+ completed step names (or says none were declared) before guest setup checks. A
133
+ failed step reports its name, command, status, labeled stdout/stderr, and
134
+ remediation without marking the environment ready. It provisions/preflights
135
+ every effective primary and alternate runtime, then runs `commands.setup`, loads
136
+ repository plugins, and checks every
137
+ selected primary/alternate runtime and model, and performs a read-only Store
138
+ request in the candidate execution context. If the local database is absent,
139
+ validation reports that no repository history is available without creating
140
+ `.autobuild` or any SQLite files. If it exists, validation copies the database
141
+ and any WAL/SHM sidecars to a disposable filesystem snapshot and inspects that
142
+ copy without SQLite-opening or modifying the repository Store files. It never
143
+ silently falls back from Vercel to local execution. Local launcher probes
144
+ printed by ordinary `ab init` are only setup-agent discovery and are not remote
145
+ readiness evidence.
146
+
147
+ Typical remediation is intentionally specific: add a missing system executable
148
+ to `workspace.config.provisioning` (or a package dependency to setup) while
149
+ retaining the universal image; add a runtime credential name to
150
+ `environmentVariables` and its value to the dispatcher environment; correct the
151
+ Vercel team/project credential set; provide separate private-clone credentials;
152
+ use an HTTPS GitHub origin and hosted Store; authorize the Store token; or commit
153
+ and push the selected base branch.
154
+
155
+ ## Repository identity is the origin, not a checkout path
156
+
157
+ Repository identity in the Store, dispatcher, `ab builds`, `ab build status`,
158
+ `ab repository status`, and the web app is the repository's **normalized origin
159
+ URL** (`https://github.com/owner/repository`), not a checkout's absolute path.
160
+ Two checkouts of the same repository — on different hosts, or a dispatcher and
161
+ its sandboxes — agree on one identity.
162
+
163
+ Records written before this change are keyed by checkout path and are **not
164
+ migrated**. They remain visible only where their recorded `repoOrigin` matches
165
+ the querying checkout's origin; dropping the old identity's history is an
166
+ accepted trade for path-free operation.
167
+
168
+ ## Running the dispatcher without a checkout (origin mode)
169
+
170
+ A dispatcher can operate a repository with no local checkout at all — from a
171
+ serverless function or any host with only network access:
172
+
173
+ ```sh
174
+ ab dispatch --repository https://github.com/owner/repository \\
175
+ --plain --store https://hosted-store.example \\
176
+ # environment: AB_TOKEN (store), GITHUB_TOKEN or GH_TOKEN (GitHub API)
177
+ ```
178
+
179
+ `--repository` (or `AB_REPOSITORY`) is the normalized origin. Origin mode
180
+ requires an HTTPS `AB_STORE` plus `AB_TOKEN`, an exported `GITHUB_TOKEN` or
181
+ `GH_TOKEN`, and `forge = "github"`; the interactive dashboard is unavailable
182
+ (`--plain` or no TTY). Origin mode never consults the gh CLI: a checkout-less
183
+ host has no gh and no keyring, and the only workspace provider it can run,
184
+ `vercel-sandbox`, injects that same exported token for publication. The gh CLI
185
+ fallback (`GITHUB_TOKEN`, then `GH_TOKEN`, then the login stored by `gh auth
186
+ login`) is a checkout-mode convenience for a local dispatcher whose workspace
187
+ provider is not `vercel-sandbox`; that provider requires the exported token in
188
+ every mode. The
189
+ startup configuration — and every per-tick reload — is `autobuild.toml` read
190
+ from the forge at the current `baseBranch` (the first read resolves against the
191
+ repository's default branch), so a push to the base branch is honored by a
192
+ later tick without restarting anything. Configs declaring local `plugins` are
193
+ rejected: plugin code is checkout-relative. The guest installs the Autobuild
194
+ distribution published for its version — the npm registry tarball, else the
195
+ GitHub release asset `autobuild-<version>.tgz` — so origin-mode dispatch
196
+ requires a published release.
197
+
198
+ ### Guest distribution version selection and delivery
199
+
200
+ The guest's distribution version is selected by the archive source, and both
201
+ sources agree with the running system by construction:
202
+
203
+ - **Source checkout** (dispatcher running from a repository checkout): the
204
+ guest archive is packed from the host tree with `bun pm pack`, so the guest
205
+ runs the dispatcher's own code.
206
+ - **Origin mode** (checkout-less dispatcher): the guest archive is the release
207
+ asset `autobuild-<version>.tgz` fetched from the canonical repository at the
208
+ **running dispatcher's version** (read from the deployed distribution's
209
+ `package.json`), so the guest runs the dispatcher's own release.
210
+
211
+ The hosted remote store enforces exact **version lockstep**: every client
212
+ request must carry an `x-autobuild-version` equal to the server's, and any
213
+ mismatch — a guest older *or* newer than the store — is rejected with a 409
214
+ `remote store version mismatch`. Guest, store, and dispatcher versions
215
+ therefore cannot be mixed: a distribution fix reaches guests only after
216
+ `tools/release.ts` cuts a release (credential-gated; requires GitHub
217
+ credentials — a documented delivery dependency, not an automatic propagation)
218
+ **and** the hosted store and dispatcher are upgraded to that release in the
219
+ same lockstep window. If the release is cut but the store upgrade lags, guests
220
+ carrying the new distribution fail loudly against the old store (409) rather
221
+ than running silently stale.
222
+
223
+ Provisioning records the installed distribution's version in the guest's
224
+ `/opt/autobuild/.distribution-version` marker. A reused persistent sandbox
225
+ whose marker disagrees with the version the current system would deliver —
226
+ which includes every guest provisioned before the marker existed — is
227
+ refreshed in place (archive re-fetched, extracted, and production-installed)
228
+ before being reused, so an upgraded dispatcher retrofits its existing guests
229
+ instead of resuming a stale distribution. A refresh failure deletes the
230
+ sandbox so the next provisioning pass rematerializes it from scratch.
231
+
232
+ After a lockstep upgrade, confirm a fix-bearing guest from the guest
233
+ perspective:
234
+
235
+ 1. `ab build status <slug> --json` with the ambient build identity for a
236
+ build whose record carries `repoOrigin` succeeds and exposes `.pr.number`
237
+ and `.pr.url` even though the guest's checkout path differs from the path
238
+ recorded at build creation (post-#297 origin-equality behavior).
239
+ 2. The same command for a genuinely foreign repository's slug still fails
240
+ with the `belongs to repository … not …` rejection.
241
+
242
+ Local `git-worktree` dispatch keeps working from a checkout exactly as before;
243
+ apart from the identity change, `ab dispatch` behaves as it did.
244
+
245
+ ## Hosted deployment variables
246
+
247
+ A hosted-store deployment configures its web/auth variables once — see the
248
+ hosted service README and the complete environment reference in the pinned
249
+ distribution checkout: `BETTER_AUTH_URL`, `AB_WEB_ALLOWED_EMAILS`,
250
+ `AB_WEB_REPOSITORIES`, and the optional `AB_WEB_MCP_RESOURCE` — the protected
251
+ resource the hosted MCP server (docs/mcp.md) binds its OAuth tokens to,
252
+ defaulting to `<BETTER_AUTH_URL>/mcp`. Set it only when a proxy or custom
253
+ domain fronts the deployment under a different public URL than
254
+ `BETTER_AUTH_URL`; the value must be an absolute http(s) URL (https in
255
+ production) or every MCP client's discovery binds tokens to the wrong
256
+ resource.
257
+
258
+ ## Authoring an agent verifier
259
+
260
+ A repository-owned agent-verify skill is a verifier, not a reviewer: it drives
261
+ the running application and observes whether the spec's acceptance criteria
262
+ hold. It does not inspect the diff for style or edit product code.
263
+
264
+ Its session instructions must preserve this contract:
265
+
266
+ 1. Run `ab context`. The verifier receives `.ab/spec.md`, the configured step,
267
+ the commit range, and, after escalation is answered, `.ab/guidance.json`.
268
+ 2. Exercise each applicable acceptance criterion through the repository's real
269
+ application lifecycle. Prefer the narrowest honest flow that catches a
270
+ regression.
271
+ 3. Write criterion-oriented evidence: criterion, action, observation, and
272
+ pass/fail. Failures include reproduction inputs, expected/observed behavior,
273
+ and relevant repository-native logs.
274
+ 4. Deposit passing review evidence explicitly with
275
+ `ab artifact put <kind> <file> --attach`. Never attach failed or partial
276
+ output; use stable kinds so retries replace the designation.
277
+ 5. Finish with exactly one terminal:
278
+
279
+ ```text
280
+ ab verdict pass --notes <report-file>
281
+ ab verdict fail --report <report-file>
282
+ ab verdict skip --reason "Why this entire step does not apply"
283
+ ```
284
+
285
+ An applicable behavior that cannot be exercised is a failure with an
286
+ explanation, never a skip or silent pass. Use `skip` only when the complete step
287
+ does not apply. If guidance still cannot make a verdict possible, escalate and
288
+ explain what remains unresolved. Record out-of-scope work with `ab observe`;
289
+ the verifier does not fix it.
@@ -0,0 +1,63 @@
1
+ # The spec standard
2
+
3
+ This document is the complete reference definition of **buildable**. Every
4
+ ticket-producing surface uses the same standard: interactive specification,
5
+ harvest, ingesters, and dispatch. An ingester's proposal is a spec written to
6
+ this standard with weaker evidence. Dispatch's quality gate returns any Ready
7
+ ticket that cannot be expanded into a conforming spec to Triage, citing this
8
+ standard.
9
+
10
+ A conforming spec has four parts:
11
+
12
+ ## 1. What and why — never how
13
+
14
+ State the change in terms of observable behavior and the reason it matters.
15
+ Implementation strategy belongs to the `plan` phase; a spec that prescribes
16
+ file names, function signatures, or libraries is over-specified and will
17
+ mislead the planner. One or two paragraphs.
18
+
19
+ - Bad: "Add a `RateLimiter` class in `src/middleware/` using a token bucket."
20
+ - Good: "Login attempts are currently unlimited; an attacker can brute-force
21
+ credentials. After this change, repeated failed logins from one source are
22
+ throttled, and legitimate users see a clear retry-after message."
23
+
24
+ ## 2. Acceptance criteria
25
+
26
+ A checklist of verifiable statements that define done. Each criterion must be
27
+ something a reviewer or a verify step can actually check — behavior, not
28
+ intention. These become the contract that `plan-review`, `code-review`, and
29
+ `verify:*` all measure against.
30
+
31
+ - Each criterion is a single observable fact ("a sixth failed login within
32
+ five minutes returns 429 with a Retry-After header").
33
+ - Avoid criteria that cannot fail ("code is clean").
34
+ - Do not predict which repository paths implementation will touch. Tickets
35
+ describe observable behavior; any repository-configured path applicability
36
+ is evaluated later by the kernel from the build's actual diff in each verify
37
+ cycle.
38
+
39
+ ## 3. Out of scope — explicit
40
+
41
+ Name the adjacent work this spec deliberately excludes. This is what keeps
42
+ builds from thrashing: the implementer files an `ab observe` observation for
43
+ out-of-scope discoveries instead of expanding the diff, and the reviewer
44
+ cannot demand out-of-scope work in findings.
45
+
46
+ ## 4. Evidence
47
+
48
+ Links and data supporting the why: the Sentry issue and its frequency, the
49
+ observation events that were clustered into this proposal, the conversation
50
+ where the human decided this matters. Evidence strength varies by origin —
51
+ a human-authored `/spec` may cite a decision; an `ingest:sentry` proposal
52
+ cites error counts and affected users. Weak evidence is acceptable; absent
53
+ evidence is not.
54
+
55
+ ---
56
+
57
+ ## Immutability during a build
58
+
59
+ The spec is the build's contract artifact (kind `spec`, revision 0). It
60
+ cannot change during a build because every downstream reviewer approves
61
+ conformance *to it*. A phase that discovers the spec itself is wrong raises
62
+ an escalation (`ab escalate`); a human answers, the spec gets revision N+1,
63
+ and the build restarts from `plan`.
@@ -0,0 +1,59 @@
1
+ # Filing tickets with blockers safely
2
+
3
+ `ab ticket create --blocked-by` validates prerequisite ids and records blocking
4
+ relationships, but a single CLI command is **not an atomic publication guarantee**.
5
+ In particular, direct Linear and hosted Linear create the issue first and add
6
+ its blocker relationships in separate requests. If the issue is already in the
7
+ ready state, a dispatcher can see it before those relationships exist. A
8
+ successful create response containing every blocker does not prove that no build
9
+ was claimed during the request. Harvest's durable creation reservations protect
10
+ its own filing workflow; ordinary interactive ticket creation has no such hold.
11
+
12
+ ## Safe interactive workflow
13
+
14
+ For tickets with prerequisites, determine the intended final state from the
15
+ human's instruction, then the configured create state or source default. Do not
16
+ invent a different final destination. If that destination is ready, or the source
17
+ default's eligibility is unknown, stage the ticket in a known non-ready state
18
+ before publishing it. Use the repository's triage state when it differs from its
19
+ ready state. This temporary staging does not require another placement approval.
20
+ If no non-ready state can be established, resolve that before creating the
21
+ dependent; never guess that a name such as "Backlog" is safe in every repository.
22
+
23
+ 1. Create prerequisites in dependency order and extract each new `.ref.id` from
24
+ the complete `--json` response, never the human confirmation line.
25
+ 2. Create the dependent in the non-ready staging state with **all** known
26
+ `--blocked-by` ids in the create command.
27
+ 3. Read it back with `ab ticket show <id> --json`. Verify its state is still
28
+ non-ready and every expected blocker is present. Repair missing relationships
29
+ through `ab ticket block`, then read back again.
30
+ 4. Only after verification, move it to the intended final state with
31
+ `ab ticket move <id> <state> --json`. Verify the final state and blockers.
32
+
33
+ For a repository whose configured triage and ready states are `Triage` and
34
+ `Ready`, respectively, and whose human requested ready placement:
35
+
36
+ ```sh
37
+ ab ticket create "Dependent" --body dependent.md --state Triage --blocked-by ENG-8,ENG-9 --json > dependent-ticket.json
38
+ dependent_id="$(jq -r '.ref.id' dependent-ticket.json)"
39
+ ab ticket show "$dependent_id" --json
40
+ # Verify state and the full blocker set before the following command.
41
+ ab ticket move "$dependent_id" Ready --json
42
+ ```
43
+
44
+ If creation fails after an issue may have been written, find and repair that
45
+ issue rather than blindly creating a duplicate. Leave partial work non-ready
46
+ until the blockers are verified. If the intended destination was already
47
+ non-ready, create there, verify, and leave it there. For a source default that
48
+ cannot be determined, clarify the final destination rather than silently making
49
+ the ticket ready.
50
+
51
+ ## Already-claimed work
52
+
53
+ Adding blockers does not stop a build already claimed from an earlier listing.
54
+ When the human authorizes restarting premature work: request `ab abort <slug>`,
55
+ wait for dispatcher cleanup to finish and return the ticket to triage, verify
56
+ or repair the blocker set, and only then move the ticket back to ready. Moving
57
+ the ticket before cleanup finishes can be overwritten by cleanup. Ready with
58
+ unresolved blockers is the normal waiting state: dispatch rechecks dependencies
59
+ and claims the ticket only after they resolve and other readiness gates pass.
@@ -0,0 +1,7 @@
1
+ # Vercel Sandbox rollout probe
2
+
3
+ This PR records the rollout probe for hosted ticket [AUT-295](https://linear.app/defrex/issue/AUT-295) and build `vercel-recovery-probe-2`, published from branch `ab/vercel-recovery-probe-2`.
4
+
5
+ The build's durable Store event stream and attached artifacts are the substantive evidence. Together they record Vercel Sandbox execution with noninteractive Pi served through Vercel AI Gateway; controlled replacement of the original environment with same-build resumption; configured checks and manual terminal/web visual verdicts; finalization and publication to this PR; and exact resource cleanup. Store execution, workspace, session, verification, publication, finalize, PR, and cleanup events carry the operational identities and outcomes without duplicating them here.
6
+
7
+ The passing visual reports are attached as `rollout-probe:terminal-report` and `rollout-probe:web-report`. Every inspected image is attached under its stable `dashboard-frame:<frame>:png` or `web-dashboard-frame:<frame>:png` kind.
package/package.json ADDED
@@ -0,0 +1,135 @@
1
+ {
2
+ "name": "@defrex/autobuild",
3
+ "version": "0.8.0",
4
+ "description": "Agent-driven software delivery from groomed ticket to merged PR",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/defrex/autobuild.git"
8
+ },
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
12
+ "license": "Apache-2.0",
13
+ "type": "module",
14
+ "workspaces": [
15
+ "packages/*"
16
+ ],
17
+ "engines": {
18
+ "bun": ">=1.4.0"
19
+ },
20
+ "packageManager": "bun@1.4.0",
21
+ "bin": {
22
+ "ab": "bin/ab.ts"
23
+ },
24
+ "exports": {
25
+ "./plugin-sdk": {
26
+ "types": "./packages/core/src/plugin-sdk/index.ts",
27
+ "import": "./packages/core/src/plugin-sdk/index.ts",
28
+ "default": "./packages/core/src/plugin-sdk/index.ts"
29
+ },
30
+ "./store-adapter": {
31
+ "types": "./packages/core/src/store/adapter.ts",
32
+ "import": "./packages/core/src/store/adapter.ts",
33
+ "default": "./packages/core/src/store/adapter.ts"
34
+ },
35
+ "./remote-store": {
36
+ "types": "./packages/core/src/store/remote/index.ts",
37
+ "import": "./packages/core/src/store/remote/index.ts",
38
+ "default": "./packages/core/src/store/remote/index.ts"
39
+ },
40
+ "./operator-api": {
41
+ "types": "./packages/core/src/operator/index.ts",
42
+ "import": "./packages/core/src/operator/index.ts",
43
+ "default": "./packages/core/src/operator/index.ts"
44
+ },
45
+ "./operator-presentation": {
46
+ "types": "./packages/core/src/operator/presentation.ts",
47
+ "import": "./packages/core/src/operator/presentation.ts",
48
+ "default": "./packages/core/src/operator/presentation.ts"
49
+ },
50
+ "./ticket-update": {
51
+ "types": "./packages/core/src/ports/tickets/update.ts",
52
+ "import": "./packages/core/src/ports/tickets/update.ts",
53
+ "default": "./packages/core/src/ports/tickets/update.ts"
54
+ },
55
+ "./remote-tickets": {
56
+ "types": "./packages/core/src/ports/tickets/remote-index.ts",
57
+ "import": "./packages/core/src/ports/tickets/remote-index.ts",
58
+ "default": "./packages/core/src/ports/tickets/remote-index.ts"
59
+ },
60
+ "./origin": {
61
+ "types": "./packages/core/src/kernel/origin.ts",
62
+ "import": "./packages/core/src/kernel/origin.ts",
63
+ "default": "./packages/core/src/kernel/origin.ts"
64
+ },
65
+ "./cli": {
66
+ "types": "./packages/core/src/cli/dispatch.ts",
67
+ "import": "./packages/core/src/cli/dispatch.ts",
68
+ "default": "./packages/core/src/cli/dispatch.ts"
69
+ },
70
+ "./git-worktree": {
71
+ "types": "./packages/core/src/ports/workspace/git-worktree.ts",
72
+ "import": "./packages/core/src/ports/workspace/git-worktree.ts",
73
+ "default": "./packages/core/src/ports/workspace/git-worktree.ts"
74
+ },
75
+ "./distribution": {
76
+ "types": "./packages/core/src/ports/workspace/distribution-archive.ts",
77
+ "import": "./packages/core/src/ports/workspace/distribution-archive.ts",
78
+ "default": "./packages/core/src/ports/workspace/distribution-archive.ts"
79
+ }
80
+ },
81
+ "files": [
82
+ "bin",
83
+ "packages/core/src",
84
+ "!packages/core/src/**/*.test.ts",
85
+ "skills",
86
+ "templates",
87
+ "LICENSE",
88
+ "README.md",
89
+ "SPEC.md",
90
+ "docs"
91
+ ],
92
+ "scripts": {
93
+ "dev": "bun run --bun next dev",
94
+ "dev:cli": "bun --hot --no-clear-screen bin/ab-dev.ts",
95
+ "build": "bun run --bun next build",
96
+ "deploy:build": "bun packages/hosted-store-service/src/bin.ts pack-distribution && bun run postgres:migrate && bun run build && bun tools/ship-packed-distribution.ts",
97
+ "start": "bun run --bun next start",
98
+ "hosted-store": "bun server.ts",
99
+ "capture:dashboard": "bun tools/dashboard-capture.ts",
100
+ "capture:web-dashboard": "bun tools/web-dashboard-capture.tsx",
101
+ "capture:readme-headline": "bun tools/readme-headline.ts",
102
+ "release": "bun tools/release.ts",
103
+ "postgres:migrate": "bun packages/postgres-store/src/bin.ts migrate",
104
+ "check": "bun tools/biome-check.ts && bun tools/product-name-check.ts && bun tools/docs-asset-check.ts && bun tools/readme-headline.ts --check && bun tools/workspace-manifest-check.ts",
105
+ "format:staged": "git-format-staged --formatter './node_modules/.bin/biome format --stdin-file-path {}' '*.js' '*.jsx' '*.ts' '*.tsx' '*.json' '*.jsonc' '*.css' '*.graphql' '*.gql'",
106
+ "prepare": "husky",
107
+ "test": "bun test packages/*/src tools bin app",
108
+ "typecheck": "tsc --noEmit"
109
+ },
110
+ "dependencies": {
111
+ "@modelcontextprotocol/sdk": "^1.30.0",
112
+ "@vercel/sandbox": "^3.1.0",
113
+ "ai": "^7.0.101",
114
+ "drizzle-orm": "^0.45.2",
115
+ "semver": "^7.7.4",
116
+ "smol-toml": "^1.7.0",
117
+ "zod": "^4.4.3"
118
+ },
119
+ "devDependencies": {
120
+ "@biomejs/biome": "2.5.5",
121
+ "@resvg/resvg-js": "2.6.2",
122
+ "@types/bun": "^1.3.14",
123
+ "@types/node": "^24.0.0",
124
+ "@types/pg": "8.16.0",
125
+ "@types/react": "19.2.14",
126
+ "@types/react-dom": "19.2.3",
127
+ "@types/semver": "^7.7.1",
128
+ "dejavu-fonts-ttf": "2.37.0",
129
+ "drizzle-kit": "^0.31.10",
130
+ "git-format-staged": "4.0.1",
131
+ "husky": "9.1.7",
132
+ "typescript": "5.9.3",
133
+ "vercel": "^59.11.2"
134
+ }
135
+ }