@astrosheep/keiyaku 4.6.11 → 4.6.13
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/plugins/claude/skills/keiyaku/SKILL.md +3 -1
- package/build/plugins/claude/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/claude/skills/keiyaku-bind/SKILL.md +3 -2
- package/build/plugins/claude/skills/keiyaku-workflow/SKILL.md +9 -8
- package/build/plugins/codex/skills/keiyaku/SKILL.md +3 -1
- package/build/plugins/codex/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/codex/skills/keiyaku-bind/SKILL.md +3 -2
- package/build/plugins/codex/skills/keiyaku-workflow/SKILL.md +9 -8
- package/build/plugins/opencode/skills/keiyaku/SKILL.md +3 -1
- package/build/plugins/opencode/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/opencode/skills/keiyaku-bind/SKILL.md +3 -2
- package/build/plugins/opencode/skills/keiyaku-workflow/SKILL.md +9 -8
- package/build/skills/keiyaku/SKILL.md +3 -1
- package/build/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/skills/keiyaku-bind/SKILL.md +3 -2
- package/build/skills/keiyaku-workflow/SKILL.md +9 -8
- package/build/src/akuma/akuma-errors.d.ts +5 -0
- package/build/src/akuma/akuma-errors.js +9 -0
- package/build/src/akuma/akuma-owner.d.ts +14 -19
- package/build/src/akuma/akuma-owner.js +56 -54
- package/build/src/akuma/akuma-selection-execution.d.ts +5 -4
- package/build/src/akuma/akuma-selection-execution.js +59 -17
- package/build/src/akuma/akuma.d.ts +1 -2
- package/build/src/akuma/allowed.d.ts +2 -3
- package/build/src/akuma/allowed.js +1 -3
- package/build/src/akuma/body.js +17 -7
- package/build/src/akuma/call-initial-tell.d.ts +18 -0
- package/build/src/akuma/call-initial-tell.js +18 -0
- package/build/src/akuma/call-request.d.ts +20 -4
- package/build/src/akuma/heart/facts.d.ts +13 -0
- package/build/src/akuma/heart/facts.js +6 -0
- package/build/src/akuma/heart/index.d.ts +29 -14
- package/build/src/akuma/heart/index.js +75 -29
- package/build/src/akuma/heart/rows.d.ts +9 -2
- package/build/src/akuma/heart/rows.js +72 -11
- package/build/src/akuma/heart/storage.d.ts +2 -8
- package/build/src/akuma/heart/storage.js +13 -13
- package/build/src/akuma/heart/tells.d.ts +3 -1
- package/build/src/akuma/heart/tells.js +18 -2
- package/build/src/akuma/provider.d.ts +2 -4
- package/build/src/akuma/provider.js +29 -6
- package/build/src/akuma/providers/acp/core.js +23 -21
- package/build/src/akuma/providers/claude/index.js +0 -8
- package/build/src/akuma/providers/codex-app-server/index.js +9 -8
- package/build/src/akuma/providers/execution-environment.d.ts +1 -1
- package/build/src/akuma/providers/execution-environment.js +1 -0
- package/build/src/akuma/providers/opencode-sdk/events.js +111 -81
- package/build/src/akuma/providers/opencode-sdk/index.js +179 -150
- package/build/src/akuma/providers/opencode-sdk/native-http.js +7 -3
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +5 -3
- package/build/src/akuma/providers/opencode-sdk/session.js +32 -27
- package/build/src/akuma/providers/paseo/index.js +0 -2
- package/build/src/akuma/providers/pi/index.js +23 -20
- package/build/src/akuma/selection-observation.d.ts +78 -9
- package/build/src/akuma/selection-owner-port.d.ts +2 -1
- package/build/src/akuma/selection-owner-port.js +6 -1
- package/build/src/akuma/selection-request.d.ts +1 -1
- package/build/src/akuma/selection-request.js +8 -3
- package/build/src/akuma/turn-drive.js +79 -48
- package/build/src/akuma-body.js +5 -3
- package/build/src/cli/commands/akuma-grammar.js +2 -2
- package/build/src/cli/commands/akuma.js +24 -16
- package/build/src/cli/commands/contract-grammar.d.ts +3 -7
- package/build/src/cli/commands/contract-grammar.js +12 -10
- package/build/src/cli/commands/contract-help.d.ts +3 -13
- package/build/src/cli/commands/contract-help.js +7 -16
- package/build/src/cli/commands/contract.js +19 -35
- package/build/src/cli/commands/debt.js +30 -29
- package/build/src/cli/parse.js +0 -1
- package/build/src/cli/render/akuma-activity.d.ts +36 -9
- package/build/src/cli/render/akuma-activity.js +142 -65
- package/build/src/cli/render/akuma.d.ts +6 -0
- package/build/src/cli/render/akuma.js +67 -24
- package/build/src/cli/render/catalog.js +0 -1
- package/build/src/cli/render/contract-observation.d.ts +16 -3
- package/build/src/cli/render/contract-observation.js +3 -0
- package/build/src/cli/render/contract.d.ts +2 -2
- package/build/src/cli/render/contract.js +4 -4
- package/build/src/cli/render/delivery-preview.d.ts +7 -0
- package/build/src/cli/render/{audit.js → delivery-preview.js} +29 -27
- package/build/src/cli/render/kanshi-akuma.d.ts +3 -1
- package/build/src/cli/render/kanshi-akuma.js +23 -8
- package/build/src/cli/render/kanshi.js +4 -1
- package/build/src/cli/render/receipt.js +3 -3
- package/build/src/cli/render/refusal.js +2 -2
- package/build/src/cli/render/terminal.d.ts +0 -1
- package/build/src/cli/render/terminal.js +1 -1
- package/build/src/cli/square-identity.d.ts +15 -0
- package/build/src/cli/square-identity.js +180 -0
- package/build/src/contract-worktree.js +1 -1
- package/build/src/core/verbs/placement.d.ts +2 -1
- package/build/src/core/verbs/placement.js +1 -1
- package/build/src/debt/context.d.ts +0 -5
- package/build/src/debt/context.js +32 -44
- package/build/src/git/process.d.ts +1 -0
- package/build/src/git/process.js +18 -1
- package/build/src/git/read-observation.js +2 -1
- package/build/src/git/scratch.d.ts +5 -1
- package/build/src/git/scratch.js +41 -12
- package/build/src/git/target-placement.d.ts +22 -4
- package/build/src/git/target-placement.js +44 -20
- package/build/src/index.d.ts +2 -2
- package/build/src/kanshi/read.js +187 -105
- package/build/src/kanshi/report.d.ts +5 -0
- package/build/src/library/address.d.ts +18 -4
- package/build/src/library/address.js +27 -6
- package/build/src/library/contract-address.d.ts +6 -0
- package/build/src/library/contract-address.js +12 -1
- package/build/src/library/contract-execution.d.ts +2 -2
- package/build/src/library/contract-execution.js +13 -17
- package/build/src/library/contract-operations.d.ts +59 -94
- package/build/src/library/contract-operations.js +23 -19
- package/build/src/library/contract-outcomes.d.ts +3 -3
- package/build/src/library/contract-settings.d.ts +1 -0
- package/build/src/library/contract-settings.js +1 -1
- package/build/src/library/invocation.d.ts +2 -2
- package/build/src/library/invocation.js +1 -1
- package/build/src/library/keiyaku.d.ts +2 -2
- package/build/src/library/keiyaku.js +2 -2
- package/build/src/library/outcome.d.ts +148 -268
- package/build/src/library/outcome.js +4 -8
- package/build/src/library/refusal.d.ts +2 -2
- package/build/src/library/refusal.js +2 -2
- package/build/src/plugin/runtime.js +15 -19
- package/build/src/protocol/{audit.d.ts → delivery-preview.d.ts} +62 -97
- package/build/src/protocol/delivery-preview.js +167 -0
- package/build/src/protocol/progress.d.ts +1 -1
- package/build/src/runtime/proc/run.js +22 -4
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/verification/execution.d.ts +1 -1
- package/build/src/verification/execution.js +5 -3
- package/package.json +5 -2
- package/skills/keiyaku/SKILL.md +3 -1
- package/skills/keiyaku-babysit/SKILL.md +1 -1
- package/skills/keiyaku-bind/SKILL.md +3 -2
- package/skills/keiyaku-workflow/SKILL.md +9 -8
- package/build/src/cli/render/audit.d.ts +0 -7
- package/build/src/protocol/audit.js +0 -203
package/build/src/kanshi/read.js
CHANGED
|
@@ -152,18 +152,35 @@ async function readHolders(observation) {
|
|
|
152
152
|
return { kind: "failed", failure: { message: diagnostic(error) } };
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
|
-
function attachRoster(contracts, akuma) {
|
|
155
|
+
function attachRoster(contracts, akuma, dispatches) {
|
|
156
156
|
if (contracts.kind !== "present")
|
|
157
157
|
return contracts;
|
|
158
|
+
if (dispatches.kind === "failed" || akuma.kind === "failed") {
|
|
159
|
+
return {
|
|
160
|
+
kind: "present",
|
|
161
|
+
value: {
|
|
162
|
+
...contracts.value,
|
|
163
|
+
rows: contracts.value.rows.map((row) => ({ ...row, roster: [], rosterUnavailable: true })),
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
if (dispatches.kind === "absent" || akuma.kind === "absent") {
|
|
168
|
+
return {
|
|
169
|
+
kind: "present",
|
|
170
|
+
value: { ...contracts.value, rows: contracts.value.rows.map((row) => ({ ...row, roster: [] })) },
|
|
171
|
+
};
|
|
172
|
+
}
|
|
158
173
|
const attachments = new Map();
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
174
|
+
for (const row of akuma.value.rows) {
|
|
175
|
+
if (row.contract === undefined)
|
|
176
|
+
continue;
|
|
177
|
+
const current = attachments.get(row.contract.id) ?? [];
|
|
178
|
+
current.push({
|
|
179
|
+
id: row.id,
|
|
180
|
+
aliases: row.aliases,
|
|
181
|
+
...(akuma.value.aliasesUnavailable === true ? { aliasesUnavailable: true } : {}),
|
|
182
|
+
});
|
|
183
|
+
attachments.set(row.contract.id, current);
|
|
167
184
|
}
|
|
168
185
|
return {
|
|
169
186
|
kind: "present",
|
|
@@ -173,7 +190,7 @@ function attachRoster(contracts, akuma) {
|
|
|
173
190
|
},
|
|
174
191
|
};
|
|
175
192
|
}
|
|
176
|
-
function decorateContracts(contracts, holders, namespaceDebts) {
|
|
193
|
+
function decorateContracts(contracts, holders, dispatches, namespaceDebts) {
|
|
177
194
|
if (contracts.kind !== "present")
|
|
178
195
|
return contracts;
|
|
179
196
|
return {
|
|
@@ -182,22 +199,17 @@ function decorateContracts(contracts, holders, namespaceDebts) {
|
|
|
182
199
|
...contracts.value,
|
|
183
200
|
rows: contracts.value.rows.map((row) => {
|
|
184
201
|
const selected = namespaceDebts?.(row.id);
|
|
185
|
-
if (holders.kind === "failed") {
|
|
186
|
-
return {
|
|
187
|
-
...row,
|
|
188
|
-
holder: { kind: "unavailable" },
|
|
189
|
-
roster: [],
|
|
190
|
-
...(selected === undefined ? {} : { namespaceDebts: selected }),
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
202
|
const holder = holders.kind === "present" ? holders.value.get(row.id) : undefined;
|
|
194
203
|
return {
|
|
195
204
|
...row,
|
|
196
205
|
roster: [],
|
|
206
|
+
...(dispatches.kind === "failed" ? { rosterUnavailable: true } : {}),
|
|
197
207
|
...(selected === undefined ? {} : { namespaceDebts: selected }),
|
|
198
|
-
holder:
|
|
199
|
-
? { kind: "
|
|
200
|
-
:
|
|
208
|
+
holder: holders.kind === "failed"
|
|
209
|
+
? { kind: "unavailable" }
|
|
210
|
+
: holder?.disposition === "held"
|
|
211
|
+
? { kind: "held", debtId: holder.debtId }
|
|
212
|
+
: { kind: "none" },
|
|
201
213
|
};
|
|
202
214
|
}),
|
|
203
215
|
},
|
|
@@ -214,18 +226,26 @@ function contractEndpointObserver(contracts) {
|
|
|
214
226
|
return "hasMore" in contracts.value ? "unavailable" : "missing";
|
|
215
227
|
};
|
|
216
228
|
}
|
|
217
|
-
function joinDebts(
|
|
229
|
+
function joinDebts(section, holders, observeContract) {
|
|
230
|
+
if (section.kind !== "present")
|
|
231
|
+
return section;
|
|
218
232
|
const associations = new Map(holders.kind === "present"
|
|
219
233
|
? [...holders.value.values()]
|
|
220
234
|
.filter((holder) => holder.disposition === "held")
|
|
221
235
|
.map((holder) => [holder.debtId, holder.contractId])
|
|
222
236
|
: []);
|
|
223
|
-
return
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
237
|
+
return {
|
|
238
|
+
kind: "present",
|
|
239
|
+
value: {
|
|
240
|
+
...section.value,
|
|
241
|
+
rows: section.value.rows.map((row) => {
|
|
242
|
+
if (holders.kind === "failed")
|
|
243
|
+
return { ...row, contractAssociationUnavailable: true };
|
|
244
|
+
const id = associations.get(row.id);
|
|
245
|
+
return id === undefined ? row : { ...row, contract: { id, observed: observeContract(id) } };
|
|
246
|
+
}),
|
|
247
|
+
},
|
|
248
|
+
};
|
|
229
249
|
}
|
|
230
250
|
/** Attribute a Debt board failure to the malformed document that caused it, when one is known. */
|
|
231
251
|
function debtFailure(error) {
|
|
@@ -257,13 +277,38 @@ function namespaceDebtSection(board, id) {
|
|
|
257
277
|
return undefined;
|
|
258
278
|
return { kind: "present", value: board.observation.selectNamespace(contractNamespace(id)) };
|
|
259
279
|
}
|
|
260
|
-
|
|
261
|
-
if (
|
|
262
|
-
return { kind: "
|
|
263
|
-
|
|
280
|
+
function debtRowsFromBoard(path, board) {
|
|
281
|
+
if (path === null || board.kind === "absent")
|
|
282
|
+
return { kind: "absent" };
|
|
283
|
+
if (board.kind === "failed")
|
|
284
|
+
return { kind: "failed", failure: board.failure };
|
|
285
|
+
const recent = board.observation.selectRecentStatus(10);
|
|
286
|
+
return {
|
|
264
287
|
kind: "present",
|
|
265
|
-
value: {
|
|
266
|
-
|
|
288
|
+
value: {
|
|
289
|
+
root: path,
|
|
290
|
+
hasMore: recent.hasMore,
|
|
291
|
+
rows: recent.rows.map((row) => {
|
|
292
|
+
const copy = { ...row };
|
|
293
|
+
delete copy.children;
|
|
294
|
+
return copy;
|
|
295
|
+
}),
|
|
296
|
+
},
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
async function readDebtRows(path) {
|
|
300
|
+
if (path === null)
|
|
301
|
+
return { kind: "absent" };
|
|
302
|
+
try {
|
|
303
|
+
const recent = await observeRecentDebtStatus(path, { limit: 10 });
|
|
304
|
+
return {
|
|
305
|
+
kind: "present",
|
|
306
|
+
value: { root: path, hasMore: recent.hasMore, rows: recent.rows },
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
catch (error) {
|
|
310
|
+
return { kind: "failed", failure: debtFailure(error) };
|
|
311
|
+
}
|
|
267
312
|
}
|
|
268
313
|
/**
|
|
269
314
|
* Placement discharge for the observed roster snapshots: an associated Contract
|
|
@@ -285,33 +330,10 @@ async function claimedAssociatedContracts(observation, dispatches) {
|
|
|
285
330
|
}));
|
|
286
331
|
return claimed;
|
|
287
332
|
}
|
|
288
|
-
async function
|
|
289
|
-
const { aliases, limit = ROSTER_VISIBLE_ROWS } = input;
|
|
290
|
-
if (aliases.kind !== "present")
|
|
291
|
-
return aliases;
|
|
333
|
+
async function readAkumaProduct(path, limit = ROSTER_VISIBLE_ROWS) {
|
|
292
334
|
try {
|
|
293
335
|
const source = await observeAkumaRoster(path, limit);
|
|
294
|
-
const
|
|
295
|
-
for (const binding of aliases.value)
|
|
296
|
-
aliasById.set(binding.akuId, [...(aliasById.get(binding.akuId) ?? []), binding]);
|
|
297
|
-
const dispatchById = new Map(dispatches.map((dispatch) => [dispatch.akuId, dispatch]));
|
|
298
|
-
const rows = source.rows.map((row) => {
|
|
299
|
-
const dispatch = dispatchById.get(row.id);
|
|
300
|
-
return {
|
|
301
|
-
...row,
|
|
302
|
-
aliases: (aliasById.get(row.id) ?? []).map((binding) => binding.alias),
|
|
303
|
-
...(dispatch === undefined
|
|
304
|
-
? {}
|
|
305
|
-
: {
|
|
306
|
-
contract: {
|
|
307
|
-
id: dispatch.contractId,
|
|
308
|
-
observed: observeContract(dispatch.contractId),
|
|
309
|
-
},
|
|
310
|
-
}),
|
|
311
|
-
};
|
|
312
|
-
});
|
|
313
|
-
const snapshotRows = rows.slice(0, ROSTER_SNAPSHOT_ROWS);
|
|
314
|
-
const snapshots = new Map(await Promise.all(snapshotRows.map(async (row) => {
|
|
336
|
+
const snapshots = new Map(await Promise.all(source.rows.slice(0, ROSTER_SNAPSHOT_ROWS).map(async (row) => {
|
|
315
337
|
try {
|
|
316
338
|
return [row.id, await readAkumaTimeline(path, row.id)];
|
|
317
339
|
}
|
|
@@ -323,12 +345,9 @@ async function joinAkuma(path, observeContract, isContractClaimed, dispatches, i
|
|
|
323
345
|
kind: "present",
|
|
324
346
|
value: {
|
|
325
347
|
...source,
|
|
326
|
-
rows: rows.map((row) => {
|
|
348
|
+
rows: source.rows.map((row) => {
|
|
327
349
|
const snapshot = snapshots.get(row.id);
|
|
328
|
-
|
|
329
|
-
return row;
|
|
330
|
-
const placed = row.contract !== undefined && isContractClaimed(row.contract.id);
|
|
331
|
-
return { ...row, snapshot: placed ? withoutReportedChanges(snapshot) : snapshot };
|
|
350
|
+
return snapshot === undefined ? row : { ...row, snapshot };
|
|
332
351
|
}),
|
|
333
352
|
},
|
|
334
353
|
};
|
|
@@ -337,6 +356,43 @@ async function joinAkuma(path, observeContract, isContractClaimed, dispatches, i
|
|
|
337
356
|
return { kind: "failed", failure: { message: diagnostic(error) } };
|
|
338
357
|
}
|
|
339
358
|
}
|
|
359
|
+
function attachAkumaAssociations(product, aliases, dispatches, observeContract, claimed) {
|
|
360
|
+
if (product.kind !== "present")
|
|
361
|
+
return product;
|
|
362
|
+
const aliasById = new Map();
|
|
363
|
+
if (aliases.kind === "present") {
|
|
364
|
+
for (const binding of aliases.value)
|
|
365
|
+
aliasById.set(binding.akuId, [...(aliasById.get(binding.akuId) ?? []), binding]);
|
|
366
|
+
}
|
|
367
|
+
const dispatchById = new Map(dispatches.kind === "present" ? dispatches.value.map((dispatch) => [dispatch.akuId, dispatch]) : []);
|
|
368
|
+
return {
|
|
369
|
+
kind: "present",
|
|
370
|
+
value: {
|
|
371
|
+
...product.value,
|
|
372
|
+
...(aliases.kind === "failed" ? { aliasesUnavailable: true } : {}),
|
|
373
|
+
rows: product.value.rows.map((row) => {
|
|
374
|
+
const dispatch = dispatchById.get(row.id);
|
|
375
|
+
const { snapshot } = row;
|
|
376
|
+
const placed = dispatch !== undefined && claimed.has(dispatch.contractId);
|
|
377
|
+
return {
|
|
378
|
+
...row,
|
|
379
|
+
aliases: aliases.kind === "present" ? (aliasById.get(row.id) ?? []).map((binding) => binding.alias) : [],
|
|
380
|
+
...(dispatches.kind === "failed"
|
|
381
|
+
? { contractAssociationUnavailable: true }
|
|
382
|
+
: dispatch === undefined
|
|
383
|
+
? {}
|
|
384
|
+
: {
|
|
385
|
+
contract: {
|
|
386
|
+
id: dispatch.contractId,
|
|
387
|
+
observed: observeContract(dispatch.contractId),
|
|
388
|
+
},
|
|
389
|
+
}),
|
|
390
|
+
...(snapshot === undefined ? {} : { snapshot: placed ? withoutReportedChanges(snapshot) : snapshot }),
|
|
391
|
+
};
|
|
392
|
+
}),
|
|
393
|
+
},
|
|
394
|
+
};
|
|
395
|
+
}
|
|
340
396
|
async function readAliasBindings(path) {
|
|
341
397
|
try {
|
|
342
398
|
return { kind: "present", value: await readAliases(path) };
|
|
@@ -356,12 +412,15 @@ async function readDispatches(observation) {
|
|
|
356
412
|
async function observeWithoutRepo(world, region, observedAt, branch) {
|
|
357
413
|
const contracts = { kind: "absent" };
|
|
358
414
|
const holders = { kind: "absent" };
|
|
415
|
+
const dispatches = { kind: "absent" };
|
|
416
|
+
const [debtRows, aliases, akumaProduct] = world === null
|
|
417
|
+
? [{ kind: "absent" }, { kind: "absent" }, { kind: "absent" }]
|
|
418
|
+
: await Promise.all([readDebtRows(world), readAliasBindings(world), readAkumaProduct(world)]);
|
|
359
419
|
const observeContract = contractEndpointObserver(contracts);
|
|
360
|
-
const debts = world === null ?
|
|
361
|
-
const aliases = world === null ? { kind: "absent" } : await readAliasBindings(world);
|
|
420
|
+
const debts = world === null ? debtRows : joinDebts(debtRows, holders, observeContract);
|
|
362
421
|
const akuma = world === null
|
|
363
|
-
?
|
|
364
|
-
:
|
|
422
|
+
? akumaProduct
|
|
423
|
+
: attachAkumaAssociations(akumaProduct, aliases, dispatches, observeContract, new Set());
|
|
365
424
|
return {
|
|
366
425
|
report: {
|
|
367
426
|
root: world,
|
|
@@ -375,8 +434,42 @@ async function observeWithoutRepo(world, region, observedAt, branch) {
|
|
|
375
434
|
aliases,
|
|
376
435
|
};
|
|
377
436
|
}
|
|
437
|
+
/**
|
|
438
|
+
* The repository-observation failure view: a failed Contract and Region beside the
|
|
439
|
+
* independently observed Debt, Alias, and Akuma sections. Debt reports the rows
|
|
440
|
+
* already observed before the failure and performs the existing fallback read only
|
|
441
|
+
* when none were.
|
|
442
|
+
*/
|
|
443
|
+
async function observeRepoFailure(input, error, akumaProduct, aliases, observedDebtRows) {
|
|
444
|
+
const { world, region, observedAt, branch } = input;
|
|
445
|
+
const failure = { kind: "failed", failure: { message: diagnostic(error) } };
|
|
446
|
+
const debtRows = observedDebtRows ?? (await readDebtRows(world));
|
|
447
|
+
const observeContract = contractEndpointObserver(failure);
|
|
448
|
+
return {
|
|
449
|
+
report: {
|
|
450
|
+
root: world,
|
|
451
|
+
observedAt,
|
|
452
|
+
branch,
|
|
453
|
+
contracts: failure,
|
|
454
|
+
debts: world === null ? { kind: "absent" } : joinDebts(debtRows, failure, observeContract),
|
|
455
|
+
akuma: world === null
|
|
456
|
+
? { kind: "absent" }
|
|
457
|
+
: attachAkumaAssociations(akumaProduct, aliases, failure, observeContract, new Set()),
|
|
458
|
+
...(region === undefined ? {} : { region: failure }),
|
|
459
|
+
},
|
|
460
|
+
aliases,
|
|
461
|
+
};
|
|
462
|
+
}
|
|
378
463
|
async function observeRepo(input) {
|
|
379
464
|
const { world, repo, region, contract, observedAt, branch } = input;
|
|
465
|
+
const [initialDebtRows, aliases, akumaProduct] = world === null
|
|
466
|
+
? [{ kind: "absent" }, { kind: "absent" }, { kind: "absent" }]
|
|
467
|
+
: await Promise.all([
|
|
468
|
+
contract === undefined ? readDebtRows(world) : Promise.resolve(undefined),
|
|
469
|
+
readAliasBindings(world),
|
|
470
|
+
readAkumaProduct(world),
|
|
471
|
+
]);
|
|
472
|
+
let observedDebtRows = initialDebtRows;
|
|
380
473
|
try {
|
|
381
474
|
return await withGitDecodeChannel(repo, (channel) => withGitReadObservation(repo, channel, async (observation) => {
|
|
382
475
|
const [contractSection, holders, dispatches, regionSection] = await Promise.all([
|
|
@@ -389,23 +482,26 @@ async function observeRepo(input) {
|
|
|
389
482
|
contractSection.kind === "present" &&
|
|
390
483
|
contractSection.value.rows.some((row) => row.id === contract);
|
|
391
484
|
const board = selectedContract ? await readDebtWorld(world) : undefined;
|
|
392
|
-
|
|
485
|
+
observedDebtRows =
|
|
486
|
+
world === null
|
|
487
|
+
? { kind: "absent" }
|
|
488
|
+
: board === undefined
|
|
489
|
+
? (initialDebtRows ?? (await readDebtRows(world)))
|
|
490
|
+
: debtRowsFromBoard(world, board);
|
|
491
|
+
const contracts = decorateContracts(contractSection, holders, dispatches, board === undefined ? undefined : (id) => (id === contract ? namespaceDebtSection(board, id) : undefined));
|
|
393
492
|
const observeContract = contractEndpointObserver(contracts);
|
|
394
|
-
const
|
|
395
|
-
const debts = world === null ? { kind: "absent" } : await readDebts(world, holders, observeContract);
|
|
493
|
+
const debts = world === null ? observedDebtRows : joinDebts(observedDebtRows, holders, observeContract);
|
|
396
494
|
const claimed = dispatches.kind === "present"
|
|
397
495
|
? await claimedAssociatedContracts(observation, dispatches.value)
|
|
398
496
|
: new Set();
|
|
399
497
|
const akuma = world === null
|
|
400
|
-
?
|
|
401
|
-
: dispatches
|
|
402
|
-
? dispatches
|
|
403
|
-
: await joinAkuma(world, observeContract, (id) => claimed.has(id), dispatches.value, { aliases });
|
|
498
|
+
? akumaProduct
|
|
499
|
+
: attachAkumaAssociations(akumaProduct, aliases, dispatches, observeContract, claimed);
|
|
404
500
|
const assembled = {
|
|
405
501
|
root: world,
|
|
406
502
|
observedAt,
|
|
407
503
|
branch,
|
|
408
|
-
contracts: attachRoster(contracts, akuma),
|
|
504
|
+
contracts: attachRoster(contracts, akuma, dispatches),
|
|
409
505
|
debts,
|
|
410
506
|
akuma,
|
|
411
507
|
...(regionSection === undefined ? {} : { region: regionSection }),
|
|
@@ -423,19 +519,7 @@ async function observeRepo(input) {
|
|
|
423
519
|
}));
|
|
424
520
|
}
|
|
425
521
|
catch (error) {
|
|
426
|
-
|
|
427
|
-
return {
|
|
428
|
-
report: {
|
|
429
|
-
root: world,
|
|
430
|
-
observedAt,
|
|
431
|
-
branch,
|
|
432
|
-
contracts: failure,
|
|
433
|
-
debts: world === null ? { kind: "absent" } : failure,
|
|
434
|
-
akuma: world === null ? { kind: "absent" } : failure,
|
|
435
|
-
...(region === undefined ? {} : { region: failure }),
|
|
436
|
-
},
|
|
437
|
-
aliases: world === null ? { kind: "absent" } : failure,
|
|
438
|
-
};
|
|
522
|
+
return await observeRepoFailure(input, error, akumaProduct, aliases, observedDebtRows);
|
|
439
523
|
}
|
|
440
524
|
}
|
|
441
525
|
export async function observeKanshi(input) {
|
|
@@ -459,25 +543,23 @@ async function observeAkumaCategory(world, repo, limit, observedAt) {
|
|
|
459
543
|
});
|
|
460
544
|
if (world === null)
|
|
461
545
|
return report({ kind: "absent" });
|
|
462
|
-
const
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
return report(aliases);
|
|
466
|
-
if (observation === undefined)
|
|
467
|
-
return report(await joinAkuma(world, () => "unavailable", () => false, [], { aliases, limit }));
|
|
468
|
-
const dispatches = await readDispatches(observation);
|
|
469
|
-
if (dispatches.kind === "failed")
|
|
470
|
-
return report(dispatches);
|
|
471
|
-
const claimed = await claimedAssociatedContracts(observation, dispatches.value);
|
|
472
|
-
return report(await joinAkuma(world, () => "unavailable", (id) => claimed.has(id), dispatches.value, { aliases, limit }));
|
|
473
|
-
};
|
|
546
|
+
const aliases = await readAliasBindings(world);
|
|
547
|
+
const product = await readAkumaProduct(world, limit);
|
|
548
|
+
const compose = (dispatches, claimed) => report(attachAkumaAssociations(product, aliases, dispatches, () => "unavailable", claimed));
|
|
474
549
|
if (repo === undefined)
|
|
475
|
-
return
|
|
550
|
+
return compose({ kind: "absent" }, new Set());
|
|
476
551
|
try {
|
|
477
|
-
return await withGitDecodeChannel(repo, (channel) => withGitReadObservation(repo, channel,
|
|
552
|
+
return await withGitDecodeChannel(repo, (channel) => withGitReadObservation(repo, channel, async (observation) => {
|
|
553
|
+
const dispatches = await readDispatches(observation);
|
|
554
|
+
const claimed = dispatches.kind === "present"
|
|
555
|
+
? await claimedAssociatedContracts(observation, dispatches.value)
|
|
556
|
+
: new Set();
|
|
557
|
+
return compose(dispatches, claimed);
|
|
558
|
+
}));
|
|
478
559
|
}
|
|
479
560
|
catch (error) {
|
|
480
|
-
|
|
561
|
+
const failure = { kind: "failed", failure: { message: diagnostic(error) } };
|
|
562
|
+
return compose(failure, new Set());
|
|
481
563
|
}
|
|
482
564
|
}
|
|
483
565
|
async function observeContractCategory(world, repo, limit, observedAt) {
|
|
@@ -493,7 +575,7 @@ async function observeContractCategory(world, repo, limit, observedAt) {
|
|
|
493
575
|
readContracts(observation, undefined, limit),
|
|
494
576
|
readHolders(observation),
|
|
495
577
|
]);
|
|
496
|
-
return report(decorateContracts(contracts, holders));
|
|
578
|
+
return report(decorateContracts(contracts, holders, { kind: "absent" }));
|
|
497
579
|
}));
|
|
498
580
|
}
|
|
499
581
|
catch (error) {
|
|
@@ -33,11 +33,13 @@ export type ContractHolderObservation = Readonly<{
|
|
|
33
33
|
export type ContractRosterAttachment = Readonly<{
|
|
34
34
|
id: string;
|
|
35
35
|
aliases: readonly AkumaAlias[];
|
|
36
|
+
aliasesUnavailable?: true;
|
|
36
37
|
}>;
|
|
37
38
|
export type ContractKanshiRow = ContractBoard["rows"][number] & Readonly<{
|
|
38
39
|
phase: ContractPhase;
|
|
39
40
|
holder: ContractHolderObservation;
|
|
40
41
|
roster: readonly ContractRosterAttachment[];
|
|
42
|
+
rosterUnavailable?: true;
|
|
41
43
|
namespaceDebts?: Section<readonly DebtRow[]>;
|
|
42
44
|
issue?: CurrentPhysicalIssue;
|
|
43
45
|
}>;
|
|
@@ -50,6 +52,7 @@ export type DebtKanshiRow = DebtRow & Readonly<{
|
|
|
50
52
|
id: string;
|
|
51
53
|
observed: ContractEndpointObservation;
|
|
52
54
|
}>;
|
|
55
|
+
contractAssociationUnavailable?: true;
|
|
53
56
|
blockers?: readonly DebtRef[];
|
|
54
57
|
}>;
|
|
55
58
|
export type DebtKanshiWorld = BoundedList<DebtKanshiRow> & Readonly<{
|
|
@@ -61,10 +64,12 @@ export type AkumaKanshiRow = (AkumaListRow | UnbornAkumaListRow) & Readonly<{
|
|
|
61
64
|
id: string;
|
|
62
65
|
observed: ContractEndpointObservation;
|
|
63
66
|
}>;
|
|
67
|
+
contractAssociationUnavailable?: true;
|
|
64
68
|
snapshot?: ActivitySnapshot;
|
|
65
69
|
}>;
|
|
66
70
|
export type AkumaKanshiWorld = Omit<AkumaList, "rows"> & Readonly<{
|
|
67
71
|
rows: readonly AkumaKanshiRow[];
|
|
72
|
+
aliasesUnavailable?: true;
|
|
68
73
|
}>;
|
|
69
74
|
export type KanshiRegionSelection = Readonly<{
|
|
70
75
|
kind: "declarations";
|
|
@@ -3,8 +3,9 @@ import { type AliasBinding } from "../alias/index.js";
|
|
|
3
3
|
import { type AkuId } from "../akuma/identity.js";
|
|
4
4
|
import { contractId } from "../core/facts/types.js";
|
|
5
5
|
import { type AkumaAlias } from "../identity/selector.js";
|
|
6
|
+
import type { Section } from "../kanshi/index.js";
|
|
7
|
+
import type { ContractRow } from "../protocol/read/status.js";
|
|
6
8
|
import { type WorldRoot } from "../world.js";
|
|
7
|
-
import type { KanshiReport, Section } from "../kanshi/index.js";
|
|
8
9
|
import { type Repo } from "./repo.js";
|
|
9
10
|
export type AkumaAddressInput = Readonly<{
|
|
10
11
|
akuma: string;
|
|
@@ -46,11 +47,24 @@ export type NamedAddress = Readonly<{
|
|
|
46
47
|
kind: "akuma";
|
|
47
48
|
id: AkuId;
|
|
48
49
|
}>;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
/** The frozen authority a named selector is adjudicated against. */
|
|
51
|
+
export type NamedAddressAuthority = Readonly<{
|
|
52
|
+
contracts: Section<readonly ContractRow[]>;
|
|
52
53
|
aliases: Section<readonly AliasBinding[]>;
|
|
53
54
|
}>;
|
|
55
|
+
export type NamedAddressInput = NamedAddressAuthority & Readonly<{
|
|
56
|
+
selector: string;
|
|
57
|
+
}>;
|
|
58
|
+
/**
|
|
59
|
+
* Freeze the one complete Contract candidate observation and the Alias
|
|
60
|
+
* observation a named selector is judged against. The complete candidate set is
|
|
61
|
+
* the Contract owner's board, so display-age bounds never decide membership. An
|
|
62
|
+
* absent Repo is a World without a Contract family, not a failed observation.
|
|
63
|
+
*/
|
|
64
|
+
export declare function observeNamedAddress(input: Readonly<{
|
|
65
|
+
world: WorldRoot | null;
|
|
66
|
+
repo: Repo | null;
|
|
67
|
+
}>): Promise<NamedAddressAuthority>;
|
|
54
68
|
export declare function resolveNamedAddress(input: NamedAddressInput): NamedAddress;
|
|
55
69
|
type AddressedAkuma = Readonly<{
|
|
56
70
|
path: WorldRoot;
|
|
@@ -7,7 +7,7 @@ import { contractId } from "../core/facts/types.js";
|
|
|
7
7
|
import { readDispatches } from "../dispatch/index.js";
|
|
8
8
|
import { matchesAkumaGlob, parseReadableAkumaAlias, parseAkumaGlob, } from "../identity/selector.js";
|
|
9
9
|
import { World } from "../world.js";
|
|
10
|
-
import { matchContractCandidates } from "./contract-address.js";
|
|
10
|
+
import { matchContractCandidates, readCompleteContractCandidates } from "./contract-address.js";
|
|
11
11
|
import { requireInput } from "./input.js";
|
|
12
12
|
import { scopeForRepo } from "./repo.js";
|
|
13
13
|
export class AkumaAddressError extends Error {
|
|
@@ -63,6 +63,27 @@ async function directId(path, selector) {
|
|
|
63
63
|
}
|
|
64
64
|
return parseAddressId(selector).id;
|
|
65
65
|
}
|
|
66
|
+
async function observe(read) {
|
|
67
|
+
try {
|
|
68
|
+
return { kind: "present", value: await read() };
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
return { kind: "failed", failure: { message: error instanceof Error ? error.message : String(error) } };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Freeze the one complete Contract candidate observation and the Alias
|
|
76
|
+
* observation a named selector is judged against. The complete candidate set is
|
|
77
|
+
* the Contract owner's board, so display-age bounds never decide membership. An
|
|
78
|
+
* absent Repo is a World without a Contract family, not a failed observation.
|
|
79
|
+
*/
|
|
80
|
+
export async function observeNamedAddress(input) {
|
|
81
|
+
const { world, repo } = input;
|
|
82
|
+
return {
|
|
83
|
+
contracts: repo === null ? { kind: "absent" } : await observe(() => readCompleteContractCandidates(repo)),
|
|
84
|
+
aliases: world === null ? { kind: "absent" } : await observe(() => readAliases(world)),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
66
87
|
export function resolveNamedAddress(input) {
|
|
67
88
|
const selector = nonblank(input.selector, "selector");
|
|
68
89
|
if (selector.startsWith("kei/"))
|
|
@@ -70,7 +91,9 @@ export function resolveNamedAddress(input) {
|
|
|
70
91
|
if (selector.startsWith("aku/"))
|
|
71
92
|
return { kind: "akuma", id: parseAddressId(selector).id };
|
|
72
93
|
const alias = parseAddressAlias(selector);
|
|
73
|
-
const contractMatches = matchContractCandidates(input.
|
|
94
|
+
const contractMatches = matchContractCandidates(input.contracts.kind === "present" ? input.contracts.value : [], {
|
|
95
|
+
selector: alias,
|
|
96
|
+
});
|
|
74
97
|
const aliasId = input.aliases.kind === "present"
|
|
75
98
|
? (input.aliases.value.find((binding) => binding.alias === alias)?.akuId ?? null)
|
|
76
99
|
: null;
|
|
@@ -84,12 +107,10 @@ export function resolveNamedAddress(input) {
|
|
|
84
107
|
return { kind: "contract", id: contractMatches[0].id };
|
|
85
108
|
if (contractMatches.length > 1)
|
|
86
109
|
throw new TypeError(`ambiguous Contract selector: ${selector}`);
|
|
87
|
-
if (input.
|
|
110
|
+
if (input.contracts.kind === "failed")
|
|
88
111
|
throw new TypeError("cannot resolve a named selector while the Contract world is failed");
|
|
89
|
-
|
|
90
|
-
if (input.aliases.kind === "failed") {
|
|
112
|
+
if (input.aliases.kind === "failed")
|
|
91
113
|
throw new TypeError("cannot resolve a named selector while Alias authority is failed");
|
|
92
|
-
}
|
|
93
114
|
throw new AkumaAddressError({ kind: "akuma-alias-not-found", alias });
|
|
94
115
|
}
|
|
95
116
|
/**
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import type { ContractRow } from "../protocol/read/status.js";
|
|
2
2
|
import type { ContractResolution, ContractResolveInput } from "./contract-types.js";
|
|
3
|
+
import { type Repo } from "./repo.js";
|
|
3
4
|
/** Pure Contract membership shared with mixed Address; no cross-family judgment. */
|
|
4
5
|
export declare function matchContractCandidates(rows: readonly ContractRow[], selection: Readonly<{
|
|
5
6
|
selector: string;
|
|
6
7
|
}> | Readonly<{
|
|
7
8
|
cwd: string;
|
|
8
9
|
}>): readonly ContractRow[];
|
|
10
|
+
/**
|
|
11
|
+
* The complete live Contract candidates a named selection judges membership
|
|
12
|
+
* against. No display bound applies, so age never decides which names exist.
|
|
13
|
+
*/
|
|
14
|
+
export declare function readCompleteContractCandidates(repo: Repo): Promise<readonly ContractRow[]>;
|
|
9
15
|
export declare function resolveContract(input: ContractResolveInput): Promise<ContractResolution>;
|
|
@@ -15,6 +15,17 @@ export function matchContractCandidates(rows, selection) {
|
|
|
15
15
|
? `@${row.id.slice("kei/".length)}` === selection.selector
|
|
16
16
|
: normalize(row.worktreePath) === selection.cwd));
|
|
17
17
|
}
|
|
18
|
+
/** The complete live Contract board: the Contract owner's own candidate set, never a display catalogue. */
|
|
19
|
+
function completeBoard(scope) {
|
|
20
|
+
return withGitDecodeChannel(scope, (channel) => contractsOperation({ scope, channel }));
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The complete live Contract candidates a named selection judges membership
|
|
24
|
+
* against. No display bound applies, so age never decides which names exist.
|
|
25
|
+
*/
|
|
26
|
+
export async function readCompleteContractCandidates(repo) {
|
|
27
|
+
return (await completeBoard(scopeForRepo(repo))).rows;
|
|
28
|
+
}
|
|
18
29
|
export async function resolveContract(input) {
|
|
19
30
|
const values = requireInput(input, "Keiyaku.with().resolve input", ["repo", "selector", "cwd"]);
|
|
20
31
|
const scope = scopeForRepo(values.repo);
|
|
@@ -54,7 +65,7 @@ export async function resolveContract(input) {
|
|
|
54
65
|
};
|
|
55
66
|
}
|
|
56
67
|
}
|
|
57
|
-
const board = await readContractValue(() =>
|
|
68
|
+
const board = await readContractValue(() => completeBoard(scope));
|
|
58
69
|
const candidates = matchContractCandidates(board.rows, selector === undefined ? { cwd } : { selector });
|
|
59
70
|
if (candidates.length === 1)
|
|
60
71
|
return { kind: "resolved", id: candidates[0].id };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ExecutionContext } from "../akuma/requests.js";
|
|
2
2
|
import { type ContractId } from "../core/facts/types.js";
|
|
3
3
|
import { type RepositoryScope } from "../protocol/operations.js";
|
|
4
|
-
import type { AbandonOutcome, AmendOutcome, ArcOutcome,
|
|
4
|
+
import type { AbandonOutcome, AmendOutcome, ArcOutcome, DeliveryPreviewInput, DeliveryPreviewOutcome, DeliverOutcome, MutationObservation, ReviewOutcome } from "./contract-outcomes.js";
|
|
5
5
|
import { type LocalContractCompositionCapture } from "./contract-settings.js";
|
|
6
6
|
import type { AbandonInput, AmendInput, ArcInput, DeliverInput, ReviewInput } from "./contract-types.js";
|
|
7
7
|
export declare class ContractExecution {
|
|
@@ -23,7 +23,7 @@ export declare class ContractExecution {
|
|
|
23
23
|
review(input: ReviewInput, options?: MutationObservation): Promise<ReviewOutcome>;
|
|
24
24
|
abandon(input?: AbandonInput): Promise<AbandonOutcome>;
|
|
25
25
|
arc(input: ArcInput): Promise<ArcOutcome>;
|
|
26
|
-
|
|
26
|
+
previewDelivery(input?: DeliveryPreviewInput, options?: MutationObservation): Promise<DeliveryPreviewOutcome>;
|
|
27
27
|
/** One accumulator before the first admission-capable await, one projector after teardown. */
|
|
28
28
|
private local;
|
|
29
29
|
private conclude;
|