@astrosheep/keiyaku 4.5.7 → 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 +10 -0
- 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/opencode.js +3 -2
- package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +12 -11
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +33 -12
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-babysit/SKILL.md +35 -96
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +28 -49
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +21 -15
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +148 -89
- package/build/src/akuma/abort.d.ts +2 -1
- package/build/src/akuma/abort.js +6 -23
- package/build/src/akuma/akuma-handle.js +4 -2
- package/build/src/akuma/akuma-observe.d.ts +2 -0
- package/build/src/akuma/akuma-observe.js +1 -0
- package/build/src/akuma/akuma-product.js +9 -7
- package/build/src/akuma/akuma.d.ts +392 -9
- package/build/src/akuma/akuma.js +31 -1
- package/build/src/akuma/allowed.d.ts +1 -1
- package/build/src/akuma/allowed.js +1 -0
- package/build/src/akuma/archetype.js +1 -1
- package/build/src/akuma/body.d.ts +8 -5
- package/build/src/akuma/body.js +12 -5
- package/build/src/akuma/call-request.d.ts +80 -0
- package/build/src/akuma/call-request.js +211 -0
- package/build/src/akuma/heart/facts.d.ts +16 -78
- 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/heart/request-authority.d.ts +5 -4
- package/build/src/akuma/heart/request-authority.js +20 -34
- package/build/src/akuma/heart/request-rows.js +12 -23
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +5 -13
- package/build/src/akuma/index.d.ts +1 -1
- package/build/src/akuma/index.js +1 -1
- package/build/src/akuma/projection-read.d.ts +1 -0
- package/build/src/akuma/projection-read.js +8 -1
- package/build/src/akuma/projection.d.ts +907 -137
- package/build/src/akuma/projection.js +193 -9
- package/build/src/akuma/provider.d.ts +30 -3
- package/build/src/akuma/provider.js +111 -0
- package/build/src/akuma/providers/acp/core.d.ts +2 -2
- package/build/src/akuma/providers/acp/core.js +13 -6
- package/build/src/akuma/providers/acp/index.js +5 -4
- 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/claude/index.d.ts +3 -3
- package/build/src/akuma/providers/claude/index.js +16 -5
- 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/codex-app-server/index.js +18 -6
- package/build/src/akuma/providers/grok-build/index.js +5 -4
- package/build/src/akuma/providers/opencode-sdk/index.js +66 -25
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +3 -2
- package/build/src/akuma/providers/opencode-sdk/session.js +28 -11
- package/build/src/akuma/providers/pi/index.js +72 -58
- package/build/src/akuma/request-lifecycle.d.ts +4 -10
- package/build/src/akuma/request-lifecycle.js +7 -5
- package/build/src/akuma/request-rendezvous.d.ts +26 -0
- package/build/src/akuma/request-rendezvous.js +100 -0
- package/build/src/akuma/request-serve.d.ts +6 -66
- package/build/src/akuma/request-serve.js +83 -210
- package/build/src/akuma/request-wire.d.ts +109 -115
- package/build/src/akuma/request-wire.js +63 -318
- package/build/src/akuma/requests.d.ts +19 -47
- package/build/src/akuma/requests.js +51 -107
- package/build/src/akuma/turn-drive.d.ts +5 -3
- package/build/src/akuma/turn-drive.js +39 -11
- package/build/src/akuma-body.d.ts +7 -2
- package/build/src/akuma-body.js +68 -46
- package/build/src/body/amend.js +18 -19
- package/build/src/cli/accepted.d.ts +1 -1
- package/build/src/cli/accepted.js +2 -2
- package/build/src/cli/commands/akuma-invoke.d.ts +2 -0
- package/build/src/cli/commands/akuma-invoke.js +17 -9
- package/build/src/cli/commands/akuma.js +8 -8
- package/build/src/cli/commands/contract-invoke.d.ts +3 -2
- package/build/src/cli/commands/contract-invoke.js +42 -30
- package/build/src/cli/commands/contract.d.ts +16 -20
- package/build/src/cli/commands/contract.js +58 -25
- package/build/src/cli/commands/install.d.ts +2 -1
- package/build/src/cli/commands/install.js +3 -2
- package/build/src/cli/commands/task-invoke.d.ts +3 -0
- package/build/src/cli/commands/task-invoke.js +23 -140
- package/build/src/cli/commands/task.js +54 -20
- package/build/src/cli/invoke.js +39 -25
- package/build/src/cli/main.js +2 -1
- package/build/src/cli/parse.d.ts +2 -2
- package/build/src/cli/parse.js +56 -27
- package/build/src/cli/render/akuma-activity.d.ts +3 -0
- package/build/src/cli/render/akuma-activity.js +45 -29
- package/build/src/cli/render/akuma-tool.d.ts +5 -1
- package/build/src/cli/render/akuma.js +4 -8
- package/build/src/cli/render/audit.js +1 -1
- package/build/src/cli/render/catalog.js +80 -21
- package/build/src/cli/render/contract-observation.d.ts +2 -0
- package/build/src/cli/render/contract-observation.js +11 -0
- package/build/src/cli/render/contract.js +35 -62
- package/build/src/cli/render/kanshi-akuma.d.ts +8 -0
- package/build/src/cli/render/kanshi-akuma.js +132 -0
- package/build/src/cli/render/kanshi.js +131 -213
- package/build/src/cli/render/receipt.d.ts +1 -2
- package/build/src/cli/render/receipt.js +76 -26
- package/build/src/cli/render/refusal.js +2 -10
- package/build/src/cli/render/region.js +5 -2
- package/build/src/cli/render/settings.d.ts +1 -1
- package/build/src/cli/render/settings.js +27 -8
- package/build/src/cli/render/task.js +22 -5
- package/build/src/cli/render/terminal.d.ts +32 -1
- package/build/src/cli/render/terminal.js +77 -1
- package/build/src/cli/result.d.ts +3 -3
- package/build/src/cli/runtime.js +4 -2
- package/build/src/cli/selectors.d.ts +2 -1
- package/build/src/cli/selectors.js +4 -3
- package/build/src/cli/square-edge.js +120 -36
- package/build/src/cli/usage.js +2 -1
- package/build/src/contract-guidance.d.ts +5 -0
- package/build/src/contract-guidance.js +121 -0
- package/build/src/contract-worktree.d.ts +0 -1
- package/build/src/contract-worktree.js +32 -83
- package/build/src/coordination/sqlite-transaction-lock.d.ts +1 -0
- package/build/src/coordination/sqlite-transaction-lock.js +5 -0
- package/build/src/core/facts/codec.d.ts +2 -0
- package/build/src/core/facts/codec.js +4 -0
- package/build/src/core/verbs/placement.d.ts +6 -1
- package/build/src/core/verbs/placement.js +5 -3
- package/build/src/dispatch/index.d.ts +0 -2
- package/build/src/dispatch/index.js +54 -55
- package/build/src/git/admission.js +2 -2
- package/build/src/git/hooks.d.ts +9 -15
- package/build/src/git/hooks.js +23 -317
- package/build/src/git/nuke.d.ts +2 -1
- package/build/src/git/nuke.js +39 -21
- package/build/src/git/private-state-seat.d.ts +12 -0
- package/build/src/git/private-state-seat.js +39 -0
- package/build/src/git/process.d.ts +6 -0
- package/build/src/git/process.js +26 -11
- package/build/src/git/read-observation.js +29 -20
- package/build/src/git/reconcile.d.ts +13 -1
- package/build/src/git/reconcile.js +70 -11
- 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 +10 -6
- package/build/src/git/repository.js +16 -8
- package/build/src/git/target-placement.d.ts +1 -0
- package/build/src/git/target-placement.js +5 -0
- package/build/src/git/tender.d.ts +1 -0
- package/build/src/git/terminal-reconcile.d.ts +1 -1
- package/build/src/git/terminal-reconcile.js +22 -20
- package/build/src/git/workspace.d.ts +14 -0
- package/build/src/git/workspace.js +44 -0
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/read.js +16 -16
- package/build/src/kanshi/report.d.ts +2 -2
- package/build/src/library/address.d.ts +9 -3
- package/build/src/library/address.js +3 -2
- package/build/src/library/akuma-creation.d.ts +4 -3
- package/build/src/library/akuma-creation.js +19 -13
- package/build/src/library/audit.d.ts +14 -6
- package/build/src/library/audit.js +13 -23
- package/build/src/library/catalog.d.ts +3 -1
- package/build/src/library/catalog.js +20 -6
- package/build/src/library/composition.d.ts +385 -0
- package/build/src/library/composition.js +28 -0
- package/build/src/library/configuration.js +8 -2
- package/build/src/library/continuation.js +66 -30
- package/build/src/library/contract-bind.js +10 -2
- package/build/src/library/contract-forwarding-reconciliation-result.d.ts +102 -0
- package/build/src/library/contract-forwarding-reconciliation-result.js +92 -0
- package/build/src/library/contract-forwarding-result.d.ts +4464 -0
- package/build/src/library/contract-forwarding-result.js +521 -0
- package/build/src/library/contract-forwarding.d.ts +71 -0
- package/build/src/library/contract-forwarding.js +114 -0
- package/build/src/library/contract-handle.d.ts +38 -0
- package/build/src/library/contract-handle.js +314 -0
- package/build/src/library/contract-operations.d.ts +214 -69
- package/build/src/library/contract-operations.js +189 -118
- package/build/src/library/contract-types.d.ts +7 -3
- package/build/src/library/contract.d.ts +21 -34
- package/build/src/library/contract.js +29 -287
- package/build/src/library/fleet-result.d.ts +1580 -0
- package/build/src/library/fleet-result.js +98 -0
- package/build/src/library/fleet.d.ts +112 -54
- package/build/src/library/fleet.js +211 -71
- package/build/src/library/input.d.ts +3 -1
- package/build/src/library/input.js +11 -1
- package/build/src/library/keiyaku.d.ts +388 -20
- package/build/src/library/keiyaku.js +13 -21
- package/build/src/library/mutation.d.ts +3 -3
- package/build/src/library/mutation.js +5 -9
- package/build/src/library/nuke.d.ts +1 -1
- package/build/src/library/nuke.js +4 -3
- package/build/src/library/reconcile.d.ts +4 -0
- package/build/src/library/reconcile.js +2 -0
- package/build/src/library/refusal.d.ts +0 -9
- package/build/src/library/refusal.js +0 -7
- package/build/src/protocol/amend.js +56 -50
- package/build/src/protocol/attempt.d.ts +2 -0
- package/build/src/protocol/attempt.js +8 -1
- package/build/src/protocol/completion.js +7 -0
- package/build/src/protocol/deliver.js +6 -2
- package/build/src/protocol/operations.d.ts +4 -1
- package/build/src/protocol/operations.js +5 -2
- package/build/src/protocol/placement.d.ts +1 -0
- package/build/src/protocol/placement.js +52 -38
- package/build/src/protocol/read/observation.d.ts +1 -4
- package/build/src/protocol/read/observation.js +2 -15
- package/build/src/protocol/reintegrate.js +62 -58
- package/build/src/protocol/review.js +5 -0
- package/build/src/protocol/run.js +17 -13
- package/build/src/runtime/proc/run.d.ts +9 -0
- package/build/src/runtime/proc/run.js +51 -4
- package/build/src/runtime/proc/termination.js +26 -22
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/settlement/holder.d.ts +2 -1
- package/build/src/settlement/holder.js +15 -4
- package/build/src/settlement/settle.js +99 -33
- package/build/src/task/board.d.ts +68 -27
- package/build/src/task/board.js +31 -1
- package/build/src/task/catalog.d.ts +4 -0
- package/build/src/task/catalog.js +23 -0
- package/build/src/task/compose-language.js +33 -7
- package/build/src/task/compose-parser.d.ts +1 -1
- package/build/src/task/compose-parser.js +1 -1
- package/build/src/task/compose.js +2 -0
- package/build/src/task/index.d.ts +12 -4
- package/build/src/task/index.js +97 -16
- package/build/src/task/mutation-result.d.ts +923 -0
- package/build/src/task/mutation-result.js +140 -0
- package/build/src/task/mutation.d.ts +552 -28
- package/build/src/task/mutation.js +304 -97
- package/build/src/task/operations.d.ts +1 -4
- package/build/src/task/operations.js +0 -6
- package/build/src/task/public.d.ts +2 -0
- package/build/src/task/public.js +1 -0
- package/build/src/workspace-place.d.ts +7 -2
- package/build/src/workspace-place.js +34 -24
- package/build/src/world.d.ts +1 -0
- package/build/src/world.js +11 -0
- package/package.json +8 -6
- package/build/src/akuma/request-execution.d.ts +0 -8
- package/build/src/akuma/request-execution.js +0 -98
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
function overlapBlocks(overlaps) {
|
|
2
2
|
return overlaps.flatMap((overlap) => {
|
|
3
|
-
const
|
|
3
|
+
const patterns = overlap.patterns.filter((pattern) => pattern.mine !== pattern.theirs);
|
|
4
|
+
if (patterns.length === 0)
|
|
5
|
+
return [`overlap ${overlap.contract} exact match`];
|
|
6
|
+
const count = patterns.length;
|
|
4
7
|
return [
|
|
5
8
|
`overlap ${overlap.contract} ${count} ${count === 1 ? "pair" : "pairs"}`,
|
|
6
|
-
...
|
|
9
|
+
...patterns.map((pattern) => ` ${pattern.mine} ~ ${pattern.theirs}`),
|
|
7
10
|
];
|
|
8
11
|
});
|
|
9
12
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { Settings } from "../../settings.js";
|
|
2
2
|
export declare function settingsJsonValue(value: Settings): unknown;
|
|
3
|
-
export declare function renderSettingsText(value: Settings): string;
|
|
3
|
+
export declare function renderSettingsText(value: Settings, columns?: number): string;
|
|
@@ -1,11 +1,19 @@
|
|
|
1
|
+
import { displayColumns, renderTextBlock } from "./terminal.js";
|
|
1
2
|
function namespaceNames(value) {
|
|
2
3
|
return [
|
|
3
4
|
...new Set([value.scopes.user, value.scopes.project].flatMap((scope) => (scope.kind === "read" ? scope.namespaces : []))),
|
|
4
5
|
].sort();
|
|
5
6
|
}
|
|
6
|
-
function
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
function jsonLines(value, indent) {
|
|
8
|
+
return JSON.stringify(value, null, 2)
|
|
9
|
+
.split("\n")
|
|
10
|
+
.map((line) => `${indent}${line}`);
|
|
11
|
+
}
|
|
12
|
+
function labeledTokens(label, tokens, indent, columns) {
|
|
13
|
+
const inline = [label, ...tokens].filter((part) => part.length > 0).join(" ");
|
|
14
|
+
if (displayColumns(`${indent}${inline}`) <= columns)
|
|
15
|
+
return [`${indent}${inline}`];
|
|
16
|
+
return [...renderTextBlock(label, indent, columns), ...tokens.map((token) => `${indent} ${token}`)];
|
|
9
17
|
}
|
|
10
18
|
export function settingsJsonValue(value) {
|
|
11
19
|
return {
|
|
@@ -13,18 +21,29 @@ export function settingsJsonValue(value) {
|
|
|
13
21
|
namespaces: namespaceNames(value).map((name) => value.namespace(name)),
|
|
14
22
|
};
|
|
15
23
|
}
|
|
16
|
-
export function renderSettingsText(value) {
|
|
17
|
-
const lines = [
|
|
24
|
+
export function renderSettingsText(value, columns = 80) {
|
|
25
|
+
const lines = [
|
|
26
|
+
"settings",
|
|
27
|
+
...scopeLines("user", value.scopes.user, columns),
|
|
28
|
+
...scopeLines("project", value.scopes.project, columns),
|
|
29
|
+
];
|
|
18
30
|
for (const name of namespaceNames(value)) {
|
|
19
31
|
const view = value.namespace(name);
|
|
20
|
-
lines.push(`namespace ${name} ${view.kind}
|
|
32
|
+
lines.push(...renderTextBlock(`namespace ${name} ${view.kind}`, " ", columns));
|
|
21
33
|
if (view.kind === "failed") {
|
|
22
34
|
for (const failure of view.failures)
|
|
23
|
-
lines.push(`failure ${failure.scope} ${failure.diagnostic}
|
|
35
|
+
lines.push(...renderTextBlock(`failure ${failure.scope} ${failure.diagnostic}`, " ", columns));
|
|
24
36
|
}
|
|
25
37
|
for (const entry of view.entries) {
|
|
26
|
-
lines.push(`entry ${entry.name} ${entry.source}${entry.shadows ? " shadows user" : ""}
|
|
38
|
+
lines.push(...renderTextBlock(`entry ${entry.name} ${entry.source}${entry.shadows ? " shadows user" : ""}`, " ", columns));
|
|
39
|
+
lines.push(...jsonLines(entry.value, " "));
|
|
27
40
|
}
|
|
28
41
|
}
|
|
29
42
|
return lines.join("\n");
|
|
30
43
|
}
|
|
44
|
+
function scopeLines(name, value, columns) {
|
|
45
|
+
const tokens = value.path === undefined ? [] : [value.path];
|
|
46
|
+
if (value.kind === "failed")
|
|
47
|
+
tokens.push(value.diagnostic);
|
|
48
|
+
return labeledTokens(`${name} ${value.kind}`, tokens, " ", columns);
|
|
49
|
+
}
|
|
@@ -12,10 +12,12 @@ function markFor(word) {
|
|
|
12
12
|
return "●";
|
|
13
13
|
if (word === "ready" || word === "open")
|
|
14
14
|
return "○";
|
|
15
|
-
if (word === "blocked"
|
|
15
|
+
if (word === "blocked")
|
|
16
|
+
return "‖";
|
|
17
|
+
if (word === "missing")
|
|
16
18
|
return "!";
|
|
17
19
|
if (word === "on_hold")
|
|
18
|
-
return "
|
|
20
|
+
return "⧗";
|
|
19
21
|
if (word === "done")
|
|
20
22
|
return "✓";
|
|
21
23
|
if (word === "drop")
|
|
@@ -104,7 +106,7 @@ function compactFacts(item) {
|
|
|
104
106
|
return [
|
|
105
107
|
`updated ${updatedAge(item.updatedAt)}`,
|
|
106
108
|
...(item.bodyPresent ? [] : ["no body"]),
|
|
107
|
-
...(item.children === undefined ? [] : [`children ${item.children.live}
|
|
109
|
+
...(item.children === undefined ? [] : [`children ${item.children.live} live · ${item.children.total} total`]),
|
|
108
110
|
].join(" · ");
|
|
109
111
|
}
|
|
110
112
|
function listEntity(item, omitDisposition) {
|
|
@@ -130,6 +132,8 @@ function shellQuote(value) {
|
|
|
130
132
|
function recoveryCommand(command, total) {
|
|
131
133
|
const parts = ["keiyaku", "task", command.action];
|
|
132
134
|
if (command.action === "ls") {
|
|
135
|
+
if (command.positionals.length > 0)
|
|
136
|
+
parts.push(command.positionals[0]);
|
|
133
137
|
if (command.flags.closed === true)
|
|
134
138
|
parts.push("--closed");
|
|
135
139
|
if (command.flags.all === true)
|
|
@@ -158,8 +162,16 @@ function renderRows(command, result, columns) {
|
|
|
158
162
|
` ${recoveryCommand(command, result.value.total)}`,
|
|
159
163
|
]
|
|
160
164
|
: [];
|
|
165
|
+
const scope = command.action === "ls"
|
|
166
|
+
? command.flags.world === true
|
|
167
|
+
? "world"
|
|
168
|
+
: command.positionals.length > 0
|
|
169
|
+
? `namespace ${command.positionals[0].replace(/^task\//u, "").replace(/\/$/u, "") || "root"}`
|
|
170
|
+
: "current namespace"
|
|
171
|
+
: undefined;
|
|
172
|
+
const heading = scope === undefined ? pageHeading(view, result.value) : `${pageHeading(view, result.value)} · ${scope}`;
|
|
161
173
|
return [
|
|
162
|
-
|
|
174
|
+
heading,
|
|
163
175
|
...result.value.rows.flatMap((item) => renderListRow(item, columns, command.action === "ready")),
|
|
164
176
|
...footer,
|
|
165
177
|
].join("\n");
|
|
@@ -328,7 +340,12 @@ function renderTaskValue(command, result, columns) {
|
|
|
328
340
|
}
|
|
329
341
|
if (command.action === "compose")
|
|
330
342
|
return renderCompose(result, columns);
|
|
331
|
-
if (command.action === "
|
|
343
|
+
if (command.action === "start" ||
|
|
344
|
+
command.action === "hold" ||
|
|
345
|
+
command.action === "done" ||
|
|
346
|
+
command.action === "drop") {
|
|
347
|
+
if (!(typeof result === "object" && result !== null && "items" in result))
|
|
348
|
+
return renderMutation(command, result, columns);
|
|
332
349
|
return renderBatch(command.action, result);
|
|
333
350
|
}
|
|
334
351
|
return renderMutation(command, result, columns);
|
|
@@ -23,6 +23,37 @@ export declare function renderBoundedTextBlock(value: string, input: Readonly<{
|
|
|
23
23
|
truncated?: boolean;
|
|
24
24
|
}>): readonly string[];
|
|
25
25
|
export declare function safeText(value: string): string;
|
|
26
|
+
type CheckoutNotFollowable = Readonly<{
|
|
27
|
+
reason: "staged" | "conflict" | "untracked";
|
|
28
|
+
path: string;
|
|
29
|
+
target: string;
|
|
30
|
+
paths: readonly string[];
|
|
31
|
+
}>;
|
|
32
|
+
export declare function checkoutNotFollowableLines(refusal: CheckoutNotFollowable): readonly string[];
|
|
26
33
|
export declare function renderTextBlock(value: string, indent: string, columns: number): readonly string[];
|
|
27
34
|
export declare function renderOpaqueBlock(value: string, indent: string, columns: number): readonly string[];
|
|
28
|
-
export
|
|
35
|
+
export type SemanticTone = "dim" | "recent" | "attention" | "alert";
|
|
36
|
+
export declare const RECENT_TONE_MS: number;
|
|
37
|
+
export declare function elapsedMilliseconds(source: string | null | undefined, observedAt: string): number | null;
|
|
38
|
+
export declare function tone(value: string, kind: SemanticTone, color: boolean): string;
|
|
39
|
+
export declare function boundedActivity(value: string, columns: number, prefix: string): string;
|
|
40
|
+
export declare function plumbFacts(facts: readonly string[], columns: number): readonly string[];
|
|
41
|
+
export declare function identityLine(mark: string, identity: string, extra?: string): string;
|
|
42
|
+
export declare function entityLines(entity: Readonly<{
|
|
43
|
+
mark: string;
|
|
44
|
+
identity: string;
|
|
45
|
+
state: string;
|
|
46
|
+
title: string;
|
|
47
|
+
facts: readonly string[];
|
|
48
|
+
context: TextRenderContext;
|
|
49
|
+
}>): readonly string[];
|
|
50
|
+
export declare function renderSectionBlock({ name, unit, selector, continuation, rows, total, neutral, }: Readonly<{
|
|
51
|
+
name: string;
|
|
52
|
+
unit: string;
|
|
53
|
+
selector: string;
|
|
54
|
+
continuation?: string;
|
|
55
|
+
rows: readonly (readonly string[])[];
|
|
56
|
+
total: number;
|
|
57
|
+
neutral?: boolean;
|
|
58
|
+
}>): readonly string[];
|
|
59
|
+
export {};
|
|
@@ -118,6 +118,22 @@ export function renderBoundedTextBlock(value, input) {
|
|
|
118
118
|
export function safeText(value) {
|
|
119
119
|
return value.replaceAll(/[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/gu, (character) => (/\s/u.test(character) ? " " : "�"));
|
|
120
120
|
}
|
|
121
|
+
export function checkoutNotFollowableLines(refusal) {
|
|
122
|
+
const lines = [
|
|
123
|
+
"! checkout-not-followable",
|
|
124
|
+
` checkout: ${safeText(refusal.path)}`,
|
|
125
|
+
` target: ${safeText(refusal.target)}`,
|
|
126
|
+
` reason: ${refusal.reason}`,
|
|
127
|
+
];
|
|
128
|
+
if (refusal.paths.length === 0) {
|
|
129
|
+
lines.push(" paths: (none)");
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
lines.push(" paths:");
|
|
133
|
+
lines.push(...refusal.paths.map((path) => ` - ${JSON.stringify(path)}`));
|
|
134
|
+
}
|
|
135
|
+
return lines;
|
|
136
|
+
}
|
|
121
137
|
export function renderTextBlock(value, indent, columns) {
|
|
122
138
|
const words = safeText(value)
|
|
123
139
|
.trim()
|
|
@@ -172,8 +188,68 @@ export function renderOpaqueBlock(value, indent, columns) {
|
|
|
172
188
|
}
|
|
173
189
|
return lines;
|
|
174
190
|
}
|
|
191
|
+
export const RECENT_TONE_MS = 5 * 60 * 1_000;
|
|
192
|
+
export function elapsedMilliseconds(source, observedAt) {
|
|
193
|
+
if (source === null || source === undefined)
|
|
194
|
+
return null;
|
|
195
|
+
const sourceMs = Date.parse(source);
|
|
196
|
+
const observedMs = Date.parse(observedAt);
|
|
197
|
+
if (!Number.isFinite(sourceMs) || !Number.isFinite(observedMs))
|
|
198
|
+
return null;
|
|
199
|
+
return Math.max(0, observedMs - sourceMs);
|
|
200
|
+
}
|
|
175
201
|
export function tone(value, kind, color) {
|
|
176
202
|
if (!color)
|
|
177
203
|
return value;
|
|
178
|
-
|
|
204
|
+
const code = kind === "dim" ? 2 : kind === "recent" ? 32 : kind === "attention" ? 33 : 31;
|
|
205
|
+
return `\u001b[${code}m${value}\u001b[0m`;
|
|
206
|
+
}
|
|
207
|
+
const KANSHI_NARROW_COLUMNS = 72;
|
|
208
|
+
export function boundedActivity(value, columns, prefix) {
|
|
209
|
+
const budget = Math.max(1, columns - displayColumns(prefix));
|
|
210
|
+
return `activity "${truncateDisplayText(value, Math.max(1, budget - displayColumns('activity ""')))}` + `"`;
|
|
211
|
+
}
|
|
212
|
+
export function plumbFacts(facts, columns) {
|
|
213
|
+
const clean = facts.map(safeText).filter((fact) => fact.length > 0);
|
|
214
|
+
if (clean.length === 0)
|
|
215
|
+
return [];
|
|
216
|
+
const lines = [];
|
|
217
|
+
let current = " │ ";
|
|
218
|
+
for (const fact of clean) {
|
|
219
|
+
const candidate = current === " │ " ? ` │ ${fact}` : `${current} · ${fact}`;
|
|
220
|
+
if (current !== " │ " && displayColumns(candidate) > columns) {
|
|
221
|
+
lines.push(current);
|
|
222
|
+
current = ` │ ${fact}`;
|
|
223
|
+
}
|
|
224
|
+
else
|
|
225
|
+
current = candidate;
|
|
226
|
+
}
|
|
227
|
+
lines.push(current);
|
|
228
|
+
return lines;
|
|
229
|
+
}
|
|
230
|
+
export function identityLine(mark, identity, extra = "") {
|
|
231
|
+
return extra.length === 0 ? `${mark} ${safeText(identity)}` : `${mark} ${safeText(identity)} ${safeText(extra)}`;
|
|
232
|
+
}
|
|
233
|
+
export function entityLines(entity) {
|
|
234
|
+
const { mark, identity, state, title, facts, context } = entity;
|
|
235
|
+
if (context.columns > KANSHI_NARROW_COLUMNS) {
|
|
236
|
+
return [identityLine(mark, identity, `· ${state} · ${title}`), ...plumbFacts(facts, context.columns)];
|
|
237
|
+
}
|
|
238
|
+
return [
|
|
239
|
+
`${mark} ${safeText(state)}`,
|
|
240
|
+
` ${safeText(identity)}`,
|
|
241
|
+
...(title.length === 0 ? [] : renderTextBlock(safeText(title), " ", context.columns)),
|
|
242
|
+
...plumbFacts(facts, context.columns),
|
|
243
|
+
];
|
|
244
|
+
}
|
|
245
|
+
export function renderSectionBlock({ name, unit, selector, continuation, rows, total, neutral = false, }) {
|
|
246
|
+
const lines = [`[ ${name} ] ${total}${neutral ? ` ${unit}` : " live"}`, "", ...rows.flat()];
|
|
247
|
+
if (lines.at(-1) !== "")
|
|
248
|
+
lines.push("");
|
|
249
|
+
lines.push(rows.length === total
|
|
250
|
+
? ` (all ${total}${neutral ? "" : " live"} ${unit} shown)`
|
|
251
|
+
: ` + ${total - rows.length} more${neutral ? "" : " live"} ${unit} not shown`);
|
|
252
|
+
if (rows.length !== total)
|
|
253
|
+
lines.push(` ${continuation ?? `keiyaku ls ${selector}/`}`);
|
|
254
|
+
return lines;
|
|
179
255
|
}
|
|
@@ -27,14 +27,14 @@ export type AcceptedFact = (AcceptedFactEnvelope & Readonly<{
|
|
|
27
27
|
}>["data"];
|
|
28
28
|
}>);
|
|
29
29
|
export type Lag = ReconcileReport["lag"][number];
|
|
30
|
-
type MutationEnvelope = Pick<MutationResult<unknown>, "head" | "
|
|
30
|
+
type MutationEnvelope = Pick<MutationResult<unknown>, "head" | "settlementLags" | "recoverySnapshot">;
|
|
31
31
|
export type AcceptedEnvelope = Readonly<{
|
|
32
32
|
kind: "accepted";
|
|
33
33
|
contract: ContractId;
|
|
34
34
|
head: MutationEnvelope["head"];
|
|
35
35
|
facts: readonly AcceptedFact[];
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
settlementLags: MutationEnvelope["settlementLags"];
|
|
37
|
+
recoverySnapshot?: MutationEnvelope["recoverySnapshot"];
|
|
38
38
|
lag?: readonly [Lag, ...Lag[]];
|
|
39
39
|
}>;
|
|
40
40
|
export type AcceptedBindResult = AcceptedEnvelope & Readonly<{
|
package/build/src/cli/runtime.js
CHANGED
|
@@ -11,7 +11,7 @@ export function invocationStart(command) {
|
|
|
11
11
|
return "⧖ auditing";
|
|
12
12
|
if (command.command === "reconcile")
|
|
13
13
|
return "⧖ reconciling";
|
|
14
|
-
return command.command === "install" ? "⧖ installing
|
|
14
|
+
return command.command === "install" ? "⧖ installing harness integrations" : undefined;
|
|
15
15
|
}
|
|
16
16
|
function writeCliStream(stream, body) {
|
|
17
17
|
stream.write(body.endsWith("\n") ? body : `${body}\n`);
|
|
@@ -106,7 +106,9 @@ async function writeResult(command, result) {
|
|
|
106
106
|
if (command.command === "settings") {
|
|
107
107
|
const { renderSettingsText, settingsJsonValue } = await import("./render/settings.js");
|
|
108
108
|
const value = result.value;
|
|
109
|
-
writeCliStream(process.stdout, command.output === "json"
|
|
109
|
+
writeCliStream(process.stdout, command.output === "json"
|
|
110
|
+
? JSON.stringify(settingsJsonValue(value))
|
|
111
|
+
: renderSettingsText(value, displayContext().columns));
|
|
110
112
|
return 0;
|
|
111
113
|
}
|
|
112
114
|
if (isAkumaOutput(command, result))
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Keiyaku, type ContractBoard, type ContractId, type Repo } from "../index.js";
|
|
2
|
+
import { type ExecutionContext } from "../akuma/requests.js";
|
|
2
3
|
import type { KanshiReport } from "../kanshi/index.js";
|
|
3
4
|
export type SelectedContract = Readonly<{
|
|
4
5
|
id: ContractId;
|
|
5
6
|
contract: Keiyaku;
|
|
6
7
|
}>;
|
|
7
|
-
export declare function contractFromInput(repo: Repo, value: string): SelectedContract;
|
|
8
|
+
export declare function contractFromInput(repo: Repo, value: string, execution?: ExecutionContext): SelectedContract;
|
|
8
9
|
export declare function resolveContextualContract(board: ContractBoard, selector: string | undefined, scope: string): ContractId;
|
|
9
10
|
export declare function canonicalContractSelector(selector: string): ContractId;
|
|
10
11
|
export declare function resolveKanshiContract(report: KanshiReport, selector: string): string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { resolve } from "node:path";
|
|
2
2
|
import { identitySegments } from "../identity/coordinates.js";
|
|
3
|
-
import {
|
|
3
|
+
import { keiyakuOf } from "../library/contract.js";
|
|
4
|
+
import { localExecutionContext } from "../akuma/requests.js";
|
|
4
5
|
import { CliUsageError } from "./parse.js";
|
|
5
6
|
function selectorError(message) {
|
|
6
7
|
throw new CliUsageError(message);
|
|
@@ -12,10 +13,10 @@ function activeManagedCandidates(rows) {
|
|
|
12
13
|
return [{ id: contract.id, worktreePath: contract.worktreePath }];
|
|
13
14
|
});
|
|
14
15
|
}
|
|
15
|
-
export function contractFromInput(repo, value) {
|
|
16
|
+
export function contractFromInput(repo, value, execution = localExecutionContext()) {
|
|
16
17
|
try {
|
|
17
18
|
const id = value;
|
|
18
|
-
return { id, contract:
|
|
19
|
+
return { id, contract: keiyakuOf({ repo, id }, execution) };
|
|
19
20
|
}
|
|
20
21
|
catch (error) {
|
|
21
22
|
selectorError(error instanceof Error ? error.message : String(error));
|
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
import { bindCurrentParticipant, Square, squareAssignedParticipantName,
|
|
1
|
+
import { bindCurrentParticipant, createHostLedgerPort, Square, squareAssignedParticipantName, } from "@astrosheep/square";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
2
4
|
import { keiyakuSquarePath } from "../world.js";
|
|
3
|
-
async function openKeiyakuSquare(path) {
|
|
5
|
+
async function openKeiyakuSquare(path, environment, hostLedger) {
|
|
4
6
|
try {
|
|
5
|
-
return await Square.at({ path });
|
|
7
|
+
return await Square.at({ path, env: environment, hostLedger });
|
|
6
8
|
}
|
|
7
9
|
catch (error) {
|
|
8
10
|
if (error.code !== "ENOENT" && error.code !== "unavailable")
|
|
9
11
|
throw error;
|
|
10
12
|
try {
|
|
11
|
-
return await Square.build({ path, markdown: "" });
|
|
13
|
+
return await Square.build({ path, markdown: "", env: environment, hostLedger });
|
|
12
14
|
}
|
|
13
15
|
catch (buildError) {
|
|
14
16
|
try {
|
|
15
|
-
return await Square.at({ path });
|
|
17
|
+
return await Square.at({ path, env: environment, hostLedger });
|
|
16
18
|
}
|
|
17
19
|
catch {
|
|
18
20
|
throw buildError;
|
|
@@ -20,56 +22,138 @@ async function openKeiyakuSquare(path) {
|
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
24
|
}
|
|
25
|
+
function squareInvocationEnvironment(environment, path) {
|
|
26
|
+
const ledgerRoot = environment.SQUARE_REGISTRY === undefined ? undefined : dirname(environment.SQUARE_REGISTRY);
|
|
27
|
+
return {
|
|
28
|
+
...environment,
|
|
29
|
+
SQUARE_HOST_LEDGER_USER: environment.SQUARE_HOST_LEDGER_USER ?? ledgerRoot ?? join(homedir(), ".square", "host-ledger"),
|
|
30
|
+
SQUARE_HOST_LEDGER_LOCAL: environment.SQUARE_HOST_LEDGER_LOCAL ??
|
|
31
|
+
ledgerRoot ??
|
|
32
|
+
join(environment.PWD ?? dirname(path), ".square", "host-ledger"),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function invocationHostLedger(environment) {
|
|
36
|
+
return createHostLedgerPort({
|
|
37
|
+
userPath: environment.SQUARE_HOST_LEDGER_USER,
|
|
38
|
+
localPath: environment.SQUARE_HOST_LEDGER_LOCAL,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
async function participantBindings(hostLedger, path, name) {
|
|
42
|
+
return await hostLedger.listPresence({ location: path, participant: name });
|
|
43
|
+
}
|
|
44
|
+
function presenceKey({ location, participant, session, channel }) {
|
|
45
|
+
return JSON.stringify([location, participant, session, channel]);
|
|
46
|
+
}
|
|
47
|
+
function exactPresenceKey({ location, participant, session, channel }) {
|
|
48
|
+
return { location, participant, session, channel };
|
|
49
|
+
}
|
|
50
|
+
async function bestEffort(operation) {
|
|
51
|
+
try {
|
|
52
|
+
await operation();
|
|
53
|
+
}
|
|
54
|
+
catch { }
|
|
55
|
+
}
|
|
56
|
+
async function rollbackSquareEdge(input) {
|
|
57
|
+
const { path, environment, hostLedger, name, allocated, joined, listening, createdBindings } = input;
|
|
58
|
+
if (listening || joined) {
|
|
59
|
+
let square;
|
|
60
|
+
await bestEffort(async () => {
|
|
61
|
+
square = await Square.at({ path, env: environment, hostLedger });
|
|
62
|
+
});
|
|
63
|
+
let participant;
|
|
64
|
+
if (square !== undefined)
|
|
65
|
+
await bestEffort(async () => {
|
|
66
|
+
participant = await square.join(name);
|
|
67
|
+
});
|
|
68
|
+
if (participant !== undefined && listening)
|
|
69
|
+
await bestEffort(async () => participant.ignore(allocated.id));
|
|
70
|
+
if (participant !== undefined && joined)
|
|
71
|
+
await bestEffort(async () => participant.done());
|
|
72
|
+
if (square !== undefined)
|
|
73
|
+
await bestEffort(async () => square.close());
|
|
74
|
+
}
|
|
75
|
+
for (const binding of createdBindings)
|
|
76
|
+
await bestEffort(async () => hostLedger.removePresence(binding));
|
|
77
|
+
}
|
|
23
78
|
export async function recognizeAndListen(worldRoot, environment, allocated) {
|
|
24
|
-
const name = squareAssignedParticipantName(environment);
|
|
25
|
-
if (name === undefined)
|
|
26
|
-
return;
|
|
27
79
|
const path = keiyakuSquarePath(worldRoot);
|
|
28
|
-
const
|
|
80
|
+
const squareEnvironment = squareInvocationEnvironment(environment, path);
|
|
81
|
+
let name;
|
|
82
|
+
try {
|
|
83
|
+
const assigned = squareAssignedParticipantName(squareEnvironment);
|
|
84
|
+
if (assigned === undefined)
|
|
85
|
+
return;
|
|
86
|
+
name = assigned;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const hostLedger = invocationHostLedger(squareEnvironment);
|
|
29
92
|
let joined = false;
|
|
30
|
-
let bound = false;
|
|
31
93
|
let listening = false;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
94
|
+
let bindingsBeforeCall = [];
|
|
95
|
+
let hasBindingSnapshot = false;
|
|
96
|
+
let createdBindings = [];
|
|
97
|
+
const rememberCreatedBindings = async () => {
|
|
98
|
+
const beforeKeys = new Set(bindingsBeforeCall.map(presenceKey));
|
|
99
|
+
createdBindings = (await participantBindings(hostLedger, path, name))
|
|
100
|
+
.filter((binding) => !beforeKeys.has(presenceKey(binding)))
|
|
101
|
+
.map(exactPresenceKey);
|
|
102
|
+
};
|
|
103
|
+
const refreshCreatedBindings = async () => {
|
|
104
|
+
try {
|
|
105
|
+
await rememberCreatedBindings();
|
|
45
106
|
}
|
|
46
|
-
|
|
47
|
-
await unbindCurrentParticipant(path, name, environment);
|
|
107
|
+
catch { }
|
|
48
108
|
};
|
|
109
|
+
const rollback = async () => await rollbackSquareEdge({
|
|
110
|
+
path,
|
|
111
|
+
environment: squareEnvironment,
|
|
112
|
+
hostLedger,
|
|
113
|
+
name,
|
|
114
|
+
allocated,
|
|
115
|
+
joined,
|
|
116
|
+
listening,
|
|
117
|
+
createdBindings,
|
|
118
|
+
});
|
|
119
|
+
let square;
|
|
49
120
|
try {
|
|
121
|
+
bindingsBeforeCall = await participantBindings(hostLedger, path, name);
|
|
122
|
+
hasBindingSnapshot = true;
|
|
123
|
+
square = await openKeiyakuSquare(path, squareEnvironment, hostLedger);
|
|
50
124
|
const joinedResult = await square.joinWithActivity(name);
|
|
51
125
|
joined = joinedResult.activity !== null;
|
|
52
126
|
const participant = joinedResult.participant;
|
|
53
|
-
|
|
127
|
+
await bindCurrentParticipant(path, name, squareEnvironment);
|
|
128
|
+
await rememberCreatedBindings();
|
|
54
129
|
const listener = participant;
|
|
55
|
-
|
|
130
|
+
let change;
|
|
131
|
+
try {
|
|
132
|
+
change = await listener.listen(allocated.id);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// Keep birth independent from an older or drifting Square name grammar.
|
|
136
|
+
await refreshCreatedBindings();
|
|
137
|
+
await rollback();
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
56
140
|
listening = change.activity !== null;
|
|
141
|
+
await square.close();
|
|
142
|
+
square = undefined;
|
|
57
143
|
return {
|
|
58
144
|
committed: true,
|
|
59
145
|
participantName: name,
|
|
60
146
|
rollback,
|
|
61
147
|
};
|
|
62
148
|
}
|
|
63
|
-
catch
|
|
64
|
-
|
|
65
|
-
await
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
/* preserve the original Square edge failure */
|
|
69
|
-
}
|
|
70
|
-
throw error;
|
|
149
|
+
catch {
|
|
150
|
+
if (hasBindingSnapshot)
|
|
151
|
+
await refreshCreatedBindings();
|
|
152
|
+
await rollback();
|
|
153
|
+
return;
|
|
71
154
|
}
|
|
72
155
|
finally {
|
|
73
|
-
|
|
156
|
+
if (square !== undefined)
|
|
157
|
+
await square.close().catch(() => undefined);
|
|
74
158
|
}
|
|
75
159
|
}
|
package/build/src/cli/usage.js
CHANGED
|
@@ -17,7 +17,8 @@ export function usageLine(usage) {
|
|
|
17
17
|
.map((line, index) => {
|
|
18
18
|
if (index === 0)
|
|
19
19
|
return `usage: keiyaku ${line}`;
|
|
20
|
-
|
|
20
|
+
const continuation = line.trimStart();
|
|
21
|
+
return ` keiyaku ${continuation.startsWith("keiyaku ") ? continuation.slice("keiyaku ".length) : continuation}`;
|
|
21
22
|
})
|
|
22
23
|
.join("\n");
|
|
23
24
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ContractId, ContractState } from "./core/facts/types.js";
|
|
2
|
+
export declare const CONTRACT_DELIVERER_SKILL: string;
|
|
3
|
+
export declare const CONTRACT_REVIEWER_SKILL: string;
|
|
4
|
+
export declare function renderContractAppointment(contract: ContractId): string;
|
|
5
|
+
export declare function renderContractGuidance(state: ContractState): string;
|