@astrosheep/keiyaku 4.1.0 → 4.1.2
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/README.md +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +3 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +3 -6
- package/build/src/akuma/akuma-errors.d.ts +6 -0
- package/build/src/akuma/akuma-errors.js +9 -0
- package/build/src/akuma/akuma-handle.d.ts +39 -0
- package/build/src/akuma/akuma-handle.js +263 -0
- package/build/src/akuma/akuma-observe.d.ts +19 -0
- package/build/src/akuma/akuma-observe.js +74 -0
- package/build/src/akuma/akuma-product-symbols.d.ts +1 -0
- package/build/src/akuma/akuma-product-symbols.js +1 -0
- package/build/src/akuma/akuma-product.d.ts +18 -0
- package/build/src/akuma/akuma-product.js +154 -0
- package/build/src/akuma/akuma.d.ts +37 -81
- package/build/src/akuma/akuma.js +39 -447
- package/build/src/akuma/allowed.d.ts +1 -0
- package/build/src/akuma/allowed.js +6 -0
- package/build/src/akuma/archetype.js +8 -5
- package/build/src/akuma/body-supervisor.d.ts +26 -0
- package/build/src/akuma/body-supervisor.js +89 -0
- package/build/src/akuma/body.d.ts +45 -4
- package/build/src/akuma/body.js +145 -35
- package/build/src/akuma/coordinate.js +17 -7
- package/build/src/akuma/heart/facts.js +1 -1
- package/build/src/akuma/heart/index.d.ts +1 -1
- package/build/src/akuma/heart/index.js +2 -4
- package/build/src/akuma/heart/request-authority.js +4 -4
- package/build/src/akuma/heart/request-rows.js +27 -16
- package/build/src/akuma/heart/rows.js +79 -41
- package/build/src/akuma/heart/soul.js +1 -1
- package/build/src/akuma/heart/storage.d.ts +1 -0
- package/build/src/akuma/heart/storage.js +76 -11
- package/build/src/akuma/heart/tells.js +35 -18
- package/build/src/akuma/heart/timeline.js +19 -11
- package/build/src/akuma/identity.d.ts +1 -0
- package/build/src/akuma/identity.js +1 -0
- package/build/src/akuma/index.d.ts +3 -3
- package/build/src/akuma/index.js +1 -1
- package/build/src/akuma/nuke.js +106 -14
- package/build/src/akuma/projection-read.d.ts +17 -0
- package/build/src/akuma/projection-read.js +135 -0
- package/build/src/akuma/projection.d.ts +1 -16
- package/build/src/akuma/projection.js +77 -154
- package/build/src/akuma/provider-recipe.js +11 -5
- package/build/src/akuma/provider.js +105 -62
- package/build/src/akuma/providers/acp/config.js +5 -6
- package/build/src/akuma/providers/acp/core.js +17 -10
- package/build/src/akuma/providers/acp/events.js +38 -29
- package/build/src/akuma/providers/acp/index.js +13 -9
- package/build/src/akuma/providers/claude/events.js +8 -12
- package/build/src/akuma/providers/claude/index.d.ts +1 -0
- package/build/src/akuma/providers/claude/index.js +55 -26
- package/build/src/akuma/providers/claude/input.js +6 -2
- package/build/src/akuma/providers/codex-app-server/events.js +61 -36
- package/build/src/akuma/providers/codex-app-server/index.js +25 -13
- package/build/src/akuma/providers/grok-build/index.js +22 -25
- package/build/src/akuma/providers/index.js +2 -18
- package/build/src/akuma/providers/opencode-sdk/events.js +32 -18
- package/build/src/akuma/providers/opencode-sdk/index.js +26 -17
- package/build/src/akuma/providers/opencode-sdk/session.js +21 -5
- package/build/src/akuma/providers/pi/events.js +26 -19
- package/build/src/akuma/providers/pi/index.js +58 -40
- package/build/src/akuma/publication.js +9 -9
- package/build/src/akuma/request-execution.d.ts +6 -0
- package/build/src/akuma/request-execution.js +86 -0
- package/build/src/akuma/request-serve.d.ts +12 -1
- package/build/src/akuma/request-serve.js +19 -122
- package/build/src/akuma/request-wire.d.ts +2 -2
- package/build/src/akuma/request-wire.js +75 -102
- package/build/src/akuma/requests.js +2 -2
- package/build/src/akuma/{body-turn.d.ts → turn-drive.d.ts} +2 -25
- package/build/src/akuma/{body-turn.js → turn-drive.js} +20 -103
- package/build/src/akuma-body.js +6 -5
- package/build/src/body/amend.d.ts +4 -1
- package/build/src/body/amend.js +14 -6
- package/build/src/body/decode.js +2 -4
- package/build/src/body/envelope.js +2 -4
- package/build/src/body/region.d.ts +1 -2
- package/build/src/body/region.js +2 -70
- package/build/src/body/render.js +17 -12
- package/build/src/body/shape.js +1 -7
- package/build/src/cli/accepted.d.ts +1 -1
- package/build/src/cli/accepted.js +8 -1
- package/build/src/cli/commands/akuma-invoke.js +18 -6
- package/build/src/cli/commands/akuma.d.ts +0 -6
- package/build/src/cli/commands/akuma.js +11 -24
- package/build/src/cli/commands/amend.d.ts +2 -2
- package/build/src/cli/commands/amend.js +2 -4
- package/build/src/cli/commands/bind.d.ts +4 -4
- package/build/src/cli/commands/bind.js +16 -6
- package/build/src/cli/commands/contract-invoke.d.ts +25 -0
- package/build/src/cli/commands/contract-invoke.js +193 -0
- package/build/src/cli/commands/contract.d.ts +109 -10
- package/build/src/cli/commands/contract.js +339 -16
- package/build/src/cli/commands/install.d.ts +1 -1
- package/build/src/cli/commands/install.js +23 -15
- package/build/src/cli/commands/task-invoke.js +187 -67
- package/build/src/cli/commands/task-query.js +48 -24
- package/build/src/cli/commands/task.js +150 -38
- package/build/src/cli/coordinates.js +2 -4
- package/build/src/cli/invoke.js +92 -208
- package/build/src/cli/main.js +4 -2
- package/build/src/cli/parse.d.ts +3 -90
- package/build/src/cli/parse.js +27 -233
- package/build/src/cli/render/akuma-activity.d.ts +38 -0
- package/build/src/cli/render/akuma-activity.js +362 -0
- package/build/src/cli/render/akuma-tool-command.js +6 -7
- package/build/src/cli/render/akuma-tool.js +10 -8
- package/build/src/cli/render/akuma.d.ts +1 -1
- package/build/src/cli/render/akuma.js +61 -353
- package/build/src/cli/render/audit.js +5 -15
- package/build/src/cli/render/board.d.ts +1 -0
- package/build/src/cli/render/board.js +17 -0
- package/build/src/cli/render/catalog.js +81 -8
- package/build/src/cli/render/contract-history.d.ts +2 -0
- package/build/src/cli/render/contract-history.js +83 -0
- package/build/src/cli/render/contract-observation.d.ts +10 -0
- package/build/src/cli/render/contract-observation.js +58 -0
- package/build/src/cli/render/contract.d.ts +1 -2
- package/build/src/cli/render/contract.js +41 -142
- package/build/src/cli/render/kanshi.js +239 -215
- package/build/src/cli/render/receipt.js +2 -9
- package/build/src/cli/render/refusal.js +10 -15
- package/build/src/cli/render/region.js +22 -6
- package/build/src/cli/render/settings.js +4 -4
- package/build/src/cli/render/task.js +34 -14
- package/build/src/cli/render/terminal.js +16 -5
- package/build/src/cli/result.d.ts +3 -3
- package/build/src/cli/runtime.d.ts +6 -1
- package/build/src/cli/runtime.js +84 -63
- package/build/src/cli/selectors.js +2 -4
- package/build/src/cli/usage.js +6 -5
- package/build/src/contract-worktree.d.ts +1 -23
- package/build/src/contract-worktree.js +79 -155
- package/build/src/coordination/durable-file.js +7 -3
- package/build/src/coordination/sqlite-transaction-lock.js +29 -12
- package/build/src/core/facts/codec.js +7 -3
- package/build/src/core/facts/types.d.ts +1 -1
- package/build/src/core/subject.js +16 -9
- package/build/src/core/verbs/abandon.d.ts +1 -1
- package/build/src/core/verbs/abandon.js +1 -1
- package/build/src/core/verbs/amend.d.ts +1 -1
- package/build/src/core/verbs/amend.js +7 -7
- package/build/src/core/verbs/attestation.js +4 -1
- package/build/src/core/verbs/bind.d.ts +1 -1
- package/build/src/core/verbs/bind.js +1 -1
- package/build/src/core/verbs/placement.d.ts +1 -1
- package/build/src/core/verbs/placement.js +10 -8
- package/build/src/dispatch/index.js +8 -6
- package/build/src/duration.js +5 -1
- package/build/src/git/admission.js +5 -3
- package/build/src/git/hooks.d.ts +8 -0
- package/build/src/git/hooks.js +63 -14
- package/build/src/git/identity.js +1 -4
- package/build/src/git/integration.d.ts +2 -3
- package/build/src/git/integration.js +32 -39
- package/build/src/git/nuke.d.ts +1 -1
- package/build/src/git/nuke.js +110 -57
- package/build/src/git/observe.d.ts +13 -1
- package/build/src/git/observe.js +51 -44
- package/build/src/git/process.js +4 -2
- package/build/src/git/read-observation.js +10 -8
- package/build/src/git/reconcile.d.ts +22 -2
- package/build/src/git/reconcile.js +38 -274
- package/build/src/git/repository.d.ts +2 -0
- package/build/src/git/repository.js +13 -22
- package/build/src/git/scratch.d.ts +8 -5
- package/build/src/git/scratch.js +29 -2
- package/build/src/git/target-placement.d.ts +9 -10
- package/build/src/git/target-placement.js +59 -62
- package/build/src/git/tender.js +13 -46
- package/build/src/git/terminal-reconcile.d.ts +21 -0
- package/build/src/git/terminal-reconcile.js +278 -0
- package/build/src/git/terminal-seal.js +15 -12
- package/build/src/git/tree.js +5 -2
- package/build/src/git/workspace.d.ts +24 -2
- package/build/src/git/workspace.js +120 -16
- package/build/src/identity/coordinates.js +3 -1
- package/build/src/identity/selector.js +6 -3
- package/build/src/kanshi/fleet.d.ts +6 -0
- package/build/src/kanshi/fleet.js +27 -0
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/read.js +60 -48
- package/build/src/kanshi/report.d.ts +11 -23
- package/build/src/kanshi/select.js +25 -24
- package/build/src/library/address.d.ts +2 -1
- package/build/src/library/address.js +7 -8
- package/build/src/library/akuma-creation.js +20 -12
- package/build/src/library/audit.d.ts +0 -1
- package/build/src/library/audit.js +1 -2
- package/build/src/library/bind.d.ts +53 -5
- package/build/src/library/bind.js +98 -22
- package/build/src/library/catalog.d.ts +1 -0
- package/build/src/library/catalog.js +6 -3
- package/build/src/library/configuration.js +3 -1
- package/build/src/library/continuation.d.ts +15 -4
- package/build/src/library/continuation.js +24 -16
- package/build/src/library/contract-bind.d.ts +26 -0
- package/build/src/library/contract-bind.js +106 -0
- package/build/src/library/contract-operations.d.ts +77 -0
- package/build/src/library/contract-operations.js +130 -0
- package/build/src/library/contract-types.d.ts +95 -0
- package/build/src/library/contract-types.js +1 -0
- package/build/src/library/contract.d.ts +19 -154
- package/build/src/library/contract.js +46 -261
- package/build/src/library/fleet.d.ts +1 -1
- package/build/src/library/fleet.js +19 -11
- package/build/src/library/input.d.ts +2 -0
- package/build/src/library/input.js +14 -0
- package/build/src/library/keiyaku.d.ts +8 -7
- package/build/src/library/keiyaku.js +3 -3
- package/build/src/library/nuke.js +14 -5
- package/build/src/library/reconcile.d.ts +9 -4
- package/build/src/library/reconcile.js +30 -24
- package/build/src/library/refusal.d.ts +13 -5
- package/build/src/library/refusal.js +7 -0
- package/build/src/library/region.d.ts +8 -7
- package/build/src/library/region.js +31 -11
- package/build/src/library/repo.js +2 -2
- package/build/src/markdown/lex.js +9 -2
- package/build/src/markdown/parse.js +11 -7
- package/build/src/markdown/query.js +4 -2
- package/build/src/protocol/amend.js +3 -1
- package/build/src/protocol/attempt.d.ts +7 -3
- package/build/src/protocol/attempt.js +9 -5
- package/build/src/protocol/audit.d.ts +1 -1
- package/build/src/protocol/audit.js +4 -14
- package/build/src/protocol/bind.d.ts +19 -6
- package/build/src/protocol/bind.js +28 -13
- package/build/src/protocol/completion.d.ts +0 -1
- package/build/src/protocol/completion.js +1 -3
- package/build/src/protocol/deliver.d.ts +1 -3
- package/build/src/protocol/deliver.js +15 -39
- package/build/src/protocol/intent.d.ts +1 -0
- package/build/src/protocol/intent.js +9 -7
- package/build/src/protocol/operations.d.ts +3 -7
- package/build/src/protocol/operations.js +5 -3
- package/build/src/protocol/placement.d.ts +0 -1
- package/build/src/protocol/placement.js +6 -6
- package/build/src/protocol/read/observation.d.ts +11 -0
- package/build/src/protocol/read/observation.js +37 -0
- package/build/src/protocol/read/status.d.ts +23 -12
- package/build/src/protocol/read/status.js +90 -72
- package/build/src/protocol/reconcile.d.ts +1 -0
- package/build/src/protocol/reconcile.js +2 -3
- package/build/src/protocol/reintegrate.js +1 -1
- package/build/src/protocol/review.d.ts +0 -1
- package/build/src/protocol/review.js +15 -22
- package/build/src/protocol/run.d.ts +1 -0
- package/build/src/protocol/run.js +4 -5
- package/build/src/runtime/proc/launch.d.ts +33 -0
- package/build/src/runtime/proc/launch.js +98 -0
- package/build/src/runtime/proc/line-rpc.js +9 -3
- package/build/src/runtime/proc/run.d.ts +12 -6
- package/build/src/runtime/proc/run.js +78 -21
- package/build/src/runtime/proc/stdio.js +7 -10
- package/build/src/settings.js +6 -2
- package/build/src/settlement/holder.js +13 -10
- package/build/src/settlement/settle.js +39 -6
- package/build/src/task/board.js +12 -6
- package/build/src/task/compose.js +85 -22
- package/build/src/task/context.js +21 -8
- package/build/src/task/document.js +46 -10
- package/build/src/task/identity.js +5 -2
- package/build/src/task/index.d.ts +0 -1
- package/build/src/task/index.js +119 -34
- package/build/src/task/input.js +29 -7
- package/build/src/task/mutation.js +61 -19
- package/build/src/task/operations.d.ts +6 -1
- package/build/src/task/operations.js +83 -29
- package/build/src/task/query.js +55 -26
- package/build/src/task/store.d.ts +3 -1
- package/build/src/task/store.js +81 -17
- package/build/src/verification/execution.js +14 -11
- package/build/src/workspace-place.js +19 -7
- package/build/src/world.js +16 -6
- package/package.json +8 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { observeActiveContractWorld, observeContractsForAdmissionInObservationAt, observeDeliveryTargetAt, withContractReadObservationAt, } from "../../git/observe.js";
|
|
2
2
|
import { decodeContractDocument } from "../../body/decode.js";
|
|
3
|
-
import { observeTargetLag, observeWorkspace, worktreePath
|
|
4
|
-
import { appointmentFor, readPlaceRegister
|
|
3
|
+
import { observeTargetLag, observeWorkspace, worktreePath } from "../../git/workspace.js";
|
|
4
|
+
import { appointmentFor, readPlaceRegister } from "../../workspace-place.js";
|
|
5
5
|
import { gateReports } from "../../core/facts/gate.js";
|
|
6
6
|
function titleFor(state) {
|
|
7
7
|
try {
|
|
@@ -19,7 +19,7 @@ function phaseFor(state) {
|
|
|
19
19
|
if (state.terminal?.kind === "abandoned")
|
|
20
20
|
return "abandoned";
|
|
21
21
|
if (state.delivery !== null)
|
|
22
|
-
return "
|
|
22
|
+
return "tendered";
|
|
23
23
|
if (state.bound !== null)
|
|
24
24
|
return "bound";
|
|
25
25
|
return "waiting";
|
|
@@ -49,37 +49,32 @@ async function managedWorkspaceFacts(repository, state, register, targetObservat
|
|
|
49
49
|
]);
|
|
50
50
|
return { appointed, workspaceObservation, targetLag };
|
|
51
51
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
observeTargetLag(repository, resolved.path, targetObservation?.head),
|
|
73
|
-
]);
|
|
74
|
-
return { appointed: undefined, workspaceObservation, targetLag };
|
|
52
|
+
function afterEndpoint(state) {
|
|
53
|
+
if (state === undefined || state === null)
|
|
54
|
+
return { kind: "missing" };
|
|
55
|
+
if (state.terminal?.kind === "claimed")
|
|
56
|
+
return { kind: "claimed" };
|
|
57
|
+
if (state.terminal?.kind === "abandoned")
|
|
58
|
+
return { kind: "abandoned" };
|
|
59
|
+
return { kind: "active", phase: phaseFor(state) };
|
|
60
|
+
}
|
|
61
|
+
function afterEdges(state, endpoints) {
|
|
62
|
+
return state.terms.after.map((contractId) => ({
|
|
63
|
+
contractId,
|
|
64
|
+
endpoint: afterEndpoint(endpoints.get(contractId)),
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
function reverseDependents(id, rows) {
|
|
68
|
+
return rows
|
|
69
|
+
.filter((row) => row.disposition === "active" && row.after.some((edge) => edge.contractId === id))
|
|
70
|
+
.map((row) => ({ contractId: row.id, phase: row.phase }))
|
|
71
|
+
.sort((left, right) => left.contractId.localeCompare(right.contractId));
|
|
75
72
|
}
|
|
76
73
|
async function rowFor(input) {
|
|
77
|
-
const { repository, state, bindAt, lastJournalAt, targetObservation, register,
|
|
74
|
+
const { repository, state, bindAt, lastJournalAt, targetObservation, register, after, dependents } = input;
|
|
78
75
|
const workspace = state.coordinates.workspace;
|
|
79
76
|
const gates = gateReports(state);
|
|
80
|
-
const { appointed, workspaceObservation, targetLag } =
|
|
81
|
-
? await managedWorkspaceFacts(repository, state, register, targetObservation)
|
|
82
|
-
: await hereWorkspaceFacts(repository, state.id, targetObservation, resolveHereWorkspace);
|
|
77
|
+
const { appointed, workspaceObservation, targetLag } = await managedWorkspaceFacts(repository, state, register, targetObservation);
|
|
83
78
|
return {
|
|
84
79
|
id: state.id,
|
|
85
80
|
title: titleFor(state),
|
|
@@ -100,62 +95,85 @@ async function rowFor(input) {
|
|
|
100
95
|
reports: gates.reports.map((report) => ({ gate: report.gate, current: report.current })),
|
|
101
96
|
satisfied: gates.satisfied,
|
|
102
97
|
},
|
|
98
|
+
after,
|
|
99
|
+
dependents,
|
|
103
100
|
};
|
|
104
101
|
}
|
|
102
|
+
async function afterEndpointMap(observation, known, ids) {
|
|
103
|
+
const missing = ids.filter((id) => !known.has(id));
|
|
104
|
+
if (missing.length === 0)
|
|
105
|
+
return known;
|
|
106
|
+
const extra = await observeContractsForAdmissionInObservationAt(observation, missing);
|
|
107
|
+
return new Map([...known, ...[...extra.journals].map(([id, record]) => [id, record.state])]);
|
|
108
|
+
}
|
|
105
109
|
/** Build the Contract board from one immutable git observation. */
|
|
106
|
-
export async function readContractBoard(observation,
|
|
107
|
-
|
|
108
|
-
const contract = await readContractObservation(observation, selected, resolveHereWorkspace);
|
|
109
|
-
return {
|
|
110
|
-
root: observation.repository.primaryWorktree,
|
|
111
|
-
state: observation.snapshot.commit,
|
|
112
|
-
rows: contract.kind === "missing" ? [] : [contract.row],
|
|
113
|
-
};
|
|
114
|
-
}
|
|
110
|
+
export async function readContractBoard(observation, include) {
|
|
111
|
+
const observedAt = new Date().toISOString();
|
|
115
112
|
const observed = await observeActiveContractWorld(observation);
|
|
113
|
+
const contracts = new Map(observed.contracts);
|
|
114
|
+
let endpoints = new Map(observed.eligibility);
|
|
115
|
+
if (include !== undefined && !contracts.has(include)) {
|
|
116
|
+
const extra = await observeContractsForAdmissionInObservationAt(observation, [include]);
|
|
117
|
+
const record = extra.journals.get(include);
|
|
118
|
+
if (record === undefined)
|
|
119
|
+
throw new Error(`missing requested Contract observation: ${include}`);
|
|
120
|
+
contracts.set(include, record);
|
|
121
|
+
endpoints.set(include, record.state);
|
|
122
|
+
if (record.state !== null) {
|
|
123
|
+
endpoints = new Map(await afterEndpointMap(observation, endpoints, record.state.terms.after));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
116
126
|
const register = await readPlaceRegister(observation.repository);
|
|
117
|
-
const
|
|
118
|
-
for (const value of observed.contracts.values()) {
|
|
127
|
+
const projected = await Promise.all([...contracts.values()].flatMap((value) => {
|
|
119
128
|
if (value.state === null)
|
|
120
|
-
|
|
129
|
+
return [];
|
|
121
130
|
const state = value.state;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
131
|
+
return [
|
|
132
|
+
observeDeliveryTargetAt(observation, state).then((target) => rowFor({
|
|
133
|
+
repository: observation.repository,
|
|
134
|
+
state,
|
|
135
|
+
bindAt: value.entries[0].at,
|
|
136
|
+
lastJournalAt: lastJournalAtFor(value.entries),
|
|
137
|
+
targetObservation: target,
|
|
138
|
+
register,
|
|
139
|
+
after: afterEdges(state, endpoints),
|
|
140
|
+
dependents: [],
|
|
141
|
+
})),
|
|
142
|
+
];
|
|
143
|
+
}));
|
|
144
|
+
const rows = projected.map((row) => ({ ...row, dependents: reverseDependents(row.id, projected) }));
|
|
145
|
+
return {
|
|
146
|
+
root: observation.repository.primaryWorktree,
|
|
147
|
+
state: observed.snapshot,
|
|
148
|
+
observedAt,
|
|
149
|
+
rows,
|
|
150
|
+
};
|
|
135
151
|
}
|
|
136
152
|
/** Observe one Contract and its target from one fresh ref epoch. */
|
|
137
|
-
export async function readContractObservation(observation, id
|
|
153
|
+
export async function readContractObservation(observation, id) {
|
|
138
154
|
const observed = await observeContractsForAdmissionInObservationAt(observation, [id]);
|
|
139
155
|
const record = observed.journals.get(id);
|
|
140
156
|
if (record === undefined)
|
|
141
157
|
throw new Error(`missing requested Contract observation: ${id}`);
|
|
142
158
|
const state = record.state;
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
159
|
+
if (state === null)
|
|
160
|
+
return { kind: "missing", id };
|
|
161
|
+
const endpoints = await afterEndpointMap(observation, new Map([[id, state]]), state.terms.after);
|
|
162
|
+
return {
|
|
163
|
+
kind: "present",
|
|
164
|
+
row: await rowFor({
|
|
165
|
+
repository: observation.repository,
|
|
166
|
+
state,
|
|
167
|
+
bindAt: record.entries[0].at,
|
|
168
|
+
lastJournalAt: lastJournalAtFor(record.entries),
|
|
169
|
+
targetObservation: await observeDeliveryTargetAt(observation, state),
|
|
170
|
+
register: await readPlaceRegister(observation.repository),
|
|
171
|
+
after: afterEdges(state, endpoints),
|
|
172
|
+
dependents: [],
|
|
173
|
+
}),
|
|
174
|
+
};
|
|
157
175
|
}
|
|
158
176
|
/** Observe one Contract and its target from one fresh ref epoch. */
|
|
159
|
-
export async function readContractObservationAt(repository, channel, id
|
|
160
|
-
return withContractReadObservationAt(repository, channel, id, async (observation) => await readContractObservation(observation, id
|
|
177
|
+
export async function readContractObservationAt(repository, channel, id) {
|
|
178
|
+
return withContractReadObservationAt(repository, channel, id, async (observation) => await readContractObservation(observation, id));
|
|
161
179
|
}
|
|
@@ -31,5 +31,6 @@ export declare function worldContractStates(input: Readonly<{
|
|
|
31
31
|
export declare function reconcileAllOperation(input: Readonly<{
|
|
32
32
|
scope: RepositoryScope;
|
|
33
33
|
channel: GitDecodeChannel;
|
|
34
|
+
states: readonly ContractState[];
|
|
34
35
|
}> & ReconcileOptions): Promise<RepoReconcileReport>;
|
|
35
36
|
export {};
|
|
@@ -23,11 +23,10 @@ export async function reconcileOperation(input) {
|
|
|
23
23
|
}
|
|
24
24
|
export async function worldContractStates(input) {
|
|
25
25
|
const observation = await withGitReadObservation(input.scope, input.channel, async (read) => await observeContractWorld(read));
|
|
26
|
-
return [...observation.contracts.values()].flatMap((value) => value.state === null ? [] : [value.state]);
|
|
26
|
+
return [...observation.contracts.values()].flatMap((value) => (value.state === null ? [] : [value.state]));
|
|
27
27
|
}
|
|
28
28
|
export async function reconcileAllOperation(input) {
|
|
29
|
-
const
|
|
30
|
-
const contracts = (await reconcileBatch(input.scope, input.channel, observation.contracts.keys(), {
|
|
29
|
+
const contracts = (await reconcileBatch(input.scope, input.channel, input.states.map((state) => state.id), {
|
|
31
30
|
hooks: input.hooks,
|
|
32
31
|
retryHooks: input.retryHooks,
|
|
33
32
|
retainTerminalWorktree: input.retainTerminalWorktree ?? false,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { contractState } from "../core/facts/observation.js";
|
|
2
|
-
import { decideReintegrate
|
|
2
|
+
import { decideReintegrate } from "../core/verbs/reintegrate.js";
|
|
3
3
|
import { materializeReintegrationSnapshot, persistedTender, planIntegration, } from "../git/integration.js";
|
|
4
4
|
import { observeContractsForAdmissionAt } from "../git/observe.js";
|
|
5
5
|
import { admitDecidedOffer, mintAttempts } from "./attempt.js";
|
|
@@ -19,7 +19,6 @@ export type ReviewValue = CompletionEvidence & Readonly<{
|
|
|
19
19
|
export declare function prepareReview(repository: RepositoryScope, stage: Readonly<{
|
|
20
20
|
contractId: import("../core/facts/types.js").ContractId;
|
|
21
21
|
coordinates: ContractState["coordinates"];
|
|
22
|
-
workspacePath?: string;
|
|
23
22
|
}>): Promise<{
|
|
24
23
|
kind: "prepared";
|
|
25
24
|
data: Readonly<{
|
|
@@ -18,7 +18,6 @@ async function captureReviewableWorktree(repository, stage) {
|
|
|
18
18
|
const tender = await captureTender(repository, {
|
|
19
19
|
...stage,
|
|
20
20
|
...(appointed === undefined ? {} : { place: appointed.place }),
|
|
21
|
-
...(stage.workspacePath === undefined ? {} : { workspacePath: stage.workspacePath }),
|
|
22
21
|
});
|
|
23
22
|
if (tender.kind === "refused")
|
|
24
23
|
return tender;
|
|
@@ -59,30 +58,26 @@ async function reviewAttempt(input, attempt) {
|
|
|
59
58
|
let preparation;
|
|
60
59
|
let workspace;
|
|
61
60
|
let tender;
|
|
62
|
-
let workspacePath;
|
|
63
61
|
if (state !== null) {
|
|
64
|
-
workspacePath = state.terminal === null && state.coordinates.workspace === "here"
|
|
65
|
-
? await input.resolveHereWorkspace?.(state.id)
|
|
66
|
-
: undefined;
|
|
67
62
|
const prepared = await captureReviewableWorktree(input.scope, {
|
|
68
63
|
contractId: state.id,
|
|
69
64
|
coordinates: state.coordinates,
|
|
70
|
-
...(workspacePath === undefined ? {} : { workspacePath }),
|
|
71
65
|
});
|
|
72
|
-
preparation =
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
66
|
+
preparation =
|
|
67
|
+
prepared.kind === "refused"
|
|
68
|
+
? { kind: "refused", refusal: prepared.refusal }
|
|
69
|
+
: {
|
|
70
|
+
kind: "prepared",
|
|
71
|
+
data: {
|
|
72
|
+
gate: REVIEWED,
|
|
73
|
+
subject: dependencyKeySet([
|
|
74
|
+
{ kind: "document", value: state.terms.document.key },
|
|
75
|
+
{ kind: "change", value: prepared.data.changeId },
|
|
76
|
+
]),
|
|
77
|
+
verdict: input.verdict,
|
|
78
|
+
...(input.summary === undefined ? {} : { summary: input.summary }),
|
|
79
|
+
},
|
|
80
|
+
};
|
|
86
81
|
if (prepared.kind === "prepared") {
|
|
87
82
|
workspace = prepared.data.workspace;
|
|
88
83
|
tender = prepared.data.tender;
|
|
@@ -114,7 +109,6 @@ async function reviewAttempt(input, attempt) {
|
|
|
114
109
|
value: {
|
|
115
110
|
...(workspace === undefined ? {} : { workspace }),
|
|
116
111
|
...(tender === undefined ? {} : { tender }),
|
|
117
|
-
...(workspacePath === undefined ? {} : { workspacePath }),
|
|
118
112
|
},
|
|
119
113
|
};
|
|
120
114
|
return admission;
|
|
@@ -150,7 +144,6 @@ export async function reviewOperation(input) {
|
|
|
150
144
|
verification: derivation?.verification ?? { kind: "prepared", data: null },
|
|
151
145
|
initial: review,
|
|
152
146
|
verifyInitial: false,
|
|
153
|
-
...(review.value.workspacePath === undefined ? {} : { hereWorkspacePath: review.value.workspacePath }),
|
|
154
147
|
});
|
|
155
148
|
return admitted(completed.admission, reviewValue(review.value, completed.evidence));
|
|
156
149
|
}
|
|
@@ -35,6 +35,7 @@ export type RunProtocolInput<Input extends Readonly<{
|
|
|
35
35
|
extendAttempt?: (attempt: AttemptContext, observedContractCount: number) => AttemptContext;
|
|
36
36
|
/** Add opaque companions from the exact immutable observation for this attempt. */
|
|
37
37
|
decorateOffer?: CompanionDecorator;
|
|
38
|
+
validateAdmission?: (observation: GitDecisionObservation) => Refusal | undefined | Promise<Refusal | undefined>;
|
|
38
39
|
observationSelection?: GitTreeSelection;
|
|
39
40
|
}> & (Readonly<{
|
|
40
41
|
input: Input;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { extendAdmissionPathsAt, observeContractsForAdmissionAt
|
|
1
|
+
import { extendAdmissionPathsAt, observeContractsForAdmissionAt } from "../git/observe.js";
|
|
2
2
|
import { admitDecidedOffer } from "./attempt.js";
|
|
3
3
|
/** Form one decided offer without admitting or reinterpreting it. */
|
|
4
4
|
export async function prepareProtocolAttempt(input, baseAttempt) {
|
|
@@ -11,9 +11,7 @@ export async function prepareProtocolAttempt(input, baseAttempt) {
|
|
|
11
11
|
: { kind: "prepared", input: input.input, assertions: [] };
|
|
12
12
|
if (preparedInput.kind === "refused")
|
|
13
13
|
return preparedInput;
|
|
14
|
-
const attempt = input.extendAttempt === undefined
|
|
15
|
-
? baseAttempt
|
|
16
|
-
: input.extendAttempt(baseAttempt, observation.size);
|
|
14
|
+
const attempt = input.extendAttempt === undefined ? baseAttempt : input.extendAttempt(baseAttempt, observation.size);
|
|
17
15
|
const decision = input.decide({ input: preparedInput.input, attempt, observation });
|
|
18
16
|
if (decision.kind === "refused")
|
|
19
17
|
return decision;
|
|
@@ -54,8 +52,9 @@ export async function runProtocol(input) {
|
|
|
54
52
|
offer: prepared.offer,
|
|
55
53
|
primaryContract: input.input.contractId,
|
|
56
54
|
assertions: prepared.assertions,
|
|
55
|
+
...(input.validateAdmission === undefined ? {} : { validateAdmission: input.validateAdmission }),
|
|
57
56
|
});
|
|
58
|
-
if (result.kind === "accepted" || result.kind === "publication-failed")
|
|
57
|
+
if (result.kind === "accepted" || result.kind === "publication-failed" || result.kind === "refused")
|
|
59
58
|
return result;
|
|
60
59
|
if (result.kind === "collision" && index + 1 === attempts.length)
|
|
61
60
|
return result;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type ChildProcess } from "node:child_process";
|
|
2
|
+
export type LaunchIntent = "handoff" | "retained";
|
|
3
|
+
export type DetachedProcessInput = Readonly<{
|
|
4
|
+
argv: readonly string[];
|
|
5
|
+
cwd: string;
|
|
6
|
+
env?: NodeJS.ProcessEnv;
|
|
7
|
+
log: string;
|
|
8
|
+
}>;
|
|
9
|
+
export type SpawnLaunchPolicy = Readonly<{
|
|
10
|
+
kind: "spawn";
|
|
11
|
+
detached: boolean;
|
|
12
|
+
windowsHide: true;
|
|
13
|
+
shell: false;
|
|
14
|
+
}>;
|
|
15
|
+
export type PlatformLaunchPolicy = Readonly<{
|
|
16
|
+
kind: "windows-launcher";
|
|
17
|
+
}> | SpawnLaunchPolicy;
|
|
18
|
+
export declare function platformLaunchPolicy(intent: LaunchIntent, platform?: NodeJS.Platform): PlatformLaunchPolicy;
|
|
19
|
+
export declare function spawnOptionsFor<Stdio>(intent: LaunchIntent, input: Readonly<{
|
|
20
|
+
cwd?: string;
|
|
21
|
+
env?: NodeJS.ProcessEnv;
|
|
22
|
+
}>, stdio: Stdio, platform?: NodeJS.Platform): Readonly<{
|
|
23
|
+
cwd: string | undefined;
|
|
24
|
+
env: NodeJS.ProcessEnv | undefined;
|
|
25
|
+
detached: boolean;
|
|
26
|
+
stdio: Stdio;
|
|
27
|
+
windowsHide: true;
|
|
28
|
+
shell: false;
|
|
29
|
+
}>;
|
|
30
|
+
export declare function windowsLauncherPath(): string;
|
|
31
|
+
export declare function spawnLoggedProcess(input: DetachedProcessInput, intent: LaunchIntent): Promise<ChildProcess>;
|
|
32
|
+
export declare function handoffWindowsLaunch(input: DetachedProcessInput, launcher?: string): Promise<void>;
|
|
33
|
+
export declare function handoffProcess(input: DetachedProcessInput): Promise<void>;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { open } from "node:fs/promises";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
export function platformLaunchPolicy(intent, platform = process.platform) {
|
|
6
|
+
if (platform === "win32" && intent === "handoff")
|
|
7
|
+
return { kind: "windows-launcher" };
|
|
8
|
+
return {
|
|
9
|
+
kind: "spawn",
|
|
10
|
+
detached: platform !== "win32",
|
|
11
|
+
windowsHide: true,
|
|
12
|
+
shell: false,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export function spawnOptionsFor(intent, input, stdio, platform = process.platform) {
|
|
16
|
+
const policy = platformLaunchPolicy(intent, platform);
|
|
17
|
+
if (policy.kind !== "spawn")
|
|
18
|
+
throw new Error("Windows Body handoff uses the GUI launcher");
|
|
19
|
+
return {
|
|
20
|
+
cwd: input.cwd,
|
|
21
|
+
env: input.env,
|
|
22
|
+
detached: policy.detached,
|
|
23
|
+
stdio,
|
|
24
|
+
windowsHide: policy.windowsHide,
|
|
25
|
+
shell: policy.shell,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export function windowsLauncherPath() {
|
|
29
|
+
const sourcePath = fileURLToPath(new URL("./windows-launch.exe", import.meta.url));
|
|
30
|
+
if (process.platform === "win32" && !/[\\/]build[\\/]/u.test(sourcePath)) {
|
|
31
|
+
return resolve(sourcePath, "../../../../build/src/runtime/proc/windows-launch.exe");
|
|
32
|
+
}
|
|
33
|
+
return sourcePath;
|
|
34
|
+
}
|
|
35
|
+
function launchFailure(command, diagnostic) {
|
|
36
|
+
const error = new Error(diagnostic.length > 0 ? diagnostic : `spawn ${command} UNKNOWN`);
|
|
37
|
+
const code = /\b(?:ENOENT|EACCES|EINVAL)\b/.exec(error.message)?.[0];
|
|
38
|
+
if (code)
|
|
39
|
+
error.code = code;
|
|
40
|
+
error.syscall = "spawn";
|
|
41
|
+
error.path = command;
|
|
42
|
+
return error;
|
|
43
|
+
}
|
|
44
|
+
async function waitSpawned(child) {
|
|
45
|
+
await new Promise((resolve, reject) => {
|
|
46
|
+
child.once("spawn", resolve);
|
|
47
|
+
child.once("error", reject);
|
|
48
|
+
});
|
|
49
|
+
if (child.pid === undefined)
|
|
50
|
+
throw new Error("detached process spawned without a pid");
|
|
51
|
+
}
|
|
52
|
+
export async function spawnLoggedProcess(input, intent) {
|
|
53
|
+
const log = await open(input.log, "a");
|
|
54
|
+
try {
|
|
55
|
+
const child = spawn(input.argv[0], input.argv.slice(1), spawnOptionsFor(intent, input, ["ignore", log.fd, log.fd]));
|
|
56
|
+
await waitSpawned(child);
|
|
57
|
+
return child;
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
await log.close();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export async function handoffWindowsLaunch(input, launcher = windowsLauncherPath()) {
|
|
64
|
+
const child = spawn(launcher, [input.log, ...input.argv], {
|
|
65
|
+
cwd: input.cwd,
|
|
66
|
+
env: input.env,
|
|
67
|
+
stdio: ["ignore", "ignore", "pipe"],
|
|
68
|
+
windowsHide: true,
|
|
69
|
+
shell: false,
|
|
70
|
+
});
|
|
71
|
+
let stderr = "";
|
|
72
|
+
child.stderr?.setEncoding("utf8");
|
|
73
|
+
child.stderr?.on("data", (chunk) => {
|
|
74
|
+
stderr = `${stderr}${chunk}`.slice(-4_000);
|
|
75
|
+
});
|
|
76
|
+
const closed = new Promise((resolve) => {
|
|
77
|
+
child.once("close", (exitCode) => resolve(exitCode));
|
|
78
|
+
});
|
|
79
|
+
try {
|
|
80
|
+
await waitSpawned(child);
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
84
|
+
}
|
|
85
|
+
const code = await closed;
|
|
86
|
+
if (code === 0)
|
|
87
|
+
return;
|
|
88
|
+
throw launchFailure(input.argv[0] ?? launcher, stderr.trim());
|
|
89
|
+
}
|
|
90
|
+
export async function handoffProcess(input) {
|
|
91
|
+
const policy = platformLaunchPolicy("handoff");
|
|
92
|
+
if (policy.kind === "windows-launcher") {
|
|
93
|
+
await handoffWindowsLaunch(input);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const child = await spawnLoggedProcess(input, "handoff");
|
|
97
|
+
child.unref();
|
|
98
|
+
}
|
|
@@ -24,9 +24,15 @@ export class LineRpcProcess {
|
|
|
24
24
|
this.fail(new Error(`line RPC process exited${exit.code === null ? "" : ` with code ${exit.code}`}`));
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
|
-
onNotification(listener) {
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
onNotification(listener) {
|
|
28
|
+
this.notifications.add(listener);
|
|
29
|
+
}
|
|
30
|
+
onServerRequest(listener) {
|
|
31
|
+
this.serverRequests.add(listener);
|
|
32
|
+
}
|
|
33
|
+
onExit(listener) {
|
|
34
|
+
void this.process.exited.then(listener);
|
|
35
|
+
}
|
|
30
36
|
consume(chunk) {
|
|
31
37
|
this.stdout += chunk;
|
|
32
38
|
for (;;) {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type ChildProcess } from "node:child_process";
|
|
2
|
+
import { type DetachedProcessInput } from "./launch.js";
|
|
3
|
+
export { handoffProcess, type DetachedProcessInput } from "./launch.js";
|
|
2
4
|
type ProcessLaunch = Readonly<{
|
|
3
5
|
readonly argv: readonly string[];
|
|
4
6
|
readonly cwd?: string;
|
|
@@ -37,14 +39,19 @@ export type ProcessConsumption = Readonly<{
|
|
|
37
39
|
readonly outcome: ProcessOutcome | ProcessStreamError;
|
|
38
40
|
readonly pid: number | null;
|
|
39
41
|
}>;
|
|
40
|
-
export type
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
export type RunLogReference = Readonly<{
|
|
43
|
+
path: string;
|
|
44
|
+
from: number;
|
|
45
|
+
to: number;
|
|
46
|
+
}>;
|
|
47
|
+
export type DetachedProcessExit = Readonly<{
|
|
48
|
+
code: number | null;
|
|
49
|
+
signal: NodeJS.Signals | null;
|
|
50
|
+
log: RunLogReference;
|
|
45
51
|
}>;
|
|
46
52
|
export type OwnedProcess = Readonly<{
|
|
47
53
|
pid: number;
|
|
54
|
+
exited: Promise<DetachedProcessExit>;
|
|
48
55
|
terminate(force?: boolean): Promise<void>;
|
|
49
56
|
release(): void;
|
|
50
57
|
}>;
|
|
@@ -54,4 +61,3 @@ export declare function runProcess(input: ProcessInput): Promise<ProcessOutcome>
|
|
|
54
61
|
export declare function runCrossPlatformProcess(input: ProcessInput): Promise<ProcessOutcome>;
|
|
55
62
|
export declare function runProcessToExit(input: ProcessLaunch): Promise<ProcessOutcome>;
|
|
56
63
|
export declare function consumeProcessStdout(input: ProcessInput, consume: (chunk: Buffer) => void): Promise<ProcessConsumption>;
|
|
57
|
-
export {};
|