@astrosheep/keiyaku 2.9.3 → 2.9.5
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/build/.tsbuildinfo +1 -1
- package/build/agents/call-terms.js +14 -94
- package/build/agents/harness/activity-values.js +16 -0
- package/build/agents/harness/event-persistence.js +218 -0
- package/build/agents/harness/execution-handle.js +26 -222
- package/build/agents/harness/index.js +3 -1
- package/build/agents/harness/outcome.js +68 -5
- package/build/agents/harness/projection.js +179 -124
- package/build/agents/harness/provider-adapter.js +58 -0
- package/build/agents/harness/router.js +11 -187
- package/build/agents/harness/runtime.js +17 -4
- package/build/agents/harness/session.js +15 -0
- package/build/agents/launch-snapshot/model.js +15 -236
- package/build/agents/launch-snapshot/parse-helpers.js +114 -0
- package/build/agents/launch-snapshot/resolve.js +17 -43
- package/build/agents/opencode-sdk.js +45 -12
- package/build/agents/providers/claude-agent-sdk/adapter.js +6 -17
- package/build/agents/providers/claude-agent-sdk/registration.js +214 -0
- package/build/agents/providers/claude-agent-sdk/session-schema.js +2 -0
- package/build/agents/providers/codex-app-server/adapter.js +82 -53
- package/build/agents/providers/codex-app-server/events.js +90 -11
- package/build/agents/providers/codex-app-server/identity.js +1 -0
- package/build/agents/providers/codex-app-server/policy.js +29 -0
- package/build/agents/providers/codex-app-server/registration.js +248 -0
- package/build/agents/providers/codex-app-server/session-schema.js +6 -0
- package/build/agents/providers/codex-app-server/session.js +23 -17
- package/build/agents/providers/codex-app-server/terms.js +1 -0
- package/build/agents/providers/opencode-sdk/adapter.js +94 -50
- package/build/agents/providers/opencode-sdk/events.js +8 -4
- package/build/agents/providers/opencode-sdk/registration.js +135 -0
- package/build/agents/providers/opencode-sdk/session-schema.js +2 -0
- package/build/agents/providers/opencode-sdk/session.js +21 -14
- package/build/agents/providers/opencode-sdk/terms.js +1 -0
- package/build/agents/providers/pi/adapter.js +36 -30
- package/build/agents/providers/pi/events.js +4 -3
- package/build/agents/providers/pi/registration.js +145 -0
- package/build/agents/providers/pi/session-schema.js +6 -0
- package/build/agents/providers/pi/terms.js +1 -0
- package/build/agents/providers/registration.js +7 -0
- package/build/agents/providers/registry.js +76 -0
- package/build/agents/selector.js +2 -29
- package/build/agents/types.js +10 -0
- package/build/artifact-directories.js +22 -0
- package/build/cli/commands/akuma/akuma/handler.js +1 -1
- package/build/cli/commands/akuma/akuma/meta.js +1 -1
- package/build/cli/commands/akuma/list/meta-ls.js +1 -1
- package/build/cli/commands/akuma/view/handler.js +5 -4
- package/build/cli/commands/akuma/view/meta.js +1 -1
- package/build/cli/commands/akuma.js +6 -0
- package/build/cli/commands/contract/amend/handler.js +8 -2
- package/build/cli/commands/contract/amend/meta.js +4 -4
- package/build/cli/commands/contract/arc/handler.js +8 -2
- package/build/cli/commands/contract/arc/meta.js +4 -4
- package/build/cli/commands/contract/audit/handler.js +16 -0
- package/build/cli/commands/contract/audit/meta.js +16 -0
- package/build/cli/commands/contract/bind/handler.js +4 -3
- package/build/cli/commands/contract/bind/meta.js +44 -8
- package/build/cli/commands/contract/catalog.js +2 -0
- package/build/cli/commands/contract/forfeit/handler.js +4 -4
- package/build/cli/commands/contract/forfeit/meta.js +1 -1
- package/build/cli/commands/contract/log/handler.js +3 -3
- package/build/cli/commands/contract/log/meta.js +1 -1
- package/build/cli/commands/contract/petition/handler.js +5 -8
- package/build/cli/commands/contract/petition/meta.js +6 -6
- package/build/cli/commands/contract/renew/handler.js +20 -6
- package/build/cli/commands/contract/renew/meta.js +6 -5
- package/build/cli/commands/metadata.js +59 -0
- package/build/cli/commands/projection/call/handler.js +6 -5
- package/build/cli/commands/projection/call/meta.js +4 -1
- package/build/cli/commands/projection/kill/handler.js +16 -32
- package/build/cli/commands/projection/kill/meta.js +1 -1
- package/build/cli/commands/projection/revive/meta.js +4 -1
- package/build/cli/commands/projection/shared.js +28 -0
- package/build/cli/commands/projection/status/handler.js +1 -1
- package/build/cli/commands/projection/status/meta.js +1 -1
- package/build/cli/commands/projection/tell/handler.js +14 -30
- package/build/cli/commands/projection/tell/meta.js +4 -1
- package/build/cli/commands/projection/wait/handler.js +45 -22
- package/build/cli/commands/projection/wait/meta.js +8 -3
- package/build/cli/commands/registry.js +2 -54
- package/build/cli/commands/shared.js +10 -7
- package/build/cli/commands/skills/install/handler.js +2 -5
- package/build/cli/commands/skills/install/meta.js +1 -1
- package/build/cli/commands/skills/skills/handler.js +1 -1
- package/build/cli/commands/skills/skills/meta.js +1 -1
- package/build/cli/commands/system/completion/meta.js +1 -1
- package/build/cli/commands/system/dump-env/meta.js +1 -1
- package/build/cli/commands/system/guide/meta.js +1 -1
- package/build/cli/commands/task/add/handler.js +7 -15
- package/build/cli/commands/task/add/meta.js +4 -1
- package/build/cli/commands/task/catalog.js +2 -2
- package/build/cli/commands/task/doctor/meta.js +1 -1
- package/build/cli/commands/task/done/handler.js +4 -8
- package/build/cli/commands/task/done/meta.js +1 -1
- package/build/cli/commands/task/drop/handler.js +3 -6
- package/build/cli/commands/task/drop/meta.js +1 -1
- package/build/cli/commands/task/ls/handler.js +12 -8
- package/build/cli/commands/task/ls/meta.js +3 -3
- package/build/cli/commands/task/shared.js +14 -4
- package/build/cli/commands/task/{view → show}/handler.js +7 -8
- package/build/cli/commands/task/show/meta.js +8 -0
- package/build/cli/commands/task/start/handler.js +3 -6
- package/build/cli/commands/task/start/meta.js +1 -1
- package/build/cli/commands/task/stop/handler.js +4 -8
- package/build/cli/commands/task/stop/meta.js +1 -1
- package/build/cli/commands/task/task/handler.js +1 -1
- package/build/cli/commands/task/task/meta.js +1 -1
- package/build/cli/commands/task/update/handler.js +6 -11
- package/build/cli/commands/task/update/meta.js +4 -1
- package/build/cli/completion.js +1 -1
- package/build/cli/flags.js +37 -6
- package/build/cli/help.js +7 -14
- package/build/cli/index.js +112 -154
- package/build/cli/missing-subcommand.js +7 -0
- package/build/cli/output-stream-error-policy.js +19 -5
- package/build/cli/parse-flags.js +33 -7
- package/build/cli/parse-metadata.js +3 -9
- package/build/cli/parse-selectors.js +2 -1
- package/build/cli/parse.js +35 -5
- package/build/cli/projection-address.js +12 -12
- package/build/cli/render/address.js +41 -37
- package/build/cli/render/arc.js +24 -12
- package/build/cli/render/audit.js +121 -0
- package/build/cli/render/call.js +11 -5
- package/build/cli/render/errors.js +36 -1
- package/build/cli/render/format.js +4 -0
- package/build/cli/render/kanshi.js +6 -12
- package/build/cli/render/kill.js +9 -0
- package/build/cli/render/misc.js +58 -13
- package/build/cli/render/petition.js +20 -15
- package/build/cli/render/projection-activity.js +15 -6
- package/build/cli/render/shared.js +60 -21
- package/build/cli/render/skills.js +10 -0
- package/build/cli/render/status.js +56 -23
- package/build/cli/render/success-response.js +78 -0
- package/build/cli/render/task.js +66 -57
- package/build/cli/render/tell.js +5 -0
- package/build/cli/render/terminal-failure.js +63 -0
- package/build/cli/render/types.js +1 -0
- package/build/cli/render/wait.js +68 -38
- package/build/cli/types.js +1 -1
- package/build/config/akuma-loader.js +0 -5
- package/build/config/env-keys.js +3 -1
- package/build/config/env.js +3 -0
- package/build/config/provider-policy-ownership.js +3 -32
- package/build/config/settings/disease.js +8 -1
- package/build/config/settings/loader.js +11 -3
- package/build/config/settings/provider-instance-fields.js +51 -0
- package/build/config/settings/schema.js +6 -176
- package/build/core/addressing.js +66 -16
- package/build/core/amend.js +61 -18
- package/build/core/arc.js +33 -73
- package/build/core/audit.js +650 -0
- package/build/core/bind.js +82 -35
- package/build/core/call/call.js +15 -9
- package/build/core/call/context.js +6 -51
- package/build/core/call/execution.js +22 -22
- package/build/core/call/prompt.js +14 -1
- package/build/core/command-markdown.js +45 -0
- package/build/core/context.js +13 -7
- package/build/core/contract-view.js +22 -6
- package/build/core/draft.js +139 -19
- package/build/core/entry.js +3 -4
- package/build/core/forfeit.js +5 -2
- package/build/core/hints.js +1 -75
- package/build/core/identifier-slug.js +66 -0
- package/build/core/ids.js +25 -11
- package/build/core/ledger.js +20 -68
- package/build/core/markdown/lex.js +2 -1
- package/build/core/markdown/parser.js +0 -68
- package/build/core/markdown/render.js +68 -0
- package/build/core/markdown/sections.js +2 -1
- package/build/core/outcome-base.js +4 -0
- package/build/core/projection/generation/database.js +41 -52
- package/build/core/projection/generation/model.js +63 -2
- package/build/core/{projection-generation-continuation.js → projection/generation/projection-generation-continuation.js} +3 -3
- package/build/core/{projection-generation-execution.js → projection/generation/projection-generation-execution.js} +36 -53
- package/build/core/{projection-generation-identity.js → projection/generation/projection-generation-identity.js} +2 -2
- package/build/core/{projection-generation-launcher.js → projection/generation/projection-generation-launcher.js} +9 -7
- package/build/core/{projection-generation-process.js → projection/generation/projection-generation-process.js} +2 -1
- package/build/core/{projection-generation-runner.js → projection/generation/projection-generation-runner.js} +19 -3
- package/build/core/projection/generation/store.js +3 -3
- package/build/core/projection/generation/transitions.js +19 -3
- package/build/core/projection/index.js +27 -0
- package/build/core/{projection-activity.js → projection/projection-activity.js} +12 -0
- package/build/core/{projection-alias.js → projection/projection-alias.js} +13 -13
- package/build/core/projection/projection-coordinate.js +61 -0
- package/build/core/{projection-core.js → projection/projection-core.js} +9 -9
- package/build/core/{projection-execution-observer.js → projection/projection-execution-observer.js} +37 -78
- package/build/core/{projection-identity.js → projection/projection-identity.js} +1 -1
- package/build/core/{projection-kill.js → projection/projection-kill.js} +1 -1
- package/build/core/{projection-life-observer.js → projection/projection-life-observer.js} +16 -2
- package/build/core/{projection-mint.js → projection/projection-mint.js} +10 -10
- package/build/core/{projection-status.js → projection/projection-status.js} +163 -45
- package/build/core/projection/projection-terminal-failure.js +106 -0
- package/build/core/projection/projection-wait.js +275 -0
- package/build/core/projection/projection-wake.js +227 -0
- package/build/core/provider-loader-ports.js +4 -0
- package/build/core/ref-log.js +65 -40
- package/build/core/registry.js +63 -10
- package/build/core/renew-session.js +128 -0
- package/build/core/renew.js +448 -102
- package/build/core/scope.js +272 -68
- package/build/core/seal.js +165 -40
- package/build/core/{claim-delivery.js → settlement/claim-delivery.js} +8 -8
- package/build/core/{claim.js → settlement/claim.js} +32 -8
- package/build/core/settlement/index.js +19 -0
- package/build/core/{petition-claim-gates.js → settlement/petition-claim-gates.js} +24 -49
- package/build/core/{petition-forfeit.js → settlement/petition-forfeit.js} +2 -2
- package/build/core/{petition-head-guard.js → settlement/petition-head-guard.js} +2 -2
- package/build/core/settlement/petition-io.js +1 -0
- package/build/core/{petition-preview.js → settlement/petition-preview.js} +2 -2
- package/build/core/{petition.js → settlement/petition.js} +21 -12
- package/build/core/settlement/queue-read-model.js +143 -0
- package/build/core/settlement/queue-seat-allocation.js +156 -0
- package/build/core/settlement/queue.js +6 -0
- package/build/core/settlement/settlement.js +288 -0
- package/build/core/{verdict.js → settlement/verdict.js} +9 -37
- package/build/core/settlement/verification.js +59 -0
- package/build/core/status/board.js +62 -41
- package/build/core/status/ledger-batch.js +158 -0
- package/build/core/status/reconciliation.js +10 -4
- package/build/core/stored-agent-event.js +6 -2
- package/build/core/task/board.js +41 -4
- package/build/core/task/commands.js +45 -28
- package/build/core/task/document.js +5 -0
- package/build/core/task/index.js +12 -0
- package/build/core/task/model.js +8 -1
- package/build/core/task/query.js +172 -0
- package/build/core/task/settlement-git.js +265 -74
- package/build/core/task/settlement-policy.js +67 -29
- package/build/core/task/source-board.js +1 -0
- package/build/core/task/task-contract.js +444 -0
- package/build/core/{task-doctor.js → task/task-doctor.js} +1 -1
- package/build/core/{task-git-actor.js → task/task-git-actor.js} +5 -10
- package/build/core/{task-git-runtime.js → task/task-git-runtime.js} +3 -3
- package/build/core/{task-git-store.js → task/task-git-store.js} +90 -19
- package/build/core/task/task-repository.js +1 -0
- package/build/core/{task-store-repository.js → task/task-store-repository.js} +6 -4
- package/build/core/task/task-store.js +1 -0
- package/build/core/{task-worktree.js → task/task-worktree.js} +2 -1
- package/build/core/task/task.js +7 -0
- package/build/core/task/tree.js +37 -0
- package/build/core/task/validation.js +5 -2
- package/build/core/transcripts.js +15 -3
- package/build/core/worktree-path.js +43 -28
- package/build/flow-error.js +83 -39
- package/build/fs/path-coordinate.js +16 -0
- package/build/generated/version.js +3 -2
- package/build/git/branches.js +2 -1
- package/build/git/core.js +106 -2
- package/build/git/diff/parsers.js +23 -13
- package/build/git/diff/structured.js +127 -0
- package/build/git/path-coordinate.js +17 -0
- package/build/git/refs.js +57 -0
- package/build/git/streaming-batch.js +301 -0
- package/build/git/worktree.js +65 -0
- package/build/index.js +9 -9
- package/build/keiyaku.js +2 -36
- package/build/telemetry/logger.js +4 -2
- package/package.json +4 -10
- package/skills/keiyaku/SKILL.md +5 -4
- package/skills/keiyaku-akuma/SKILL.md +25 -11
- package/skills/keiyaku-task/SKILL.md +17 -8
- package/skills/keiyaku-workflow/SKILL.md +58 -9
- package/build/agents/providers/codex-sdk.js +0 -329
- package/build/cli/commands/task/view/meta.js +0 -8
- package/build/core/command-io.js +0 -174
- package/build/core/path-coordinate.js +0 -27
- package/build/core/petition-claim.js +0 -117
- package/build/core/petition-run.js +0 -83
- package/build/core/projection-coordinate.js +0 -63
- package/build/core/projection-wait.js +0 -165
- package/build/core/projection-wake.js +0 -136
- package/build/core/queue.js +0 -343
- package/build/core/task-contract.js +0 -237
- package/build/core/task.js +0 -4
- /package/build/{core/task-repository.js → agents/launch-snapshot/types.js} +0 -0
- /package/build/{core/task-store.js → agents/providers/claude-agent-sdk/terms.js} +0 -0
- /package/build/core/{projection-generation-runtime.js → projection/generation/projection-generation-runtime.js} +0 -0
- /package/build/core/{projection-life-protocol.js → projection/projection-life-protocol.js} +0 -0
- /package/build/core/{projection-runner-lock.js → projection/projection-runner-lock.js} +0 -0
package/build/core/bind.js
CHANGED
|
@@ -3,12 +3,12 @@ import { assertSettingsKnobUsable } from "../config/settings/disease.js";
|
|
|
3
3
|
import { loadKeiyakuSettings } from "../config/settings/loader.js";
|
|
4
4
|
import { FlowError } from "../flow-error.js";
|
|
5
5
|
import { activeLedgerRef, appendEntry, appendWithRetry, readLedger } from "./ledger.js";
|
|
6
|
-
import { parseBindDraft } from "./draft.js";
|
|
6
|
+
import { describeMissingBindSections, materializeBindDraft, mergeBindDraft, missingBindDraftSections, parseBindDraft, parsePartialBindDraft, renderMissingBindSectionsTemplate, } from "./draft.js";
|
|
7
7
|
import { assertValidContractId, buildContractId } from "./ids.js";
|
|
8
8
|
import { registerScope, releaseScope } from "./registry.js";
|
|
9
9
|
import { resolveDefaultBranch } from "./status/drift.js";
|
|
10
10
|
import { normalizeTargetRef } from "./target-ref.js";
|
|
11
|
-
import { reconcileTaskForfeit, settleTaskBoardForBind } from "./task
|
|
11
|
+
import { reconcileTaskForfeit, settleTaskBoardForBind } from "./task/index.js";
|
|
12
12
|
import { bootstrapEntryDataFromObservation, isBootstrapSuccess, runWorktreeBootstrap, } from "./worktree-bootstrap.js";
|
|
13
13
|
import { contractWorktreePathFromBind, stableRepoRoot } from "./worktree-path.js";
|
|
14
14
|
import { allocateWorktreePlace, cleanupCreatedBindResources, createContractBranch, defaultCreateWorktree, materializeContractView, resolveTreeRoot, } from "./bind-workspace.js";
|
|
@@ -107,8 +107,40 @@ function makeBindEntry(input) {
|
|
|
107
107
|
},
|
|
108
108
|
};
|
|
109
109
|
}
|
|
110
|
+
function taskBindDefaults(task) {
|
|
111
|
+
const defaults = { name: task.title };
|
|
112
|
+
const objective = task.body.trim();
|
|
113
|
+
if (objective.length > 0)
|
|
114
|
+
defaults.objective = objective;
|
|
115
|
+
return defaults;
|
|
116
|
+
}
|
|
117
|
+
function incompleteTaskBindError(taskId, missing) {
|
|
118
|
+
const coordinate = taskId;
|
|
119
|
+
const template = renderMissingBindSectionsTemplate(missing);
|
|
120
|
+
const message = [
|
|
121
|
+
`task ${coordinate} carries no ${describeMissingBindSections(missing)}`,
|
|
122
|
+
`» keiyaku bind --task ${coordinate} - <<'KEIYAKU'`,
|
|
123
|
+
template,
|
|
124
|
+
"KEIYAKU",
|
|
125
|
+
].join("\n");
|
|
126
|
+
return new FlowError("BIND_TASK_INCOMPLETE", message);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Section-level merge for `bind --task`: task title/body are name/objective
|
|
130
|
+
* defaults; stdin partial markdown sections override. Missing required sections
|
|
131
|
+
* fail with a paste-ready partial heredoc template.
|
|
132
|
+
*/
|
|
133
|
+
export function composeTaskBindDraft(input) {
|
|
134
|
+
const merged = mergeBindDraft(taskBindDefaults(input.task), parsePartialBindDraft(input.draft));
|
|
135
|
+
const missing = missingBindDraftSections(merged);
|
|
136
|
+
if (missing.length > 0) {
|
|
137
|
+
throw incompleteTaskBindError(input.task.id, missing);
|
|
138
|
+
}
|
|
139
|
+
return materializeBindDraft(merged);
|
|
140
|
+
}
|
|
110
141
|
export async function bindContract(input) {
|
|
111
|
-
const
|
|
142
|
+
const isTaskBound = input.taskIds !== undefined && input.taskIds.length > 0;
|
|
143
|
+
const ordinaryDraft = !isTaskBound ? parseBindDraft(input.draft) : undefined;
|
|
112
144
|
const workspace = input.workspace ?? "here";
|
|
113
145
|
const at = new Date(input.nowMs).toISOString();
|
|
114
146
|
const defaultBranch = await resolveDefaultBranch(input.cwd);
|
|
@@ -126,47 +158,60 @@ export async function bindContract(input) {
|
|
|
126
158
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
127
159
|
const randomBytes = input.randomBytes?.(attempt) ?? randomBytesDefault();
|
|
128
160
|
const place = workspace === "worktree" ? await allocateWorktreePlace(input.cwd, randomBytes) : undefined;
|
|
129
|
-
const id = buildContractId({
|
|
130
|
-
name: draft.name,
|
|
131
|
-
nowMs: input.nowMs,
|
|
132
|
-
randomBytes,
|
|
133
|
-
});
|
|
134
|
-
await assertValidContractId(input.cwd, id);
|
|
135
|
-
const ref = activeLedgerRef(id);
|
|
136
161
|
let settlement;
|
|
137
162
|
try {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
163
|
+
const prepare = async (draft) => {
|
|
164
|
+
const id = buildContractId({ name: draft.name, nowMs: input.nowMs, randomBytes });
|
|
165
|
+
await assertValidContractId(input.cwd, id);
|
|
166
|
+
const ref = activeLedgerRef(id);
|
|
167
|
+
return {
|
|
168
|
+
contractId: id,
|
|
169
|
+
publishLedger: async (base) => {
|
|
170
|
+
const entry = makeBindEntry({
|
|
171
|
+
id,
|
|
172
|
+
at,
|
|
173
|
+
actor: input.actor,
|
|
174
|
+
draft,
|
|
175
|
+
base,
|
|
176
|
+
target,
|
|
177
|
+
after: input.after ?? [],
|
|
178
|
+
workspace,
|
|
179
|
+
place,
|
|
180
|
+
bootstrap: bootstrapPlan,
|
|
181
|
+
});
|
|
182
|
+
const appended = await appendEntry(input.cwd, ref, entry, null);
|
|
183
|
+
if (!appended.ok)
|
|
184
|
+
throw new BindLedgerCollisionError(id);
|
|
185
|
+
return { entry, appended };
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
};
|
|
189
|
+
settlement = !isTaskBound
|
|
190
|
+
? await (async () => {
|
|
191
|
+
const prepared = await prepare(ordinaryDraft);
|
|
192
|
+
return settleTaskBoardForBind({ cwd: input.cwd, signal: input.signal, ...prepared });
|
|
193
|
+
})()
|
|
194
|
+
: await (async () => {
|
|
195
|
+
return settleTaskBoardForBind({
|
|
196
|
+
cwd: input.cwd,
|
|
197
|
+
taskIds: input.taskIds,
|
|
198
|
+
signal: input.signal,
|
|
199
|
+
prepare: async (tasks) => prepare(composeTaskBindDraft({ task: tasks[0], draft: input.draft })),
|
|
154
200
|
});
|
|
155
|
-
|
|
156
|
-
if (!appended.ok)
|
|
157
|
-
throw new BindLedgerCollisionError(id);
|
|
158
|
-
return { entry, appended };
|
|
159
|
-
},
|
|
160
|
-
});
|
|
201
|
+
})();
|
|
161
202
|
}
|
|
162
203
|
catch (error) {
|
|
163
204
|
if (error instanceof BindLedgerCollisionError) {
|
|
164
|
-
|
|
205
|
+
// The selected task's locked snapshot chose this attempted identity.
|
|
206
|
+
// Record the concrete id only when preparation reached publication.
|
|
207
|
+
collidedIds.push(error.contractId);
|
|
165
208
|
continue;
|
|
166
209
|
}
|
|
167
210
|
throw error;
|
|
168
211
|
}
|
|
169
212
|
const { entry, appended } = settlement.ledger;
|
|
213
|
+
const id = settlement.contractId;
|
|
214
|
+
const ref = activeLedgerRef(id);
|
|
170
215
|
const base = settlement.boardCommit;
|
|
171
216
|
const resources = { id };
|
|
172
217
|
const branch = `keiyaku/${id}`;
|
|
@@ -179,7 +224,7 @@ export async function bindContract(input) {
|
|
|
179
224
|
const tree = await resolveTreeRoot(input.cwd, workspace, id, entry);
|
|
180
225
|
const registration = await registerScope(input.cwd, {
|
|
181
226
|
contractId: id,
|
|
182
|
-
scope:
|
|
227
|
+
scope: entry.data.scope,
|
|
183
228
|
tree,
|
|
184
229
|
actor: input.actor,
|
|
185
230
|
at,
|
|
@@ -219,11 +264,13 @@ export async function bindContract(input) {
|
|
|
219
264
|
return {
|
|
220
265
|
id,
|
|
221
266
|
ref,
|
|
267
|
+
target,
|
|
268
|
+
place: workspace === "worktree" ? entry.data.place ?? null : null,
|
|
222
269
|
branch: workspace === "worktree" ? branch : undefined,
|
|
223
270
|
worktreePath: targetRoot,
|
|
224
271
|
workspace,
|
|
225
272
|
ledgerHead,
|
|
226
|
-
|
|
273
|
+
scopeOverlaps: registration.overlaps,
|
|
227
274
|
};
|
|
228
275
|
}
|
|
229
276
|
catch (error) {
|
package/build/core/call/call.js
CHANGED
|
@@ -8,10 +8,8 @@ import { ACTOR_IDENTITY } from "../../keiyaku.js";
|
|
|
8
8
|
import { appendDebugBlock } from "../../telemetry/debug-log.js";
|
|
9
9
|
import { logInfo } from "../../telemetry/logger.js";
|
|
10
10
|
import { withResolvedAddress } from "../addressing.js";
|
|
11
|
-
import { assertProjectionAlias } from "../projection
|
|
12
|
-
import {
|
|
13
|
-
import { observeProjectionLife } from "../projection-life-observer.js";
|
|
14
|
-
import { waitForProjection } from "../projection-wait.js";
|
|
11
|
+
import { assertProjectionAlias, PROJECTION_ADOPTION_TIMEOUT_MS, observeProjectionLife, waitForProjection, } from "../projection/index.js";
|
|
12
|
+
import { normalizeFilesystemCoordinate } from "../../fs/path-coordinate.js";
|
|
15
13
|
import { requireResumableArtifact } from "../transcripts.js";
|
|
16
14
|
import { stableRepoRoot } from "../worktree-path.js";
|
|
17
15
|
import { readCallKeiyakuContext } from "./context.js";
|
|
@@ -23,6 +21,9 @@ function renderSubagentWarning(warning) {
|
|
|
23
21
|
const status = warning.errorStatus === null ? "no response" : String(warning.errorStatus);
|
|
24
22
|
return `Provider warning: retry. attempt=${warning.attempt}, maxRetries=${warning.maxRetries}, retryDelayMs=${warning.retryDelayMs}, errorStatus=${status}`;
|
|
25
23
|
}
|
|
24
|
+
if (warning.reason === "rate-limit") {
|
|
25
|
+
return "Provider warning: rate limit exhausted.";
|
|
26
|
+
}
|
|
26
27
|
const modelTransition = warning.originalModel && warning.fallbackModel
|
|
27
28
|
? `${warning.originalModel} -> ${warning.fallbackModel}`
|
|
28
29
|
: warning.originalModel ?? warning.fallbackModel;
|
|
@@ -42,18 +43,18 @@ export async function execSubagent(agentName, prompt, cwd, options) {
|
|
|
42
43
|
export async function runCall(input) {
|
|
43
44
|
const { signal, agent } = input;
|
|
44
45
|
const reviveArtifact = input.reviveArtifact ? requireResumableArtifact(input.reviveArtifact) : undefined;
|
|
45
|
-
let rawCwd = input.cwd;
|
|
46
|
-
let rawRepo = input.repo;
|
|
46
|
+
let rawCwd = normalizeFilesystemCoordinate(input.cwd);
|
|
47
|
+
let rawRepo = input.repo === undefined ? undefined : normalizeFilesystemCoordinate(input.repo);
|
|
47
48
|
if (reviveArtifact?.provenance.authority.kind === "user") {
|
|
48
49
|
if (!("workdir" in reviveArtifact.provenance.evidence)) {
|
|
49
50
|
throw new FlowError("INVALID_RESPONSE_PATH", `Invalid response artifact '${reviveArtifact.artifactId}': field 'provenance.evidence.workdir' is missing.`);
|
|
50
51
|
}
|
|
51
|
-
rawCwd = reviveArtifact.provenance.evidence.workdir;
|
|
52
|
+
rawCwd = normalizeFilesystemCoordinate(reviveArtifact.provenance.evidence.workdir);
|
|
52
53
|
rawRepo = undefined;
|
|
53
54
|
}
|
|
54
55
|
else if (reviveArtifact?.provenance.authority.kind === "repository") {
|
|
55
56
|
const artifactHome = await fs.realpath(reviveArtifact.storageRoot);
|
|
56
|
-
const addressed = input.repo ?? input.cwd;
|
|
57
|
+
const addressed = normalizeFilesystemCoordinate(input.repo ?? input.cwd);
|
|
57
58
|
const observation = await observeGitRepository(addressed);
|
|
58
59
|
const coordinate = assertGitObservation(observation, "revive");
|
|
59
60
|
if (coordinate === "repository") {
|
|
@@ -91,6 +92,7 @@ export async function runCall(input) {
|
|
|
91
92
|
context: input.context,
|
|
92
93
|
referenceFiles,
|
|
93
94
|
currentIntent: keiyakuContext.currentIntent,
|
|
95
|
+
commissioned: keiyakuContext.address.binding.kind === "commission",
|
|
94
96
|
});
|
|
95
97
|
const launchSnapshot = reviveArtifact
|
|
96
98
|
? input.effort !== undefined
|
|
@@ -146,7 +148,11 @@ export async function runCall(input) {
|
|
|
146
148
|
...(launched.projection.alias ? { alias: launched.projection.alias } : {}),
|
|
147
149
|
...(launched.projection.previousAliasTarget ? { previousAliasTarget: launched.projection.previousAliasTarget } : {}),
|
|
148
150
|
};
|
|
149
|
-
input.onLaunch?.({
|
|
151
|
+
input.onLaunch?.({
|
|
152
|
+
address: keiyakuContext.address,
|
|
153
|
+
projection: adoptedProjection,
|
|
154
|
+
akumaName: launchSnapshot.akuma.name,
|
|
155
|
+
});
|
|
150
156
|
if (input.detach) {
|
|
151
157
|
return {
|
|
152
158
|
state: "launched",
|
|
@@ -3,10 +3,11 @@ import { FlowError } from "../../flow-error.js";
|
|
|
3
3
|
import { assertGitObservation, observeGitRepository } from "../../git/branches.js";
|
|
4
4
|
import { createGit, wrapGitError } from "../../git/core.js";
|
|
5
5
|
import { AddressResolutionError, buildResolutionAttempt, buildUncommissionedAddress, buildUncommissionedRepositoryAddress, resolveContractAddress, withResolvedAddress, } from "../addressing.js";
|
|
6
|
+
import { normalizeFilesystemCoordinate } from "../../fs/path-coordinate.js";
|
|
6
7
|
import { findOpenArcView } from "../arc.js";
|
|
7
8
|
import { readLedger } from "../ledger.js";
|
|
8
9
|
import { deriveContractState, isTerminalState } from "../status/lifecycle.js";
|
|
9
|
-
import {
|
|
10
|
+
import { contractWorktreePathFromBind, stableRepoRoot } from "../worktree-path.js";
|
|
10
11
|
async function findWorktreePathForContract(cwd, contractId) {
|
|
11
12
|
const git = createGit(cwd);
|
|
12
13
|
let output;
|
|
@@ -47,6 +48,8 @@ async function resolveWorkspaceCwd(cwd, contractId, bind) {
|
|
|
47
48
|
return worktreePath;
|
|
48
49
|
}
|
|
49
50
|
export async function readCallKeiyakuContext(executionCwd, input) {
|
|
51
|
+
executionCwd = normalizeFilesystemCoordinate(executionCwd);
|
|
52
|
+
input.repoCwd = input.repoCwd === undefined ? undefined : normalizeFilesystemCoordinate(input.repoCwd);
|
|
50
53
|
const ledgerCandidate = input.repoCwd ?? executionCwd;
|
|
51
54
|
const ledgerObservation = await observeGitRepository(ledgerCandidate);
|
|
52
55
|
if (ledgerObservation.capability === "unknown")
|
|
@@ -136,7 +139,7 @@ export async function readCallKeiyakuContext(executionCwd, input) {
|
|
|
136
139
|
},
|
|
137
140
|
}));
|
|
138
141
|
}
|
|
139
|
-
if (input.bare) {
|
|
142
|
+
if (input.bare || !input.contractId) {
|
|
140
143
|
return {
|
|
141
144
|
activeKeiyaku: false,
|
|
142
145
|
effectiveCwd: executionCwd,
|
|
@@ -150,55 +153,7 @@ export async function readCallKeiyakuContext(executionCwd, input) {
|
|
|
150
153
|
}),
|
|
151
154
|
};
|
|
152
155
|
}
|
|
153
|
-
|
|
154
|
-
if (input.contractId) {
|
|
155
|
-
address = await resolveContractAddress(ledgerCwd, input.contractId, input.contractAddressSource);
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
const executionObservation = await observeGitRepository(executionCwd);
|
|
159
|
-
if (executionObservation.capability === "unknown")
|
|
160
|
-
throw executionObservation.error;
|
|
161
|
-
if (executionObservation.capability === "available" && executionObservation.coordinate === "repository") {
|
|
162
|
-
const executionRepo = await stableRepoRoot(executionCwd);
|
|
163
|
-
if (input.repoCwd && executionRepo !== ledgerCwd) {
|
|
164
|
-
const presented = await contractPresentedByWorktree(executionCwd);
|
|
165
|
-
if (presented) {
|
|
166
|
-
throw new FlowError("EMPTY_PARAM", `cross-repository contract-worktree addressing is pending: -C presents @${presented} from ${executionRepo}, but --repo selects ${ledgerCwd}`);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
const presented = await contractPresentedByWorktree(executionCwd);
|
|
171
|
-
if (presented) {
|
|
172
|
-
address = await resolveContractAddress(ledgerCwd, presented, "worktree-presented");
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
if (!address) {
|
|
178
|
-
try {
|
|
179
|
-
address = await resolveContractAddress(ledgerCwd);
|
|
180
|
-
}
|
|
181
|
-
catch (error) {
|
|
182
|
-
if (error instanceof AddressResolutionError
|
|
183
|
-
&& error.code === "EMPTY_PARAM"
|
|
184
|
-
&& error.attempt.expected === "commission"
|
|
185
|
-
&& error.attempt.candidates.length === 0) {
|
|
186
|
-
return {
|
|
187
|
-
activeKeiyaku: false,
|
|
188
|
-
effectiveCwd: executionCwd,
|
|
189
|
-
historyCwd: ledgerCwd,
|
|
190
|
-
profileCwd: ledgerCwd,
|
|
191
|
-
projectionCwd: ledgerCwd,
|
|
192
|
-
address: buildUncommissionedRepositoryAddress({
|
|
193
|
-
stableRoot: ledgerCwd,
|
|
194
|
-
workdir: executionCwd,
|
|
195
|
-
binding: "unbound",
|
|
196
|
-
}),
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
throw error;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
156
|
+
const address = await resolveContractAddress(ledgerCwd, input.contractId, input.contractAddressSource);
|
|
202
157
|
return await withResolvedAddress(address, async () => {
|
|
203
158
|
const contractId = address.binding.commissionId;
|
|
204
159
|
const ledger = await readLedger(ledgerCwd, contractId);
|
|
@@ -3,14 +3,14 @@ import { createAbortError, restoreOutcome, SubagentFailure, } from "../../agents
|
|
|
3
3
|
import { resolveAkumaLaunchSnapshot } from "../../agents/launch-snapshot/resolve.js";
|
|
4
4
|
import { selectSubagent } from "../../agents/selector.js";
|
|
5
5
|
import { FlowError } from "../../flow-error.js";
|
|
6
|
-
import { assertProjectionAlias, moveProjectionAlias } from "../projection
|
|
7
|
-
import { projectionDir } from "../projection
|
|
8
|
-
import { createProjectionExecutionId } from "../projection
|
|
9
|
-
import { PROJECTION_ADOPTION_TIMEOUT_MS, startProjectionGeneration } from "../projection
|
|
10
|
-
import { openProjectionGenerationStore, openProjectionGenerationStoreReadOnly, } from "../projection/
|
|
11
|
-
import { observeProjectionLife } from "../projection
|
|
12
|
-
import { mintProjection, mintRepositoryProjection } from "../projection
|
|
13
|
-
import { waitForProjection } from "../projection
|
|
6
|
+
import { assertProjectionAlias, moveProjectionAlias } from "../projection/index.js";
|
|
7
|
+
import { projectionDir } from "../projection/index.js";
|
|
8
|
+
import { createProjectionExecutionId } from "../projection/index.js";
|
|
9
|
+
import { PROJECTION_ADOPTION_TIMEOUT_MS, startProjectionGeneration } from "../projection/index.js";
|
|
10
|
+
import { openProjectionGenerationStore, openProjectionGenerationStoreReadOnly, } from "../projection/index.js";
|
|
11
|
+
import { observeProjectionLife } from "../projection/index.js";
|
|
12
|
+
import { mintProjection, mintRepositoryProjection } from "../projection/index.js";
|
|
13
|
+
import { waitForProjection } from "../projection/index.js";
|
|
14
14
|
export function readCurrentGenerationOrThrow(projectionDirectory) {
|
|
15
15
|
const store = openProjectionGenerationStoreReadOnly(projectionDirectory);
|
|
16
16
|
try {
|
|
@@ -148,7 +148,7 @@ export async function buildCallConfig(agentName, prompt, cwd, options) {
|
|
|
148
148
|
};
|
|
149
149
|
const minted = options.authority.kind === "repository"
|
|
150
150
|
? await mintRepositoryProjection({ ...mintInput, authority: { kind: "repository" } })
|
|
151
|
-
: mintProjection({ ...mintInput, authority: { kind: "user" } });
|
|
151
|
+
: await mintProjection({ ...mintInput, authority: { kind: "user" } });
|
|
152
152
|
const executionId = createProjectionExecutionId();
|
|
153
153
|
const launchFacts = JSON.parse(JSON.stringify({
|
|
154
154
|
executionId,
|
|
@@ -159,6 +159,7 @@ export async function buildCallConfig(agentName, prompt, cwd, options) {
|
|
|
159
159
|
task: options.task ?? prompt,
|
|
160
160
|
launchSnapshot,
|
|
161
161
|
idleTimeoutMs: resolvedTerms.idleTimeoutMs,
|
|
162
|
+
executionTimeoutMs: resolvedTerms.executionTimeoutMs,
|
|
162
163
|
cwd,
|
|
163
164
|
historyCwd: options.historyStorageCwd ?? cwd,
|
|
164
165
|
...(options.evidenceCwd !== undefined ? { evidenceCwd: options.evidenceCwd } : {}),
|
|
@@ -184,20 +185,19 @@ export async function buildCallConfig(agentName, prompt, cwd, options) {
|
|
|
184
185
|
}
|
|
185
186
|
const previousAliasTarget = options.alias === undefined
|
|
186
187
|
? undefined
|
|
187
|
-
: moveProjectionAlias(options.projectionCwd ?? cwd, assertProjectionAlias(options.alias), minted.id);
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
? previousAliasTarget
|
|
195
|
-
: undefined;
|
|
196
|
-
}
|
|
197
|
-
catch {
|
|
198
|
-
return undefined;
|
|
188
|
+
: await moveProjectionAlias(options.projectionCwd ?? cwd, assertProjectionAlias(options.alias), minted.id);
|
|
189
|
+
let previousAliasTargetStillRunning;
|
|
190
|
+
if (previousAliasTarget !== undefined) {
|
|
191
|
+
try {
|
|
192
|
+
const phase = observeProjectionLife(await projectionDir(options.projectionCwd ?? cwd, previousAliasTarget), { nowMs: Date.now(), startupTimeoutMs: PROJECTION_ADOPTION_TIMEOUT_MS }).phase;
|
|
193
|
+
if (phase === "minting" || phase === "active" || phase === "quiescent") {
|
|
194
|
+
previousAliasTargetStillRunning = previousAliasTarget;
|
|
199
195
|
}
|
|
200
|
-
}
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
previousAliasTargetStillRunning = undefined;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
201
|
return {
|
|
202
202
|
id: minted.id,
|
|
203
203
|
dir: minted.dir,
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { ACTOR_IDENTITY } from "../../keiyaku.js";
|
|
2
|
+
const COMMISSIONED_DELIVERY_BOUNDARY = [
|
|
3
|
+
"Delivery boundary: edit and test only inside this linked contract worktree.",
|
|
4
|
+
"Leave source changes uncommitted as a dirty working tree, then report changed files and checks run.",
|
|
5
|
+
"Do not run git add, git commit, or any command that writes Git metadata. A refused Git metadata write is not a failed delivery.",
|
|
6
|
+
"The host coordinator reviews and commits accepted bytes, then continues arc, renew, or petition settlement.",
|
|
7
|
+
].join(" ");
|
|
2
8
|
export function buildCallPrompt(input) {
|
|
3
9
|
const references = [...new Set((input.referenceFiles ?? []).map((file) => file.trim()).filter(Boolean))];
|
|
4
10
|
if (input.currentIntent?.source === "arc") {
|
|
@@ -9,6 +15,7 @@ export function buildCallPrompt(input) {
|
|
|
9
15
|
`Title: ${arc.title}`,
|
|
10
16
|
`Objective: ${arc.objective}`,
|
|
11
17
|
`Brief:\n${arc.brief}`,
|
|
18
|
+
COMMISSIONED_DELIVERY_BOUNDARY,
|
|
12
19
|
"",
|
|
13
20
|
`Task:\n${input.task}`,
|
|
14
21
|
`Context:\n${input.context?.trim() || "(none provided)"}`,
|
|
@@ -30,13 +37,19 @@ export function buildCallPrompt(input) {
|
|
|
30
37
|
`Scope:\n${bind.scope.map((value) => `- ${value}`).join("\n")}`,
|
|
31
38
|
`Checks:\n${bind.checks.map((value) => `- ${value}`).join("\n")}`,
|
|
32
39
|
extensionsBlock,
|
|
40
|
+
COMMISSIONED_DELIVERY_BOUNDARY,
|
|
33
41
|
`Task:\n${input.task}`,
|
|
34
42
|
trimmedContext ? `Context:\n${trimmedContext}` : "",
|
|
35
43
|
references.length > 0 ? `Reference files:\n${references.map((file) => `- ${file}`).join("\n")}` : "",
|
|
36
44
|
"Provide the final result for the caller/main agent.",
|
|
37
45
|
].filter(Boolean).join("\n\n");
|
|
38
46
|
}
|
|
39
|
-
return [
|
|
47
|
+
return [
|
|
48
|
+
input.task,
|
|
49
|
+
input.context?.trim() ?? "",
|
|
50
|
+
input.commissioned ? COMMISSIONED_DELIVERY_BOUNDARY : "",
|
|
51
|
+
references.length > 0 ? `Reference files:\n${references.map((file) => `- ${file}`).join("\n")}` : "",
|
|
52
|
+
]
|
|
40
53
|
.filter(Boolean)
|
|
41
54
|
.join("\n\n");
|
|
42
55
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { FlowError } from "../flow-error.js";
|
|
2
|
+
import { parseMarkdownListSection, parseMarkdownStructure } from "./markdown/sections.js";
|
|
3
|
+
import { KeiyakuParseError } from "./markdown/types.js";
|
|
4
|
+
import { normalizeSectionTitle } from "./markdown/titles.js";
|
|
5
|
+
export function parseCommandMarkdown(content) {
|
|
6
|
+
try {
|
|
7
|
+
const parsed = parseMarkdownStructure(content);
|
|
8
|
+
const sections = new Map();
|
|
9
|
+
for (const [key, lines] of parsed.sections.entries()) {
|
|
10
|
+
sections.set(key, lines.join("\n").trim());
|
|
11
|
+
}
|
|
12
|
+
return { title: parsed.title, sections };
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
if (error instanceof KeiyakuParseError) {
|
|
16
|
+
throw new FlowError("INVALID_KEIYAKU_DRAFT", error.message, { cause: error });
|
|
17
|
+
}
|
|
18
|
+
throw error;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function requireMarkdownTextSection(parts, name) {
|
|
22
|
+
const normalized = normalizeSectionTitle(name);
|
|
23
|
+
const value = parts.sections.get(normalized)?.trim();
|
|
24
|
+
if (!value) {
|
|
25
|
+
throw new FlowError("INVALID_KEIYAKU_DRAFT", `missing required section: ## ${name}`);
|
|
26
|
+
}
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
export function requireMarkdownListSection(parts, name) {
|
|
30
|
+
const text = requireMarkdownTextSection(parts, name);
|
|
31
|
+
const items = parseMarkdownListSection(text)
|
|
32
|
+
.map((item) => item.trim())
|
|
33
|
+
.filter((item) => item.length > 0);
|
|
34
|
+
if (items.length === 0) {
|
|
35
|
+
throw new FlowError("INVALID_KEIYAKU_DRAFT", `missing required section: ## ${name}`);
|
|
36
|
+
}
|
|
37
|
+
return items;
|
|
38
|
+
}
|
|
39
|
+
export function requireMarkdownTitle(parts) {
|
|
40
|
+
const title = parts.title?.trim();
|
|
41
|
+
if (!title) {
|
|
42
|
+
throw new FlowError("INVALID_KEIYAKU_DRAFT", "missing required title: # Title");
|
|
43
|
+
}
|
|
44
|
+
return title;
|
|
45
|
+
}
|
package/build/core/context.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import * as path from "node:path";
|
|
2
1
|
import { KEIYAKU_BRANCH_PREFIX } from "../keiyaku.js";
|
|
3
2
|
import { FlowError } from "../flow-error.js";
|
|
4
|
-
import { createGit, errorContainsAnyPattern, MISSING_HEAD_PATTERNS, wrapGitError } from "../git/core.js";
|
|
3
|
+
import { createGit, errorContainsAnyPattern, MISSING_HEAD_PATTERNS, NOT_GIT_REPOSITORY_PATTERNS, wrapGitError } from "../git/core.js";
|
|
5
4
|
import { getCurrentBranch, listLocalBranches } from "../git/branches.js";
|
|
6
5
|
import { readLedger } from "./ledger.js";
|
|
7
6
|
import { listContractIds } from "./ledger.js";
|
|
8
7
|
import { deriveContractState, isTerminalState } from "./status/lifecycle.js";
|
|
9
8
|
import { latestBase } from "./status/drift.js";
|
|
10
|
-
import {
|
|
9
|
+
import { activeContractBoundByEngineWorktree } from "./worktree-path.js";
|
|
11
10
|
function isOperableLedger(entries) {
|
|
12
11
|
const state = deriveContractState(entries);
|
|
13
12
|
return state.state !== "corrupt" && !isTerminalState(state);
|
|
@@ -25,6 +24,17 @@ async function isOperableContract(cwd, contractId) {
|
|
|
25
24
|
return (await operableContractIds(cwd)).includes(contractId);
|
|
26
25
|
}
|
|
27
26
|
export async function resolveImplicitCurrentContractId(cwd) {
|
|
27
|
+
// Prefer the verified engine-worktree binding (same tier as existing-commission verbs).
|
|
28
|
+
try {
|
|
29
|
+
const bound = await activeContractBoundByEngineWorktree(cwd);
|
|
30
|
+
if (bound)
|
|
31
|
+
return bound;
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
if (!errorContainsAnyPattern(error, NOT_GIT_REPOSITORY_PATTERNS))
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
// Branch remains a residual signal for workspace:here checkouts without an engine worktree.
|
|
28
38
|
const git = createGit(cwd);
|
|
29
39
|
try {
|
|
30
40
|
const branch = (await git.raw(["branch", "--show-current"])).trim();
|
|
@@ -39,10 +49,6 @@ export async function resolveImplicitCurrentContractId(cwd) {
|
|
|
39
49
|
throw wrapGitError("branch --show-current", error, cwd);
|
|
40
50
|
}
|
|
41
51
|
}
|
|
42
|
-
const worktreeId = path.basename(cwd);
|
|
43
|
-
const worktreeContractId = await activeContractIdForWorktreeDir(cwd, worktreeId);
|
|
44
|
-
if (worktreeContractId)
|
|
45
|
-
return worktreeContractId;
|
|
46
52
|
return undefined;
|
|
47
53
|
}
|
|
48
54
|
export async function resolveCurrentContractId(cwd) {
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { FlowError } from "../flow-error.js";
|
|
1
4
|
import { shortCommitHash } from "../git/commits.js";
|
|
5
|
+
import { KEIYAKU_FILE } from "../keiyaku.js";
|
|
6
|
+
import { readLedger } from "./ledger.js";
|
|
2
7
|
import { deriveContractState } from "./status/lifecycle.js";
|
|
8
|
+
import { renderScopeFragment } from "./scope.js";
|
|
3
9
|
const VERB_COLUMN_WIDTH = 11;
|
|
4
10
|
const TIME_COLUMN_WIDTH = 6;
|
|
5
11
|
const ACTOR_COLUMN_WIDTH = 11;
|
|
@@ -36,8 +42,6 @@ function sealAggregate(entries) {
|
|
|
36
42
|
function scopeStatusFact(entry) {
|
|
37
43
|
if (entry.data.scopeAudit.violations.length === 0)
|
|
38
44
|
return "scope ✓ clean";
|
|
39
|
-
if (entry.data.scopeAudit.waived)
|
|
40
|
-
return `scope ▲ waived ${entry.data.scopeAudit.violations.length}`;
|
|
41
45
|
return `scope ✕ ${entry.data.scopeAudit.violations.length}`;
|
|
42
46
|
}
|
|
43
47
|
function formatDiffstat(insertions, deletions) {
|
|
@@ -208,6 +212,18 @@ export function renderVerticalLog(input) {
|
|
|
208
212
|
}
|
|
209
213
|
return renderLedgerRows(input.entries).join("\n");
|
|
210
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Sole post-mutation KEIYAKU.md refresh: read the authoritative ledger at
|
|
217
|
+
* ledgerCwd, then write the projection at renderCwd. ledgerCwd and renderCwd
|
|
218
|
+
* are distinct coordinates (hub vs linked delivery worktree).
|
|
219
|
+
*/
|
|
220
|
+
export async function refreshContractView(input) {
|
|
221
|
+
const ledger = await readLedger(input.ledgerCwd, input.contractId);
|
|
222
|
+
if (!ledger) {
|
|
223
|
+
throw new FlowError("INTERNAL_STATE", `contract ${input.contractId} active ledger disappeared before render`);
|
|
224
|
+
}
|
|
225
|
+
await fs.writeFile(path.join(input.renderCwd, KEIYAKU_FILE), renderContractView({ id: input.contractId, entries: ledger.entries }), "utf8");
|
|
226
|
+
}
|
|
211
227
|
export function renderContractView(input) {
|
|
212
228
|
const bind = input.entries.find((entry) => entry.kind === "bind");
|
|
213
229
|
const state = deriveContractState(input.entries);
|
|
@@ -237,13 +253,13 @@ export function renderContractView(input) {
|
|
|
237
253
|
`place: ${bind.data.place ?? "(none)"}`,
|
|
238
254
|
`after: ${(bind.data.after ?? []).join(", ") || "(none)"}`,
|
|
239
255
|
"",
|
|
240
|
-
"
|
|
256
|
+
"## Objective",
|
|
241
257
|
bind.data.objective,
|
|
242
258
|
"",
|
|
243
|
-
"
|
|
244
|
-
...bind.data.scope.
|
|
259
|
+
"## Scope",
|
|
260
|
+
...renderScopeFragment(bind.data.scope).split("\n"),
|
|
245
261
|
"",
|
|
246
|
-
"
|
|
262
|
+
"## Checks",
|
|
247
263
|
...bind.data.checks.map((check) => `- ${check}`),
|
|
248
264
|
"",
|
|
249
265
|
...(bind.data.extensions.length > 0
|