@astrosheep/keiyaku 2.9.2 → 2.9.4
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 +13 -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 +25 -222
- package/build/agents/harness/index.js +3 -1
- package/build/agents/harness/outcome.js +47 -4
- package/build/agents/harness/projection.js +42 -59
- 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 +50 -53
- package/build/agents/providers/codex-app-server/events.js +67 -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/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 +8 -0
- package/build/artifact-directories.js +22 -0
- package/build/cli/commands/akuma/akuma/handler.js +1 -1
- package/build/cli/commands/akuma/view/handler.js +5 -4
- package/build/cli/commands/akuma.js +6 -0
- package/build/cli/commands/contract/amend/handler.js +8 -2
- package/build/cli/commands/contract/arc/handler.js +7 -1
- package/build/cli/commands/contract/bind/handler.js +4 -3
- package/build/cli/commands/contract/bind/meta.js +34 -7
- package/build/cli/commands/contract/forfeit/handler.js +4 -4
- package/build/cli/commands/contract/log/handler.js +3 -3
- package/build/cli/commands/contract/petition/handler.js +4 -6
- package/build/cli/commands/contract/renew/handler.js +20 -6
- package/build/cli/commands/contract/renew/meta.js +5 -4
- package/build/cli/commands/metadata.js +58 -0
- package/build/cli/commands/projection/call/handler.js +6 -5
- package/build/cli/commands/projection/kill/handler.js +16 -32
- package/build/cli/commands/projection/shared.js +28 -0
- package/build/cli/commands/projection/status/handler.js +1 -1
- package/build/cli/commands/projection/tell/handler.js +14 -30
- package/build/cli/commands/projection/wait/handler.js +45 -22
- package/build/cli/commands/projection/wait/meta.js +7 -2
- 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/skills/handler.js +1 -1
- package/build/cli/commands/task/add/handler.js +5 -13
- package/build/cli/commands/task/catalog.js +2 -2
- package/build/cli/commands/task/done/handler.js +4 -8
- package/build/cli/commands/task/drop/handler.js +3 -6
- package/build/cli/commands/task/ls/handler.js +3 -5
- 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/stop/handler.js +4 -8
- package/build/cli/commands/task/task/handler.js +1 -1
- package/build/cli/commands/task/update/handler.js +4 -8
- package/build/cli/completion.js +1 -1
- package/build/cli/flags.js +19 -3
- package/build/cli/help.js +4 -11
- package/build/cli/index.js +57 -83
- package/build/cli/missing-subcommand.js +7 -0
- package/build/cli/parse-flags.js +14 -5
- package/build/cli/parse-metadata.js +3 -3
- package/build/cli/parse-selectors.js +1 -1
- package/build/cli/parse.js +21 -0
- package/build/cli/projection-address.js +7 -12
- package/build/cli/render/address.js +41 -37
- package/build/cli/render/arc.js +24 -12
- 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 +55 -12
- package/build/cli/render/petition.js +20 -15
- package/build/cli/render/projection-activity.js +3 -0
- package/build/cli/render/shared.js +60 -21
- package/build/cli/render/skills.js +10 -0
- package/build/cli/render/status.js +37 -14
- package/build/cli/render/success-response.js +77 -0
- package/build/cli/render/task.js +54 -14
- package/build/cli/render/tell.js +5 -0
- package/build/cli/render/terminal-failure.js +58 -0
- package/build/cli/render/types.js +1 -0
- package/build/cli/render/wait.js +38 -36
- package/build/cli/types.js +1 -1
- package/build/config/akuma-loader.js +0 -5
- package/build/config/env-keys.js +1 -1
- 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 +135 -18
- package/build/core/arc.js +19 -67
- 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 +21 -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 +20 -3
- package/build/core/draft.js +123 -16
- 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/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 +2 -38
- package/build/core/projection/generation/model.js +42 -1
- 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} +19 -49
- 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} +5 -3
- 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} +18 -3
- package/build/core/projection/generation/store.js +2 -2
- package/build/core/projection/generation/transitions.js +1 -1
- 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} +14 -19
- 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} +2 -57
- 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} +1 -1
- package/build/core/{projection-mint.js → projection/projection-mint.js} +10 -10
- package/build/core/{projection-status.js → projection/projection-status.js} +98 -25
- package/build/core/projection/projection-terminal-failure.js +104 -0
- package/build/core/projection/projection-wait.js +278 -0
- package/build/core/projection/projection-wake.js +203 -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 +426 -99
- package/build/core/scope.js +143 -66
- package/build/core/seal.js +139 -35
- package/build/core/{claim-delivery.js → settlement/claim-delivery.js} +9 -14
- 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} +22 -18
- 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} +1 -1
- package/build/core/{petition.js → settlement/petition.js} +12 -10
- 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 +295 -0
- package/build/core/{verdict.js → settlement/verdict.js} +9 -37
- package/build/core/status/board.js +24 -23
- package/build/core/status/ledger-batch.js +158 -0
- package/build/core/status/reconciliation.js +10 -4
- package/build/core/stored-agent-event.js +3 -0
- package/build/core/task/board.js +40 -4
- package/build/core/task/commands.js +30 -21
- package/build/core/task/index.js +12 -0
- package/build/core/task/settlement-git.js +157 -65
- package/build/core/task/settlement-policy.js +54 -24
- package/build/core/task/task-contract.js +370 -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} +92 -29
- package/build/core/task/task-repository.js +1 -0
- package/build/core/{task-store-repository.js → task/task-store-repository.js} +5 -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 +5 -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 +85 -39
- package/build/fs/durability.js +27 -0
- 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/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 +3 -3
- package/build/keiyaku.js +2 -36
- package/package.json +4 -10
- package/skills/keiyaku/SKILL.md +3 -2
- package/skills/keiyaku-akuma/SKILL.md +10 -6
- package/skills/keiyaku-task/SKILL.md +1 -1
- package/skills/keiyaku-workflow/SKILL.md +25 -4
- 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
|
@@ -10,7 +10,7 @@ How a contract lives. Running akuma is the `keiyaku-akuma` skill; task planning
|
|
|
10
10
|
|
|
11
11
|
## Mind model
|
|
12
12
|
|
|
13
|
-
A contract = one branch + one worktree + a ledger (its record file in the repo).
|
|
13
|
+
A contract = one branch + one linked worktree + a ledger (its record file in the repo). A sandbox worker edits and tests inside that worktree, then hands the host coordinator an uncommitted dirty tree plus its changed-file and check report. The host reviews and commits accepted bytes before running workflow verbs that seal or rewrite delivery. States:
|
|
14
14
|
|
|
15
15
|
```
|
|
16
16
|
bound → active → petitioned → claimed | forfeited
|
|
@@ -25,18 +25,25 @@ keiyaku bind --place fix-pump --objective "make the pump test pass" \
|
|
|
25
25
|
# (# <name> / ## Objective / ## Scope / ## Checks)
|
|
26
26
|
# or promote a ready task: keiyaku bind --task k-xxxx
|
|
27
27
|
|
|
28
|
-
cd .keiyaku/wt/fix-pump #
|
|
28
|
+
cd .keiyaku/wt/fix-pump # worker edits/tests here and leaves a dirty tree
|
|
29
|
+
|
|
30
|
+
# Back on the host after reviewing the worker's diff and test report:
|
|
31
|
+
git -C .keiyaku/wt/fix-pump add -- <accepted-paths>
|
|
32
|
+
git -C .keiyaku/wt/fix-pump commit -m "fix pump"
|
|
29
33
|
|
|
30
34
|
keiyaku petition <<'EOF'
|
|
31
35
|
## Oath
|
|
32
36
|
I made the pump test pass; ran the suite, all green.
|
|
33
37
|
EOF
|
|
34
|
-
# petition seals your work
|
|
38
|
+
# petition seals your work (a seal = your commits + intent frozen into one
|
|
39
|
+
# reviewable unit; arc and renew also seal) and runs the settlement pipeline —
|
|
35
40
|
# passes → claimed (merged to main); a gate fails → fix, petition again.
|
|
36
41
|
# The oath is required (OATH_MISSING otherwise) and checked for presence, not content.
|
|
37
42
|
```
|
|
38
43
|
|
|
39
|
-
That's the whole small case: bind → commit → petition.
|
|
44
|
+
That's the whole small case: bind → worker dirty-tree handoff → host review/commit → petition.
|
|
45
|
+
|
|
46
|
+
Commissioned workers never run `git add`, `git commit`, or another command that writes Git metadata. Codex workspace-write deliberately keeps `.git` and a linked worktree's resolved gitdir read-only; adding either location to writable roots is not an authorization mechanism. A worker-side Git metadata refusal is therefore not failed delivery. The host coordinator alone commits accepted bytes with native Git, then continues `arc`, `renew`, or `petition`.
|
|
40
47
|
|
|
41
48
|
## Mid-flight commands (use when needed, skip otherwise)
|
|
42
49
|
|
|
@@ -50,6 +57,20 @@ keiyaku amend < amendment.md # scope/checks changed → update the paper before
|
|
|
50
57
|
keiyaku log # this contract's history
|
|
51
58
|
```
|
|
52
59
|
|
|
60
|
+
`amend` accepts prose plus an optional ordered scope-pattern delta:
|
|
61
|
+
|
|
62
|
+
```markdown
|
|
63
|
+
Clarify the owned documentation surface.
|
|
64
|
+
|
|
65
|
+
## Scope Add
|
|
66
|
+
docs/**
|
|
67
|
+
!docs/generated/**
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`Scope Add` appends patterns to the contract; it is not set-union semantics.
|
|
71
|
+
Patterns retain ordered Git-ignore behavior, so a later `!pattern` excludes a
|
|
72
|
+
previous match and can narrow the effective scope.
|
|
73
|
+
|
|
53
74
|
Gotchas:
|
|
54
75
|
- Base drift blocks petition — if main moved, `renew` first; petition tells you.
|
|
55
76
|
- After an explicit `arc` seals, new loose commits need another `arc` before `renew`/`petition` accept them.
|
|
@@ -1,329 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { Codex, } from "@openai/codex-sdk";
|
|
3
|
-
import { CODEX_MODEL_REASONING_EFFORT_CONFIG_KEY } from "../../keiyaku.js";
|
|
4
|
-
import { appendDebugBlock, appendDebugLog } from "../../telemetry/debug-log.js";
|
|
5
|
-
import { SUBAGENT_SESSION_VERSION } from "../session.js";
|
|
6
|
-
import { createProjectionDriver } from "../harness/execution-handle.js";
|
|
7
|
-
import { boundActivityExcerpt } from "../harness/activity-values.js";
|
|
8
|
-
import { buildSubagentEnv, emitProviderEvidence, sha256Utf8 } from "../harness/runtime.js";
|
|
9
|
-
import { coerceString } from "../harness/runtime.js";
|
|
10
|
-
import { AGENT_PLAN_ITEM_TEXT_MAX_CHARS, AGENT_PLAN_MAX_ITEMS, AGENT_THOUGHT_TEXT_MAX_CHARS, } from "../harness/events.js";
|
|
11
|
-
import { appendEventType, renderEventTypeSummary } from "./event-type-tail.js";
|
|
12
|
-
/** Identity-only opacity boundary for Codex SDK ThreadOptions modelReasoningEffort. */
|
|
13
|
-
function toCodexSdkModelReasoningEffort(effort) {
|
|
14
|
-
return effort;
|
|
15
|
-
}
|
|
16
|
-
function withCodexSdkModelReasoningEffort(threadOptions) {
|
|
17
|
-
const raw = threadOptions.modelReasoningEffort;
|
|
18
|
-
if (typeof raw !== "string")
|
|
19
|
-
return threadOptions;
|
|
20
|
-
return {
|
|
21
|
-
...threadOptions,
|
|
22
|
-
modelReasoningEffort: toCodexSdkModelReasoningEffort(raw),
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
let codexConstructor = Codex;
|
|
26
|
-
function getCodexConstructor(override) {
|
|
27
|
-
if (override)
|
|
28
|
-
return override;
|
|
29
|
-
return codexConstructor;
|
|
30
|
-
}
|
|
31
|
-
/** @deprecated Use CodexSdkOptions.codexConstructor instead. */
|
|
32
|
-
export function setCodexSdkConstructorForTests(constructor) {
|
|
33
|
-
codexConstructor = constructor;
|
|
34
|
-
}
|
|
35
|
-
/** @deprecated Use CodexSdkOptions.codexConstructor instead. */
|
|
36
|
-
export function resetCodexSdkConstructorForTests() {
|
|
37
|
-
codexConstructor = Codex;
|
|
38
|
-
}
|
|
39
|
-
export const codexThreadSchema = z.object({ threadId: z.string().trim().min(1) });
|
|
40
|
-
const CODEX_EVENT_THREAD_STARTED = "thread.started";
|
|
41
|
-
const CODEX_EVENT_TURN_STARTED = "turn.started";
|
|
42
|
-
const CODEX_EVENT_TURN_FAILED = "turn.failed";
|
|
43
|
-
const CODEX_EVENT_ERROR = "error";
|
|
44
|
-
const CODEX_EVENT_ITEM_STARTED = "item.started";
|
|
45
|
-
const CODEX_EVENT_ITEM_COMPLETED = "item.completed";
|
|
46
|
-
const CODEX_EVENT_ITEM_UPDATED = "item.updated";
|
|
47
|
-
const CODEX_EVENT_TURN_COMPLETED = "turn.completed";
|
|
48
|
-
const CODEX_SDK_PROVIDER = "codex-sdk";
|
|
49
|
-
const CODEX_SDK_ACKNOWLEDGED_UNPERSISTED = new Set([CODEX_EVENT_THREAD_STARTED]);
|
|
50
|
-
const CODEX_SDK_MAPPED = new Set([
|
|
51
|
-
CODEX_EVENT_TURN_STARTED,
|
|
52
|
-
CODEX_EVENT_TURN_COMPLETED,
|
|
53
|
-
CODEX_EVENT_TURN_FAILED,
|
|
54
|
-
CODEX_EVENT_ERROR,
|
|
55
|
-
CODEX_EVENT_ITEM_STARTED,
|
|
56
|
-
CODEX_EVENT_ITEM_UPDATED,
|
|
57
|
-
CODEX_EVENT_ITEM_COMPLETED,
|
|
58
|
-
]);
|
|
59
|
-
function codexSdkIngressDisposition(type) {
|
|
60
|
-
if (CODEX_SDK_ACKNOWLEDGED_UNPERSISTED.has(type))
|
|
61
|
-
return "acknowledged-unpersisted";
|
|
62
|
-
if (CODEX_SDK_MAPPED.has(type))
|
|
63
|
-
return "mapped";
|
|
64
|
-
return "unknown";
|
|
65
|
-
}
|
|
66
|
-
function extractAgentMessage(event) {
|
|
67
|
-
if (event.type !== CODEX_EVENT_ITEM_COMPLETED && event.type !== CODEX_EVENT_ITEM_UPDATED) {
|
|
68
|
-
return undefined;
|
|
69
|
-
}
|
|
70
|
-
if (event.item.type !== "agent_message")
|
|
71
|
-
return undefined;
|
|
72
|
-
const text = coerceString(event.item.text);
|
|
73
|
-
if (!text)
|
|
74
|
-
return undefined;
|
|
75
|
-
return { id: event.item.id, text };
|
|
76
|
-
}
|
|
77
|
-
function codexActivityCall(item) {
|
|
78
|
-
switch (item.type) {
|
|
79
|
-
case "command_execution": return { kind: "run", command: item.command };
|
|
80
|
-
case "file_change": return {
|
|
81
|
-
kind: "fileChange",
|
|
82
|
-
changes: item.changes.map((change) => ({ op: change.kind, path: change.path })),
|
|
83
|
-
};
|
|
84
|
-
case "mcp_tool_call": return { kind: "other", display: `${item.server}.${item.tool}` };
|
|
85
|
-
case "web_search": return { kind: "search", query: item.query };
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
function codexMcpResultMessage(item) {
|
|
89
|
-
if (item.error?.message)
|
|
90
|
-
return boundActivityExcerpt(item.error.message);
|
|
91
|
-
const text = item.result?.content.flatMap((block) => (block.type === "text" && typeof block.text === "string" ? [block.text] : [])).join("\n");
|
|
92
|
-
return text ? boundActivityExcerpt(text) : undefined;
|
|
93
|
-
}
|
|
94
|
-
function codexActivityResult(item) {
|
|
95
|
-
switch (item.type) {
|
|
96
|
-
case "command_execution": return {
|
|
97
|
-
status: item.status === "failed" || (item.exit_code !== undefined && item.exit_code !== 0) ? "error" : "ok",
|
|
98
|
-
...(item.aggregated_output ? { message: boundActivityExcerpt(item.aggregated_output) } : {}),
|
|
99
|
-
...(item.exit_code === undefined ? {} : { exitCode: item.exit_code }),
|
|
100
|
-
};
|
|
101
|
-
case "file_change": return { status: item.status === "failed" ? "error" : "ok" };
|
|
102
|
-
case "mcp_tool_call": {
|
|
103
|
-
const message = codexMcpResultMessage(item);
|
|
104
|
-
return { status: item.status === "failed" ? "error" : "ok", ...(message ? { message } : {}) };
|
|
105
|
-
}
|
|
106
|
-
case "web_search": return { status: "ok" };
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
function emitCodexSemanticEvent(builder, event) {
|
|
110
|
-
if (event.type === CODEX_EVENT_TURN_STARTED) {
|
|
111
|
-
builder.emit({ type: "turn", phase: "started" });
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
if (event.type === CODEX_EVENT_TURN_COMPLETED) {
|
|
115
|
-
builder.emit({
|
|
116
|
-
type: "usage",
|
|
117
|
-
inputTokens: event.usage.input_tokens,
|
|
118
|
-
outputTokens: event.usage.output_tokens,
|
|
119
|
-
cachedInputTokens: event.usage.cached_input_tokens,
|
|
120
|
-
});
|
|
121
|
-
builder.emit({ type: "turn", phase: "completed" });
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
if (event.type !== CODEX_EVENT_ITEM_STARTED &&
|
|
125
|
-
event.type !== CODEX_EVENT_ITEM_UPDATED &&
|
|
126
|
-
event.type !== CODEX_EVENT_ITEM_COMPLETED) {
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
if (event.item.type === "reasoning" &&
|
|
130
|
-
(event.type === CODEX_EVENT_ITEM_UPDATED || event.type === CODEX_EVENT_ITEM_COMPLETED)) {
|
|
131
|
-
const truncated = event.item.text.length > AGENT_THOUGHT_TEXT_MAX_CHARS;
|
|
132
|
-
builder.emit({
|
|
133
|
-
type: "thought",
|
|
134
|
-
id: event.item.id,
|
|
135
|
-
text: event.item.text.slice(0, AGENT_THOUGHT_TEXT_MAX_CHARS),
|
|
136
|
-
final: event.type === CODEX_EVENT_ITEM_COMPLETED,
|
|
137
|
-
...(truncated ? { truncated: true } : {}),
|
|
138
|
-
});
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
if (event.item.type === "todo_list") {
|
|
142
|
-
builder.emit({
|
|
143
|
-
type: "plan",
|
|
144
|
-
id: event.item.id,
|
|
145
|
-
items: event.item.items.slice(0, AGENT_PLAN_MAX_ITEMS).map((item) => ({
|
|
146
|
-
text: item.text.slice(0, AGENT_PLAN_ITEM_TEXT_MAX_CHARS),
|
|
147
|
-
done: item.completed,
|
|
148
|
-
})),
|
|
149
|
-
});
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
if (event.item.type !== "command_execution" &&
|
|
153
|
-
event.item.type !== "file_change" &&
|
|
154
|
-
event.item.type !== "mcp_tool_call" &&
|
|
155
|
-
event.item.type !== "web_search") {
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
const phase = event.type === CODEX_EVENT_ITEM_STARTED
|
|
159
|
-
? "started"
|
|
160
|
-
: event.type === CODEX_EVENT_ITEM_UPDATED
|
|
161
|
-
? "updated"
|
|
162
|
-
: "completed";
|
|
163
|
-
builder.emit({
|
|
164
|
-
type: "activity",
|
|
165
|
-
phase,
|
|
166
|
-
id: event.item.id,
|
|
167
|
-
tool: event.item.type,
|
|
168
|
-
call: codexActivityCall(event.item),
|
|
169
|
-
...(phase === "started" ? {} : { result: codexActivityResult(event.item) }),
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
/** @deprecated Use the codex-app-server adapter. */
|
|
173
|
-
export async function startCodexSdk(prompt, cwd, options) {
|
|
174
|
-
const threadId = options.threadId?.trim();
|
|
175
|
-
const recordedEventTypes = [];
|
|
176
|
-
let totalEventCount = 0;
|
|
177
|
-
let activeAbort;
|
|
178
|
-
let runReturned = false;
|
|
179
|
-
appendDebugLog(`startCodexSdk: executable=${options.executable ?? "codex"} model=${options.model ?? "default"} ${CODEX_MODEL_REASONING_EFFORT_CONFIG_KEY}=${String(options.config?.[CODEX_MODEL_REASONING_EFFORT_CONFIG_KEY] ?? "default")} mode=${threadId ? "resume" : "fresh"}`, { cwd, section: CODEX_SDK_PROVIDER });
|
|
180
|
-
return createProjectionDriver({
|
|
181
|
-
steerMode: "replay",
|
|
182
|
-
initialTurn: options.initialTurn,
|
|
183
|
-
onIngress: options.onIngress,
|
|
184
|
-
async abort(mode) {
|
|
185
|
-
activeAbort?.abort();
|
|
186
|
-
if (mode === "force" && !runReturned) {
|
|
187
|
-
throw new Error("codex-sdk cannot guarantee forced termination");
|
|
188
|
-
}
|
|
189
|
-
},
|
|
190
|
-
async run(builder) {
|
|
191
|
-
activeAbort = new AbortController();
|
|
192
|
-
const linked = options.signal ?? builder.signal;
|
|
193
|
-
const onOuterAbort = () => activeAbort?.abort();
|
|
194
|
-
linked.addEventListener("abort", onOuterAbort, { once: true });
|
|
195
|
-
if (linked.aborted)
|
|
196
|
-
onOuterAbort();
|
|
197
|
-
builder.signal.addEventListener("abort", onOuterAbort, { once: true });
|
|
198
|
-
try {
|
|
199
|
-
const env = buildSubagentEnv();
|
|
200
|
-
const codexOptions = {
|
|
201
|
-
codexPathOverride: options.executable,
|
|
202
|
-
profile: options.profile,
|
|
203
|
-
config: options.config,
|
|
204
|
-
env,
|
|
205
|
-
};
|
|
206
|
-
const sdk = new (getCodexConstructor(options.codexConstructor))(codexOptions);
|
|
207
|
-
const threadOptions = withCodexSdkModelReasoningEffort(options.threadOptions);
|
|
208
|
-
const thread = threadId ? sdk.resumeThread(threadId, threadOptions) : sdk.startThread(threadOptions);
|
|
209
|
-
const streamed = await thread.runStreamed(prompt, { signal: activeAbort.signal });
|
|
210
|
-
const eventIterator = streamed.events[Symbol.asyncIterator]();
|
|
211
|
-
// The SDK iterable is lazy: its first next() starts the native run.
|
|
212
|
-
// Record outbound bytes immediately before that crossing, then ack only
|
|
213
|
-
// after it settles (including a legitimate no-event completion).
|
|
214
|
-
if (options.onEvidence) {
|
|
215
|
-
emitProviderEvidence(options.onEvidence, {
|
|
216
|
-
type: "outbound",
|
|
217
|
-
provider: CODEX_SDK_PROVIDER,
|
|
218
|
-
direction: "input",
|
|
219
|
-
kind: "replay-prompt",
|
|
220
|
-
...sha256Utf8(prompt),
|
|
221
|
-
}, (text) => builder.emit({ type: "diagnostic", text }));
|
|
222
|
-
}
|
|
223
|
-
const firstEvent = await eventIterator.next();
|
|
224
|
-
if (options.onEvidence) {
|
|
225
|
-
emitProviderEvidence(options.onEvidence, {
|
|
226
|
-
type: "ack",
|
|
227
|
-
provider: CODEX_SDK_PROVIDER,
|
|
228
|
-
fence: { kind: "ordinal", ordinal: 0 },
|
|
229
|
-
outbound: "run",
|
|
230
|
-
}, (text) => builder.emit({ type: "diagnostic", text }));
|
|
231
|
-
}
|
|
232
|
-
const events = async function* () {
|
|
233
|
-
if (!firstEvent.done)
|
|
234
|
-
yield firstEvent.value;
|
|
235
|
-
while (true) {
|
|
236
|
-
const next = await eventIterator.next();
|
|
237
|
-
if (next.done)
|
|
238
|
-
return;
|
|
239
|
-
yield next.value;
|
|
240
|
-
}
|
|
241
|
-
};
|
|
242
|
-
let resumeToken;
|
|
243
|
-
let lastAgentMessage;
|
|
244
|
-
let turnFailedMessage;
|
|
245
|
-
let streamErrorMessage;
|
|
246
|
-
for await (const event of events()) {
|
|
247
|
-
if (activeAbort.signal.aborted) {
|
|
248
|
-
throw Object.assign(new Error(`${CODEX_SDK_PROVIDER} exec cancelled by client`), { name: "AbortError" });
|
|
249
|
-
}
|
|
250
|
-
totalEventCount += 1;
|
|
251
|
-
appendEventType(recordedEventTypes, event.type);
|
|
252
|
-
builder.ingress(CODEX_SDK_PROVIDER, event.type, event, codexSdkIngressDisposition(event.type), () => {
|
|
253
|
-
if (event.type === CODEX_EVENT_THREAD_STARTED) {
|
|
254
|
-
resumeToken = event.thread_id;
|
|
255
|
-
if (options.onEvidence)
|
|
256
|
-
emitProviderEvidence(options.onEvidence, { type: "session", provider: CODEX_SDK_PROVIDER, threadId: resumeToken }, (text) => builder.emit({ type: "diagnostic", text }));
|
|
257
|
-
}
|
|
258
|
-
else if (event.type === CODEX_EVENT_TURN_STARTED && !resumeToken) {
|
|
259
|
-
builder.emit({
|
|
260
|
-
type: "fail",
|
|
261
|
-
message: `${CODEX_SDK_PROVIDER} exec emitted turn.started before thread.started with thread_id`,
|
|
262
|
-
});
|
|
263
|
-
throw new Error(`${CODEX_SDK_PROVIDER} exec emitted turn.started before thread.started with thread_id`);
|
|
264
|
-
}
|
|
265
|
-
else if (event.type === CODEX_EVENT_TURN_FAILED) {
|
|
266
|
-
turnFailedMessage = coerceString(event.error.message) ?? `${CODEX_SDK_PROVIDER} turn failed`;
|
|
267
|
-
}
|
|
268
|
-
else if (event.type === CODEX_EVENT_ERROR) {
|
|
269
|
-
streamErrorMessage = coerceString(event.message) ?? `${CODEX_SDK_PROVIDER} stream error`;
|
|
270
|
-
builder.emit({ type: "diagnostic", text: `${streamErrorMessage}\n` });
|
|
271
|
-
}
|
|
272
|
-
emitCodexSemanticEvent(builder, event);
|
|
273
|
-
const message = extractAgentMessage(event);
|
|
274
|
-
if (message) {
|
|
275
|
-
lastAgentMessage = message.text;
|
|
276
|
-
builder.emit({ type: "message", id: message.id, text: message.text });
|
|
277
|
-
}
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
if (turnFailedMessage) {
|
|
281
|
-
builder.emit({ type: "diagnostic", text: turnFailedMessage });
|
|
282
|
-
builder.emit({ type: "fail", message: turnFailedMessage });
|
|
283
|
-
throw new Error(turnFailedMessage);
|
|
284
|
-
}
|
|
285
|
-
if (streamErrorMessage && !lastAgentMessage) {
|
|
286
|
-
builder.emit({ type: "fail", message: streamErrorMessage });
|
|
287
|
-
throw new Error(streamErrorMessage);
|
|
288
|
-
}
|
|
289
|
-
if (!resumeToken) {
|
|
290
|
-
appendDebugLog(`Missing required codex event: ${CODEX_EVENT_THREAD_STARTED} with thread_id.`, {
|
|
291
|
-
cwd,
|
|
292
|
-
section: CODEX_SDK_PROVIDER,
|
|
293
|
-
});
|
|
294
|
-
appendDebugBlock("codex-sdk stdout event types", renderEventTypeSummary(recordedEventTypes, totalEventCount), {
|
|
295
|
-
cwd,
|
|
296
|
-
section: CODEX_SDK_PROVIDER,
|
|
297
|
-
});
|
|
298
|
-
builder.emit({
|
|
299
|
-
type: "fail",
|
|
300
|
-
message: `${CODEX_SDK_PROVIDER} exec succeeded but did not emit a ${CODEX_EVENT_THREAD_STARTED} event with thread_id`,
|
|
301
|
-
});
|
|
302
|
-
throw new Error(`${CODEX_SDK_PROVIDER} exec succeeded but did not emit a ${CODEX_EVENT_THREAD_STARTED} event with thread_id`);
|
|
303
|
-
}
|
|
304
|
-
const finalMessage = lastAgentMessage ?? "";
|
|
305
|
-
const session = {
|
|
306
|
-
provider: "codex-sdk",
|
|
307
|
-
version: SUBAGENT_SESSION_VERSION,
|
|
308
|
-
handle: { threadId: resumeToken },
|
|
309
|
-
};
|
|
310
|
-
if (options.onEvidence)
|
|
311
|
-
emitProviderEvidence(options.onEvidence, { type: "checkpoint", provider: CODEX_SDK_PROVIDER, fence: { kind: "ordinal", ordinal: 1 }, source: "response" }, (text) => builder.emit({ type: "diagnostic", text }));
|
|
312
|
-
builder.emit({
|
|
313
|
-
type: "done",
|
|
314
|
-
finalMessage,
|
|
315
|
-
session,
|
|
316
|
-
});
|
|
317
|
-
return { finalMessage, session };
|
|
318
|
-
}
|
|
319
|
-
catch (error) {
|
|
320
|
-
appendDebugLog(`startCodexSdk error: ${error instanceof Error ? `${error.name}: ${error.message}` : String(error)}`, { cwd, section: CODEX_SDK_PROVIDER });
|
|
321
|
-
throw error;
|
|
322
|
-
}
|
|
323
|
-
finally {
|
|
324
|
-
runReturned = true;
|
|
325
|
-
linked.removeEventListener("abort", onOuterAbort);
|
|
326
|
-
}
|
|
327
|
-
},
|
|
328
|
-
});
|
|
329
|
-
}
|
package/build/core/command-io.js
DELETED
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
import { ACTOR_IDENTITY } from "../keiyaku.js";
|
|
2
|
-
import { FlowError } from "../flow-error.js";
|
|
3
|
-
import { parseMarkdownListSection, parseMarkdownStructure } from "./markdown/sections.js";
|
|
4
|
-
import { KeiyakuParseError } from "./markdown/types.js";
|
|
5
|
-
import { normalizeSectionTitle } from "./markdown/titles.js";
|
|
6
|
-
import { isBlankScopePatternLine, normalizeScopePattern, ScopePatternError } from "./scope.js";
|
|
7
|
-
function amendScopeHeading(name) {
|
|
8
|
-
return `## Scope ${name[0].toUpperCase()}${name.slice(1)}`;
|
|
9
|
-
}
|
|
10
|
-
function sourceLines(markdown) {
|
|
11
|
-
const lines = [];
|
|
12
|
-
let start = 0;
|
|
13
|
-
while (start < markdown.length) {
|
|
14
|
-
const newline = markdown.indexOf("\n", start);
|
|
15
|
-
const end = newline === -1 ? markdown.length : newline;
|
|
16
|
-
const next = newline === -1 ? markdown.length : newline + 1;
|
|
17
|
-
const raw = markdown.slice(start, end);
|
|
18
|
-
lines.push({ text: raw.endsWith("\r") ? raw.slice(0, -1) : raw, start, end, next });
|
|
19
|
-
start = next;
|
|
20
|
-
}
|
|
21
|
-
return lines;
|
|
22
|
-
}
|
|
23
|
-
function amendHeading(line) {
|
|
24
|
-
const match = line.match(/^ {0,3}(#{1,2})(?!#)[ \t]+(.+)$/);
|
|
25
|
-
if (!match)
|
|
26
|
-
return null;
|
|
27
|
-
const level = match[1].length;
|
|
28
|
-
const title = normalizeSectionTitle(match[2]);
|
|
29
|
-
if (level !== 2)
|
|
30
|
-
return { level };
|
|
31
|
-
if (title === "scope add")
|
|
32
|
-
return { level, name: "add" };
|
|
33
|
-
return { level };
|
|
34
|
-
}
|
|
35
|
-
function amendFence(line) {
|
|
36
|
-
const match = line.match(/^ {0,3}(`{3,}|~{3,})/);
|
|
37
|
-
if (!match)
|
|
38
|
-
return null;
|
|
39
|
-
const marker = match[1];
|
|
40
|
-
return { delimiter: marker[0], length: marker.length };
|
|
41
|
-
}
|
|
42
|
-
function parseAmendScopeSections(markdown) {
|
|
43
|
-
const lines = sourceLines(markdown);
|
|
44
|
-
const sections = {};
|
|
45
|
-
let active;
|
|
46
|
-
let fence;
|
|
47
|
-
let frontMatterEnd = -1;
|
|
48
|
-
if (lines[0]?.text.trim() === "---") {
|
|
49
|
-
for (let index = 1; index < lines.length; index += 1) {
|
|
50
|
-
if (lines[index].text.trim() === "---") {
|
|
51
|
-
frontMatterEnd = index;
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
const finishActive = (end) => {
|
|
57
|
-
if (!active)
|
|
58
|
-
return;
|
|
59
|
-
sections[active.name] = { ...active, end };
|
|
60
|
-
active = undefined;
|
|
61
|
-
};
|
|
62
|
-
for (let index = 0; index < lines.length; index += 1) {
|
|
63
|
-
const line = lines[index];
|
|
64
|
-
if (index <= frontMatterEnd)
|
|
65
|
-
continue;
|
|
66
|
-
const marker = amendFence(line.text);
|
|
67
|
-
if (fence) {
|
|
68
|
-
if (marker && marker.delimiter === fence.delimiter && marker.length >= fence.length) {
|
|
69
|
-
fence = undefined;
|
|
70
|
-
}
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
if (marker) {
|
|
74
|
-
fence = marker;
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
const heading = amendHeading(line.text);
|
|
78
|
-
if (!heading)
|
|
79
|
-
continue;
|
|
80
|
-
finishActive(line.start);
|
|
81
|
-
if (!heading.name)
|
|
82
|
-
continue;
|
|
83
|
-
if (sections[heading.name]) {
|
|
84
|
-
throw new FlowError("INVALID_KEIYAKU_DRAFT", `amend input may contain ${amendScopeHeading(heading.name)} at most once`);
|
|
85
|
-
}
|
|
86
|
-
active = { name: heading.name, start: line.start, contentStart: line.next };
|
|
87
|
-
}
|
|
88
|
-
finishActive(markdown.length);
|
|
89
|
-
let prose = markdown;
|
|
90
|
-
for (const section of Object.values(sections).sort((left, right) => right.start - left.start)) {
|
|
91
|
-
prose = `${prose.slice(0, section.start)}${prose.slice(section.end)}`;
|
|
92
|
-
}
|
|
93
|
-
return { sections, prose };
|
|
94
|
-
}
|
|
95
|
-
function scopePatterns(markdown, section) {
|
|
96
|
-
const patterns = markdown
|
|
97
|
-
.slice(section.contentStart, section.end)
|
|
98
|
-
.split(/\r?\n/)
|
|
99
|
-
.filter((line) => !isBlankScopePatternLine(line))
|
|
100
|
-
.map((pattern) => {
|
|
101
|
-
try {
|
|
102
|
-
// Do not trim() here: gitignore treats trailing `\ ` as a significant space.
|
|
103
|
-
return normalizeScopePattern(pattern);
|
|
104
|
-
}
|
|
105
|
-
catch (error) {
|
|
106
|
-
if (error instanceof ScopePatternError) {
|
|
107
|
-
throw new FlowError("INVALID_KEIYAKU_DRAFT", error.message);
|
|
108
|
-
}
|
|
109
|
-
throw error;
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
if (patterns.length === 0) {
|
|
113
|
-
throw new FlowError("INVALID_KEIYAKU_DRAFT", `amend input has an empty ${amendScopeHeading(section.name)} section`);
|
|
114
|
-
}
|
|
115
|
-
return patterns;
|
|
116
|
-
}
|
|
117
|
-
export function buildAmendInput(markdown, cwd, contractId, contractAddressSource) {
|
|
118
|
-
const { sections, prose } = parseAmendScopeSections(markdown);
|
|
119
|
-
const add = sections.add ? scopePatterns(markdown, sections.add) : [];
|
|
120
|
-
if (!prose.trim()) {
|
|
121
|
-
throw new FlowError("EMPTY_PARAM", "amendment cannot be empty");
|
|
122
|
-
}
|
|
123
|
-
return {
|
|
124
|
-
cwd,
|
|
125
|
-
...(contractId ? { contractId } : {}),
|
|
126
|
-
...(contractAddressSource ? { contractAddressSource } : {}),
|
|
127
|
-
amendment: prose,
|
|
128
|
-
...(sections.add ? { scopeDelta: { add } } : {}),
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
export function defaultActorClock(nowMs = Date.now()) {
|
|
132
|
-
return { actor: ACTOR_IDENTITY, nowMs };
|
|
133
|
-
}
|
|
134
|
-
export function parseCommandMarkdown(content) {
|
|
135
|
-
try {
|
|
136
|
-
const parsed = parseMarkdownStructure(content);
|
|
137
|
-
const sections = new Map();
|
|
138
|
-
for (const [key, lines] of parsed.sections.entries()) {
|
|
139
|
-
sections.set(key, lines.join("\n").trim());
|
|
140
|
-
}
|
|
141
|
-
return { title: parsed.title, sections };
|
|
142
|
-
}
|
|
143
|
-
catch (error) {
|
|
144
|
-
if (error instanceof KeiyakuParseError) {
|
|
145
|
-
throw new FlowError("INVALID_KEIYAKU_DRAFT", error.message, { cause: error });
|
|
146
|
-
}
|
|
147
|
-
throw error;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
export function requireMarkdownTextSection(parts, name) {
|
|
151
|
-
const normalized = normalizeSectionTitle(name);
|
|
152
|
-
const value = parts.sections.get(normalized)?.trim();
|
|
153
|
-
if (!value) {
|
|
154
|
-
throw new FlowError("INVALID_KEIYAKU_DRAFT", `missing required section: ## ${name}`);
|
|
155
|
-
}
|
|
156
|
-
return value;
|
|
157
|
-
}
|
|
158
|
-
export function requireMarkdownListSection(parts, name) {
|
|
159
|
-
const text = requireMarkdownTextSection(parts, name);
|
|
160
|
-
const items = parseMarkdownListSection(text)
|
|
161
|
-
.map((item) => item.trim())
|
|
162
|
-
.filter((item) => item.length > 0);
|
|
163
|
-
if (items.length === 0) {
|
|
164
|
-
throw new FlowError("INVALID_KEIYAKU_DRAFT", `missing required section: ## ${name}`);
|
|
165
|
-
}
|
|
166
|
-
return items;
|
|
167
|
-
}
|
|
168
|
-
export function requireMarkdownTitle(parts) {
|
|
169
|
-
const title = parts.title?.trim();
|
|
170
|
-
if (!title) {
|
|
171
|
-
throw new FlowError("INVALID_KEIYAKU_DRAFT", "missing required title: # Title");
|
|
172
|
-
}
|
|
173
|
-
return title;
|
|
174
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import * as fs from "node:fs";
|
|
2
|
-
import * as fsPromises from "node:fs/promises";
|
|
3
|
-
import * as path from "node:path";
|
|
4
|
-
/**
|
|
5
|
-
* Git for Windows may emit native, slash-normalized, or MSYS drive paths.
|
|
6
|
-
* Keep one host-native spelling before using a coordinate as a filesystem cwd.
|
|
7
|
-
*/
|
|
8
|
-
export function normalizeGitPath(raw, platform = process.platform) {
|
|
9
|
-
const value = raw.trim();
|
|
10
|
-
if (platform !== "win32")
|
|
11
|
-
return path.normalize(value);
|
|
12
|
-
const msysDrive = value.match(/^\/([A-Za-z])(?:\/|$)(.*)$/);
|
|
13
|
-
if (msysDrive)
|
|
14
|
-
return path.win32.normalize(`${msysDrive[1].toUpperCase()}:/${msysDrive[2]}`);
|
|
15
|
-
const normalized = path.win32.normalize(value);
|
|
16
|
-
return normalized.replace(/^([a-z]):/, (_, drive) => `${drive.toUpperCase()}:`);
|
|
17
|
-
}
|
|
18
|
-
export function gitCommonRootPath(raw, platform = process.platform) {
|
|
19
|
-
const paths = platform === "win32" ? path.win32 : path.posix;
|
|
20
|
-
return paths.dirname(normalizeGitPath(raw, platform));
|
|
21
|
-
}
|
|
22
|
-
export async function resolveGitCommonRoot(raw) {
|
|
23
|
-
return await fsPromises.realpath(gitCommonRootPath(raw));
|
|
24
|
-
}
|
|
25
|
-
export function resolveGitCommonRootSync(raw) {
|
|
26
|
-
return fs.realpathSync(gitCommonRootPath(raw));
|
|
27
|
-
}
|