@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,47 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/** Private shipped child: one operating-system process per build. */
|
|
3
|
+
import { runBuildChild } from '../packages/core/src/processes/build-child'
|
|
4
|
+
import { BuildChildExitCoordinator } from '../packages/core/src/processes/build-child-exit'
|
|
5
|
+
import { watchBuildParent } from '../packages/core/src/processes/build-parent-watch'
|
|
6
|
+
import { BUILD_RUNNER_OPTIONS_ENV } from '../packages/core/src/ports/workspace/local-build-execution'
|
|
7
|
+
import {
|
|
8
|
+
parseBuildChildLaunch,
|
|
9
|
+
type BuildChildLaunch,
|
|
10
|
+
} from '../packages/core/src/ports/workspace/build-execution'
|
|
11
|
+
|
|
12
|
+
const raw = process.env[BUILD_RUNNER_OPTIONS_ENV]
|
|
13
|
+
let input: BuildChildLaunch | undefined
|
|
14
|
+
try {
|
|
15
|
+
input = parseBuildChildLaunch(raw === undefined ? undefined : JSON.parse(raw))
|
|
16
|
+
} catch {
|
|
17
|
+
// Invalid immutable launch envelope exits below.
|
|
18
|
+
}
|
|
19
|
+
if (input === undefined) process.exit(2)
|
|
20
|
+
|
|
21
|
+
let exitCode = 0
|
|
22
|
+
if (input.supervision.kind === 'local-parent') {
|
|
23
|
+
// Every local exit first transfers group teardown to an owner outside this
|
|
24
|
+
// session. Environment-owned execution deliberately installs neither this
|
|
25
|
+
// group reaper nor a meaningless host-PID watchdog.
|
|
26
|
+
const terminal = new BuildChildExitCoordinator({ groupId: process.pid })
|
|
27
|
+
process.on('SIGINT', () => terminal.terminate(130))
|
|
28
|
+
process.on('SIGTERM', () => terminal.terminate(143))
|
|
29
|
+
terminal.setParentWatch(
|
|
30
|
+
watchBuildParent(input.supervision.parentPid, () => terminal.terminate(143)),
|
|
31
|
+
)
|
|
32
|
+
try {
|
|
33
|
+
await runBuildChild(input, process.env)
|
|
34
|
+
} catch {
|
|
35
|
+
exitCode = 1
|
|
36
|
+
}
|
|
37
|
+
terminal.terminate(exitCode)
|
|
38
|
+
} else {
|
|
39
|
+
// Vercel owns teardown of the complete VM session. Addressing a POSIX group
|
|
40
|
+
// here could leave the SDK believing a still-running environment completed.
|
|
41
|
+
try {
|
|
42
|
+
await runBuildChild(input, process.env)
|
|
43
|
+
} catch {
|
|
44
|
+
exitCode = 1
|
|
45
|
+
}
|
|
46
|
+
process.exit(exitCode)
|
|
47
|
+
}
|
package/bin/ab-dev.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/** Repo-local Bun hot entry. This file is not exposed through package.json#bin. */
|
|
3
|
+
import { runBinary } from '../packages/core/src/cli/binary'
|
|
4
|
+
import { evaluateDevCli, type DevCliState } from '../packages/core/src/cli/dev'
|
|
5
|
+
import { renderDashboard } from '../packages/core/src/cli/dashboard/render'
|
|
6
|
+
|
|
7
|
+
const STATE_KEY = Symbol.for('autobuild.cli.dashboard-dev')
|
|
8
|
+
const globals = globalThis as unknown as Record<symbol, DevCliState | undefined>
|
|
9
|
+
const state = globals[STATE_KEY] ?? {}
|
|
10
|
+
globals[STATE_KEY] = state
|
|
11
|
+
|
|
12
|
+
// Do not top-level-await: Bun must be able to finish evaluating this module and
|
|
13
|
+
// evaluate it again when presentation sources change.
|
|
14
|
+
evaluateDevCli({
|
|
15
|
+
state,
|
|
16
|
+
renderer: renderDashboard,
|
|
17
|
+
launch: (resolveDashboardRenderer) => runBinary(process.argv.slice(2), resolveDashboardRenderer),
|
|
18
|
+
settle: (run) => {
|
|
19
|
+
void run.then(
|
|
20
|
+
(code) => process.exit(code),
|
|
21
|
+
(error: unknown) => {
|
|
22
|
+
console.error(error instanceof Error ? error.message : String(error))
|
|
23
|
+
process.exit(1)
|
|
24
|
+
},
|
|
25
|
+
)
|
|
26
|
+
},
|
|
27
|
+
})
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/** Private, shipped child for the interactive `ab dispatch` kernel. It owns no
|
|
3
|
+
* terminal handles; the public command launches it with immutable options. */
|
|
4
|
+
import { abDispatch } from '../packages/core/src/cli/dispatch'
|
|
5
|
+
import {
|
|
6
|
+
DISPATCH_CHILD_OPTIONS_ENV,
|
|
7
|
+
type DispatchChildOptions,
|
|
8
|
+
installDispatchKernelSignalHandlers,
|
|
9
|
+
watchDispatchParent,
|
|
10
|
+
} from '../packages/core/src/cli/dispatch-process'
|
|
11
|
+
import { DISPATCHER } from '../packages/core/src/events/envelope'
|
|
12
|
+
import { spawnExec } from '../packages/core/src/ports/workspace/git-worktree'
|
|
13
|
+
import { resolveRepoState } from '../packages/core/src/cli/repo-state'
|
|
14
|
+
import { openStoreForRepoState } from '../packages/core/src/cli/store-opening'
|
|
15
|
+
|
|
16
|
+
const raw = process.env[DISPATCH_CHILD_OPTIONS_ENV]
|
|
17
|
+
if (raw === undefined) process.exit(2)
|
|
18
|
+
let options: DispatchChildOptions
|
|
19
|
+
try {
|
|
20
|
+
options = JSON.parse(raw) as DispatchChildOptions
|
|
21
|
+
} catch {
|
|
22
|
+
process.exit(2)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const stop = new AbortController()
|
|
26
|
+
const requestStop = (): void => stop.abort()
|
|
27
|
+
// Keep both handlers installed through the complete graceful drain. The first
|
|
28
|
+
// targeted SIGINT comes from the supervisor; later foreground-group signals
|
|
29
|
+
// must not regain their default disposition inside an open claim tick.
|
|
30
|
+
const signalHandlers = installDispatchKernelSignalHandlers(requestStop)
|
|
31
|
+
const parentWatch = watchDispatchParent(process.ppid, requestStop)
|
|
32
|
+
let exitCode = 0
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
await abDispatch({
|
|
36
|
+
targetRepo: options.targetRepo,
|
|
37
|
+
storeRef: options.storeRef,
|
|
38
|
+
env: process.env,
|
|
39
|
+
exec: spawnExec,
|
|
40
|
+
stdout: () => {},
|
|
41
|
+
stderr: () => {},
|
|
42
|
+
once: options.once,
|
|
43
|
+
...(options.intervalMs !== undefined ? { intervalMs: options.intervalMs } : {}),
|
|
44
|
+
signal: stop.signal,
|
|
45
|
+
plain: true,
|
|
46
|
+
silent: true,
|
|
47
|
+
kernelRunId: options.run,
|
|
48
|
+
})
|
|
49
|
+
} catch (error) {
|
|
50
|
+
exitCode = 1
|
|
51
|
+
// Config/plugin/adapter startup can fail before abDispatch owns a Store and
|
|
52
|
+
// writes run-started. Reopen only the already-resolved Store identity so the
|
|
53
|
+
// terminal frontend receives the actionable failure rather than a generic
|
|
54
|
+
// child exit status.
|
|
55
|
+
try {
|
|
56
|
+
const state = await resolveRepoState({
|
|
57
|
+
targetRepo: options.targetRepo,
|
|
58
|
+
storeRef: options.storeRef,
|
|
59
|
+
exec: spawnExec,
|
|
60
|
+
})
|
|
61
|
+
const opened = openStoreForRepoState(state, { env: process.env })
|
|
62
|
+
try {
|
|
63
|
+
await opened.store.ensureRepo(state.repo)
|
|
64
|
+
const events = await opened.store.getRepoEvents(state.repo)
|
|
65
|
+
if (
|
|
66
|
+
!events.some(
|
|
67
|
+
(event) => event.type === 'dispatcher.run-stopped' && event.payload.run === options.run,
|
|
68
|
+
)
|
|
69
|
+
) {
|
|
70
|
+
await opened.store.appendRepo(state.repo, {
|
|
71
|
+
actor: DISPATCHER,
|
|
72
|
+
type: 'dispatcher.run-stopped',
|
|
73
|
+
payload: {
|
|
74
|
+
run: options.run,
|
|
75
|
+
outcome: 'abnormal',
|
|
76
|
+
exitCode: 1,
|
|
77
|
+
error: error instanceof Error ? error.message : String(error),
|
|
78
|
+
},
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
} finally {
|
|
82
|
+
await opened.store.close()
|
|
83
|
+
}
|
|
84
|
+
} catch {
|
|
85
|
+
// The supervisor still records the process exit if even the Store cannot
|
|
86
|
+
// be opened. Preserve the original startup failure as the exit cause.
|
|
87
|
+
}
|
|
88
|
+
} finally {
|
|
89
|
+
parentWatch.close()
|
|
90
|
+
signalHandlers.close()
|
|
91
|
+
}
|
|
92
|
+
process.exit(exitCode)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/** Private shipped child: one disposable environment per hosted harvest run.
|
|
3
|
+
* The environment owns teardown (no process-group reaper, no parent watchdog)
|
|
4
|
+
* — the same contract as the build child's `environment` branch. */
|
|
5
|
+
import { runHarvestChild } from '../packages/core/src/processes/harvest-child'
|
|
6
|
+
import {
|
|
7
|
+
HARVEST_RUNNER_OPTIONS_ENV,
|
|
8
|
+
parseHarvestRunnerLaunch,
|
|
9
|
+
type HarvestRunnerLaunch,
|
|
10
|
+
} from '../packages/core/src/ports/workspace/harvest-execution'
|
|
11
|
+
|
|
12
|
+
const raw = process.env[HARVEST_RUNNER_OPTIONS_ENV]
|
|
13
|
+
let input: HarvestRunnerLaunch | undefined
|
|
14
|
+
try {
|
|
15
|
+
input = parseHarvestRunnerLaunch(raw === undefined ? undefined : JSON.parse(raw))
|
|
16
|
+
} catch {
|
|
17
|
+
// Invalid immutable launch envelope exits below.
|
|
18
|
+
}
|
|
19
|
+
if (input === undefined) process.exit(2)
|
|
20
|
+
|
|
21
|
+
let exitCode = 0
|
|
22
|
+
try {
|
|
23
|
+
await runHarvestChild(input, process.env)
|
|
24
|
+
} catch {
|
|
25
|
+
// The durable outcome lives in the repository journal; the guest exit code
|
|
26
|
+
// is liveness evidence only.
|
|
27
|
+
exitCode = 1
|
|
28
|
+
}
|
|
29
|
+
process.exit(exitCode)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/** Private shipped child used only inside a disposable readiness workspace. */
|
|
3
|
+
import { INIT_PROBE_MARKER, runGuestReadinessProbe } from '../packages/core/src/cli/init-validation'
|
|
4
|
+
|
|
5
|
+
try {
|
|
6
|
+
const report = await runGuestReadinessProbe({ repo: process.cwd(), env: process.env })
|
|
7
|
+
console.log(`${INIT_PROBE_MARKER}${JSON.stringify(report)}`)
|
|
8
|
+
// A complete report is transport success even when one readiness check fails;
|
|
9
|
+
// the host owns the user-facing nonzero status.
|
|
10
|
+
process.exit(0)
|
|
11
|
+
} catch (error) {
|
|
12
|
+
const detail = error instanceof Error ? error.message : String(error)
|
|
13
|
+
console.log(
|
|
14
|
+
`${INIT_PROBE_MARKER}${JSON.stringify({ checks: [{ name: 'readiness probe', status: 'fail', detail }] })}`,
|
|
15
|
+
)
|
|
16
|
+
// Emitting the structured marker is transport success. The host turns its
|
|
17
|
+
// failing check into the command's user-facing nonzero result.
|
|
18
|
+
process.exit(0)
|
|
19
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/** Private shipped helper: reap one abandoned local build process group. */
|
|
3
|
+
import { terminateProcessGroup } from '../packages/core/src/processes/process-group'
|
|
4
|
+
import {
|
|
5
|
+
PROCESS_GROUP_REAPER_OPTIONS_ENV,
|
|
6
|
+
type ProcessGroupReaperOptions,
|
|
7
|
+
} from '../packages/core/src/processes/process-group-reaper'
|
|
8
|
+
|
|
9
|
+
const raw = process.env[PROCESS_GROUP_REAPER_OPTIONS_ENV]
|
|
10
|
+
let options: ProcessGroupReaperOptions | undefined
|
|
11
|
+
try {
|
|
12
|
+
const parsed =
|
|
13
|
+
raw === undefined ? undefined : (JSON.parse(raw) as Partial<ProcessGroupReaperOptions>)
|
|
14
|
+
if (
|
|
15
|
+
parsed !== undefined &&
|
|
16
|
+
Number.isSafeInteger(parsed.groupId) &&
|
|
17
|
+
parsed.groupId! > 0 &&
|
|
18
|
+
Number.isFinite(parsed.stopTimeoutMs) &&
|
|
19
|
+
parsed.stopTimeoutMs! >= 0
|
|
20
|
+
) {
|
|
21
|
+
options = parsed as ProcessGroupReaperOptions
|
|
22
|
+
}
|
|
23
|
+
} catch {
|
|
24
|
+
// Invalid immutable launch envelope exits below.
|
|
25
|
+
}
|
|
26
|
+
if (options === undefined) process.exit(2)
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
await terminateProcessGroup(options.groupId, options.stopTimeoutMs)
|
|
30
|
+
} catch {
|
|
31
|
+
process.exit(1)
|
|
32
|
+
}
|
package/bin/ab.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/** Published `ab` entry: unconditional production wiring, with no watcher or
|
|
3
|
+
* dev-state branch. The repo-local hot entry lives separately in ab-dev.ts. */
|
|
4
|
+
import { runBinary } from '../packages/core/src/cli/binary'
|
|
5
|
+
|
|
6
|
+
process.exit(await runBinary(process.argv.slice(2)))
|
package/bin/agent/ab
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Answering blocked builds
|
|
2
|
+
|
|
3
|
+
A build is **blocked** while one or more escalations are open. Inspect them with
|
|
4
|
+
`ab build status <slug>`, then choose the resolution that matches the problem.
|
|
5
|
+
Every action below is sessionless, records a human-authored fact, and accepts
|
|
6
|
+
`--store <ref>`.
|
|
7
|
+
|
|
8
|
+
| Need | Command | Effect |
|
|
9
|
+
|---|---|---|
|
|
10
|
+
| Give the phase a decision or missing information | `ab answer <slug> <text>` | Records `guidance`. In a review loop it feeds the next producer round. |
|
|
11
|
+
| Try again without guidance | `ab answer <slug>` | Records a bare `retry`; no prose is delivered to an agent. |
|
|
12
|
+
| Widen an exhausted review loop | `ab answer <slug> [<text>] --review-round-ceiling <n>` | Answers the open `review-round-limit` escalation and replaces the configured cap with absolute ceiling `n` for that loop and spec revision only. |
|
|
13
|
+
| Retire a review disagreement | `ab answer <slug> --dismiss` | Records `dismiss-finding` for each escalation that cites a real finding id. The next reviewer is told not to re-raise that chain. |
|
|
14
|
+
| Replace the build contract from a file | `ab answer <slug> --revise-spec <file>` | Records the replacement as the next spec revision and restarts at `plan`. |
|
|
15
|
+
| Re-import an amended ticket | `ab answer <slug> --revise-spec-from-ticket` | Reads the build's recorded ticket and performs the same revision. |
|
|
16
|
+
| Abandon the build | `ab abort <slug>` | Irrevocably requests abort; cleanup returns the ticket to Triage. |
|
|
17
|
+
|
|
18
|
+
The dashboard's blocked-build `r` shortcut requests an inline answer step that
|
|
19
|
+
supports guidance and a blank retry. While that step is open, it is exclusive
|
|
20
|
+
to the selected row: the row exposes only **SUBMIT** and **CANCEL**. Its ordinary
|
|
21
|
+
**RESUME**, **ABORT**, auto-merge, and detail controls are unavailable, and the
|
|
22
|
+
`r` and `a` row shortcuts do not trigger them (those letters remain ordinary
|
|
23
|
+
text while typing in the guidance field).
|
|
24
|
+
|
|
25
|
+
A successful submit records the trimmed guidance, or a bare retry for blank
|
|
26
|
+
input, resumes through the normal answer lifecycle, and closes the local step.
|
|
27
|
+
**CANCEL** or Esc closes it without writing and preserves both the selected
|
|
28
|
+
build and whether its detail was open. A later **RESUME** can request a fresh,
|
|
29
|
+
empty answer step. A later **ABORT** first replaces the row controls with local
|
|
30
|
+
**CONFIRM ABORT** and **CANCEL** confirmation; no durable abort occurs until it
|
|
31
|
+
is confirmed.
|
|
32
|
+
|
|
33
|
+
Controls on unrelated rows retain their established target-aware behavior.
|
|
34
|
+
Activating one leaves the old answer mode, selects that row, and performs its
|
|
35
|
+
normal action. The selected build's full detail names the CLI-only dismissal
|
|
36
|
+
and revision commands; it does not provide a spec editor.
|
|
37
|
+
|
|
38
|
+
Restarting `ab dispatch` or running `ab dispatch --once` is not an answer or a
|
|
39
|
+
retry action. Every open escalation, including every policy and setup cause,
|
|
40
|
+
survives dispatcher startup until a human uses one of the paths above. Startup
|
|
41
|
+
still recovers unblocked work and acknowledges pending operator commands.
|
|
42
|
+
|
|
43
|
+
## Widening an exhausted review loop
|
|
44
|
+
|
|
45
|
+
`--review-round-ceiling` is available only while the selected build has one open
|
|
46
|
+
`review-round-limit` policy escalation. The positive integer is an absolute
|
|
47
|
+
ceiling, not an increment: setting 12 again leaves the cap at 12. The answer and
|
|
48
|
+
override are one durable human-authored event, so no dispatcher restart is
|
|
49
|
+
needed and replay preserves the value.
|
|
50
|
+
|
|
51
|
+
The escalation's phase selects the plan or code loop. The other loop and every
|
|
52
|
+
other build keep the configured `maxReviewRounds`; `spec.revised` clears both
|
|
53
|
+
loop overrides. The stall threshold still applies before the widened round cap.
|
|
54
|
+
A ceiling cannot be supplied pre-emptively, as a standalone control, or together
|
|
55
|
+
with `--revise-spec`/`--revise-spec-from-ticket` because revision resets the
|
|
56
|
+
round budget itself. Current overrides appear in `ab build status` and on the
|
|
57
|
+
dashboard.
|
|
58
|
+
|
|
59
|
+
## Dismissing findings
|
|
60
|
+
|
|
61
|
+
Dismissal is evaluated per escalation. A blocker that cites no real
|
|
62
|
+
plan-review or code-review finding remains open, even when another blocker is
|
|
63
|
+
dismissed. Answer the remainder with guidance or a blank retry. Dismissal
|
|
64
|
+
settles only the cited chain: a reviewer can still report a genuinely different
|
|
65
|
+
problem in the same file under a new finding id.
|
|
66
|
+
|
|
67
|
+
## Revising the spec
|
|
68
|
+
|
|
69
|
+
Revision requires an open escalation because the spec is the contract against
|
|
70
|
+
which every downstream approval is measured. The replacement must satisfy the
|
|
71
|
+
same spec-standard quality gate used at dispatch; a non-conforming body is
|
|
72
|
+
rejected before an artifact or event is recorded, leaving the build blocked on
|
|
73
|
+
its current revision.
|
|
74
|
+
|
|
75
|
+
A successful answer records a human `escalation.answered` fact naming the exact
|
|
76
|
+
replacement artifact, followed by kernel `spec.revised`. The build re-plans and
|
|
77
|
+
pre-revision reviews, verification, and finalize completion do not satisfy the
|
|
78
|
+
new run. Historical phase runs remain pinned to the revision they saw. An
|
|
79
|
+
already-open pull request is retained and updated rather than duplicated.
|
|
80
|
+
|
|
81
|
+
The two events make interrupted work safely resumable. If the answer was
|
|
82
|
+
recorded but `spec.revised` was not, a repeated revision command publishes the
|
|
83
|
+
body named by that earlier answer; it does not read or authorize a newly
|
|
84
|
+
supplied file or ticket body.
|
|
85
|
+
|
|
86
|
+
A build that has already become terminal cannot restart. This includes the
|
|
87
|
+
short windows where its PR has merged or closed and completion is underway, or
|
|
88
|
+
where an abort request is pending. Abort is irrevocable; after cleanup, dispatch
|
|
89
|
+
the returned ticket as a fresh build if work should continue.
|