@astrosheep/keiyaku 2.8.5 → 2.9.1
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 +35 -15
- package/build/.tsbuildinfo +1 -1
- package/build/agents/{call-terms_v2.js → call-terms.js} +12 -8
- package/build/agents/harness/control-types.js +1 -0
- package/build/agents/harness/execution-handle.js +23 -3
- package/build/agents/harness/index.js +6 -607
- package/build/agents/harness/outcome.js +141 -0
- package/build/agents/harness/projection.js +310 -0
- package/build/agents/harness/router.js +201 -0
- package/build/agents/harness/runtime.js +2 -1
- package/build/agents/{launch-snapshot_v2.js → launch-snapshot/model.js} +69 -74
- package/build/agents/launch-snapshot/resolve.js +72 -0
- package/build/agents/opencode-sdk.js +24 -3
- package/build/agents/providers/{claude-agent-sdk.js → claude-agent-sdk/adapter.js} +46 -368
- package/build/agents/providers/claude-agent-sdk/events.js +218 -0
- package/build/agents/providers/claude-agent-sdk/session.js +158 -0
- package/build/agents/providers/codex-app-server/adapter.js +347 -0
- package/build/agents/providers/codex-app-server/events.js +352 -0
- package/build/agents/providers/codex-app-server/session.js +266 -0
- package/build/agents/providers/codex-sdk.js +23 -5
- package/build/agents/providers/opencode-sdk/adapter.js +344 -0
- package/build/agents/providers/opencode-sdk/events.js +354 -0
- package/build/agents/providers/opencode-sdk/session.js +180 -0
- package/build/agents/providers/pi/adapter.js +269 -0
- package/build/agents/providers/pi/checkpoint.js +41 -0
- package/build/agents/providers/pi/events.js +282 -0
- package/build/agents/{selector_v2.js → selector.js} +8 -6
- package/build/cli/commands/akuma/akuma/handler.js +4 -0
- package/build/cli/commands/akuma/akuma/meta.js +16 -0
- package/build/cli/commands/akuma/catalog.js +8 -0
- package/build/cli/commands/akuma/list/handler.js +15 -0
- package/build/cli/commands/akuma/list/meta-ls.js +9 -0
- package/build/cli/commands/akuma/view/handler.js +34 -0
- package/build/cli/commands/akuma/view/meta.js +8 -0
- package/build/cli/commands/akuma.js +1 -1
- package/build/cli/commands/contract/amend/handler.js +10 -0
- package/build/cli/commands/contract/amend/meta.js +12 -0
- package/build/cli/commands/contract/arc/handler.js +9 -0
- package/build/cli/commands/contract/arc/meta.js +26 -0
- package/build/cli/commands/contract/bind/handler.js +23 -0
- package/build/cli/commands/contract/bind/meta.js +30 -0
- package/build/cli/commands/contract/catalog.js +16 -0
- package/build/cli/commands/contract/forfeit/handler.js +13 -0
- package/build/cli/commands/contract/forfeit/meta.js +12 -0
- package/build/cli/commands/contract/log/handler.js +12 -0
- package/build/cli/commands/contract/log/meta.js +12 -0
- package/build/cli/commands/contract/petition/handler.js +26 -0
- package/build/cli/commands/contract/petition/meta.js +23 -0
- package/build/cli/commands/contract/renew/handler.js +10 -0
- package/build/cli/commands/contract/renew/meta.js +17 -0
- package/build/cli/commands/projection/call/handler.js +42 -0
- package/build/cli/commands/projection/call/meta.js +9 -0
- package/build/cli/commands/projection/catalog.js +14 -0
- package/build/cli/commands/projection/kill/handler.js +37 -0
- package/build/cli/commands/projection/kill/meta.js +11 -0
- package/build/cli/commands/projection/revive/handler.js +56 -0
- package/build/cli/commands/projection/revive/meta.js +9 -0
- package/build/cli/commands/projection/status/handler.js +25 -0
- package/build/cli/commands/projection/status/meta.js +9 -0
- package/build/cli/commands/projection/tell/handler.js +36 -0
- package/build/cli/commands/projection/tell/meta.js +9 -0
- package/build/cli/commands/projection/wait/handler.js +23 -0
- package/build/cli/commands/projection/wait/meta.js +11 -0
- package/build/cli/commands/registry.js +100 -0
- package/build/cli/commands/shared.js +71 -0
- package/build/cli/commands/skills/catalog.js +6 -0
- package/build/cli/commands/skills/install/handler.js +10 -0
- package/build/cli/commands/skills/install/meta.js +9 -0
- package/build/cli/commands/skills/skills/handler.js +4 -0
- package/build/cli/commands/skills/skills/meta.js +10 -0
- package/build/cli/commands/system/catalog.js +8 -0
- package/build/cli/commands/system/completion/handler.js +10 -0
- package/build/cli/commands/system/completion/meta.js +9 -0
- package/build/cli/commands/system/dump-env/handler.js +3 -0
- package/build/cli/commands/system/dump-env/meta.js +10 -0
- package/build/cli/commands/system/guide/handler.js +4 -0
- package/build/cli/commands/system/guide/meta.js +9 -0
- package/build/cli/commands/task/add/handler.js +21 -0
- package/build/cli/commands/task/add/meta.js +8 -0
- package/build/cli/commands/task/catalog.js +22 -0
- package/build/cli/commands/task/doctor/handler.js +4 -0
- package/build/cli/commands/task/doctor/meta.js +8 -0
- package/build/cli/commands/task/done/handler.js +17 -0
- package/build/cli/commands/task/done/meta.js +8 -0
- package/build/cli/commands/task/drop/handler.js +6 -0
- package/build/cli/commands/task/drop/meta.js +8 -0
- package/build/cli/commands/task/ls/handler.js +13 -0
- package/build/cli/commands/task/ls/meta.js +8 -0
- package/build/cli/commands/task/shared.js +131 -0
- package/build/cli/commands/task/start/handler.js +6 -0
- package/build/cli/commands/task/start/meta.js +8 -0
- package/build/cli/commands/task/stop/handler.js +17 -0
- package/build/cli/commands/task/stop/meta.js +8 -0
- package/build/cli/commands/task/task/handler.js +5 -0
- package/build/cli/commands/task/task/meta.js +11 -0
- package/build/cli/commands/task/update/handler.js +18 -0
- package/build/cli/commands/task/update/meta.js +8 -0
- package/build/cli/commands/task/view/handler.js +14 -0
- package/build/cli/commands/task/view/meta.js +8 -0
- package/build/cli/completion.js +26 -27
- package/build/cli/flags.js +79 -2
- package/build/cli/help.js +27 -49
- package/build/cli/index.js +121 -374
- package/build/cli/output-stream-error-policy.js +17 -0
- package/build/cli/parse-flags.js +197 -0
- package/build/cli/parse-metadata.js +129 -0
- package/build/cli/parse-selectors.js +65 -0
- package/build/cli/parse.js +46 -313
- package/build/cli/projection-address.js +5 -0
- package/build/cli/render/arc.js +1 -1
- package/build/cli/render/errors.js +4 -3
- package/build/cli/render/format.js +14 -0
- package/build/cli/render/kanshi.js +106 -0
- package/build/cli/render/petition.js +24 -1
- package/build/cli/render/projection-activity.js +5 -1
- package/build/cli/render/shared.js +2 -2
- package/build/cli/render/status.js +79 -13
- package/build/cli/render/task.js +113 -0
- package/build/cli/render/wait.js +23 -3
- package/build/cli/types.js +1 -1
- package/build/config/{akuma-loader_v2.js → akuma-loader.js} +7 -4
- package/build/config/env.js +9 -4
- package/build/config/settings/disease.js +26 -0
- package/build/config/settings/knobs.js +8 -0
- package/build/config/settings/loader.js +244 -0
- package/build/config/settings/schema.js +276 -0
- package/build/core/addressing.js +1 -1
- package/build/core/amend.js +5 -8
- package/build/core/arc.js +7 -8
- package/build/core/bind-workspace.js +123 -0
- package/build/core/bind.js +75 -155
- package/build/core/call/call.js +229 -0
- package/build/core/call/context.js +251 -0
- package/build/core/call/execution.js +217 -0
- package/build/core/call/prompt.js +42 -0
- package/build/core/call/reference.js +24 -0
- package/build/core/call-persist.js +10 -3
- package/build/core/claim-delivery.js +247 -0
- package/build/core/claim.js +39 -277
- package/build/core/context.js +2 -1
- package/build/core/{render.js → contract-view.js} +12 -140
- package/build/core/draft.js +107 -9
- package/build/core/entry.js +9 -1
- package/build/core/execution-coordinate.js +4 -20
- package/build/core/execution-pact.js +16 -31
- package/build/core/forfeit.js +35 -22
- package/build/core/hints.js +2 -2
- package/build/core/log.js +2 -2
- package/build/core/path-coordinate.js +27 -0
- package/build/core/petition-claim-gates.js +8 -6
- package/build/core/petition-preview.js +97 -0
- package/build/core/petition-run.js +5 -7
- package/build/core/petition.js +39 -26
- package/build/core/projection/generation/database.js +306 -0
- package/build/core/projection/generation/identity.js +84 -0
- package/build/core/projection/generation/model.js +201 -0
- package/build/core/projection/generation/store.js +73 -0
- package/build/core/projection/generation/transitions.js +258 -0
- package/build/core/projection/heart.js +0 -307
- package/build/core/projection/tell/database.js +109 -0
- package/build/core/projection/tell/model.js +97 -0
- package/build/core/{projection-tells.js → projection/tell/store.js} +3 -158
- package/build/core/projection-activity.js +23 -2
- package/build/core/projection-coordinate.js +14 -2
- package/build/core/projection-core.js +2 -1
- package/build/core/projection-execution-observer.js +259 -0
- package/build/core/projection-generation-continuation.js +1 -1
- package/build/core/projection-generation-execution.js +90 -20
- package/build/core/projection-generation-launcher.js +1 -1
- package/build/core/projection-generation-runner.js +198 -4
- package/build/core/projection-identity.js +1 -1
- package/build/core/projection-kill.js +50 -17
- package/build/core/projection-life-observer.js +1 -1
- package/build/core/projection-life-protocol.js +10 -0
- package/build/core/projection-mint.js +1 -1
- package/build/core/projection-status.js +45 -32
- package/build/core/projection-wait.js +12 -2
- package/build/core/projection-wake.js +5 -2
- package/build/core/{queue_v2.js → queue.js} +2 -1
- package/build/core/registry.js +1 -1
- package/build/core/renew.js +9 -11
- package/build/core/response-artifact-catalog-sqlite.js +112 -0
- package/build/core/response-artifact-catalog.js +7 -0
- package/build/core/seal.js +44 -16
- package/build/core/status/board.js +289 -0
- package/build/core/status/drift.js +99 -0
- package/build/core/status/lifecycle.js +84 -0
- package/build/core/status/reconciliation.js +131 -0
- package/build/core/stored-agent-event.js +28 -4
- package/build/core/target-ref.js +10 -0
- package/build/core/task/board.js +175 -0
- package/build/core/task/commands.js +211 -0
- package/build/core/task/document.js +189 -0
- package/build/core/task/model.js +1 -0
- package/build/core/task/settlement-git.js +207 -0
- package/build/core/task/settlement-policy.js +82 -0
- package/build/core/task/source-board.js +84 -0
- package/build/core/task/source-model.js +1 -0
- package/build/core/task/validation.js +44 -0
- package/build/core/task-contract.js +237 -0
- package/build/core/task-doctor.js +14 -0
- package/build/core/task-git-actor.js +38 -0
- package/build/core/task-git-runtime.js +37 -0
- package/build/core/task-git-store.js +385 -0
- package/build/core/task-repository.js +1 -0
- package/build/core/task-store-repository.js +86 -0
- package/build/core/task-store.js +1 -0
- package/build/core/task-worktree.js +51 -0
- package/build/core/task.js +4 -0
- package/build/core/transcripts.js +138 -56
- package/build/core/validation.js +17 -0
- package/build/core/verdict.js +2 -2
- package/build/core/worktree-path.js +33 -8
- package/build/flow-error.js +5 -2
- package/build/generated/version.js +1 -1
- package/build/git/branches.js +33 -9
- package/build/git/commits.js +3 -0
- package/build/git/core.js +9 -0
- package/build/git/diff/parsers.js +0 -94
- package/build/index.js +2 -0
- package/build/keiyaku-constants.js +2 -0
- package/build/keiyaku.js +4 -3
- package/package.json +3 -2
- package/skills/keiyaku/SKILL.md +30 -13
- package/skills/keiyaku-akuma/SKILL.md +30 -57
- package/skills/keiyaku-task/SKILL.md +51 -0
- package/skills/keiyaku-workflow/SKILL.md +71 -0
- package/build/agents/harness/pump.js +0 -158
- package/build/agents/providers/codex-app-server.js +0 -864
- package/build/agents/providers/opencode-sdk.js +0 -363
- package/build/agents/providers/pi.js +0 -557
- package/build/config/settings.js +0 -533
- package/build/core/call.js +0 -686
- package/build/core/projection/generation.js +0 -412
- package/build/core/projection/identity.js +0 -81
- package/build/core/projection/mint.js +0 -174
- package/build/core/projection-generation-store.js +0 -707
- package/build/core/status.js +0 -539
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
2
|
import * as fs from "node:fs/promises";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
-
import { parseResolvedAkumaLaunchSnapshot, } from "../agents/launch-
|
|
4
|
+
import { parseResolvedAkumaLaunchSnapshot, } from "../agents/launch-snapshot/model.js";
|
|
5
5
|
import { resolvePersistedSubagentSession } from "../agents/session.js";
|
|
6
6
|
import { isErrnoException } from "../errno.js";
|
|
7
7
|
import { FlowError, requireText } from "../flow-error.js";
|
|
@@ -13,6 +13,8 @@ import { parseExecutionCoordinates } from "./execution-coordinate.js";
|
|
|
13
13
|
import { createUlid } from "./ids.js";
|
|
14
14
|
import { parseToAST } from "./markdown/parser.js";
|
|
15
15
|
import { isResponseArtifactId, RESPONSE_ARTIFACT_ID_RE } from "./response-artifact-id.js";
|
|
16
|
+
import { getResponseArtifactCatalog, } from "./response-artifact-catalog.js";
|
|
17
|
+
import { assertExactFields, assertNonBlankString, isPlainRecord, } from "./validation.js";
|
|
16
18
|
export { isResponseArtifactId, RESPONSE_ARTIFACT_ID_RE } from "./response-artifact-id.js";
|
|
17
19
|
const RESPONSE_HISTORY_SLUG_MAX_LENGTH = 24;
|
|
18
20
|
const RESPONSE_HISTORY_SESSION_KEY = "session";
|
|
@@ -30,43 +32,30 @@ const RESUMABLE_RESPONSE_HEADINGS = Object.values(RESPONSE_ARTIFACT_HEADINGS);
|
|
|
30
32
|
function artifactError(locator, field, reason) {
|
|
31
33
|
return new FlowError("INVALID_RESPONSE_PATH", `Invalid response artifact '${locator}': field '${field}' ${reason}.`);
|
|
32
34
|
}
|
|
33
|
-
function
|
|
34
|
-
return
|
|
35
|
-
}
|
|
36
|
-
function assertExactFields(value, required, locator, prefix) {
|
|
37
|
-
for (const field of required) {
|
|
38
|
-
if (!(field in value))
|
|
39
|
-
throw artifactError(locator, `${prefix}.${field}`, "is missing");
|
|
40
|
-
}
|
|
41
|
-
const allowed = new Set(required);
|
|
42
|
-
const unknown = Object.keys(value).filter((field) => !allowed.has(field)).sort()[0];
|
|
43
|
-
if (unknown !== undefined)
|
|
44
|
-
throw artifactError(locator, `${prefix}.${unknown}`, "is unknown");
|
|
45
|
-
}
|
|
46
|
-
function nonBlank(value, locator, field) {
|
|
47
|
-
if (typeof value !== "string" || value.trim() === "")
|
|
48
|
-
throw artifactError(locator, field, "must be a non-blank string");
|
|
35
|
+
function artifactInvalid(locator) {
|
|
36
|
+
return (field, reason) => artifactError(locator, field, reason);
|
|
49
37
|
}
|
|
50
38
|
/** The sole durable provenance parser. */
|
|
51
39
|
export function parseResponseArtifactProvenance(value, locator) {
|
|
52
|
-
|
|
40
|
+
const invalid = artifactInvalid(locator);
|
|
41
|
+
if (!isPlainRecord(value))
|
|
53
42
|
throw artifactError(locator, "provenance", "must be an object");
|
|
54
|
-
assertExactFields(value, ["artifactId", "authority", "binding", "evidence"],
|
|
55
|
-
|
|
43
|
+
assertExactFields(value, ["artifactId", "authority", "binding", "evidence"], [], "provenance", invalid);
|
|
44
|
+
assertNonBlankString(value.artifactId, "provenance.artifactId", invalid);
|
|
56
45
|
if (!RESPONSE_ARTIFACT_ID_RE.test(value.artifactId)) {
|
|
57
46
|
throw artifactError(locator, "provenance.artifactId", "must be rsp_ followed by a ULID");
|
|
58
47
|
}
|
|
59
48
|
const { authority, binding } = parseExecutionCoordinates(value.authority, value.binding, (field, reason) => artifactError(locator, `provenance.${field}`, reason));
|
|
60
|
-
if (!
|
|
49
|
+
if (!isPlainRecord(value.evidence))
|
|
61
50
|
throw artifactError(locator, "provenance.evidence", "must be an object");
|
|
62
51
|
if (authority.kind === "repository") {
|
|
63
|
-
assertExactFields(value.evidence, ["branch", "commit"],
|
|
64
|
-
|
|
65
|
-
|
|
52
|
+
assertExactFields(value.evidence, ["branch", "commit"], [], "provenance.evidence", invalid);
|
|
53
|
+
assertNonBlankString(value.evidence.branch, "provenance.evidence.branch", invalid);
|
|
54
|
+
assertNonBlankString(value.evidence.commit, "provenance.evidence.commit", invalid);
|
|
66
55
|
return { artifactId: value.artifactId, authority, binding, evidence: { branch: value.evidence.branch, commit: value.evidence.commit } };
|
|
67
56
|
}
|
|
68
|
-
assertExactFields(value.evidence, ["workdir"],
|
|
69
|
-
|
|
57
|
+
assertExactFields(value.evidence, ["workdir"], [], "provenance.evidence", invalid);
|
|
58
|
+
assertNonBlankString(value.evidence.workdir, "provenance.evidence.workdir", invalid);
|
|
70
59
|
if (!path.isAbsolute(value.evidence.workdir)) {
|
|
71
60
|
throw artifactError(locator, "provenance.evidence.workdir", "must be an absolute path");
|
|
72
61
|
}
|
|
@@ -130,6 +119,15 @@ export async function persistResponseHistory(input) {
|
|
|
130
119
|
const responsePath = path.join(historyDir, `${fileStamp}_${input.tool.toUpperCase()}_${slug(input.title ?? "", input.tool)}.md`);
|
|
131
120
|
await fs.mkdir(historyDir, { recursive: true });
|
|
132
121
|
await fs.writeFile(responsePath, buildMarkdown(input, iso, provenance), "utf8");
|
|
122
|
+
try {
|
|
123
|
+
getResponseArtifactCatalog()?.register({
|
|
124
|
+
id: artifactId,
|
|
125
|
+
stableRoot: await fs.realpath(input.cwd),
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// The catalog is a disposable read model; the persisted artifact remains truth.
|
|
130
|
+
}
|
|
133
131
|
return { artifactId, responsePath: path.relative(input.cwd, responsePath) };
|
|
134
132
|
}
|
|
135
133
|
function detectTool(document) {
|
|
@@ -206,43 +204,30 @@ export async function readResponseArtifact(input) {
|
|
|
206
204
|
}
|
|
207
205
|
}
|
|
208
206
|
const subagentName = frontmatter.subagent_name?.trim() || undefined;
|
|
209
|
-
const storageRoot = path.resolve(path.dirname(absolutePath), "..", "..");
|
|
207
|
+
const storageRoot = await fs.realpath(path.resolve(path.dirname(absolutePath), "..", ".."));
|
|
210
208
|
return { artifactId: provenance.artifactId, responsePath: path.relative(input.cwd, absolutePath), absolutePath, storageRoot, provenance, tool, ...(session ? { session } : {}), ...(launchSnapshot ? { launchSnapshot } : {}), ...(subagentName ? { subagentName } : {}) };
|
|
211
209
|
}
|
|
212
|
-
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
};
|
|
216
|
-
let identity;
|
|
217
|
-
try {
|
|
218
|
-
identity = requireText("artifactId", input.artifactId);
|
|
219
|
-
}
|
|
220
|
-
catch (error) {
|
|
221
|
-
return carry(error);
|
|
222
|
-
}
|
|
223
|
-
if (!isResponseArtifactId(identity)) {
|
|
224
|
-
return carry(new FlowError("INVALID_RESPONSE_PATH", `${identity} is not a response artifact handle; revive expects an artifact id`));
|
|
225
|
-
}
|
|
226
|
-
const historyDir = path.join(input.cwd, RESPONSE_HISTORY_DIR);
|
|
210
|
+
async function findResponseArtifactAtRoot(input) {
|
|
211
|
+
const physicalHistoryDir = path.join(input.stableRoot, RESPONSE_HISTORY_DIR);
|
|
212
|
+
const historyDir = path.join(input.displayRoot ?? input.stableRoot, RESPONSE_HISTORY_DIR);
|
|
227
213
|
let names;
|
|
228
214
|
try {
|
|
229
|
-
names = await fs.readdir(
|
|
215
|
+
names = await fs.readdir(physicalHistoryDir);
|
|
230
216
|
}
|
|
231
217
|
catch (error) {
|
|
232
|
-
if (isErrnoException(error) && error.code === "ENOENT")
|
|
233
|
-
return
|
|
234
|
-
|
|
235
|
-
return carry(error);
|
|
218
|
+
if (isErrnoException(error) && error.code === "ENOENT")
|
|
219
|
+
return { kind: "missing" };
|
|
220
|
+
return input.carry(error);
|
|
236
221
|
}
|
|
237
222
|
let match;
|
|
238
223
|
for (const name of names.filter((candidate) => candidate.endsWith(".md")).sort()) {
|
|
239
224
|
const responsePath = path.join(RESPONSE_HISTORY_DIR, name);
|
|
240
225
|
let document;
|
|
241
226
|
try {
|
|
242
|
-
document = await fs.readFile(path.join(input.
|
|
227
|
+
document = await fs.readFile(path.join(input.stableRoot, responsePath), "utf8");
|
|
243
228
|
}
|
|
244
229
|
catch (error) {
|
|
245
|
-
return carry(error);
|
|
230
|
+
return input.carry(error);
|
|
246
231
|
}
|
|
247
232
|
const encoded = parseToAST(document).frontmatter?.entries?.[RESPONSE_HISTORY_PROVENANCE_KEY];
|
|
248
233
|
if (encoded === undefined)
|
|
@@ -254,26 +239,123 @@ export async function locateResponseArtifact(input) {
|
|
|
254
239
|
catch {
|
|
255
240
|
continue;
|
|
256
241
|
}
|
|
257
|
-
if (!
|
|
242
|
+
if (!isPlainRecord(indexed) || indexed.artifactId !== input.artifactId)
|
|
258
243
|
continue;
|
|
259
244
|
let parsed;
|
|
260
245
|
try {
|
|
261
|
-
parsed = await readResponseArtifact({ cwd: input.
|
|
246
|
+
parsed = await readResponseArtifact({ cwd: input.stableRoot, responsePath });
|
|
262
247
|
}
|
|
263
248
|
catch (error) {
|
|
264
|
-
return carry(error);
|
|
249
|
+
return input.carry(error);
|
|
265
250
|
}
|
|
266
251
|
if (!parsed)
|
|
267
252
|
continue;
|
|
268
253
|
if (match) {
|
|
269
|
-
return carry(new FlowError("INVALID_RESPONSE_PATH", `Response artifact identity '${
|
|
254
|
+
return input.carry(new FlowError("INVALID_RESPONSE_PATH", `Response artifact identity '${input.artifactId}' is duplicated in ${historyDir}.`));
|
|
270
255
|
}
|
|
271
256
|
match = parsed;
|
|
272
257
|
}
|
|
273
|
-
|
|
274
|
-
|
|
258
|
+
return match ? { kind: "found", artifact: match } : { kind: "missing" };
|
|
259
|
+
}
|
|
260
|
+
function observeCatalogArtifact(catalog, artifact) {
|
|
261
|
+
try {
|
|
262
|
+
catalog?.touch({ id: artifact.artifactId, stableRoot: artifact.storageRoot });
|
|
263
|
+
}
|
|
264
|
+
catch {
|
|
265
|
+
// Artifact observation remains authoritative when the disposable catalog is unavailable.
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
export async function reconcileResponseArtifactCatalog(stableRoot) {
|
|
269
|
+
const catalog = getResponseArtifactCatalog();
|
|
270
|
+
if (!catalog)
|
|
271
|
+
return;
|
|
272
|
+
const physicalRoot = await fs.realpath(stableRoot);
|
|
273
|
+
const historyDir = path.join(physicalRoot, RESPONSE_HISTORY_DIR);
|
|
274
|
+
let names;
|
|
275
|
+
try {
|
|
276
|
+
names = await fs.readdir(historyDir);
|
|
277
|
+
}
|
|
278
|
+
catch (error) {
|
|
279
|
+
if (isErrnoException(error) && error.code === "ENOENT")
|
|
280
|
+
return;
|
|
281
|
+
throw error;
|
|
275
282
|
}
|
|
276
|
-
|
|
283
|
+
for (const name of names.filter((candidate) => candidate.endsWith(".md")).sort()) {
|
|
284
|
+
try {
|
|
285
|
+
const artifact = await readResponseArtifact({
|
|
286
|
+
cwd: physicalRoot,
|
|
287
|
+
responsePath: path.join(RESPONSE_HISTORY_DIR, name),
|
|
288
|
+
});
|
|
289
|
+
if (artifact)
|
|
290
|
+
catalog.register({ id: artifact.artifactId, stableRoot: artifact.storageRoot });
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
// Reconciliation observes valid local artifacts only; it never repairs artifact truth.
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
export async function locateResponseArtifact(input) {
|
|
298
|
+
const carry = (error) => {
|
|
299
|
+
throw attachAddressCarrier(error, input.attempt);
|
|
300
|
+
};
|
|
301
|
+
let identity;
|
|
302
|
+
try {
|
|
303
|
+
identity = requireText("artifactId", input.artifactId);
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
return carry(error);
|
|
307
|
+
}
|
|
308
|
+
if (!isResponseArtifactId(identity)) {
|
|
309
|
+
return carry(new FlowError("INVALID_RESPONSE_PATH", `${identity} is not a response artifact handle; revive expects an artifact id`));
|
|
310
|
+
}
|
|
311
|
+
let physicalLocalRoot;
|
|
312
|
+
try {
|
|
313
|
+
physicalLocalRoot = await fs.realpath(input.cwd);
|
|
314
|
+
}
|
|
315
|
+
catch (error) {
|
|
316
|
+
if (!isErrnoException(error) || error.code !== "ENOENT")
|
|
317
|
+
return carry(error);
|
|
318
|
+
physicalLocalRoot = path.resolve(input.cwd);
|
|
319
|
+
}
|
|
320
|
+
const local = await findResponseArtifactAtRoot({
|
|
321
|
+
stableRoot: physicalLocalRoot,
|
|
322
|
+
displayRoot: input.cwd,
|
|
323
|
+
artifactId: identity,
|
|
324
|
+
carry,
|
|
325
|
+
});
|
|
326
|
+
const catalog = getResponseArtifactCatalog();
|
|
327
|
+
if (local.kind === "found") {
|
|
328
|
+
observeCatalogArtifact(catalog, local.artifact);
|
|
329
|
+
return local.artifact;
|
|
330
|
+
}
|
|
331
|
+
let cataloged;
|
|
332
|
+
try {
|
|
333
|
+
cataloged = catalog?.lookup(identity);
|
|
334
|
+
}
|
|
335
|
+
catch {
|
|
336
|
+
cataloged = undefined;
|
|
337
|
+
}
|
|
338
|
+
if (cataloged) {
|
|
339
|
+
const catalogedRoot = cataloged.stableRoot;
|
|
340
|
+
const remote = await findResponseArtifactAtRoot({
|
|
341
|
+
stableRoot: catalogedRoot,
|
|
342
|
+
artifactId: identity,
|
|
343
|
+
carry,
|
|
344
|
+
});
|
|
345
|
+
if (remote.kind === "found") {
|
|
346
|
+
observeCatalogArtifact(catalog, remote.artifact);
|
|
347
|
+
return remote.artifact;
|
|
348
|
+
}
|
|
349
|
+
try {
|
|
350
|
+
catalog?.removeDead({ id: identity, stableRoot: catalogedRoot });
|
|
351
|
+
}
|
|
352
|
+
catch {
|
|
353
|
+
// Dead-row cleanup is best-effort; the physical lookup result owns the error.
|
|
354
|
+
}
|
|
355
|
+
return carry(new FlowError("INVALID_RESPONSE_PATH", `${identity} not found at cataloged root ${catalogedRoot}`));
|
|
356
|
+
}
|
|
357
|
+
const historyDir = path.join(input.cwd, RESPONSE_HISTORY_DIR);
|
|
358
|
+
return carry(new FlowError("INVALID_RESPONSE_PATH", `Response artifact '${identity}' was not found in ${historyDir}.`));
|
|
277
359
|
}
|
|
278
360
|
export function requireResumableArtifact(artifact) {
|
|
279
361
|
if (!artifact.session)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function isPlainRecord(value) {
|
|
2
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3
|
+
}
|
|
4
|
+
export function assertExactFields(value, required, optional, prefix, invalid) {
|
|
5
|
+
for (const field of required) {
|
|
6
|
+
if (!(field in value))
|
|
7
|
+
throw invalid(prefix ? `${prefix}.${field}` : field, "is missing");
|
|
8
|
+
}
|
|
9
|
+
const allowed = new Set([...required, ...optional]);
|
|
10
|
+
const unknown = Object.keys(value).filter((field) => !allowed.has(field)).sort()[0];
|
|
11
|
+
if (unknown !== undefined)
|
|
12
|
+
throw invalid(prefix ? `${prefix}.${unknown}` : unknown, "is unknown");
|
|
13
|
+
}
|
|
14
|
+
export function assertNonBlankString(value, field, invalid) {
|
|
15
|
+
if (typeof value !== "string" || value.trim() === "")
|
|
16
|
+
throw invalid(field, "must be a non-blank string");
|
|
17
|
+
}
|
package/build/core/verdict.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { FlowError } from "../flow-error.js";
|
|
2
2
|
import { claimContract } from "./claim.js";
|
|
3
3
|
import { activeLedgerRef, appendWithRetry, readLedger } from "./ledger.js";
|
|
4
|
-
import { assertClaimQueueHead, queueMembership, readQueueReadModel } from "./
|
|
5
|
-
import { deriveContractState } from "./status.js";
|
|
4
|
+
import { assertClaimQueueHead, queueMembership, readQueueReadModel } from "./queue.js";
|
|
5
|
+
import { deriveContractState } from "./status/lifecycle.js";
|
|
6
6
|
function latestVerdict(entries) {
|
|
7
7
|
for (let index = entries.length - 1; index >= 0; index -= 1) {
|
|
8
8
|
const entry = entries[index];
|
|
@@ -4,7 +4,8 @@ import { FlowError } from "../flow-error.js";
|
|
|
4
4
|
import { createGit, wrapGitError } from "../git/core.js";
|
|
5
5
|
import { readLedger } from "./ledger.js";
|
|
6
6
|
import { listContractIds } from "./ledger.js";
|
|
7
|
-
import { deriveContractState, isTerminalState } from "./status.js";
|
|
7
|
+
import { deriveContractState, isTerminalState } from "./status/lifecycle.js";
|
|
8
|
+
import { gitCommonRootPath, resolveGitCommonRoot } from "./path-coordinate.js";
|
|
8
9
|
export function findBindEntry(entries) {
|
|
9
10
|
return entries.find((entry) => entry.kind === "bind");
|
|
10
11
|
}
|
|
@@ -58,10 +59,16 @@ export async function stableRepoRoot(cwd) {
|
|
|
58
59
|
catch (error) {
|
|
59
60
|
throw wrapGitError("rev-parse --path-format=absolute --git-common-dir", error, cwd);
|
|
60
61
|
}
|
|
61
|
-
|
|
62
|
+
const stableRoot = gitCommonRootPath(commonDir);
|
|
63
|
+
if (!path.isAbsolute(stableRoot)) {
|
|
62
64
|
throw new FlowError("INTERNAL_STATE", `git common directory is not absolute: ${commonDir}`);
|
|
63
65
|
}
|
|
64
|
-
|
|
66
|
+
try {
|
|
67
|
+
return await resolveGitCommonRoot(commonDir);
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
throw new FlowError("INTERNAL_STATE", `cannot resolve git common directory ${stableRoot}`, { cause: error });
|
|
71
|
+
}
|
|
65
72
|
}
|
|
66
73
|
export async function contractWorktreePathFromBind(cwd, contractId, bind) {
|
|
67
74
|
return path.join(await stableRepoRoot(cwd), ".keiyaku", "wt", bind?.data.place ?? contractId);
|
|
@@ -94,11 +101,11 @@ export async function findContractWorktreePath(cwd, contractId) {
|
|
|
94
101
|
return (await findContractWorktree(cwd, contractId)).path;
|
|
95
102
|
}
|
|
96
103
|
/**
|
|
97
|
-
* Resolve the
|
|
98
|
-
*
|
|
99
|
-
* worktrees
|
|
104
|
+
* Resolve the contract id for an engine-owned bound worktree containing cwd.
|
|
105
|
+
* Matches the canonical bind place path and worktree workspace only; ledger
|
|
106
|
+
* terminal state is optional so residual worktrees after cleanup still bind.
|
|
100
107
|
*/
|
|
101
|
-
|
|
108
|
+
async function contractIdForEngineOwnedWorktree(cwd, options) {
|
|
102
109
|
const stableRoot = await stableRepoRoot(cwd);
|
|
103
110
|
const canonicalCwd = await fs.realpath(cwd);
|
|
104
111
|
for (const worktree of await listWorktrees(stableRoot)) {
|
|
@@ -107,7 +114,9 @@ export async function contractPresentedByWorktree(cwd) {
|
|
|
107
114
|
continue;
|
|
108
115
|
const contractId = worktree.branch.slice(branchPrefix.length);
|
|
109
116
|
const ledger = await readLedger(stableRoot, contractId);
|
|
110
|
-
if (!ledger
|
|
117
|
+
if (!ledger)
|
|
118
|
+
continue;
|
|
119
|
+
if (options.requireActive && isTerminalState(deriveContractState(ledger.entries)))
|
|
111
120
|
continue;
|
|
112
121
|
const bind = findBindEntry(ledger.entries);
|
|
113
122
|
if (!bind || bind.data.workspace !== "worktree")
|
|
@@ -128,6 +137,22 @@ export async function contractPresentedByWorktree(cwd) {
|
|
|
128
137
|
}
|
|
129
138
|
return undefined;
|
|
130
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Resolve the active commission presented by an engine-owned contract
|
|
142
|
+
* worktree containing cwd. Ordinary repository directories and arbitrary
|
|
143
|
+
* worktrees never present a commission address.
|
|
144
|
+
*/
|
|
145
|
+
export async function contractPresentedByWorktree(cwd) {
|
|
146
|
+
return contractIdForEngineOwnedWorktree(cwd, { requireActive: true });
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Resolve the contract bound by an engine-owned worktree containing cwd,
|
|
150
|
+
* including when the ledger is already terminal. Task CLI contract context
|
|
151
|
+
* uses this residual binding; call/addressing keep active-only presentation.
|
|
152
|
+
*/
|
|
153
|
+
export async function contractBoundByEngineWorktree(cwd) {
|
|
154
|
+
return contractIdForEngineOwnedWorktree(cwd, { requireActive: false });
|
|
155
|
+
}
|
|
131
156
|
export async function cleanupContractWorkspace(cwd, contractId) {
|
|
132
157
|
const stableRoot = await stableRepoRoot(cwd);
|
|
133
158
|
const git = createGit(stableRoot);
|
package/build/flow-error.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { ACTOR_IDENTITY,
|
|
1
|
+
import { ACTOR_IDENTITY, SETTINGS_PATH_SEGMENTS } from "./keiyaku-constants.js";
|
|
2
|
+
const SETTINGS_DISPLAY_PATH = SETTINGS_PATH_SEGMENTS.join("/");
|
|
2
3
|
const DEFAULT_HINT_CONTEXT = {
|
|
3
4
|
bindToolName: "bind",
|
|
4
5
|
arcToolName: "arc",
|
|
@@ -20,6 +21,8 @@ function resolveFlowErrorHint(code, context) {
|
|
|
20
21
|
switch (code) {
|
|
21
22
|
case "NOT_GIT_REPO":
|
|
22
23
|
return "The provided `cwd` is not a git repository.";
|
|
24
|
+
case "GIT_UNAVAILABLE":
|
|
25
|
+
return "Install Git, or use an explicitly bare command that does not require repository authority.";
|
|
23
26
|
case "ACTIVE_KEIYAKU_EXISTS":
|
|
24
27
|
return `Next: open an arc with \`${context.arcToolName}\`, then use \`${context.renewToolName}\` when delivery must follow the current base, or \`${context.closeToolName}\` to settle it.`;
|
|
25
28
|
case "CONTRACT_AMBIGUOUS":
|
|
@@ -63,7 +66,7 @@ function resolveFlowErrorHint(code, context) {
|
|
|
63
66
|
case "INVALID_CLOSE_INTENT":
|
|
64
67
|
return "Invalid close intent. Valid values are `CLAIM` and `FORFEIT`.";
|
|
65
68
|
case "INVALID_SETTINGS":
|
|
66
|
-
return `Fix invalid configuration in \`${
|
|
69
|
+
return `Fix invalid configuration in \`${SETTINGS_DISPLAY_PATH}\` and retry.`;
|
|
67
70
|
case "INVALID_EFFORT_OVERRIDE":
|
|
68
71
|
return "Choose an effort value declared by the selected Akuma's effortOptions.";
|
|
69
72
|
case "CONCURRENT_MODIFICATION":
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Auto-generated by scripts/generate-version.mjs
|
|
2
|
-
export const VERSION = "2.
|
|
2
|
+
export const VERSION = "2.9.0";
|
package/build/git/branches.js
CHANGED
|
@@ -1,17 +1,41 @@
|
|
|
1
1
|
import { simpleGit } from "simple-git";
|
|
2
2
|
import { FlowError } from "../flow-error.js";
|
|
3
|
-
import { createGit, wrapGitError } from "./core.js";
|
|
4
|
-
export async function
|
|
5
|
-
const git = simpleGit(cwd);
|
|
6
|
-
git.env("GIT_TERMINAL_PROMPT", "0");
|
|
7
|
-
git.env("GCM_INTERACTIVE", "Never");
|
|
8
|
-
git.env("GIT_MERGE_AUTOEDIT", "no");
|
|
9
|
-
git.env("LC_ALL", "C");
|
|
3
|
+
import { createGit, errorContainsAnyPattern, isGitExecutableUnavailable, NOT_GIT_REPOSITORY_PATTERNS, wrapGitError, } from "./core.js";
|
|
4
|
+
export async function observeGitRepository(cwd) {
|
|
10
5
|
try {
|
|
11
|
-
|
|
6
|
+
const git = simpleGit(cwd);
|
|
7
|
+
git.env("GIT_TERMINAL_PROMPT", "0");
|
|
8
|
+
git.env("GCM_INTERACTIVE", "Never");
|
|
9
|
+
git.env("GIT_MERGE_AUTOEDIT", "no");
|
|
10
|
+
git.env("LC_ALL", "C");
|
|
11
|
+
git.env("PATH", process.env.PATH ?? "");
|
|
12
|
+
const output = await git.raw(["rev-parse", "--is-inside-work-tree", "--is-bare-repository"]);
|
|
13
|
+
const [insideWorktree, bare] = output.trim().split(/\r?\n/);
|
|
14
|
+
return {
|
|
15
|
+
capability: "available",
|
|
16
|
+
coordinate: insideWorktree === "true" && bare !== "true" ? "repository" : "non-repository",
|
|
17
|
+
};
|
|
12
18
|
}
|
|
13
19
|
catch (err) {
|
|
14
|
-
|
|
20
|
+
if (isGitExecutableUnavailable(err))
|
|
21
|
+
return { capability: "unavailable" };
|
|
22
|
+
if (errorContainsAnyPattern(err, NOT_GIT_REPOSITORY_PATTERNS)) {
|
|
23
|
+
return { capability: "available", coordinate: "non-repository" };
|
|
24
|
+
}
|
|
25
|
+
return { capability: "unknown", error: wrapGitError("check-is-repo", err, cwd) };
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export function assertGitObservation(observation, operation) {
|
|
29
|
+
if (observation.capability === "unavailable") {
|
|
30
|
+
throw new FlowError("GIT_UNAVAILABLE", `Git executable is unavailable; ${operation} requires repository authority.`);
|
|
31
|
+
}
|
|
32
|
+
if (observation.capability === "unknown")
|
|
33
|
+
throw observation.error;
|
|
34
|
+
return observation.coordinate;
|
|
35
|
+
}
|
|
36
|
+
export async function requireGitRepository(cwd, operation) {
|
|
37
|
+
if (assertGitObservation(await observeGitRepository(cwd), operation) === "non-repository") {
|
|
38
|
+
throw new FlowError("NOT_GIT_REPO", `${cwd} is not a git repository`);
|
|
15
39
|
}
|
|
16
40
|
}
|
|
17
41
|
export async function getCurrentBranch(cwd) {
|
package/build/git/commits.js
CHANGED
package/build/git/core.js
CHANGED
|
@@ -10,6 +10,14 @@ export const MISSING_HEAD_PATTERNS = [
|
|
|
10
10
|
"unknown revision or path not in the working tree",
|
|
11
11
|
"bad revision 'HEAD'",
|
|
12
12
|
];
|
|
13
|
+
/** Git is an optional adapter for directory-local product surfaces. */
|
|
14
|
+
export function isGitExecutableUnavailable(error) {
|
|
15
|
+
const source = (error ?? {});
|
|
16
|
+
if (source.code === "ENOENT")
|
|
17
|
+
return true;
|
|
18
|
+
const message = typeof source.message === "string" ? source.message : String(error);
|
|
19
|
+
return /spawn\s+git\s+ENOENT|git(?:\.exe)?["']?\s*:\s*(?:not found|no such file)/i.test(message);
|
|
20
|
+
}
|
|
13
21
|
export function compactText(input, maxChars = GIT_ERROR_COMPACT_MAX_CHARS) {
|
|
14
22
|
const text = input.trim();
|
|
15
23
|
if (!text)
|
|
@@ -58,5 +66,6 @@ export function createGit(cwd) {
|
|
|
58
66
|
git.env("GCM_INTERACTIVE", "Never");
|
|
59
67
|
git.env("GIT_MERGE_AUTOEDIT", "no");
|
|
60
68
|
git.env("LC_ALL", "C");
|
|
69
|
+
git.env("PATH", process.env.PATH ?? "");
|
|
61
70
|
return git;
|
|
62
71
|
}
|
|
@@ -1,17 +1,4 @@
|
|
|
1
|
-
import { Buffer } from "node:buffer";
|
|
2
|
-
const DIFF_GIT_HEADER_PREFIX = "diff --git ";
|
|
3
1
|
const DIFF_TRUNCATED_MARKER = "...[truncated]";
|
|
4
|
-
const GIT_QUOTED_PATH_ESCAPES = {
|
|
5
|
-
'"': 34,
|
|
6
|
-
"\\": 92,
|
|
7
|
-
a: 7,
|
|
8
|
-
b: 8,
|
|
9
|
-
f: 12,
|
|
10
|
-
n: 10,
|
|
11
|
-
r: 13,
|
|
12
|
-
t: 9,
|
|
13
|
-
v: 11,
|
|
14
|
-
};
|
|
15
2
|
export function splitDiffByFile(content) {
|
|
16
3
|
const sections = [];
|
|
17
4
|
let current = [];
|
|
@@ -94,87 +81,6 @@ export function isMissingBaseRevisionError(err) {
|
|
|
94
81
|
text.includes("unknown revision or path not in the working tree") ||
|
|
95
82
|
text.includes("ambiguous argument"));
|
|
96
83
|
}
|
|
97
|
-
function unescapeQuotedDiffPath(value) {
|
|
98
|
-
const bytes = [];
|
|
99
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
100
|
-
const char = value[index];
|
|
101
|
-
if (char !== "\\") {
|
|
102
|
-
bytes.push(...Buffer.from(char ?? "", "utf8"));
|
|
103
|
-
continue;
|
|
104
|
-
}
|
|
105
|
-
const escaped = value[index + 1];
|
|
106
|
-
if (escaped === undefined) {
|
|
107
|
-
bytes.push(92);
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
110
|
-
if (escaped >= "0" && escaped <= "7") {
|
|
111
|
-
let octal = escaped;
|
|
112
|
-
let cursor = index + 2;
|
|
113
|
-
while (cursor < value.length && octal.length < 3) {
|
|
114
|
-
const digit = value[cursor];
|
|
115
|
-
if (digit === undefined || digit < "0" || digit > "7")
|
|
116
|
-
break;
|
|
117
|
-
octal += digit;
|
|
118
|
-
cursor += 1;
|
|
119
|
-
}
|
|
120
|
-
bytes.push(Number.parseInt(octal, 8));
|
|
121
|
-
index = cursor - 1;
|
|
122
|
-
continue;
|
|
123
|
-
}
|
|
124
|
-
const decoded = GIT_QUOTED_PATH_ESCAPES[escaped];
|
|
125
|
-
if (decoded !== undefined) {
|
|
126
|
-
bytes.push(decoded);
|
|
127
|
-
index += 1;
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
bytes.push(...Buffer.from(escaped, "utf8"));
|
|
131
|
-
index += 1;
|
|
132
|
-
}
|
|
133
|
-
return Buffer.from(bytes).toString("utf8");
|
|
134
|
-
}
|
|
135
|
-
function readDiffHeaderToken(line, startIndex) {
|
|
136
|
-
let index = startIndex;
|
|
137
|
-
while (index < line.length && line[index] === " ") {
|
|
138
|
-
index += 1;
|
|
139
|
-
}
|
|
140
|
-
if (index >= line.length)
|
|
141
|
-
return null;
|
|
142
|
-
if (line[index] !== '"') {
|
|
143
|
-
let endIndex = index;
|
|
144
|
-
while (endIndex < line.length && line[endIndex] !== " ") {
|
|
145
|
-
endIndex += 1;
|
|
146
|
-
}
|
|
147
|
-
return {
|
|
148
|
-
value: line.slice(index, endIndex),
|
|
149
|
-
nextIndex: endIndex,
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
let endIndex = index + 1;
|
|
153
|
-
let escaped = false;
|
|
154
|
-
while (endIndex < line.length) {
|
|
155
|
-
const char = line[endIndex];
|
|
156
|
-
if (!escaped && char === '"') {
|
|
157
|
-
return {
|
|
158
|
-
value: unescapeQuotedDiffPath(line.slice(index + 1, endIndex)),
|
|
159
|
-
nextIndex: endIndex + 1,
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
escaped = !escaped && char === "\\";
|
|
163
|
-
endIndex += 1;
|
|
164
|
-
}
|
|
165
|
-
return null;
|
|
166
|
-
}
|
|
167
|
-
export function parseDiffPathFromHeader(diffGitLine) {
|
|
168
|
-
if (!diffGitLine.startsWith(DIFF_GIT_HEADER_PREFIX))
|
|
169
|
-
return null;
|
|
170
|
-
const aPart = readDiffHeaderToken(diffGitLine, DIFF_GIT_HEADER_PREFIX.length);
|
|
171
|
-
if (!aPart)
|
|
172
|
-
return null;
|
|
173
|
-
const bPart = readDiffHeaderToken(diffGitLine, aPart.nextIndex)?.value ?? "";
|
|
174
|
-
if (!bPart.startsWith("b/"))
|
|
175
|
-
return null;
|
|
176
|
-
return bPart.slice(2);
|
|
177
|
-
}
|
|
178
84
|
export function totalJoinedLength(blocks) {
|
|
179
85
|
if (blocks.length === 0)
|
|
180
86
|
return 0;
|
package/build/index.js
CHANGED
|
@@ -6,7 +6,9 @@ import { ENV_KEYS } from "./config/env-keys.js";
|
|
|
6
6
|
import { logErrorWithCause } from "./telemetry/logger.js";
|
|
7
7
|
import { runProjectionGenerationRuntime } from "./core/projection-generation-runtime.js";
|
|
8
8
|
import { renderCliHelp, runCliCommand } from "./cli/index.js";
|
|
9
|
+
import { installCliOutputStreamErrorPolicy } from "./cli/output-stream-error-policy.js";
|
|
9
10
|
import { assertSubagentCliCommandAllowed } from "./cli/subagent-guard.js";
|
|
11
|
+
installCliOutputStreamErrorPolicy(process.stdout, process.stderr);
|
|
10
12
|
const packageVersion = VERSION;
|
|
11
13
|
function findCliCwd(args) {
|
|
12
14
|
for (let index = 0; index < args.length; index += 1) {
|
package/build/keiyaku.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import * as path from "path";
|
|
2
|
+
import { ACTOR_IDENTITY, SETTINGS_PATH_SEGMENTS } from "./keiyaku-constants.js";
|
|
3
|
+
export { ACTOR_IDENTITY } from "./keiyaku-constants.js";
|
|
2
4
|
export const KEIYAKU_FILE = path.join(".keiyaku", "KEIYAKU.md");
|
|
3
5
|
export const KEIYAKU_DRAFT_DIR = path.join(".keiyaku", "draft");
|
|
4
6
|
export const RESPONSE_HISTORY_DIR = path.join(".keiyaku", "response");
|
|
@@ -13,7 +15,6 @@ export const TOOL_NAMES = {
|
|
|
13
15
|
status: "status",
|
|
14
16
|
help: "help",
|
|
15
17
|
};
|
|
16
|
-
export const ACTOR_IDENTITY = "Akuma";
|
|
17
18
|
export const ACTOR_IDENTITY_PLURAL = `${ACTOR_IDENTITY}s`;
|
|
18
19
|
function formatArtifactDirectory(directory) {
|
|
19
20
|
return `\`${directory}/\``;
|
|
@@ -35,7 +36,7 @@ export const DRAFT_ARTIFACT_NOTICE = buildArtifactNotice(KEIYAKU_ARTIFACT_DIRS[0
|
|
|
35
36
|
export const RESPONSE_ARTIFACT_NOTICE = buildArtifactNotice(KEIYAKU_ARTIFACT_DIRS[1]);
|
|
36
37
|
export const KEIYAKU_BRANCH_PREFIX = "keiyaku/";
|
|
37
38
|
export const BASE_RULES_FILE = path.join(".keiyaku", "base-rules.md");
|
|
38
|
-
export const SETTINGS_FILE = path.join(
|
|
39
|
+
export const SETTINGS_FILE = path.join(...SETTINGS_PATH_SEGMENTS);
|
|
39
40
|
export const SUBAGENT_PROVIDERS = [
|
|
40
41
|
"codex-sdk",
|
|
41
42
|
"codex-app-server",
|
|
@@ -50,7 +51,7 @@ export const CODEX_MODEL_REASONING_EFFORT_CONFIG_KEY = "model_reasoning_effort";
|
|
|
50
51
|
export const BUILTIN_AGENT_NAMES = ["akuma-codex", "akuma-claude"];
|
|
51
52
|
export const DEFAULT_AGENT_NAME = "akuma-codex";
|
|
52
53
|
export const BUILTIN_AGENT_PROFILES = {
|
|
53
|
-
"akuma-codex": { provider: "codex-sdk", description: "
|
|
54
|
+
"akuma-codex": { provider: "codex-sdk", description: "Deprecated Codex SDK Akuma; use codex-app-server." },
|
|
54
55
|
"akuma-claude": { provider: "claude-agent-sdk", description: "Default Claude Agent SDK Akuma." },
|
|
55
56
|
};
|
|
56
57
|
export const CLAUDE_PERMISSION_MODES = ["default", "acceptEdits", "bypassPermissions", "plan", "dontAsk", "auto"];
|