@astrosheep/keiyaku 4.5.8 → 4.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +2 -2
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +15 -15
- package/build/src/akuma/akuma.d.ts +24 -4
- package/build/src/akuma/archetype.js +1 -1
- package/build/src/akuma/body.d.ts +2 -1
- package/build/src/akuma/body.js +7 -2
- package/build/src/akuma/call-request.js +1 -1
- package/build/src/akuma/heart/facts.d.ts +10 -0
- package/build/src/akuma/heart/facts.js +11 -0
- package/build/src/akuma/heart/index.d.ts +3 -2
- package/build/src/akuma/heart/index.js +4 -1
- package/build/src/akuma/projection.d.ts +63 -12
- package/build/src/akuma/projection.js +5 -11
- package/build/src/akuma/provider.js +8 -1
- package/build/src/akuma/providers/claude/events.d.ts +2 -2
- package/build/src/akuma/providers/claude/events.js +16 -3
- package/build/src/akuma/providers/codex-app-server/events.d.ts +2 -2
- package/build/src/akuma/providers/codex-app-server/events.js +25 -4
- package/build/src/akuma/providers/pi/index.js +55 -69
- package/build/src/akuma/request-lifecycle.d.ts +1 -1
- package/build/src/akuma/request-lifecycle.js +3 -1
- package/build/src/akuma/request-serve.d.ts +1 -1
- package/build/src/akuma/request-serve.js +4 -4
- package/build/src/akuma/turn-drive.js +8 -2
- package/build/src/body/amend.js +18 -19
- package/build/src/cli/commands/akuma.js +2 -2
- package/build/src/cli/commands/contract-invoke.js +27 -22
- package/build/src/cli/commands/contract.d.ts +6 -10
- package/build/src/cli/commands/contract.js +29 -11
- package/build/src/cli/commands/install.d.ts +1 -0
- package/build/src/cli/commands/install.js +2 -1
- package/build/src/cli/parse.js +23 -9
- package/build/src/cli/render/akuma-activity.d.ts +1 -1
- package/build/src/cli/render/akuma-activity.js +4 -3
- package/build/src/cli/render/akuma.js +1 -1
- package/build/src/cli/render/catalog.js +1 -1
- package/build/src/cli/render/contract.js +13 -0
- package/build/src/cli/render/kanshi-akuma.js +26 -5
- package/build/src/cli/render/kanshi.js +26 -3
- package/build/src/cli/render/terminal.d.ts +4 -1
- package/build/src/cli/render/terminal.js +12 -1
- package/build/src/cli/runtime.js +1 -1
- package/build/src/git/nuke.js +3 -3
- package/build/src/git/process.js +7 -4
- package/build/src/git/read-observation.js +1 -1
- package/build/src/git/reconcile.d.ts +2 -1
- package/build/src/git/reconcile.js +6 -0
- package/build/src/git/ref-migration.d.ts +22 -0
- package/build/src/git/ref-migration.js +55 -0
- package/build/src/git/repository.d.ts +4 -4
- package/build/src/git/repository.js +8 -8
- package/build/src/library/audit.d.ts +13 -5
- package/build/src/library/audit.js +9 -21
- package/build/src/library/composition.d.ts +41 -27
- package/build/src/library/composition.js +3 -3
- package/build/src/library/contract-forwarding-reconciliation-result.d.ts +17 -11
- package/build/src/library/contract-forwarding-reconciliation-result.js +11 -2
- package/build/src/library/contract-forwarding-result.d.ts +1628 -3887
- package/build/src/library/contract-forwarding-result.js +1 -1
- package/build/src/library/contract-forwarding.d.ts +12 -13
- package/build/src/library/contract-forwarding.js +17 -28
- package/build/src/library/contract-handle.d.ts +3 -1
- package/build/src/library/contract-handle.js +23 -22
- package/build/src/library/contract-operations.d.ts +61 -893
- package/build/src/library/contract-operations.js +2 -3
- package/build/src/library/contract-types.d.ts +7 -3
- package/build/src/library/contract.d.ts +12 -4
- package/build/src/library/contract.js +21 -6
- package/build/src/library/fleet-result.d.ts +138 -12
- package/build/src/library/fleet-result.js +2 -0
- package/build/src/library/input.d.ts +1 -1
- package/build/src/library/input.js +7 -1
- package/build/src/library/keiyaku.d.ts +44 -27
- package/build/src/library/keiyaku.js +6 -1
- package/build/src/runtime/proc/run.d.ts +1 -0
- package/build/src/runtime/proc/run.js +25 -5
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/package.json +1 -1
|
@@ -68,25 +68,14 @@ async function piCreateOptions(sdk, input) {
|
|
|
68
68
|
...(customTools === undefined ? {} : { customTools }),
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
|
-
async function createPiSession(sdk, execution, input
|
|
71
|
+
async function createPiSession(sdk, execution, input) {
|
|
72
72
|
const setup = piCreateOptions(sdk, input).then(async (options) => {
|
|
73
73
|
if (execution.config !== undefined) {
|
|
74
74
|
throw new TypeError("Pi provider config cannot be consumed by native CreateAgentSessionOptions");
|
|
75
75
|
}
|
|
76
76
|
return await sdk.createAgentSession(options);
|
|
77
77
|
});
|
|
78
|
-
|
|
79
|
-
if (signal.aborted) {
|
|
80
|
-
await created.session.dispose();
|
|
81
|
-
signal.throwIfAborted();
|
|
82
|
-
}
|
|
83
|
-
return created;
|
|
84
|
-
}
|
|
85
|
-
function forceDisposePi(dispose, settle, setAborting) {
|
|
86
|
-
setAborting();
|
|
87
|
-
dispose();
|
|
88
|
-
settle({ kind: "failed", diagnostic: "Pi session force-disposed" });
|
|
89
|
-
return Promise.resolve();
|
|
78
|
+
return await setup;
|
|
90
79
|
}
|
|
91
80
|
async function runPiPrompt(native, input, events, state, settle) {
|
|
92
81
|
try {
|
|
@@ -115,81 +104,80 @@ async function runPiPrompt(native, input, events, state, settle) {
|
|
|
115
104
|
}
|
|
116
105
|
}
|
|
117
106
|
async function drivePi(sdk, execution, input, signal, custody) {
|
|
118
|
-
const created = await createPiSession(sdk, execution, input
|
|
107
|
+
const created = await createPiSession(sdk, execution, input);
|
|
119
108
|
const native = created.session;
|
|
120
|
-
let retired = false;
|
|
121
109
|
let settleRetired;
|
|
122
|
-
|
|
110
|
+
let failRetired;
|
|
111
|
+
const closed = new Promise((resolve, reject) => {
|
|
123
112
|
settleRetired = resolve;
|
|
113
|
+
failRetired = reject;
|
|
124
114
|
});
|
|
125
|
-
custody?.own({
|
|
126
|
-
closed,
|
|
127
|
-
abort: async () => {
|
|
128
|
-
native.dispose();
|
|
129
|
-
retired = true;
|
|
130
|
-
settleRetired();
|
|
131
|
-
},
|
|
132
|
-
forceDispose: async () => {
|
|
133
|
-
native.dispose();
|
|
134
|
-
retired = true;
|
|
135
|
-
settleRetired();
|
|
136
|
-
},
|
|
137
|
-
});
|
|
138
|
-
if (signal.aborted) {
|
|
139
|
-
native.dispose();
|
|
140
|
-
signal.throwIfAborted();
|
|
141
|
-
}
|
|
142
|
-
if (native.sessionFile === undefined || native.sessionFile.trim().length === 0) {
|
|
143
|
-
native.dispose();
|
|
144
|
-
throw new Error("Pi session admitted without sessionFile");
|
|
145
|
-
}
|
|
146
115
|
const events = new AgentEventChannel();
|
|
147
116
|
const eventState = { answer: "", assistantSeen: false, tools: new Map() };
|
|
148
117
|
const state = {
|
|
149
118
|
terminalFailure: null,
|
|
150
|
-
disposed: false,
|
|
151
119
|
aborting: false,
|
|
152
120
|
settled: false,
|
|
153
121
|
};
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
122
|
+
let settleCompletion;
|
|
123
|
+
const completion = new Promise((resolve) => {
|
|
124
|
+
settleCompletion = resolve;
|
|
125
|
+
});
|
|
126
|
+
const unsubscribe = native.subscribe((event) => {
|
|
127
|
+
if (event.type === "agent_end" && !event.willRetry)
|
|
128
|
+
state.terminalFailure = piTerminalFailure(event.messages);
|
|
129
|
+
for (const translated of translatePiEvent(event, eventState))
|
|
130
|
+
events.emit(translated);
|
|
131
|
+
});
|
|
132
|
+
const settle = (result) => {
|
|
133
|
+
if (state.settled)
|
|
134
|
+
return closed;
|
|
135
|
+
state.settled = true;
|
|
136
|
+
let failure;
|
|
158
137
|
try {
|
|
159
138
|
unsubscribe();
|
|
160
139
|
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
failure = error;
|
|
142
|
+
}
|
|
161
143
|
finally {
|
|
162
144
|
try {
|
|
163
|
-
|
|
164
|
-
if (!retired) {
|
|
165
|
-
retired = true;
|
|
166
|
-
settleRetired();
|
|
167
|
-
}
|
|
145
|
+
events.end();
|
|
168
146
|
}
|
|
169
147
|
finally {
|
|
170
|
-
|
|
148
|
+
settleCompletion(result);
|
|
149
|
+
try {
|
|
150
|
+
native.dispose();
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
failure ??= error;
|
|
154
|
+
}
|
|
171
155
|
}
|
|
172
156
|
}
|
|
157
|
+
if (failure === undefined)
|
|
158
|
+
settleRetired();
|
|
159
|
+
else
|
|
160
|
+
failRetired(failure);
|
|
161
|
+
return closed;
|
|
173
162
|
};
|
|
174
|
-
const
|
|
175
|
-
if (
|
|
176
|
-
state.
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
});
|
|
163
|
+
const forceDispose = async () => {
|
|
164
|
+
if (!state.settled)
|
|
165
|
+
state.aborting = true;
|
|
166
|
+
await settle({ kind: "failed", diagnostic: "Pi session force-disposed" });
|
|
167
|
+
};
|
|
168
|
+
custody?.own({ closed, abort: forceDispose, forceDispose });
|
|
169
|
+
if (signal.aborted) {
|
|
170
|
+
await settle({ kind: "failed", diagnostic: "Pi session aborted" });
|
|
171
|
+
signal.throwIfAborted();
|
|
172
|
+
}
|
|
173
|
+
if (native.sessionFile === undefined || native.sessionFile.trim().length === 0) {
|
|
174
|
+
await settle({ kind: "failed", diagnostic: "Pi session admitted without sessionFile" });
|
|
175
|
+
throw new Error("Pi session admitted without sessionFile");
|
|
176
|
+
}
|
|
180
177
|
events.emit({ type: "session", coordinate: { sessionFile: native.sessionFile, sessionId: native.sessionId } });
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
settleCompletion = resolve;
|
|
178
|
+
void runPiPrompt(native, input, eventState, state, (result) => {
|
|
179
|
+
void settle(result);
|
|
184
180
|
});
|
|
185
|
-
const settle = (result) => {
|
|
186
|
-
if (state.settled)
|
|
187
|
-
return;
|
|
188
|
-
state.settled = true;
|
|
189
|
-
dispose();
|
|
190
|
-
settleCompletion(result);
|
|
191
|
-
};
|
|
192
|
-
void runPiPrompt(native, input, eventState, state, settle);
|
|
193
181
|
return {
|
|
194
182
|
admission: { fence: native.sessionId },
|
|
195
183
|
events,
|
|
@@ -205,13 +193,11 @@ async function drivePi(sdk, execution, input, signal, custody) {
|
|
|
205
193
|
catch {
|
|
206
194
|
/* prompt settlement still proves local cleanup */
|
|
207
195
|
}
|
|
208
|
-
settle({ kind: "failed", diagnostic: "Pi session aborted" });
|
|
196
|
+
await settle({ kind: "failed", diagnostic: "Pi session aborted" });
|
|
209
197
|
})();
|
|
210
198
|
return state.abortRequest;
|
|
211
199
|
},
|
|
212
|
-
forceDispose
|
|
213
|
-
state.aborting = true;
|
|
214
|
-
}),
|
|
200
|
+
forceDispose,
|
|
215
201
|
};
|
|
216
202
|
}
|
|
217
203
|
function piSessionFile(coordinate) {
|
|
@@ -16,7 +16,7 @@ type ServeClaim = (input: PumpInput & Readonly<{
|
|
|
16
16
|
claim: RequestEnvelope;
|
|
17
17
|
signal: AbortSignal;
|
|
18
18
|
admissionOpen(): boolean;
|
|
19
|
-
}>) => Promise<
|
|
19
|
+
}>) => Promise<boolean>;
|
|
20
20
|
export declare class BodyRequestPump {
|
|
21
21
|
private readonly input;
|
|
22
22
|
private readonly serveClaim;
|
|
@@ -52,7 +52,7 @@ export class BodyRequestPump {
|
|
|
52
52
|
continue;
|
|
53
53
|
}
|
|
54
54
|
if (!this.admissionClosed) {
|
|
55
|
-
await this.serveClaim({
|
|
55
|
+
const served = await this.serveClaim({
|
|
56
56
|
directory: this.directory,
|
|
57
57
|
transportId,
|
|
58
58
|
claim,
|
|
@@ -60,6 +60,8 @@ export class BodyRequestPump {
|
|
|
60
60
|
signal: this.executionSignal.signal,
|
|
61
61
|
admissionOpen: () => !this.admissionClosed,
|
|
62
62
|
});
|
|
63
|
+
if (!served)
|
|
64
|
+
await rm(path, { force: true });
|
|
63
65
|
}
|
|
64
66
|
this.handled.add(transportId);
|
|
65
67
|
}
|
|
@@ -11,7 +11,7 @@ export type ServeInput = Omit<PumpInput, "bodySequence"> & Readonly<{
|
|
|
11
11
|
claim: RequestEnvelope;
|
|
12
12
|
admissionOpen(): boolean;
|
|
13
13
|
}>;
|
|
14
|
-
export declare function serveRequest(input: ServeInput): Promise<
|
|
14
|
+
export declare function serveRequest(input: ServeInput): Promise<boolean>;
|
|
15
15
|
export declare class BodyRequestPump extends LifecycleBodyRequestPump {
|
|
16
16
|
static open(input: PumpInput): Promise<BodyRequestPump>;
|
|
17
17
|
}
|
|
@@ -112,14 +112,13 @@ export async function serveRequest(input) {
|
|
|
112
112
|
state: "refused",
|
|
113
113
|
diagnostic: `request action ${input.claim.action} is not registered`,
|
|
114
114
|
});
|
|
115
|
-
return;
|
|
115
|
+
return true;
|
|
116
116
|
}
|
|
117
|
-
|
|
118
|
-
return;
|
|
117
|
+
return await serveCommand(input, command);
|
|
119
118
|
}
|
|
120
119
|
async function serveTransportClaim(input) {
|
|
121
120
|
try {
|
|
122
|
-
await serveRequest(input);
|
|
121
|
+
return await serveRequest(input);
|
|
123
122
|
}
|
|
124
123
|
catch (error) {
|
|
125
124
|
if (!isRequestInputConflict(error))
|
|
@@ -130,6 +129,7 @@ async function serveTransportClaim(input) {
|
|
|
130
129
|
state: "refused",
|
|
131
130
|
diagnostic: error.message,
|
|
132
131
|
});
|
|
132
|
+
return true;
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
135
|
export class BodyRequestPump extends LifecycleBodyRequestPump {
|
|
@@ -106,8 +106,9 @@ async function startTurnDrive(input) {
|
|
|
106
106
|
const attempt = session === undefined
|
|
107
107
|
? input.adapter.start({ ...driveInput, session: { kind: "fresh" } })
|
|
108
108
|
: input.adapter.resume({ ...driveInput, session: { kind: "resume", coordinate: session } });
|
|
109
|
+
const custodyFailure = observeFailure(attempt.closed);
|
|
109
110
|
try {
|
|
110
|
-
const selected = await Promise.race([attempt.result, requests.failure]);
|
|
111
|
+
const selected = await Promise.race([attempt.result, requests.failure, custodyFailure]);
|
|
111
112
|
if (input.supervisor.signal.aborted) {
|
|
112
113
|
try {
|
|
113
114
|
const retirement = await retireProviderCustody(input, turn.sequence, attempt);
|
|
@@ -132,6 +133,7 @@ async function startTurnDrive(input) {
|
|
|
132
133
|
return {
|
|
133
134
|
turnSequence: turn.sequence,
|
|
134
135
|
attempt,
|
|
136
|
+
custodyFailure,
|
|
135
137
|
drive: selected,
|
|
136
138
|
requests,
|
|
137
139
|
cwd,
|
|
@@ -212,8 +214,11 @@ function pumpReceipts(writers) {
|
|
|
212
214
|
}
|
|
213
215
|
})();
|
|
214
216
|
}
|
|
217
|
+
function observeFailure(settlement) {
|
|
218
|
+
return settlement.then(() => new Promise(() => { }), (error) => Promise.reject(error));
|
|
219
|
+
}
|
|
215
220
|
function observeReceiptFailure(receiptPump) {
|
|
216
|
-
return receiptPump
|
|
221
|
+
return observeFailure(receiptPump);
|
|
217
222
|
}
|
|
218
223
|
function observeCompletionFailure(drive) {
|
|
219
224
|
return drive.completion.then(() => new Promise(() => { }), (error) => ({ kind: "completion-failed", error }));
|
|
@@ -306,6 +311,7 @@ async function consumeTurnDrive(input, active) {
|
|
|
306
311
|
receiptFailure,
|
|
307
312
|
requests.failure,
|
|
308
313
|
completionFailure,
|
|
314
|
+
active.custodyFailure,
|
|
309
315
|
]);
|
|
310
316
|
if (next.kind === "completion-failed") {
|
|
311
317
|
requests.stopAdmission();
|
package/build/src/body/amend.js
CHANGED
|
@@ -22,10 +22,11 @@ function operationSections(document) {
|
|
|
22
22
|
refusal("amend operations contain bytes outside H2 sections");
|
|
23
23
|
}
|
|
24
24
|
return sections(document).map((section) => {
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
const title = section.title.trim();
|
|
26
|
+
const match = /^(Add|Update|Replace|Append|Remove):[ ]+(.+)$/.exec(title);
|
|
27
|
+
return match
|
|
28
|
+
? { kind: match[1], target: match[2].trim(), section }
|
|
29
|
+
: { kind: "Set", target: title, section };
|
|
29
30
|
});
|
|
30
31
|
}
|
|
31
32
|
function prose(document, section, label) {
|
|
@@ -112,7 +113,7 @@ function completeBody(body) {
|
|
|
112
113
|
objective: body.objective,
|
|
113
114
|
design: body.design,
|
|
114
115
|
region: body.region,
|
|
115
|
-
criteria: body.criteria
|
|
116
|
+
criteria: body.criteria,
|
|
116
117
|
verification: body.verification,
|
|
117
118
|
extensions: body.extensions.filter((extension) => extension !== undefined),
|
|
118
119
|
};
|
|
@@ -137,15 +138,6 @@ function alteredText(body, target, value) {
|
|
|
137
138
|
}
|
|
138
139
|
function applyRemove(body, operation, document) {
|
|
139
140
|
requireEmpty(document, operation.section);
|
|
140
|
-
if (operation.target.startsWith("Criterion ")) {
|
|
141
|
-
const title = operation.target.slice("Criterion ".length);
|
|
142
|
-
const index = criterionIndex(body, title);
|
|
143
|
-
if (index < 0)
|
|
144
|
-
refusal(`unknown criterion '${title}'`);
|
|
145
|
-
body.criteria[index] = undefined;
|
|
146
|
-
body.criterionIndexes.delete(normalizeTitle(title));
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
141
|
const index = extensionIndex(body, operation.target);
|
|
150
142
|
if (index < 0)
|
|
151
143
|
refusal(`unknown extension '${operation.target}'`);
|
|
@@ -236,6 +228,13 @@ function applyReplace(body, operation, document) {
|
|
|
236
228
|
const extension = body.extensions[index];
|
|
237
229
|
body.extensions[index] = { ...extension, content: prose(document, operation.section, "extension") };
|
|
238
230
|
}
|
|
231
|
+
function applySet(body, operation, document) {
|
|
232
|
+
if (contractSectionName(operation.target) !== null || extensionIndex(body, operation.target) >= 0) {
|
|
233
|
+
applyReplace(body, operation, document);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
applyAdd(body, operation, document);
|
|
237
|
+
}
|
|
239
238
|
function applyOperation(body, operation, document) {
|
|
240
239
|
switch (operation.kind) {
|
|
241
240
|
case "Add":
|
|
@@ -253,13 +252,13 @@ function applyOperation(body, operation, document) {
|
|
|
253
252
|
case "Remove":
|
|
254
253
|
applyRemove(body, operation, document);
|
|
255
254
|
return;
|
|
255
|
+
case "Set":
|
|
256
|
+
applySet(body, operation, document);
|
|
257
|
+
return;
|
|
256
258
|
}
|
|
257
259
|
}
|
|
258
260
|
function operationKey(operation) {
|
|
259
|
-
|
|
260
|
-
? `Criterion ${normalizeTitle(operation.target.slice("Criterion ".length))}`
|
|
261
|
-
: operation.target;
|
|
262
|
-
return `${operation.kind}:${target}`;
|
|
261
|
+
return `${operation.kind}:${operation.target}`;
|
|
263
262
|
}
|
|
264
263
|
function apply(source, current) {
|
|
265
264
|
const document = parseToAST(source);
|
|
@@ -274,7 +273,7 @@ function apply(source, current) {
|
|
|
274
273
|
if (seen.has(key))
|
|
275
274
|
refusal(`duplicate amend operation '${key}'`);
|
|
276
275
|
seen.add(key);
|
|
277
|
-
changed.add(normalizeTitle(operation.target
|
|
276
|
+
changed.add(normalizeTitle(operation.target));
|
|
278
277
|
applyOperation(body, operation, document);
|
|
279
278
|
}
|
|
280
279
|
return { body: completeBody(body), changed };
|
|
@@ -25,7 +25,7 @@ const AKUMA_COMMAND_SPECS = {
|
|
|
25
25
|
"--contract dispatches the born Akuma to that Contract.",
|
|
26
26
|
"--alias assigns the world-local @name selector to the born Akuma.",
|
|
27
27
|
"--readonly adds the one-way read-only birth restriction.",
|
|
28
|
-
"Repeated --allowed adds actions to the
|
|
28
|
+
"Repeated --allowed adds actions to the selected Akuma's defaults.",
|
|
29
29
|
"With --contract, Dispatch succeeds first. If @name exists, the alias then moves.",
|
|
30
30
|
].join("\n"),
|
|
31
31
|
},
|
|
@@ -76,7 +76,7 @@ export function isParsedAkumaCommand(command) {
|
|
|
76
76
|
return isAkumaAction(command.command) && !("contract" in command && command.command === "history");
|
|
77
77
|
}
|
|
78
78
|
export function renderAkumaRootRows() {
|
|
79
|
-
return Object.entries(AKUMA_COMMAND_SPECS).map(([action, spec]) => `
|
|
79
|
+
return Object.entries(AKUMA_COMMAND_SPECS).map(([action, spec]) => ` ${action.padEnd(10)} ${spec.purpose}`);
|
|
80
80
|
}
|
|
81
81
|
export function renderAkumaHelp(action) {
|
|
82
82
|
const spec = AKUMA_COMMAND_SPECS[action];
|
|
@@ -26,13 +26,12 @@ async function selectedGitPolicy(value) {
|
|
|
26
26
|
const { requireBranchesToBeUpToDateFrom, SettingsError } = await import("../../library/configuration.js");
|
|
27
27
|
return consumeSettings(() => requireBranchesToBeUpToDateFrom({ settings: value }), SettingsError);
|
|
28
28
|
}
|
|
29
|
-
async function selectContract(repo, selector, scope,
|
|
29
|
+
async function selectContract(repo, selector, scope, library) {
|
|
30
30
|
const { contractFromInput, resolveContextualContract } = await import("../selectors.js");
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return contractFromInput(repo, id, execution);
|
|
31
|
+
const id = selector !== undefined && !selector.startsWith("@")
|
|
32
|
+
? contractFromInput(repo, selector).id
|
|
33
|
+
: resolveContextualContract(await library.list({ repo }), selector, scope);
|
|
34
|
+
return { id, contract: library.of({ repo, id }) };
|
|
36
35
|
}
|
|
37
36
|
async function bindDraftReceipt(establishWorld, markdown) {
|
|
38
37
|
const { preserveBindDraft } = await import("../draft.js");
|
|
@@ -99,22 +98,19 @@ function deliverRefusal(refusal) {
|
|
|
99
98
|
const submodules = "submodules" in refusal && Array.isArray(refusal.submodules) ? refusal.submodules : [];
|
|
100
99
|
return { ...refusal, option: { flag: "--include-dirty", available: submodules.length === 0 } };
|
|
101
100
|
}
|
|
102
|
-
async function existingSeat(input, parsed) {
|
|
103
|
-
const { repo, edge, scope, hooks
|
|
104
|
-
const { id, contract } = await selectContract(repo, parsed.contract, scope,
|
|
105
|
-
const actor = actorFromEdge(parsed.actor, edge.environment);
|
|
101
|
+
async function existingSeat(input, parsed, library) {
|
|
102
|
+
const { repo, edge, scope, hooks } = input;
|
|
103
|
+
const { id, contract } = await selectContract(repo, parsed.contract, scope, library);
|
|
104
|
+
const actor = "actor" in parsed ? actorFromEdge(parsed.actor, edge.environment) : undefined;
|
|
106
105
|
return { contract, id, ...(actor === undefined ? {} : { actor }), ...(hooks === undefined ? {} : { hooks }) };
|
|
107
106
|
}
|
|
108
|
-
async function invokeDeliver(parsed, seat
|
|
107
|
+
async function invokeDeliver(parsed, seat) {
|
|
109
108
|
const { acceptedDeliver } = await import("../accepted.js");
|
|
110
109
|
try {
|
|
111
110
|
const delivered = await seat.contract.deliver({
|
|
112
|
-
...(seat.actor === undefined ? {} : { actor: seat.actor }),
|
|
113
111
|
...(parsed.message === undefined ? {} : { message: parsed.message }),
|
|
114
|
-
requireBranchesToBeUpToDate,
|
|
115
112
|
includeDirty: parsed.includeDirty,
|
|
116
113
|
materializeConflict: parsed.materializeConflict,
|
|
117
|
-
...(seat.hooks === undefined ? {} : { hooks: seat.hooks }),
|
|
118
114
|
});
|
|
119
115
|
if (!("facts" in delivered))
|
|
120
116
|
return delivered;
|
|
@@ -135,16 +131,29 @@ async function invokeReview(parsed, seat, readStdin) {
|
|
|
135
131
|
const { acceptedReview, resultFromMutationCall } = await import("../accepted.js");
|
|
136
132
|
return resultFromMutationCall("review", () => seat.contract.review({
|
|
137
133
|
verdict: parsed.verdict,
|
|
138
|
-
...(seat.actor === undefined ? {} : { actor: seat.actor }),
|
|
139
134
|
...(summary === undefined ? {} : { summary }),
|
|
140
|
-
...(seat.hooks === undefined ? {} : { hooks: seat.hooks }),
|
|
141
135
|
}), (result) => acceptedReview(result, seat.id), { coordinate: seat.id });
|
|
142
136
|
}
|
|
137
|
+
async function contractLibrary(input, parsed) {
|
|
138
|
+
const { configuration, edge, hooks } = input;
|
|
139
|
+
if (input.execution.channel.kind !== "local" || !["audit", "deliver", "review"].includes(parsed.command)) {
|
|
140
|
+
const { Keiyaku } = await import("../../library/keiyaku.js");
|
|
141
|
+
return Keiyaku.withExecution({ execution: input.execution });
|
|
142
|
+
}
|
|
143
|
+
const requireBranchesToBeUpToDate = parsed.command !== "review" && configuration !== undefined ? await selectedGitPolicy(configuration) : false;
|
|
144
|
+
const actor = actorFromEdge(undefined, edge.environment);
|
|
145
|
+
const { Keiyaku } = await import("../../library/keiyaku.js");
|
|
146
|
+
return Keiyaku.withLocal({
|
|
147
|
+
...(actor === undefined ? {} : { actor }),
|
|
148
|
+
...(hooks === undefined ? {} : { hooks }),
|
|
149
|
+
requireBranchesToBeUpToDate,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
143
152
|
export async function invokeContractMutation(input) {
|
|
144
153
|
const { parsed, repo, edge, configuration, hooks } = input;
|
|
145
154
|
if (parsed.command === "bind")
|
|
146
155
|
return invokeBind(input);
|
|
147
|
-
const seat = await existingSeat(input, parsed);
|
|
156
|
+
const seat = await existingSeat(input, parsed, await contractLibrary(input, parsed));
|
|
148
157
|
const { id, contract, actor } = seat;
|
|
149
158
|
switch (parsed.command) {
|
|
150
159
|
case "amend": {
|
|
@@ -165,7 +174,7 @@ export async function invokeContractMutation(input) {
|
|
|
165
174
|
}), (result) => acceptedAmend(result, id), { coordinate: id });
|
|
166
175
|
}
|
|
167
176
|
case "deliver":
|
|
168
|
-
return invokeDeliver(parsed, seat
|
|
177
|
+
return invokeDeliver(parsed, seat);
|
|
169
178
|
case "review":
|
|
170
179
|
return invokeReview(parsed, seat, edge.readStdin);
|
|
171
180
|
case "arc": {
|
|
@@ -186,14 +195,10 @@ export async function invokeContractMutation(input) {
|
|
|
186
195
|
}), (result) => acceptedAbandon(result, id), { coordinate: id });
|
|
187
196
|
}
|
|
188
197
|
case "audit": {
|
|
189
|
-
const requireBranchesToBeUpToDate = configuration === undefined ? false : await selectedGitPolicy(configuration);
|
|
190
198
|
const { acceptedAudit, resultFromMutationCall } = await import("../accepted.js");
|
|
191
199
|
return resultFromMutationCall("audit", () => contract.audit({
|
|
192
|
-
...(actor === undefined ? {} : { actor }),
|
|
193
200
|
includeDirty: parsed.includeDirty,
|
|
194
201
|
showDiff: parsed.showDiff,
|
|
195
|
-
requireBranchesToBeUpToDate,
|
|
196
|
-
...(hooks === undefined ? {} : { hooks }),
|
|
197
202
|
}), (result) => acceptedAudit(result, id), { coordinate: id });
|
|
198
203
|
}
|
|
199
204
|
}
|
|
@@ -30,14 +30,14 @@ export type ParsedAmend = Output & Actor & Readonly<{
|
|
|
30
30
|
gates?: readonly string[];
|
|
31
31
|
stdin?: true;
|
|
32
32
|
}>;
|
|
33
|
-
export type ParsedDeliver = Output &
|
|
33
|
+
export type ParsedDeliver = Output & Readonly<{
|
|
34
34
|
command: "deliver";
|
|
35
35
|
contract?: string;
|
|
36
36
|
message?: string;
|
|
37
37
|
includeDirty: boolean;
|
|
38
38
|
materializeConflict: boolean;
|
|
39
39
|
}>;
|
|
40
|
-
export type ParsedReview = Output &
|
|
40
|
+
export type ParsedReview = Output & Readonly<{
|
|
41
41
|
command: "review";
|
|
42
42
|
contract?: string;
|
|
43
43
|
verdict: "satisfied" | "unsatisfied";
|
|
@@ -72,7 +72,6 @@ export type ParsedAudit = Output & Readonly<{
|
|
|
72
72
|
contract?: string;
|
|
73
73
|
includeDirty: boolean;
|
|
74
74
|
showDiff: boolean;
|
|
75
|
-
actor?: string;
|
|
76
75
|
}>;
|
|
77
76
|
export type ParsedReconcile = Output & Readonly<{
|
|
78
77
|
command: "reconcile";
|
|
@@ -129,13 +128,12 @@ export declare const CONTRACT_COMMAND_SPECS: {
|
|
|
129
128
|
readonly positional: "optional";
|
|
130
129
|
readonly stdin: "none";
|
|
131
130
|
readonly flags: {
|
|
132
|
-
readonly actor: "value";
|
|
133
131
|
readonly message: "value";
|
|
134
132
|
readonly "include-dirty": "boolean";
|
|
135
133
|
readonly "materialize-conflict": "boolean";
|
|
136
134
|
readonly json: "boolean";
|
|
137
135
|
};
|
|
138
|
-
readonly usage: "deliver [<contract>|@<contract>] [--message <text>] [--include-dirty] [--materialize-conflict] [--
|
|
136
|
+
readonly usage: "deliver [<contract>|@<contract>] [--message <text>] [--include-dirty] [--materialize-conflict] [--json]";
|
|
139
137
|
readonly purpose: "Deliver one Contract candidate from the appointed worktree.";
|
|
140
138
|
readonly details: string;
|
|
141
139
|
};
|
|
@@ -143,13 +141,12 @@ export declare const CONTRACT_COMMAND_SPECS: {
|
|
|
143
141
|
readonly positional: "optional";
|
|
144
142
|
readonly stdin: "optional";
|
|
145
143
|
readonly flags: {
|
|
146
|
-
readonly actor: "value";
|
|
147
144
|
readonly satisfied: "boolean";
|
|
148
145
|
readonly unsatisfied: "boolean";
|
|
149
146
|
readonly summary: "value";
|
|
150
147
|
readonly json: "boolean";
|
|
151
148
|
};
|
|
152
|
-
readonly usage: "review [<contract>|@<contract>] (--satisfied | --unsatisfied) (--summary <text> | -) [--
|
|
149
|
+
readonly usage: "review [<contract>|@<contract>] (--satisfied | --unsatisfied) (--summary <text> | -) [--json]";
|
|
153
150
|
readonly purpose: "Record one review verdict.";
|
|
154
151
|
};
|
|
155
152
|
readonly arc: {
|
|
@@ -206,10 +203,9 @@ export declare const CONTRACT_COMMAND_SPECS: {
|
|
|
206
203
|
readonly flags: {
|
|
207
204
|
readonly "include-dirty": "boolean";
|
|
208
205
|
readonly diff: "boolean";
|
|
209
|
-
readonly actor: "value";
|
|
210
206
|
readonly json: "boolean";
|
|
211
207
|
};
|
|
212
|
-
readonly usage: "audit [<contract>|@<contract>] [--include-dirty] [--diff] [--
|
|
208
|
+
readonly usage: "audit [<contract>|@<contract>] [--include-dirty] [--diff] [--json]";
|
|
213
209
|
readonly purpose: "Ask what candidate preparation, Verification, and target placement would do.";
|
|
214
210
|
};
|
|
215
211
|
readonly reconcile: {
|
|
@@ -239,7 +235,7 @@ export declare const CONTRACT_COMMAND_SPECS: {
|
|
|
239
235
|
readonly json: "boolean";
|
|
240
236
|
};
|
|
241
237
|
readonly usage: "settings [--json]";
|
|
242
|
-
readonly purpose: "
|
|
238
|
+
readonly purpose: "Show effective Settings (user + project, read-only)";
|
|
243
239
|
};
|
|
244
240
|
readonly region: {
|
|
245
241
|
readonly positional: "optional";
|