@astrosheep/keiyaku 4.0.4 → 4.0.6
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/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +4 -4
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +15 -7
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +5 -3
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +24 -4
- package/build/src/akuma/akuma.d.ts +2 -1
- package/build/src/akuma/akuma.js +27 -9
- package/build/src/akuma/allowed.d.ts +1 -1
- package/build/src/akuma/allowed.js +3 -10
- package/build/src/akuma/archetype.d.ts +3 -1
- package/build/src/akuma/archetype.js +11 -6
- package/build/src/akuma/body-turn.d.ts +64 -0
- package/build/src/akuma/body-turn.js +449 -0
- package/build/src/akuma/body.d.ts +4 -5
- package/build/src/akuma/body.js +9 -414
- package/build/src/akuma/heart/facts.d.ts +37 -9
- package/build/src/akuma/heart/facts.js +3 -1
- package/build/src/akuma/heart/index.d.ts +4 -13
- package/build/src/akuma/heart/index.js +14 -135
- package/build/src/akuma/heart/request-authority.d.ts +12 -0
- package/build/src/akuma/heart/request-authority.js +119 -0
- package/build/src/akuma/heart/request-rows.d.ts +16 -0
- package/build/src/akuma/heart/request-rows.js +88 -0
- package/build/src/akuma/heart/rows.d.ts +1 -28
- package/build/src/akuma/heart/rows.js +4 -138
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +11 -3
- package/build/src/akuma/heart/soul.js +0 -36
- package/build/src/akuma/heart/timeline.d.ts +1 -0
- package/build/src/akuma/heart/timeline.js +19 -0
- package/build/src/akuma/index.d.ts +1 -1
- package/build/src/akuma/nuke.d.ts +2 -0
- package/build/src/akuma/nuke.js +152 -0
- package/build/src/akuma/provider-recipe.js +1 -11
- package/build/src/akuma/provider.d.ts +4 -7
- package/build/src/akuma/providers/acp/config.d.ts +8 -0
- package/build/src/akuma/providers/acp/config.js +37 -0
- package/build/src/akuma/providers/acp/core.js +12 -2
- package/build/src/akuma/providers/acp/index.d.ts +1 -8
- package/build/src/akuma/providers/acp/index.js +2 -38
- package/build/src/akuma/providers/claude/index.d.ts +0 -4
- package/build/src/akuma/providers/claude/index.js +12 -3
- package/build/src/akuma/providers/codex-app-server/index.d.ts +2 -27
- package/build/src/akuma/providers/codex-app-server/index.js +5 -2
- package/build/src/akuma/providers/grok-build/index.js +1 -2
- package/build/src/akuma/providers/index.d.ts +3 -2
- package/build/src/akuma/providers/index.js +36 -36
- package/build/src/akuma/providers/opencode-sdk/index.d.ts +2 -28
- package/build/src/akuma/providers/opencode-sdk/index.js +14 -4
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +2 -2
- package/build/src/akuma/providers/opencode-sdk/session.js +2 -2
- package/build/src/akuma/providers/pi/index.d.ts +1 -1
- package/build/src/akuma/providers/pi/index.js +29 -6
- package/build/src/akuma/request-serve.d.ts +88 -0
- package/build/src/akuma/request-serve.js +484 -0
- package/build/src/akuma/request-wire.d.ts +125 -0
- package/build/src/akuma/request-wire.js +383 -0
- package/build/src/akuma/requests.d.ts +28 -94
- package/build/src/akuma/requests.js +52 -562
- package/build/src/akuma-body.d.ts +7 -0
- package/build/src/akuma-body.js +69 -2
- package/build/src/alias/index.d.ts +1 -0
- package/build/src/alias/index.js +34 -1
- package/build/src/body/arc.js +4 -29
- package/build/src/body/decode.js +5 -39
- package/build/src/body/envelope.d.ts +7 -0
- package/build/src/body/envelope.js +37 -0
- package/build/src/cli/accepted.js +21 -9
- package/build/src/cli/commands/akuma-invoke.js +1 -0
- package/build/src/cli/commands/akuma.d.ts +1 -0
- package/build/src/cli/commands/akuma.js +13 -10
- package/build/src/cli/commands/contract.d.ts +28 -17
- package/build/src/cli/commands/contract.js +23 -17
- package/build/src/cli/commands/install.d.ts +2 -2
- package/build/src/cli/commands/install.js +6 -6
- package/build/src/cli/commands/nuke.d.ts +10 -0
- package/build/src/cli/commands/nuke.js +20 -0
- package/build/src/cli/commands/task-invoke.d.ts +15 -0
- package/build/src/cli/commands/task-invoke.js +144 -24
- package/build/src/cli/commands/task-query.d.ts +2 -2
- package/build/src/cli/commands/task-query.js +1 -2
- package/build/src/cli/commands/task.js +22 -22
- package/build/src/cli/coordinates.d.ts +6 -2
- package/build/src/cli/coordinates.js +12 -56
- package/build/src/cli/invoke.d.ts +5 -4
- package/build/src/cli/invoke.js +112 -58
- package/build/src/cli/main.d.ts +0 -2
- package/build/src/cli/main.js +4 -140
- package/build/src/cli/parse.d.ts +17 -4
- package/build/src/cli/parse.js +93 -15
- package/build/src/cli/render/akuma.js +111 -53
- package/build/src/cli/render/audit.js +2 -6
- package/build/src/cli/render/contract.js +61 -20
- package/build/src/cli/render/kanshi.js +15 -5
- package/build/src/cli/render/nuke.d.ts +3 -0
- package/build/src/cli/render/nuke.js +8 -0
- package/build/src/cli/render/receipt.js +28 -1
- package/build/src/cli/render/refusal.d.ts +2 -1
- package/build/src/cli/render/refusal.js +31 -0
- package/build/src/cli/render/terminal.d.ts +0 -2
- package/build/src/cli/render/terminal.js +0 -29
- package/build/src/cli/render/text.js +6 -1
- package/build/src/cli/result.d.ts +36 -9
- package/build/src/cli/runtime.d.ts +2 -0
- package/build/src/cli/runtime.js +140 -0
- package/build/src/cli/usage.d.ts +0 -2
- package/build/src/cli/usage.js +0 -4
- package/build/src/contract-worktree.d.ts +29 -14
- package/build/src/contract-worktree.js +131 -70
- package/build/src/core/facts/codec.js +9 -0
- package/build/src/core/facts/fold.js +13 -1
- package/build/src/core/facts/types.d.ts +8 -1
- package/build/src/core/subject.js +4 -3
- package/build/src/core/verbs/placement.d.ts +9 -1
- package/build/src/core/verbs/placement.js +24 -6
- package/build/src/core/verbs/reintegrate.d.ts +13 -0
- package/build/src/core/verbs/reintegrate.js +24 -0
- package/build/src/dispatch/index.d.ts +1 -1
- package/build/src/git/admission.d.ts +2 -1
- package/build/src/git/hooks.d.ts +2 -0
- package/build/src/git/hooks.js +34 -1
- package/build/src/git/integration.d.ts +9 -2
- package/build/src/git/integration.js +92 -1
- package/build/src/git/nuke.d.ts +2 -0
- package/build/src/git/nuke.js +97 -0
- package/build/src/git/observe.d.ts +2 -1
- package/build/src/git/observe.js +6 -5
- package/build/src/git/process.d.ts +28 -0
- package/build/src/git/process.js +94 -0
- package/build/src/git/read-observation.d.ts +2 -1
- package/build/src/git/read-observation.js +3 -2
- package/build/src/git/reconcile.d.ts +4 -1
- package/build/src/git/reconcile.js +42 -8
- package/build/src/git/repository.d.ts +2 -29
- package/build/src/git/repository.js +7 -118
- package/build/src/git/scratch.d.ts +1 -1
- package/build/src/git/scratch.js +1 -1
- package/build/src/git/target-placement.d.ts +3 -2
- package/build/src/git/target-placement.js +15 -14
- package/build/src/git/tender.d.ts +2 -1
- package/build/src/git/tender.js +4 -3
- package/build/src/git/terminal-seal.d.ts +2 -2
- package/build/src/git/terminal-seal.js +3 -6
- package/build/src/git/workspace.d.ts +4 -1
- package/build/src/git/workspace.js +1 -1
- package/build/src/index.d.ts +1 -2
- package/build/src/index.js +1 -1
- package/build/src/kanshi/read.js +5 -1
- package/build/src/library/address.js +7 -1
- package/build/src/library/akuma-creation.d.ts +1 -0
- package/build/src/library/akuma-creation.js +8 -1
- package/build/src/library/audit.d.ts +3 -1
- package/build/src/library/audit.js +2 -1
- package/build/src/library/bind.d.ts +2 -1
- package/build/src/library/bind.js +1 -1
- package/build/src/library/configuration.d.ts +1 -1
- package/build/src/library/configuration.js +52 -18
- package/build/src/library/contract.d.ts +59 -4
- package/build/src/library/contract.js +195 -34
- package/build/src/library/delivery.d.ts +4 -2
- package/build/src/library/fleet.d.ts +27 -7
- package/build/src/library/fleet.js +79 -39
- package/build/src/library/input.d.ts +0 -1
- package/build/src/library/input.js +0 -5
- package/build/src/library/keiyaku.d.ts +6 -2
- package/build/src/library/keiyaku.js +2 -0
- package/build/src/library/mutation.d.ts +3 -1
- package/build/src/library/mutation.js +3 -0
- package/build/src/library/nuke.d.ts +14 -0
- package/build/src/library/nuke.js +54 -0
- package/build/src/library/reconcile.d.ts +2 -1
- package/build/src/library/reconcile.js +8 -3
- package/build/src/library/refusal.d.ts +10 -1
- package/build/src/library/region.d.ts +1 -1
- package/build/src/library/repo.d.ts +4 -1
- package/build/src/library/repo.js +10 -4
- package/build/src/protocol/abandon.d.ts +9 -0
- package/build/src/protocol/abandon.js +15 -0
- package/build/src/protocol/amend.d.ts +16 -0
- package/build/src/protocol/amend.js +77 -0
- package/build/src/protocol/arc.d.ts +6 -0
- package/build/src/protocol/arc.js +12 -0
- package/build/src/protocol/attempt.d.ts +2 -1
- package/build/src/protocol/audit.d.ts +53 -0
- package/build/src/protocol/audit.js +147 -0
- package/build/src/protocol/bind.d.ts +1 -1
- package/build/src/protocol/completion.d.ts +42 -0
- package/build/src/protocol/completion.js +183 -0
- package/build/src/protocol/deliver.d.ts +49 -0
- package/build/src/protocol/deliver.js +261 -0
- package/build/src/protocol/intent.d.ts +2 -1
- package/build/src/protocol/intent.js +8 -2
- package/build/src/protocol/operations.d.ts +93 -202
- package/build/src/protocol/operations.js +23 -642
- package/build/src/protocol/placement.d.ts +12 -13
- package/build/src/protocol/placement.js +8 -19
- package/build/src/protocol/read/status.d.ts +17 -5
- package/build/src/protocol/read/status.js +57 -13
- package/build/src/protocol/reconcile.d.ts +35 -0
- package/build/src/protocol/reconcile.js +41 -0
- package/build/src/protocol/reintegrate.d.ts +31 -0
- package/build/src/protocol/reintegrate.js +74 -0
- package/build/src/protocol/review.d.ts +34 -0
- package/build/src/protocol/review.js +156 -0
- package/build/src/protocol/run.d.ts +1 -1
- package/build/src/runtime/proc/run.js +9 -5
- package/build/src/settlement/fence.d.ts +3 -1
- package/build/src/settlement/fence.js +24 -0
- package/build/src/settlement/holder.d.ts +1 -1
- package/build/src/settlement/settle.d.ts +1 -1
- package/build/src/settlement/settle.js +1 -2
- package/build/src/task/board.d.ts +0 -1
- package/build/src/task/board.js +0 -3
- package/build/src/task/compose.d.ts +2 -2
- package/build/src/task/compose.js +13 -11
- package/build/src/task/context.d.ts +14 -2
- package/build/src/task/context.js +30 -7
- package/build/src/task/index.d.ts +7 -6
- package/build/src/task/index.js +17 -145
- package/build/src/task/input.d.ts +18 -0
- package/build/src/task/input.js +189 -0
- package/build/src/task/mutation.d.ts +44 -0
- package/build/src/task/mutation.js +93 -0
- package/build/src/task/operations.d.ts +14 -6
- package/build/src/task/operations.js +57 -57
- package/build/src/task/store.d.ts +1 -0
- package/build/src/task/store.js +91 -3
- package/build/src/verification/execution.d.ts +1 -1
- package/build/src/workspace-place.d.ts +3 -4
- package/build/src/workspace-place.js +26 -15
- package/package.json +3 -3
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AuthorityCorruptionError } from "../core/facts/errors.js";
|
|
2
2
|
import { gitObjectId, gitObjectIdForSnapshot, mintChangeId, mintSnapshotId } from "./identity.js";
|
|
3
|
-
import { decodeGitNameOnly, decodeGitNumstat,
|
|
3
|
+
import { decodeGitNameOnly, decodeGitNumstat, readRef, } from "./repository.js";
|
|
4
|
+
import { GitPlumbingError, runGit, runGitWithEnvironment, } from "./process.js";
|
|
4
5
|
const REQUIRED_GIT = "2.38";
|
|
5
6
|
async function runAllowingNonzero(repository, args, input) {
|
|
6
7
|
try {
|
|
@@ -55,6 +56,58 @@ export async function materializeIntegrationSnapshot(repository, tree, parent, m
|
|
|
55
56
|
})).toString("utf8").trim();
|
|
56
57
|
return mintSnapshotId(commit);
|
|
57
58
|
}
|
|
59
|
+
export async function persistedTender(repository, snapshot) {
|
|
60
|
+
const tree = (await runGit(repository, ["show", "-s", "--format=%T", gitObjectIdForSnapshot(snapshot)]))
|
|
61
|
+
.toString("ascii")
|
|
62
|
+
.trim();
|
|
63
|
+
return { head: snapshot, tree: gitObjectId(tree, "persisted tender tree") };
|
|
64
|
+
}
|
|
65
|
+
export async function materializeReintegrationSnapshot(repository, tree, parent, template) {
|
|
66
|
+
const templateObject = gitObjectIdForSnapshot(template);
|
|
67
|
+
let raw;
|
|
68
|
+
try {
|
|
69
|
+
raw = await runGit(repository, ["cat-file", "commit", templateObject]);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (error instanceof GitPlumbingError) {
|
|
73
|
+
throw new AuthorityCorruptionError(`recorded delivery snapshot cannot be read: ${template}`);
|
|
74
|
+
}
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
const separator = raw.indexOf(Buffer.from("\n\n"));
|
|
78
|
+
if (separator < 0)
|
|
79
|
+
throw new AuthorityCorruptionError(`recorded delivery snapshot has no commit message: ${template}`);
|
|
80
|
+
const message = raw.subarray(separator + 2);
|
|
81
|
+
let fields;
|
|
82
|
+
try {
|
|
83
|
+
const formatted = (await runGit(repository, [
|
|
84
|
+
"show",
|
|
85
|
+
"-s",
|
|
86
|
+
"--format=%an%x00%ae%x00%aI%x00%cn%x00%ce%x00%cI",
|
|
87
|
+
templateObject,
|
|
88
|
+
])).toString("utf8").replace(/\n$/u, "");
|
|
89
|
+
fields = formatted.split("\0");
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
if (error instanceof GitPlumbingError) {
|
|
93
|
+
throw new AuthorityCorruptionError(`recorded delivery snapshot metadata cannot be read: ${template}`);
|
|
94
|
+
}
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
if (fields.length !== 6 || fields.some((field) => field.length === 0)) {
|
|
98
|
+
throw new AuthorityCorruptionError(`recorded delivery snapshot metadata is malformed: ${template}`);
|
|
99
|
+
}
|
|
100
|
+
const [authorName, authorEmail, authorDate, committerName, committerEmail, committerDate] = fields;
|
|
101
|
+
const commit = (await runGitWithEnvironment(repository, ["commit-tree", tree, "-p", gitObjectIdForSnapshot(parent)], message, {
|
|
102
|
+
GIT_AUTHOR_NAME: authorName,
|
|
103
|
+
GIT_AUTHOR_EMAIL: authorEmail,
|
|
104
|
+
GIT_AUTHOR_DATE: authorDate,
|
|
105
|
+
GIT_COMMITTER_NAME: committerName,
|
|
106
|
+
GIT_COMMITTER_EMAIL: committerEmail,
|
|
107
|
+
GIT_COMMITTER_DATE: committerDate,
|
|
108
|
+
})).toString("utf8").trim();
|
|
109
|
+
return mintSnapshotId(commit);
|
|
110
|
+
}
|
|
58
111
|
async function isAncestor(repository, ancestor, descendant) {
|
|
59
112
|
const result = await runAllowingNonzero(repository, [
|
|
60
113
|
"merge-base",
|
|
@@ -139,6 +192,44 @@ async function mergedTree(repository, contractId, base, targetHead, tenderTree)
|
|
|
139
192
|
message: "git merge-tree --write-tree failed",
|
|
140
193
|
});
|
|
141
194
|
}
|
|
195
|
+
/** True when the appointed workspace already has Git MERGE_HEAD. */
|
|
196
|
+
export async function workspaceMergeStatePresent(repository, workspace) {
|
|
197
|
+
const result = await runAllowingNonzero(repository, [
|
|
198
|
+
"-C",
|
|
199
|
+
workspace,
|
|
200
|
+
"rev-parse",
|
|
201
|
+
"-q",
|
|
202
|
+
"--verify",
|
|
203
|
+
"MERGE_HEAD",
|
|
204
|
+
]);
|
|
205
|
+
if (result.status === 0)
|
|
206
|
+
return true;
|
|
207
|
+
if (result.status === 1)
|
|
208
|
+
return false;
|
|
209
|
+
throw new GitPlumbingError({
|
|
210
|
+
stderr: result.stderr,
|
|
211
|
+
status: result.status,
|
|
212
|
+
message: "git rev-parse --verify MERGE_HEAD failed",
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
/** Project the already-judged conflict as `git merge --no-commit <targetHead>`. */
|
|
216
|
+
export async function materializeJudgedConflict(repository, workspace, targetHead) {
|
|
217
|
+
const result = await runAllowingNonzero(repository, [
|
|
218
|
+
"-C",
|
|
219
|
+
workspace,
|
|
220
|
+
"merge",
|
|
221
|
+
"--no-commit",
|
|
222
|
+
gitObjectIdForSnapshot(targetHead),
|
|
223
|
+
]);
|
|
224
|
+
if (result.status === 0 || result.status === 1)
|
|
225
|
+
return;
|
|
226
|
+
throw new GitPlumbingError({
|
|
227
|
+
stdout: result.stdout,
|
|
228
|
+
stderr: result.stderr,
|
|
229
|
+
status: result.status,
|
|
230
|
+
message: "git merge --no-commit failed",
|
|
231
|
+
});
|
|
232
|
+
}
|
|
142
233
|
export async function planIntegration(repository, input, tender, requireBranchesToBeUpToDate) {
|
|
143
234
|
const target = input.coordinates.target;
|
|
144
235
|
if (target === undefined) {
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { access } from "node:fs/promises";
|
|
2
|
+
import { nukeContractWorktreeLock, nukeHereAppointments } from "../contract-worktree.js";
|
|
3
|
+
import { nukeSettlementFences } from "../settlement/fence.js";
|
|
4
|
+
import { nukeEmptyPlaceAuthority, readPlaceRegister, releaseManagedWorktrees, } from "../workspace-place.js";
|
|
5
|
+
import { nukeWorktreeHookResidue } from "./hooks.js";
|
|
6
|
+
import { nukeReconcileLocks } from "./reconcile.js";
|
|
7
|
+
import { runGit } from "./process.js";
|
|
8
|
+
import { NoGitWorldError, registeredWorktrees, repositoryAt, worktreeGitDirectory } from "./repository.js";
|
|
9
|
+
import { worktreePath } from "./workspace.js";
|
|
10
|
+
async function managedCustody(repository) {
|
|
11
|
+
const register = await readPlaceRegister(repository);
|
|
12
|
+
const topology = new Map((await registeredWorktrees(repository)).map((entry) => [entry.path, entry]));
|
|
13
|
+
const entries = [];
|
|
14
|
+
for (const appointment of register.appointments) {
|
|
15
|
+
const path = worktreePath(repository, appointment.place);
|
|
16
|
+
const registered = topology.get(path);
|
|
17
|
+
if (registered === undefined) {
|
|
18
|
+
try {
|
|
19
|
+
await access(path);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
entries.push({ contract: appointment.contract, path });
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
throw new Error(`managed Place path has foreign custody: ${path}`);
|
|
26
|
+
}
|
|
27
|
+
if (registered.branch !== null)
|
|
28
|
+
throw new Error(`managed Place path has a branch: ${path}`);
|
|
29
|
+
entries.push({ contract: appointment.contract, path });
|
|
30
|
+
}
|
|
31
|
+
const refs = (await runGit(repository, [
|
|
32
|
+
"for-each-ref", "--format=%(refname)", "refs/heads/keiyaku-delivery", "refs/heads/keiyaku-candidate",
|
|
33
|
+
])).toString("utf8").split("\n").filter((ref) => ref.length > 0);
|
|
34
|
+
const state = await runGit(repository, ["show-ref", "--verify", "--quiet", "refs/heads/keiyaku-state"])
|
|
35
|
+
.then(() => true, () => false);
|
|
36
|
+
return { entries, refs, state };
|
|
37
|
+
}
|
|
38
|
+
async function removeManagedWorktree(repository, entry) {
|
|
39
|
+
const topology = await registeredWorktrees(repository);
|
|
40
|
+
const registered = topology.find((candidate) => candidate.path === entry.path);
|
|
41
|
+
if (registered === undefined) {
|
|
42
|
+
try {
|
|
43
|
+
await access(entry.path);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
throw new Error(`managed Place path has foreign custody: ${entry.path}`);
|
|
49
|
+
}
|
|
50
|
+
if (registered.branch !== null)
|
|
51
|
+
throw new Error(`managed Place path has a branch: ${entry.path}`);
|
|
52
|
+
await nukeWorktreeHookResidue(await worktreeGitDirectory(repository, entry.path));
|
|
53
|
+
await runGit(repository, ["worktree", "remove", "--force", entry.path]);
|
|
54
|
+
if ((await registeredWorktrees(repository)).some((candidate) => candidate.path === entry.path)) {
|
|
55
|
+
throw new Error(`managed Place worktree remains registered: ${entry.path}`);
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
await access(entry.path);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
throw new Error(`managed Place worktree remains present: ${entry.path}`);
|
|
64
|
+
}
|
|
65
|
+
async function removeOwnedRefs(repository, refs) {
|
|
66
|
+
for (const ref of refs) {
|
|
67
|
+
const oid = (await runGit(repository, ["rev-parse", "--verify", "--quiet", ref])).toString("utf8").trim();
|
|
68
|
+
if (oid.length > 0)
|
|
69
|
+
await runGit(repository, ["update-ref", "--no-deref", "-d", ref, oid]);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export async function nukeGit(world) {
|
|
73
|
+
let repository;
|
|
74
|
+
try {
|
|
75
|
+
repository = await repositoryAt(world);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
if (error instanceof NoGitWorldError)
|
|
79
|
+
return;
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
const custody = await managedCustody(repository);
|
|
83
|
+
for (const entry of custody.entries) {
|
|
84
|
+
await removeManagedWorktree(repository, entry);
|
|
85
|
+
await releaseManagedWorktrees(repository, [entry.contract]);
|
|
86
|
+
}
|
|
87
|
+
await nukeHereAppointments(repository);
|
|
88
|
+
await nukeEmptyPlaceAuthority(repository);
|
|
89
|
+
await nukeContractWorktreeLock(repository);
|
|
90
|
+
await nukeReconcileLocks(repository);
|
|
91
|
+
await nukeSettlementFences(repository);
|
|
92
|
+
await removeOwnedRefs(repository, custody.refs);
|
|
93
|
+
if (custody.state) {
|
|
94
|
+
const oid = (await runGit(repository, ["rev-parse", "--verify", "refs/heads/keiyaku-state"])).toString("utf8").trim();
|
|
95
|
+
await runGit(repository, ["update-ref", "--no-deref", "-d", "refs/heads/keiyaku-state", oid]);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type ContractId, type ContractState, type JournalEntry, type SnapshotId } from "../core/facts/types.js";
|
|
2
2
|
import type { ContractsObservation } from "../core/facts/observation.js";
|
|
3
|
-
import { type GitSnapshot, type GitOid
|
|
3
|
+
import { type GitSnapshot, type GitOid } from "./repository.js";
|
|
4
|
+
import { type GitRepository } from "./process.js";
|
|
4
5
|
import { type GitDecodeChannel, type GitReadObservation, type GitTreeSelection } from "./read-observation.js";
|
|
5
6
|
export type TargetObservation = Readonly<{
|
|
6
7
|
head: SnapshotId | null;
|
package/build/src/git/observe.js
CHANGED
|
@@ -2,7 +2,8 @@ import { decodeJournal } from "../core/facts/codec.js";
|
|
|
2
2
|
import { AuthorityCorruptionError } from "../core/facts/errors.js";
|
|
3
3
|
import { foldJournal } from "../core/facts/fold.js";
|
|
4
4
|
import { contractJournalPath, contractJournalPaths, mintContractHead, mintSnapshotId, } from "./identity.js";
|
|
5
|
-
import {
|
|
5
|
+
import { isKeiyakuOwnedRef, } from "./repository.js";
|
|
6
|
+
import { GitPlumbingError, runGit } from "./process.js";
|
|
6
7
|
import { readGitTreeSelection, withGitTargetedReadObservation, } from "./read-observation.js";
|
|
7
8
|
export async function observeDeliveryTargetAt(observation, state) {
|
|
8
9
|
const target = state.coordinates.target;
|
|
@@ -10,12 +11,12 @@ export async function observeDeliveryTargetAt(observation, state) {
|
|
|
10
11
|
return null;
|
|
11
12
|
const value = await observation.resolveRef(target);
|
|
12
13
|
const head = value === null ? null : mintSnapshotId(value);
|
|
13
|
-
const
|
|
14
|
-
if (
|
|
14
|
+
const integration = state.currentIntegration;
|
|
15
|
+
if (integration === null)
|
|
15
16
|
return { head, drift: false };
|
|
16
17
|
const expected = state.terminal?.kind === "claimed"
|
|
17
|
-
?
|
|
18
|
-
:
|
|
18
|
+
? integration.snapshot
|
|
19
|
+
: integration.predecessor;
|
|
19
20
|
return { head, drift: head !== expected };
|
|
20
21
|
}
|
|
21
22
|
const TARGET_COORDINATES_FORMAT = "%(refname)%00%(objectname)%00";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type GitRepository = Readonly<{
|
|
2
|
+
/** The executable selected when this repository capability is created. */
|
|
3
|
+
readonly gitPath: string;
|
|
4
|
+
/** The invocation's effective working directory, including a caller -C worktree. */
|
|
5
|
+
readonly effectiveCwd: string;
|
|
6
|
+
/** The worktree root containing the invocation's effective working directory. */
|
|
7
|
+
readonly invocationWorktree: string;
|
|
8
|
+
/** The canonical primary worktree root for this repository. */
|
|
9
|
+
readonly primaryWorktree: string;
|
|
10
|
+
/** The canonical common Git directory pinned when this capability is created. */
|
|
11
|
+
readonly commonDirectory: string;
|
|
12
|
+
}>;
|
|
13
|
+
export declare class GitPlumbingError extends Error {
|
|
14
|
+
readonly stdout: Buffer;
|
|
15
|
+
readonly stderr: Buffer;
|
|
16
|
+
readonly status: number | null;
|
|
17
|
+
readonly pid: number | null;
|
|
18
|
+
constructor(input: Readonly<{
|
|
19
|
+
stdout?: string | Uint8Array;
|
|
20
|
+
stderr: string | Uint8Array;
|
|
21
|
+
status: number | null;
|
|
22
|
+
message: string;
|
|
23
|
+
pid?: number | null;
|
|
24
|
+
}>);
|
|
25
|
+
}
|
|
26
|
+
export declare function runGit(repository: GitRepository, args: readonly string[], input?: string | Uint8Array): Promise<Buffer>;
|
|
27
|
+
export declare function consumeGitStdout(repository: GitRepository, args: readonly string[], consume: (chunk: Buffer) => void): Promise<void>;
|
|
28
|
+
export declare function runGitWithEnvironment(repository: GitRepository, args: readonly string[], input: string | Uint8Array | undefined, environment: NodeJS.ProcessEnv): Promise<Buffer>;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { consumeProcessStdout } from "../runtime/proc/run.js";
|
|
3
|
+
export class GitPlumbingError extends Error {
|
|
4
|
+
stdout;
|
|
5
|
+
stderr;
|
|
6
|
+
status;
|
|
7
|
+
pid;
|
|
8
|
+
constructor(input) {
|
|
9
|
+
super(input.message);
|
|
10
|
+
this.name = "GitPlumbingError";
|
|
11
|
+
this.stdout = Buffer.from(input.stdout ?? "");
|
|
12
|
+
this.stderr = Buffer.from(input.stderr);
|
|
13
|
+
this.status = input.status;
|
|
14
|
+
this.pid = input.pid ?? null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const GIT_STDERR_BYTES = 16 * 1024;
|
|
18
|
+
function commandError(command, error) {
|
|
19
|
+
const candidate = error;
|
|
20
|
+
const stderr = candidate.stderr === undefined ? Buffer.alloc(0) : Buffer.from(candidate.stderr);
|
|
21
|
+
const stdout = candidate.stdout === undefined ? Buffer.alloc(0) : Buffer.from(candidate.stdout);
|
|
22
|
+
const detail = stderr.length === 0 ? candidate.message ?? "git command failed" : stderr.toString("utf8");
|
|
23
|
+
return new GitPlumbingError({
|
|
24
|
+
stdout,
|
|
25
|
+
stderr,
|
|
26
|
+
status: candidate.status ?? null,
|
|
27
|
+
message: `${command.join(" ")}: ${detail}`,
|
|
28
|
+
pid: candidate.pid ?? null,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
async function executeGit(repository, args, input, environment) {
|
|
32
|
+
const stdout = [];
|
|
33
|
+
const stderr = [];
|
|
34
|
+
let stderrBytes = 0;
|
|
35
|
+
let inputError;
|
|
36
|
+
const child = spawn(repository.gitPath, [...args], {
|
|
37
|
+
cwd: repository.effectiveCwd,
|
|
38
|
+
...(environment === undefined ? {} : { env: { ...process.env, ...environment } }),
|
|
39
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
40
|
+
windowsHide: true,
|
|
41
|
+
});
|
|
42
|
+
child.stdout.on("data", (chunk) => stdout.push(chunk));
|
|
43
|
+
child.stderr.on("data", (chunk) => {
|
|
44
|
+
if (stderrBytes >= GIT_STDERR_BYTES)
|
|
45
|
+
return;
|
|
46
|
+
const retained = chunk.subarray(0, GIT_STDERR_BYTES - stderrBytes);
|
|
47
|
+
stderr.push(retained);
|
|
48
|
+
stderrBytes += retained.length;
|
|
49
|
+
});
|
|
50
|
+
child.stdin.on("error", (error) => { inputError = error; });
|
|
51
|
+
child.stdin.end(input);
|
|
52
|
+
const terminal = await new Promise((resolveTerminal) => {
|
|
53
|
+
child.once("error", (error) => resolveTerminal({ code: null, error }));
|
|
54
|
+
child.once("close", (code) => resolveTerminal({ code }));
|
|
55
|
+
});
|
|
56
|
+
const output = Buffer.concat(stdout);
|
|
57
|
+
if (terminal.code === 0 && inputError === undefined)
|
|
58
|
+
return output;
|
|
59
|
+
throw commandError(args, {
|
|
60
|
+
message: terminal.error?.message ?? inputError?.message ?? `git exited with status ${terminal.code ?? "unknown"}`,
|
|
61
|
+
stdout: output,
|
|
62
|
+
stderr: Buffer.concat(stderr),
|
|
63
|
+
status: terminal.code,
|
|
64
|
+
pid: child.pid,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
export async function runGit(repository, args, input) {
|
|
68
|
+
return await executeGit(repository, args, input);
|
|
69
|
+
}
|
|
70
|
+
export async function consumeGitStdout(repository, args, consume) {
|
|
71
|
+
const result = await consumeProcessStdout({
|
|
72
|
+
argv: [repository.gitPath, ...args],
|
|
73
|
+
cwd: repository.effectiveCwd,
|
|
74
|
+
}, consume);
|
|
75
|
+
const { outcome } = result;
|
|
76
|
+
if (outcome.kind === "terminal" && outcome.code === 0)
|
|
77
|
+
return;
|
|
78
|
+
const status = outcome.kind === "terminal" ? outcome.code : null;
|
|
79
|
+
const stderr = outcome.kind === "terminal" ? outcome.stderr : "";
|
|
80
|
+
const message = outcome.kind === "terminal"
|
|
81
|
+
? `git exited with status ${outcome.code}`
|
|
82
|
+
: outcome.kind === "spawn-error" || outcome.kind === "stream-error"
|
|
83
|
+
? outcome.diagnostic
|
|
84
|
+
: `git process ended with ${outcome.kind}`;
|
|
85
|
+
throw commandError(args, {
|
|
86
|
+
message,
|
|
87
|
+
stderr,
|
|
88
|
+
status,
|
|
89
|
+
pid: result.pid ?? undefined,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
export async function runGitWithEnvironment(repository, args, input, environment) {
|
|
93
|
+
return await executeGit(repository, args, input, environment);
|
|
94
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type TreeEntry } from "./tree.js";
|
|
2
|
-
import { type GitOid, type
|
|
2
|
+
import { type GitOid, type GitSnapshot } from "./repository.js";
|
|
3
|
+
import { type GitRepository } from "./process.js";
|
|
3
4
|
declare const gitReadObservationBrand: unique symbol;
|
|
4
5
|
declare const gitDecodeChannelBrand: unique symbol;
|
|
5
6
|
export type GitBlobResult = Readonly<{
|
|
@@ -2,7 +2,8 @@ import { spawn } from "node:child_process";
|
|
|
2
2
|
import { AuthorityCorruptionError } from "../core/facts/errors.js";
|
|
3
3
|
import { gitObjectId } from "./identity.js";
|
|
4
4
|
import { parseTreeObject, validPath } from "./tree.js";
|
|
5
|
-
import { GIT_FORMAT_BYTES, GIT_FORMAT_PATH, GIT_REF,
|
|
5
|
+
import { GIT_FORMAT_BYTES, GIT_FORMAT_PATH, GIT_REF, readRef, } from "./repository.js";
|
|
6
|
+
import { GitPlumbingError } from "./process.js";
|
|
6
7
|
const gitReadObservationBrand = Symbol("GitReadObservation");
|
|
7
8
|
const gitDecodeChannelBrand = Symbol("GitDecodeChannel");
|
|
8
9
|
function streamCursor(stream) {
|
|
@@ -36,7 +37,7 @@ function streamCursor(stream) {
|
|
|
36
37
|
return { line, exact };
|
|
37
38
|
}
|
|
38
39
|
function batchObjectReader(repository) {
|
|
39
|
-
const child = spawn(
|
|
40
|
+
const child = spawn(repository.gitPath, ["cat-file", "--batch"], {
|
|
40
41
|
cwd: repository.effectiveCwd,
|
|
41
42
|
stdio: ["pipe", "pipe", "pipe"],
|
|
42
43
|
windowsHide: true,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type GitOid
|
|
1
|
+
import { type GitOid } from "./repository.js";
|
|
2
|
+
import { type GitRepository } from "./process.js";
|
|
2
3
|
import type { ContractId, ContractState, SnapshotId } from "../core/facts/types.js";
|
|
3
4
|
import type { GitDecodeChannel } from "./read-observation.js";
|
|
4
5
|
import { type TargetCheckoutEffect, type TargetCheckoutLag } from "./target-placement.js";
|
|
@@ -63,4 +64,6 @@ type ReconcileBatchOptions = Readonly<{
|
|
|
63
64
|
}>;
|
|
64
65
|
/** Reconcile each discovered Contract through its own serialized, fresh observation. */
|
|
65
66
|
export declare function reconcileBatch(repository: GitRepository, channel: GitDecodeChannel, contracts: Iterable<ContractId>, options: ReconcileBatchOptions): Promise<readonly ReconcileBatchItem[]>;
|
|
67
|
+
/** Remove only validated Contract reconciliation lock residue. */
|
|
68
|
+
export declare function nukeReconcileLocks(repository: GitRepository): Promise<void>;
|
|
66
69
|
export {};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { access, mkdir } from "node:fs/promises";
|
|
2
|
-
import { dirname, join } from "node:path";
|
|
1
|
+
import { access, mkdir, readdir } from "node:fs/promises";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
3
|
import { acquireSqliteTransactionLock } from "../coordination/sqlite-transaction-lock.js";
|
|
4
4
|
import { AuthorityCorruptionError } from "../core/facts/errors.js";
|
|
5
|
-
import { CANDIDATE_PIN_REF_NAMESPACE, commonGitDirectory, DELIVERY_REF_NAMESPACE,
|
|
5
|
+
import { CANDIDATE_PIN_REF_NAMESPACE, commonGitDirectory, DELIVERY_REF_NAMESPACE, isKeiyakuOwnedRef, readRef, registeredWorktreePaths, writeCommit, worktreeGitDirectory, } from "./repository.js";
|
|
6
|
+
import { GitPlumbingError, runGit } from "./process.js";
|
|
6
7
|
import { contractLocator, contractPhysicalName, gitObjectIdForSnapshot, mintSnapshotId, } from "./identity.js";
|
|
7
8
|
import { observeContractAt } from "./observe.js";
|
|
8
9
|
import { acquireTargetPlacementFence, recoverTargetPlacement, } from "./target-placement.js";
|
|
@@ -206,7 +207,9 @@ async function reconcileHereWorkspaceRefs({ repository }, state, { effects, lag
|
|
|
206
207
|
if (state.delivery === null)
|
|
207
208
|
effects.push(await removeRef(repository, pin));
|
|
208
209
|
else {
|
|
209
|
-
const integration = state.
|
|
210
|
+
const integration = state.currentIntegration?.snapshot;
|
|
211
|
+
if (integration === undefined)
|
|
212
|
+
return complete();
|
|
210
213
|
const custodian = await snapshotCustodian(repository, integration);
|
|
211
214
|
effects.push(await (custodian === null
|
|
212
215
|
? await updateRef(repository, pin, integration)
|
|
@@ -216,7 +219,7 @@ async function reconcileHereWorkspaceRefs({ repository }, state, { effects, lag
|
|
|
216
219
|
else if (state.bound) {
|
|
217
220
|
effects.push(await (state.delivery === null
|
|
218
221
|
? await removeRef(repository, pin)
|
|
219
|
-
: await updateRef(repository, pin, state.delivery.data.integration.snapshot)));
|
|
222
|
+
: await updateRef(repository, pin, state.currentIntegration?.snapshot ?? state.delivery.data.integration.snapshot)));
|
|
220
223
|
}
|
|
221
224
|
return complete(effects, lag);
|
|
222
225
|
}
|
|
@@ -314,7 +317,7 @@ async function releaseTerminalCustody({ repository, state, expected, ref, pin, a
|
|
|
314
317
|
return;
|
|
315
318
|
}
|
|
316
319
|
const tender = state.delivery.data.tenderSnapshot;
|
|
317
|
-
const integration = state.delivery.data.integration.snapshot;
|
|
320
|
+
const integration = state.currentIntegration?.snapshot ?? state.delivery.data.integration.snapshot;
|
|
318
321
|
const target = await targetCustodyForClaimedIntegration(repository, state, integration);
|
|
319
322
|
if (sealedTree(expected, tender) === sealedTree(expected, integration) && target !== null) {
|
|
320
323
|
effects.push(await removeRefWithCustody(repository, ref, target.ref, target.oid));
|
|
@@ -337,7 +340,7 @@ async function reconcileTerminalManagedWorktree({ repository, channel, hooks, re
|
|
|
337
340
|
const expected = await terminalSealExpectations(channel, state);
|
|
338
341
|
acc.effects.push(await updateRef(primary, ref, state.delivery?.data.tenderSnapshot ?? state.coordinates.start));
|
|
339
342
|
if (state.delivery !== null) {
|
|
340
|
-
acc.effects.push(await updateRef(primary, pin, state.delivery.data.integration.snapshot));
|
|
343
|
+
acc.effects.push(await updateRef(primary, pin, state.currentIntegration?.snapshot ?? state.delivery.data.integration.snapshot));
|
|
341
344
|
}
|
|
342
345
|
if (retainTerminalWorktree === true)
|
|
343
346
|
return complete(acc.effects, acc.lag);
|
|
@@ -367,7 +370,7 @@ async function reconcileActiveManagedWorktree({ repository, hooks, retryHooks, p
|
|
|
367
370
|
if (hookLag !== null)
|
|
368
371
|
lag.push(hookLag);
|
|
369
372
|
effects.push(await (state.delivery
|
|
370
|
-
? await updateRef(repository, candidatePinRefFor(state.id), state.delivery.data.integration.snapshot)
|
|
373
|
+
? await updateRef(repository, candidatePinRefFor(state.id), state.currentIntegration?.snapshot ?? state.delivery.data.integration.snapshot)
|
|
371
374
|
: await removeRef(repository, candidatePinRefFor(state.id))));
|
|
372
375
|
return complete(effects, lag);
|
|
373
376
|
}
|
|
@@ -463,3 +466,34 @@ export async function reconcileBatch(repository, channel, contracts, options) {
|
|
|
463
466
|
}
|
|
464
467
|
return items;
|
|
465
468
|
}
|
|
469
|
+
/** Remove only validated Contract reconciliation lock residue. */
|
|
470
|
+
export async function nukeReconcileLocks(repository) {
|
|
471
|
+
const root = join(commonGitDirectory(repository), "keiyaku", "locks", "reconcile");
|
|
472
|
+
let first;
|
|
473
|
+
try {
|
|
474
|
+
first = await readdir(root, { withFileTypes: true });
|
|
475
|
+
}
|
|
476
|
+
catch (error) {
|
|
477
|
+
if (error.code === "ENOENT")
|
|
478
|
+
return;
|
|
479
|
+
throw error;
|
|
480
|
+
}
|
|
481
|
+
let paths = [];
|
|
482
|
+
for (const directory of first) {
|
|
483
|
+
if (!/^[0-9a-f]{2}$/u.test(directory.name) || !directory.isDirectory() || directory.isSymbolicLink()) {
|
|
484
|
+
throw new Error(`reconciliation lock custody is invalid: ${resolve(root, directory.name)}`);
|
|
485
|
+
}
|
|
486
|
+
const nested = resolve(root, directory.name);
|
|
487
|
+
const files = await readdir(nested, { withFileTypes: true });
|
|
488
|
+
for (const file of files) {
|
|
489
|
+
if (!/^[0-9a-f]{62}\.sqlite$/u.test(file.name) || !file.isFile() || file.isSymbolicLink()) {
|
|
490
|
+
throw new Error(`reconciliation lock custody is invalid: ${resolve(nested, file.name)}`);
|
|
491
|
+
}
|
|
492
|
+
paths.push(resolve(nested, file.name));
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
for (const path of paths) {
|
|
496
|
+
const held = await acquireSqliteTransactionLock({ path, mode: "immediate" });
|
|
497
|
+
held.close();
|
|
498
|
+
}
|
|
499
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type GitRepository } from "./process.js";
|
|
1
2
|
import { type TreeChange, type TreeEntry } from "./tree.js";
|
|
2
3
|
export type { TreeChange } from "./tree.js";
|
|
3
4
|
export declare const GIT_REF = "refs/heads/keiyaku-state";
|
|
@@ -19,14 +20,6 @@ export type GitRefAssertion = Readonly<{
|
|
|
19
20
|
readonly ref: string;
|
|
20
21
|
readonly oid: GitOid;
|
|
21
22
|
}>;
|
|
22
|
-
export type GitRepository = Readonly<{
|
|
23
|
-
/** The invocation's effective working directory, including a caller -C worktree. */
|
|
24
|
-
readonly effectiveCwd: string;
|
|
25
|
-
/** The canonical primary worktree root for this repository. */
|
|
26
|
-
readonly primaryWorktree: string;
|
|
27
|
-
/** The canonical common Git directory pinned when this capability is created. */
|
|
28
|
-
readonly commonDirectory: string;
|
|
29
|
-
}>;
|
|
30
23
|
export type GitSnapshot = Readonly<{
|
|
31
24
|
readonly commit: GitOid | null;
|
|
32
25
|
readonly tree: GitOid | null;
|
|
@@ -36,41 +29,21 @@ export declare class NoGitWorldError extends Error {
|
|
|
36
29
|
readonly path: string;
|
|
37
30
|
constructor(path: string);
|
|
38
31
|
}
|
|
39
|
-
export declare class GitPlumbingError extends Error {
|
|
40
|
-
readonly stdout: Buffer;
|
|
41
|
-
readonly stderr: Buffer;
|
|
42
|
-
readonly status: number | null;
|
|
43
|
-
readonly pid: number | null;
|
|
44
|
-
constructor(input: Readonly<{
|
|
45
|
-
stdout?: string | Uint8Array;
|
|
46
|
-
stderr: string | Uint8Array;
|
|
47
|
-
status: number | null;
|
|
48
|
-
message: string;
|
|
49
|
-
pid?: number | null;
|
|
50
|
-
}>);
|
|
51
|
-
}
|
|
52
32
|
export type RegisteredWorktree = Readonly<{
|
|
53
33
|
path: string;
|
|
54
34
|
branch: string | null;
|
|
55
35
|
}>;
|
|
56
36
|
export declare function registeredWorktrees(repository: GitRepository): Promise<readonly RegisteredWorktree[]>;
|
|
57
37
|
export declare function registeredWorktreePaths(repository: GitRepository): Promise<readonly string[]>;
|
|
58
|
-
export declare function repositoryAt(cwd: string): Promise<GitRepository>;
|
|
38
|
+
export declare function repositoryAt(cwd: string, gitPath?: string): Promise<GitRepository>;
|
|
59
39
|
export declare function commonGitDirectory(repository: GitRepository): string;
|
|
60
40
|
export declare function worktreeGitDirectory(repository: GitRepository, worktree: string): Promise<string>;
|
|
61
41
|
export declare function worktreeRoot(repository: GitRepository): Promise<string>;
|
|
62
|
-
export declare function runGit(repository: GitRepository, args: readonly string[], input?: string | Uint8Array): Promise<Buffer>;
|
|
63
|
-
export declare function consumeGitStdout(repository: GitRepository, args: readonly string[], consume: (chunk: Buffer) => void): Promise<void>;
|
|
64
|
-
export declare function runGitWithEnvironment(repository: GitRepository, args: readonly string[], input: string | Uint8Array | undefined, environment: NodeJS.ProcessEnv): Promise<Buffer>;
|
|
65
42
|
export declare function readRef(repository: GitRepository, ref: string): Promise<GitOid | null>;
|
|
66
43
|
export declare function readTreeEntries(repository: GitRepository, tree: GitOid): Promise<Map<string, TreeEntry>>;
|
|
67
44
|
export declare function readGit(repository: GitRepository): Promise<GitSnapshot>;
|
|
68
45
|
/** Read only the requested private Git paths from one immutable Git tree. */
|
|
69
46
|
export declare function readGitPaths(repository: GitRepository, requestedPaths: readonly string[]): Promise<GitSnapshot>;
|
|
70
|
-
/** Add paths from the same immutable Git tree without rereading its ref. */
|
|
71
|
-
export declare function extendGitPaths(repository: GitRepository, snapshot: GitSnapshot, requestedPaths: readonly string[]): Promise<GitSnapshot>;
|
|
72
|
-
/** Expand a targeted immutable snapshot to its complete already-pinned tree. */
|
|
73
|
-
export declare function expandGitSnapshot(repository: GitRepository, snapshot: GitSnapshot): Promise<GitSnapshot>;
|
|
74
47
|
export declare function writeBlob(repository: GitRepository, bytes: string | Uint8Array): Promise<GitOid>;
|
|
75
48
|
export declare function readBlob(repository: GitRepository, oid: GitOid): Promise<Buffer>;
|
|
76
49
|
/** Copy only the changed paths' tree ancestors, preserving untouched subtrees by object ID. */
|