@astrosheep/keiyaku 4.0.1 → 4.0.2
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 +137 -5
- package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -3
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +91 -35
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +98 -58
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +152 -53
- package/build/src/akuma/abort.d.ts +2 -0
- package/build/src/akuma/abort.js +50 -0
- package/build/src/akuma/akuma.d.ts +23 -14
- package/build/src/akuma/akuma.js +120 -104
- package/build/src/akuma/archetype.d.ts +7 -6
- package/build/src/akuma/archetype.js +68 -41
- package/build/src/akuma/body.d.ts +3 -5
- package/build/src/akuma/body.js +408 -213
- package/build/src/akuma/heart/facts.d.ts +25 -34
- package/build/src/akuma/heart/facts.js +18 -7
- package/build/src/akuma/heart/index.d.ts +39 -42
- package/build/src/akuma/heart/index.js +134 -93
- package/build/src/akuma/heart/rows.d.ts +9 -31
- package/build/src/akuma/heart/rows.js +26 -44
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +7 -15
- package/build/src/akuma/heart/soul.d.ts +8 -0
- package/build/src/akuma/heart/soul.js +136 -0
- package/build/src/akuma/heart/storage.d.ts +28 -14
- package/build/src/akuma/heart/storage.js +86 -26
- package/build/src/akuma/identity.d.ts +2 -2
- package/build/src/akuma/identity.js +9 -9
- package/build/src/akuma/index.d.ts +6 -1
- package/build/src/akuma/index.js +6 -0
- package/build/src/akuma/projection.d.ts +117 -38
- package/build/src/akuma/projection.js +208 -97
- package/build/src/akuma/provider-recipe.d.ts +24 -0
- package/build/src/akuma/provider-recipe.js +100 -0
- package/build/src/akuma/provider.d.ts +12 -4
- package/build/src/akuma/provider.js +117 -70
- package/build/src/akuma/providers/acp/core.d.ts +19 -0
- package/build/src/akuma/providers/acp/core.js +159 -0
- package/build/src/akuma/providers/acp/events.d.ts +20 -0
- package/build/src/akuma/providers/acp/events.js +73 -0
- package/build/src/akuma/providers/acp/index.d.ts +12 -0
- package/build/src/akuma/providers/acp/index.js +94 -0
- package/build/src/akuma/providers/claude/events.js +66 -13
- package/build/src/akuma/providers/claude/index.d.ts +2 -1
- package/build/src/akuma/providers/claude/index.js +35 -21
- package/build/src/akuma/providers/codex-app-server/events.js +4 -1
- package/build/src/akuma/providers/codex-app-server/index.d.ts +3 -3
- package/build/src/akuma/providers/codex-app-server/index.js +24 -31
- package/build/src/akuma/providers/grok-build/index.d.ts +4 -0
- package/build/src/akuma/providers/grok-build/index.js +70 -0
- package/build/src/akuma/providers/index.d.ts +5 -3
- package/build/src/akuma/providers/index.js +24 -59
- package/build/src/akuma/providers/opencode-sdk/events.d.ts +40 -34
- package/build/src/akuma/providers/opencode-sdk/events.js +220 -101
- package/build/src/akuma/providers/opencode-sdk/index.d.ts +3 -2
- package/build/src/akuma/providers/opencode-sdk/index.js +233 -128
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +11 -26
- package/build/src/akuma/providers/opencode-sdk/session.js +10 -9
- package/build/src/akuma/providers/pi/events.js +49 -11
- package/build/src/akuma/providers/pi/index.d.ts +1 -1
- package/build/src/akuma/providers/pi/index.js +50 -21
- package/build/src/akuma/publication.d.ts +3 -3
- package/build/src/akuma/publication.js +28 -40
- package/build/src/akuma/requests.d.ts +9 -7
- package/build/src/akuma/requests.js +92 -65
- package/build/src/alias/index.d.ts +2 -2
- package/build/src/alias/index.js +10 -10
- package/build/src/body/decode.js +7 -1
- package/build/src/body/region.d.ts +2 -0
- package/build/src/body/region.js +77 -7
- package/build/src/cli/accepted.d.ts +17 -13
- package/build/src/cli/accepted.js +72 -34
- package/build/src/cli/actor.js +3 -3
- package/build/src/cli/commands/akuma-invoke.d.ts +4 -3
- package/build/src/cli/commands/akuma-invoke.js +14 -9
- package/build/src/cli/commands/akuma.d.ts +13 -3
- package/build/src/cli/commands/akuma.js +67 -34
- package/build/src/cli/commands/contract.d.ts +18 -5
- package/build/src/cli/commands/contract.js +9 -3
- package/build/src/cli/commands/task-invoke.d.ts +17 -4
- package/build/src/cli/commands/task-invoke.js +43 -20
- package/build/src/cli/commands/task-query.d.ts +5 -0
- package/build/src/cli/commands/task-query.js +247 -0
- package/build/src/cli/commands/task.d.ts +3 -1
- package/build/src/cli/commands/task.js +51 -13
- package/build/src/cli/coordinates.d.ts +18 -0
- package/build/src/cli/coordinates.js +120 -0
- package/build/src/cli/draft.d.ts +8 -0
- package/build/src/cli/draft.js +96 -0
- package/build/src/cli/invoke.d.ts +4 -3
- package/build/src/cli/invoke.js +160 -179
- package/build/src/cli/main.js +34 -6
- package/build/src/cli/parse.d.ts +9 -2
- package/build/src/cli/parse.js +29 -7
- package/build/src/cli/render/akuma-tool-command.d.ts +6 -0
- package/build/src/cli/render/akuma-tool-command.js +144 -0
- package/build/src/cli/render/akuma-tool.d.ts +2 -2
- package/build/src/cli/render/akuma-tool.js +30 -4
- package/build/src/cli/render/akuma.d.ts +1 -0
- package/build/src/cli/render/akuma.js +211 -116
- package/build/src/cli/render/audit.d.ts +3 -0
- package/build/src/cli/render/audit.js +104 -0
- package/build/src/cli/render/contract.d.ts +3 -3
- package/build/src/cli/render/contract.js +192 -79
- package/build/src/cli/render/kanshi.js +263 -168
- package/build/src/cli/render/receipt.d.ts +19 -0
- package/build/src/cli/render/receipt.js +106 -0
- package/build/src/cli/render/refusal.d.ts +16 -2
- package/build/src/cli/render/refusal.js +88 -20
- package/build/src/cli/render/region.d.ts +2 -0
- package/build/src/cli/render/region.js +17 -0
- package/build/src/cli/render/task.d.ts +2 -1
- package/build/src/cli/render/task.js +223 -60
- package/build/src/cli/render/terminal.d.ts +7 -0
- package/build/src/cli/render/terminal.js +46 -0
- package/build/src/cli/render/text.js +6 -3
- package/build/src/cli/result.d.ts +115 -20
- package/build/src/cli/usage.d.ts +1 -0
- package/build/src/cli/usage.js +3 -0
- package/build/src/contract-worktree.d.ts +6 -5
- package/build/src/contract-worktree.js +95 -57
- package/build/src/coordination/durable-file.d.ts +4 -3
- package/build/src/coordination/durable-file.js +29 -25
- package/build/src/coordination/sqlite-transaction-lock.d.ts +4 -0
- package/build/src/coordination/sqlite-transaction-lock.js +22 -5
- package/build/src/core/facts/fold.js +1 -6
- package/build/src/core/facts/gate.d.ts +1 -0
- package/build/src/core/facts/gate.js +1 -0
- package/build/src/core/verbs/amend.d.ts +1 -1
- package/build/src/core/verbs/amend.js +0 -11
- package/build/src/core/verbs/deliver.d.ts +1 -1
- package/build/src/core/verbs/deliver.js +1 -7
- package/build/src/core/verbs/placement.d.ts +1 -1
- package/build/src/core/verbs/placement.js +4 -1
- package/build/src/dispatch/index.d.ts +2 -2
- package/build/src/dispatch/index.js +17 -17
- package/build/src/git/admission.d.ts +1 -1
- package/build/src/git/admission.js +11 -11
- package/build/src/git/hooks.js +13 -13
- package/build/src/git/integration.d.ts +14 -15
- package/build/src/git/integration.js +80 -44
- package/build/src/git/observe.d.ts +5 -3
- package/build/src/git/observe.js +18 -12
- package/build/src/git/read-observation.js +9 -9
- package/build/src/git/reconcile.d.ts +2 -0
- package/build/src/git/reconcile.js +138 -95
- package/build/src/git/repository.d.ts +27 -19
- package/build/src/git/repository.js +155 -83
- package/build/src/git/scratch.d.ts +7 -3
- package/build/src/git/scratch.js +44 -37
- package/build/src/git/target-placement.d.ts +40 -4
- package/build/src/git/target-placement.js +221 -101
- package/build/src/git/tender.d.ts +6 -5
- package/build/src/git/tender.js +24 -43
- package/build/src/git/terminal-seal.d.ts +1 -1
- package/build/src/git/terminal-seal.js +7 -5
- package/build/src/git/workspace.d.ts +36 -4
- package/build/src/git/workspace.js +53 -18
- package/build/src/identity/selector.js +1 -1
- package/build/src/index.d.ts +3 -3
- package/build/src/index.js +1 -1
- package/build/src/kanshi/index.d.ts +2 -2
- package/build/src/kanshi/index.js +1 -1
- package/build/src/kanshi/read.d.ts +2 -1
- package/build/src/kanshi/read.js +118 -27
- package/build/src/kanshi/report.d.ts +50 -0
- package/build/src/kanshi/select.d.ts +5 -0
- package/build/src/kanshi/select.js +32 -0
- package/build/src/library/address.d.ts +12 -3
- package/build/src/library/address.js +77 -46
- package/build/src/library/akuma-creation.d.ts +6 -1
- package/build/src/library/akuma-creation.js +86 -13
- package/build/src/library/audit.d.ts +18 -0
- package/build/src/library/audit.js +44 -0
- package/build/src/library/bind.js +4 -4
- package/build/src/library/catalog.d.ts +1 -1
- package/build/src/library/catalog.js +5 -8
- package/build/src/library/contract.d.ts +5 -6
- package/build/src/library/contract.js +11 -35
- package/build/src/library/delivery.d.ts +2 -1
- package/build/src/library/fleet.d.ts +2 -2
- package/build/src/library/fleet.js +35 -71
- package/build/src/library/keiyaku.d.ts +3 -2
- package/build/src/library/keiyaku.js +1 -0
- package/build/src/library/mutation.d.ts +7 -6
- package/build/src/library/mutation.js +23 -25
- package/build/src/library/reconcile.d.ts +29 -0
- package/build/src/library/reconcile.js +179 -0
- package/build/src/library/region.d.ts +12 -0
- package/build/src/library/region.js +15 -1
- package/build/src/library/repo.d.ts +4 -16
- package/build/src/library/repo.js +13 -38
- package/build/src/protocol/attempt.js +6 -6
- package/build/src/protocol/bind.js +4 -4
- package/build/src/protocol/intent.d.ts +15 -2
- package/build/src/protocol/intent.js +21 -6
- package/build/src/protocol/operations.d.ts +73 -22
- package/build/src/protocol/operations.js +292 -88
- package/build/src/protocol/outcome.d.ts +9 -3
- package/build/src/protocol/outcome.js +3 -1
- package/build/src/protocol/placement.d.ts +15 -4
- package/build/src/protocol/placement.js +58 -25
- package/build/src/protocol/read/status.d.ts +8 -1
- package/build/src/protocol/read/status.js +61 -14
- package/build/src/runtime/proc/line-rpc.d.ts +3 -8
- package/build/src/runtime/proc/line-rpc.js +16 -43
- package/build/src/runtime/proc/run.d.ts +15 -29
- package/build/src/runtime/proc/run.js +113 -105
- package/build/src/runtime/proc/stdio.d.ts +18 -0
- package/build/src/runtime/proc/stdio.js +58 -0
- package/build/src/settings.d.ts +2 -2
- package/build/src/settings.js +8 -8
- package/build/src/settlement/fence.d.ts +0 -4
- package/build/src/settlement/fence.js +0 -9
- package/build/src/settlement/holder.d.ts +11 -1
- package/build/src/settlement/holder.js +25 -0
- package/build/src/settlement/settle.d.ts +1 -1
- package/build/src/settlement/settle.js +52 -89
- package/build/src/task/board.d.ts +3 -3
- package/build/src/task/board.js +6 -9
- package/build/src/task/compose.d.ts +1 -1
- package/build/src/task/compose.js +18 -10
- package/build/src/task/context.d.ts +3 -3
- package/build/src/task/context.js +14 -14
- package/build/src/task/document.d.ts +2 -1
- package/build/src/task/document.js +15 -5
- package/build/src/task/index.d.ts +19 -7
- package/build/src/task/index.js +42 -23
- package/build/src/task/operations.d.ts +15 -9
- package/build/src/task/operations.js +78 -48
- package/build/src/task/query.d.ts +67 -0
- package/build/src/task/query.js +279 -0
- package/build/src/task/store.d.ts +2 -2
- package/build/src/task/store.js +40 -25
- package/build/src/verification/execution.d.ts +4 -2
- package/build/src/verification/execution.js +9 -5
- package/build/src/workspace-place.d.ts +41 -0
- package/build/src/workspace-place.js +386 -0
- package/build/src/world.d.ts +13 -2
- package/build/src/world.js +81 -48
- package/package.json +3 -2
- package/build/src/protocol/read/audit.d.ts +0 -31
- package/build/src/protocol/read/audit.js +0 -55
|
@@ -1,21 +1,89 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
import { displayColumns, gitShortStat, renderOpaqueBlock, safeText } from "./terminal.js";
|
|
2
|
+
function isRecord(value) {
|
|
3
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
function wrap(lines, text, indent, columns) {
|
|
6
|
+
lines.push(...renderOpaqueBlock(text, indent, columns));
|
|
7
|
+
}
|
|
8
|
+
function collectionLines(name, members, indent, columns) {
|
|
9
|
+
if (members.length === 0)
|
|
10
|
+
return renderOpaqueBlock(`${name} 0`, indent, columns);
|
|
11
|
+
return [
|
|
12
|
+
...renderOpaqueBlock(name, indent, columns),
|
|
13
|
+
...members.flatMap((member) => renderOpaqueBlock(member, `${indent}│ `, columns)),
|
|
14
|
+
];
|
|
15
|
+
}
|
|
16
|
+
function skipAddressedContract(addressed, contractId) {
|
|
17
|
+
return addressed !== undefined && contractId === addressed;
|
|
18
|
+
}
|
|
19
|
+
function refusalIdentity(refusal, addressed) {
|
|
20
|
+
const contractId = "contractId" in refusal ? refusal.contractId : undefined;
|
|
21
|
+
return skipAddressedContract(addressed, contractId) ? undefined : contractId;
|
|
22
|
+
}
|
|
23
|
+
function refusalHead(kind, identity, details) {
|
|
24
|
+
return [kind, identity === undefined ? undefined : `contractId=${identity}`, ...details]
|
|
25
|
+
.filter((part) => part !== undefined).join(" ");
|
|
26
|
+
}
|
|
27
|
+
function renderDirtyRefusal(refusal, indent, columns, identity) {
|
|
28
|
+
const lines = [];
|
|
29
|
+
wrap(lines, refusalHead(refusal.kind, identity, []), indent, columns);
|
|
30
|
+
for (const name of ["staged", "unstaged", "untracked", "submodules"]) {
|
|
31
|
+
lines.push(...collectionLines(name, refusal[name], indent, columns));
|
|
32
|
+
}
|
|
33
|
+
wrap(lines, gitShortStat(refusal.shortStat), indent, columns);
|
|
34
|
+
if (refusal.option !== undefined) {
|
|
35
|
+
wrap(lines, `option ${refusal.option.flag} ${refusal.option.available ? "available" : "unavailable"}`, indent, columns);
|
|
36
|
+
}
|
|
37
|
+
return lines;
|
|
38
|
+
}
|
|
39
|
+
export function renderRefusalFacts(refusal, indent, columns, addressed) {
|
|
40
|
+
const identity = refusalIdentity(refusal, addressed);
|
|
41
|
+
if (refusal.kind === "dirty-workspace")
|
|
42
|
+
return renderDirtyRefusal(refusal, indent, columns, identity);
|
|
43
|
+
if (refusal.kind === "integration-failed") {
|
|
44
|
+
const lines = [
|
|
45
|
+
...renderOpaqueBlock(refusalHead(refusal.kind, identity, [`reason=${refusal.reason}`, `targetHead=${refusal.targetHead}`]), indent, columns),
|
|
46
|
+
];
|
|
47
|
+
if (refusal.conflictPaths !== undefined)
|
|
48
|
+
lines.push(...collectionLines("conflictPaths", refusal.conflictPaths, indent, columns));
|
|
49
|
+
return lines;
|
|
50
|
+
}
|
|
51
|
+
if (refusal.kind === "integration-unsupported") {
|
|
52
|
+
return renderOpaqueBlock(refusalHead(refusal.kind, identity, [`requiredGit=${refusal.requiredGit}`]), indent, columns);
|
|
53
|
+
}
|
|
54
|
+
if (refusal.kind === "checkout-not-followable") {
|
|
55
|
+
const lines = [...renderOpaqueBlock(refusalHead(refusal.kind, identity, [`target=${refusal.target}`, `path=${refusal.path}`, `reason=${refusal.reason}`]), indent, columns)];
|
|
56
|
+
lines.push(...collectionLines("paths", refusal.paths, indent, columns));
|
|
57
|
+
return lines;
|
|
58
|
+
}
|
|
59
|
+
if (refusal.kind === "workspace-not-on-target") {
|
|
60
|
+
return renderOpaqueBlock(refusalHead(refusal.kind, identity, [`target=${refusal.target}`, `branch=${refusal.branch}`]), indent, columns);
|
|
61
|
+
}
|
|
62
|
+
if (refusal.kind === "here-target-mismatch") {
|
|
63
|
+
return renderOpaqueBlock(`here-target-mismatch target=${refusal.target} branch=${refusal.branch}`, indent, columns);
|
|
64
|
+
}
|
|
65
|
+
if (refusal.kind === "here-worktree-appointed") {
|
|
66
|
+
return renderOpaqueBlock(refusalHead(refusal.kind, undefined, [refusal.contract === undefined ? "" : `contract=${refusal.contract}`, `path=${refusal.path}`]), indent, columns);
|
|
67
|
+
}
|
|
68
|
+
return renderOpaqueBlock(refusalHead(refusal.kind, identity, []), indent, columns);
|
|
69
|
+
}
|
|
70
|
+
export function renderRefusal(result, context) {
|
|
71
|
+
const columns = context?.columns ?? 80;
|
|
72
|
+
const base = `! ${result.verb} refused`;
|
|
73
|
+
const lines = result.contract === undefined
|
|
74
|
+
? [base]
|
|
75
|
+
: displayColumns(`${base} — ${result.contract}`) <= columns
|
|
76
|
+
? [`${base} — ${result.contract}`]
|
|
77
|
+
: [`${base} —`, ` ${safeText(result.contract)}`];
|
|
78
|
+
if (isRecord(result.refusal) && typeof result.refusal.kind === "string") {
|
|
79
|
+
lines.push(...renderRefusalFacts(result.refusal, " ", columns, result.contract));
|
|
80
|
+
}
|
|
81
|
+
const output = lines.join("\n");
|
|
82
|
+
return result.draft === undefined ? output : `${output}\n${renderBindDraftReceipt(result.draft)}`;
|
|
83
|
+
}
|
|
84
|
+
export function renderBindDraftReceipt(receipt) {
|
|
85
|
+
return [
|
|
86
|
+
...(receipt.path === undefined ? [] : [`draft preserved: ${receipt.path}`]),
|
|
87
|
+
...(receipt.warning === undefined ? [] : [`warning: ${receipt.warning}`]),
|
|
88
|
+
].join("\n");
|
|
21
89
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
function rows(section) {
|
|
2
|
+
if (section.kind === "absent")
|
|
3
|
+
return [];
|
|
4
|
+
if (section.kind === "failed")
|
|
5
|
+
return [`region failed ${section.failure.message}`];
|
|
6
|
+
const value = section.value;
|
|
7
|
+
if (value.kind === "declarations")
|
|
8
|
+
return value.declarations.map((declaration) => `region ${declaration.contract} ${declaration.patterns.join(" ")}`);
|
|
9
|
+
if (value.kind === "contract")
|
|
10
|
+
return [`region ${value.declaration.contract} ${value.declaration.patterns.join(" ")}`];
|
|
11
|
+
if (value.kind === "path")
|
|
12
|
+
return value.matches.map((match) => `path ${value.path} ${match.contract} ${match.pattern}`);
|
|
13
|
+
return value.intersections.flatMap((intersection) => intersection.patterns.map((pattern) => `overlap ${intersection.left} ${pattern.left} ~ ${intersection.right} ${pattern.right}`));
|
|
14
|
+
}
|
|
15
|
+
export function renderRegionText(section) {
|
|
16
|
+
return rows(section).join("\n");
|
|
17
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { TaskCompositionResult } from "../../task/index.js";
|
|
2
2
|
import type { TaskInvocationResult } from "../commands/task-invoke.js";
|
|
3
3
|
import type { ParsedTaskCommand } from "../commands/task.js";
|
|
4
|
-
|
|
4
|
+
import { type TextRenderContext } from "./terminal.js";
|
|
5
|
+
export declare function renderTaskText(command: ParsedTaskCommand, result: TaskInvocationResult, context?: TextRenderContext): string;
|
|
5
6
|
export declare function renderTaskIncompleteDiagnostic(result: TaskCompositionResult): string;
|
|
6
7
|
export declare function taskExitCode(result: TaskInvocationResult): number;
|
|
@@ -1,93 +1,256 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { outcomeLines, receiptPayload } from "./receipt.js";
|
|
2
|
+
import { displayColumns, renderTextBlock, safeText } from "./terminal.js";
|
|
3
|
+
const DEFAULT_CONTEXT = { columns: 80, color: false };
|
|
4
|
+
function isWorldObservation(result) {
|
|
5
|
+
return typeof result === "object" && result !== null
|
|
6
|
+
&& "kind" in result
|
|
7
|
+
&& (result.kind === "present" || result.kind === "absent" || result.kind === "failed");
|
|
4
8
|
}
|
|
5
|
-
function
|
|
6
|
-
|
|
9
|
+
function markFor(word) {
|
|
10
|
+
if (word === "in_progress")
|
|
11
|
+
return "●";
|
|
12
|
+
if (word === "ready" || word === "open")
|
|
13
|
+
return "○";
|
|
14
|
+
if (word === "blocked" || word === "missing")
|
|
15
|
+
return "!";
|
|
16
|
+
if (word === "on_hold")
|
|
17
|
+
return "·";
|
|
18
|
+
if (word === "done")
|
|
19
|
+
return "✓";
|
|
20
|
+
if (word === "drop")
|
|
21
|
+
return "×";
|
|
22
|
+
return "?";
|
|
7
23
|
}
|
|
8
|
-
function
|
|
9
|
-
return
|
|
24
|
+
function priorityText(priority) {
|
|
25
|
+
return priority === null ? "P?" : `P${priority}`;
|
|
10
26
|
}
|
|
11
|
-
function
|
|
27
|
+
function scanUnit(id, priority, word) {
|
|
28
|
+
return `${markFor(word)} ${id} · ${priorityText(priority)} ${word}`;
|
|
29
|
+
}
|
|
30
|
+
function entityLines(entity, columns, indent = "") {
|
|
31
|
+
const scan = `${indent}${scanUnit(entity.id, entity.priority, entity.word)}`;
|
|
32
|
+
if (entity.title === null || entity.title.length === 0)
|
|
33
|
+
return [scan];
|
|
34
|
+
const title = safeText(entity.title);
|
|
35
|
+
const inline = `${scan} — ${title}`;
|
|
36
|
+
if (displayColumns(inline) <= columns)
|
|
37
|
+
return [inline];
|
|
38
|
+
return [`${scan} —`, ...renderTextBlock(title, `${indent} `, columns)];
|
|
39
|
+
}
|
|
40
|
+
function listEntity(item) {
|
|
41
|
+
return { id: item.id, priority: item.priority, word: item.disposition, title: item.title };
|
|
42
|
+
}
|
|
43
|
+
function stateEntity(task) {
|
|
44
|
+
return { id: task.id, priority: "priority" in task && task.priority !== undefined ? task.priority : null, word: task.state, title: task.title };
|
|
45
|
+
}
|
|
46
|
+
function projectRefusal(refusal) {
|
|
47
|
+
if (refusal.kind === "task-missing")
|
|
48
|
+
return { line: `task-missing ${refusal.taskId}` };
|
|
49
|
+
if (refusal.kind === "invalid-lifecycle-transition") {
|
|
50
|
+
return { line: `invalid-lifecycle-transition ${refusal.taskId} ${refusal.state} ${refusal.verb}` };
|
|
51
|
+
}
|
|
52
|
+
if (refusal.kind === "invalid-namespace-context")
|
|
53
|
+
return { line: `invalid-namespace-context ${refusal.path}` };
|
|
54
|
+
if (refusal.kind === "relation-owned-by-other") {
|
|
55
|
+
return { line: `relation-owned-by-other ${refusal.taskId} ${refusal.related} ${refusal.declaringTask}` };
|
|
56
|
+
}
|
|
57
|
+
return { line: refusal.kind, diagnostic: refusal.diagnostic };
|
|
58
|
+
}
|
|
59
|
+
function appendDiagnostic(lines, diagnostic) {
|
|
60
|
+
if (diagnostic !== undefined)
|
|
61
|
+
receiptPayload(lines, "diagnostic", diagnostic);
|
|
62
|
+
}
|
|
63
|
+
function renderFailure(verb, result, columns) {
|
|
64
|
+
if (result.kind === "retry") {
|
|
65
|
+
return [...outcomeLines("?", verb, "retry", undefined, columns), result.reason].join("\n");
|
|
66
|
+
}
|
|
67
|
+
const lines = [...outcomeLines("!", verb, "refused", undefined, columns)];
|
|
68
|
+
const facts = projectRefusal(result.refusal);
|
|
69
|
+
lines.push(facts.line);
|
|
70
|
+
appendDiagnostic(lines, facts.diagnostic);
|
|
71
|
+
return lines.join("\n");
|
|
72
|
+
}
|
|
73
|
+
function edge(label, ref, mark) {
|
|
74
|
+
const prefix = mark === undefined ? ` ${label}` : ` ${mark} ${label}`;
|
|
75
|
+
return `${prefix} ${ref.id} · ${ref.state}`;
|
|
76
|
+
}
|
|
77
|
+
function pageHeading(view, page) {
|
|
78
|
+
if (page.truncated)
|
|
79
|
+
return `${view} ${page.returned} of ${page.total} · limit ${page.returned}`;
|
|
80
|
+
return `${view} ${page.returned}`;
|
|
81
|
+
}
|
|
82
|
+
function renderListRow(item, columns) {
|
|
83
|
+
const lines = [...entityLines(listEntity(item), columns)];
|
|
84
|
+
if ("blockers" in item) {
|
|
85
|
+
for (const blocker of item.blockers)
|
|
86
|
+
lines.push(` needs ${blocker.id} · ${blocker.state}`);
|
|
87
|
+
}
|
|
88
|
+
return lines;
|
|
89
|
+
}
|
|
90
|
+
function renderRows(command, result, columns) {
|
|
12
91
|
if (result.kind !== "accepted")
|
|
13
|
-
return
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return `${row(item)}${blockers === undefined ? "" : ` <- ${blockers}`}`;
|
|
17
|
-
}).join("\n");
|
|
92
|
+
return renderFailure(command.action, result, columns);
|
|
93
|
+
const view = command.action === "ls" ? "tasks" : command.action;
|
|
94
|
+
return [pageHeading(view, result.value), ...result.value.rows.flatMap((item) => renderListRow(item, columns))].join("\n");
|
|
18
95
|
}
|
|
19
|
-
function renderShow(result) {
|
|
96
|
+
function renderShow(result, columns) {
|
|
20
97
|
if ("kind" in result)
|
|
21
|
-
return result.kind === "accepted" ?
|
|
22
|
-
const task = result.task
|
|
23
|
-
|
|
24
|
-
|
|
98
|
+
return result.kind === "accepted" ? entityLines(stateEntity(result.value), columns).join("\n") : renderFailure("show", result, columns);
|
|
99
|
+
const task = result.task;
|
|
100
|
+
const lines = [
|
|
101
|
+
...entityLines(stateEntity(task), columns),
|
|
102
|
+
...renderTextBlock(`created ${task.createdAt} · updated ${task.updatedAt}`, "", columns),
|
|
103
|
+
...(task.createdBy === undefined ? [] : [`created-by ${task.createdBy}`]),
|
|
25
104
|
];
|
|
26
|
-
for (const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
105
|
+
for (const need of result.needs.filter((item) => !item.released))
|
|
106
|
+
lines.push(edge("needs", need, "!"));
|
|
107
|
+
for (const need of result.needs.filter((item) => item.released))
|
|
108
|
+
lines.push(edge("needs", need, "✓"));
|
|
109
|
+
for (const item of result.blocks)
|
|
110
|
+
lines.push(edge("blocks", item));
|
|
111
|
+
if (result.parent !== null)
|
|
112
|
+
lines.push(edge("parent", result.parent));
|
|
113
|
+
for (const item of result.children)
|
|
114
|
+
lines.push(edge("child", item));
|
|
115
|
+
for (const item of result.supersedes)
|
|
116
|
+
lines.push(edge("supersedes", item));
|
|
117
|
+
for (const item of result.supersededBy)
|
|
118
|
+
lines.push(edge("superseded-by", item));
|
|
119
|
+
for (const item of result.related)
|
|
120
|
+
lines.push(edge("related", item));
|
|
121
|
+
if (task.note.length > 0)
|
|
122
|
+
receiptPayload(lines, "note", task.note);
|
|
35
123
|
if (task.body.length > 0)
|
|
36
|
-
lines
|
|
124
|
+
receiptPayload(lines, "body", task.body);
|
|
37
125
|
return lines.join("\n");
|
|
38
126
|
}
|
|
39
|
-
function treeLines(node, depth = 0) {
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
127
|
+
function treeLines(node, columns, depth = 0) {
|
|
128
|
+
const indent = " ".repeat(depth);
|
|
129
|
+
if (node.cycle === true)
|
|
130
|
+
return [`${indent}! ${node.task.id} · cycle`];
|
|
131
|
+
return [
|
|
132
|
+
...entityLines(stateEntity(node.task), columns, indent),
|
|
133
|
+
...node.children.flatMap((child) => treeLines(child, columns, depth + 1)),
|
|
134
|
+
];
|
|
43
135
|
}
|
|
44
136
|
function doctorIssue(issue) {
|
|
45
137
|
if (issue.kind === "missing-target")
|
|
46
|
-
return
|
|
138
|
+
return `! missing-target ${issue.taskId} ${issue.relation} ${issue.target}`;
|
|
47
139
|
if (issue.kind === "self-relation")
|
|
48
|
-
return
|
|
49
|
-
return
|
|
140
|
+
return `! self-relation ${issue.taskId} ${issue.relation}`;
|
|
141
|
+
return `! cycle ${issue.relation} ${issue.tasks.join(" ")}`;
|
|
50
142
|
}
|
|
51
|
-
|
|
143
|
+
function renderDoctor(report) {
|
|
144
|
+
if (report.issues.length === 0)
|
|
145
|
+
return "healthy";
|
|
146
|
+
const noun = report.issues.length === 1 ? "issue" : "issues";
|
|
147
|
+
return [`${report.issues.length} ${noun}`, ...report.issues.map(doctorIssue)].join("\n");
|
|
148
|
+
}
|
|
149
|
+
function renderAcceptedMutation(verb, task, columns, documentDiff) {
|
|
150
|
+
const lines = [
|
|
151
|
+
...outcomeLines("✓", verb, "accepted", task.id, columns),
|
|
152
|
+
...entityLines(stateEntity(task), columns),
|
|
153
|
+
];
|
|
154
|
+
if (documentDiff !== undefined)
|
|
155
|
+
receiptPayload(lines, "diff", documentDiff);
|
|
156
|
+
return lines.join("\n");
|
|
157
|
+
}
|
|
158
|
+
function renderMutation(command, result, columns) {
|
|
159
|
+
if (result.kind !== "accepted")
|
|
160
|
+
return renderFailure(command.action, result, columns);
|
|
161
|
+
if (command.action !== "update") {
|
|
162
|
+
return renderAcceptedMutation(command.action, result.value, columns);
|
|
163
|
+
}
|
|
164
|
+
const value = result.value;
|
|
165
|
+
return renderAcceptedMutation(command.action, value.task, columns, value.documentDiff);
|
|
166
|
+
}
|
|
167
|
+
function renderBatchItem(verb, item) {
|
|
168
|
+
if (item.outcome.kind === "accepted")
|
|
169
|
+
return `✓ ${verb} ${item.id}`;
|
|
170
|
+
if (item.outcome.kind === "retry")
|
|
171
|
+
return `? ${verb} ${item.id} · ${item.outcome.reason}`;
|
|
172
|
+
const facts = projectRefusal(item.outcome.refusal);
|
|
173
|
+
const lines = [`! ${verb} ${item.id} · ${facts.line}`];
|
|
174
|
+
appendDiagnostic(lines, facts.diagnostic);
|
|
175
|
+
return lines.join("\n");
|
|
176
|
+
}
|
|
177
|
+
function renderBatch(verb, batch) {
|
|
178
|
+
return batch.items.map((item) => renderBatchItem(verb, item)).join("\n");
|
|
179
|
+
}
|
|
180
|
+
function composeDiffs(lines, changes) {
|
|
181
|
+
for (const change of changes)
|
|
182
|
+
receiptPayload(lines, `diff ${change.taskId}`, change.documentDiff);
|
|
183
|
+
}
|
|
184
|
+
function stoppedLines(stopped) {
|
|
185
|
+
if (stopped.kind === "retry")
|
|
186
|
+
return [`? stopped ${stopped.reason}`];
|
|
187
|
+
const facts = projectRefusal(stopped);
|
|
188
|
+
const lines = [`! stopped ${facts.line}`];
|
|
189
|
+
appendDiagnostic(lines, facts.diagnostic);
|
|
190
|
+
return lines;
|
|
191
|
+
}
|
|
192
|
+
function renderCompose(result, columns) {
|
|
193
|
+
if (result.kind === "incomplete")
|
|
194
|
+
return "";
|
|
195
|
+
if (result.kind !== "accepted")
|
|
196
|
+
return renderFailure("compose", result, columns);
|
|
197
|
+
const lines = [`✓ compose accepted · ${result.documentChanges.length} changed`];
|
|
198
|
+
composeDiffs(lines, result.documentChanges);
|
|
199
|
+
return lines.join("\n");
|
|
200
|
+
}
|
|
201
|
+
export function renderTaskText(command, result, context = DEFAULT_CONTEXT) {
|
|
202
|
+
if (isWorldObservation(result)) {
|
|
203
|
+
if (result.kind === "absent")
|
|
204
|
+
return "task world absent";
|
|
205
|
+
if (result.kind === "failed") {
|
|
206
|
+
const lines = ["task world failed"];
|
|
207
|
+
receiptPayload(lines, "diagnostic", result.failure.message);
|
|
208
|
+
return lines.join("\n");
|
|
209
|
+
}
|
|
210
|
+
result = result.value;
|
|
211
|
+
}
|
|
212
|
+
return renderTaskValue(command, result, context.columns);
|
|
213
|
+
}
|
|
214
|
+
function renderTaskValue(command, result, columns) {
|
|
52
215
|
if (command.action === "show")
|
|
53
|
-
return renderShow(result);
|
|
54
|
-
if (command.action === "ls" || command.action === "ready" || command.action === "blocked")
|
|
55
|
-
return renderRows(result);
|
|
216
|
+
return renderShow(result, columns);
|
|
217
|
+
if (command.action === "ls" || command.action === "ready" || command.action === "blocked" || command.action === "query") {
|
|
218
|
+
return renderRows(command, result, columns);
|
|
219
|
+
}
|
|
56
220
|
if (command.action === "tree") {
|
|
57
221
|
const tree = result;
|
|
58
|
-
return tree.kind === "accepted" ? treeLines(tree.value).join("\n") :
|
|
59
|
-
}
|
|
60
|
-
if (command.action === "doctor") {
|
|
61
|
-
const report = result;
|
|
62
|
-
return report.issues.length === 0 ? "healthy" : report.issues.map(doctorIssue).join("\n");
|
|
222
|
+
return tree.kind === "accepted" ? treeLines(tree.value, columns).join("\n") : renderFailure(command.action, tree, columns);
|
|
63
223
|
}
|
|
224
|
+
if (command.action === "doctor")
|
|
225
|
+
return renderDoctor(result);
|
|
64
226
|
if (command.action === "namespace") {
|
|
65
227
|
const namespace = result;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const composition = result;
|
|
70
|
-
return composition.kind === "accepted" ? changes(composition.documentChanges) : composition.kind === "incomplete" ? "" : failure(composition);
|
|
228
|
+
if (namespace.kind !== "accepted")
|
|
229
|
+
return renderFailure(command.action, namespace, columns);
|
|
230
|
+
return `namespace ${namespace.value.length === 0 ? "root" : namespace.value.join("/")}`;
|
|
71
231
|
}
|
|
232
|
+
if (command.action === "compose")
|
|
233
|
+
return renderCompose(result, columns);
|
|
72
234
|
if (command.action === "hold" || command.action === "done" || command.action === "drop") {
|
|
73
|
-
|
|
74
|
-
return batch.items.map((item) => item.outcome.kind === "accepted" ? `accepted ${item.id}` : `${item.id}: ${failure(item.outcome)}`).join("\n");
|
|
75
|
-
}
|
|
76
|
-
const mutation = result;
|
|
77
|
-
if (mutation.kind !== "accepted")
|
|
78
|
-
return failure(mutation);
|
|
79
|
-
if (command.action === "update") {
|
|
80
|
-
const value = mutation.value;
|
|
81
|
-
return [row(value.task), value.documentDiff].filter((line) => line.length > 0).join("\n");
|
|
235
|
+
return renderBatch(command.action, result);
|
|
82
236
|
}
|
|
83
|
-
return
|
|
237
|
+
return renderMutation(command, result, columns);
|
|
84
238
|
}
|
|
85
239
|
export function renderTaskIncompleteDiagnostic(result) {
|
|
86
240
|
if (result.kind !== "incomplete")
|
|
87
241
|
return "";
|
|
88
|
-
|
|
242
|
+
const lines = [`! compose incomplete · ${result.documentChanges.length} admitted`, ...stoppedLines(result.stopped)];
|
|
243
|
+
composeDiffs(lines, result.documentChanges);
|
|
244
|
+
return lines.join("\n");
|
|
89
245
|
}
|
|
90
246
|
export function taskExitCode(result) {
|
|
247
|
+
if (isWorldObservation(result)) {
|
|
248
|
+
if (result.kind === "absent")
|
|
249
|
+
return 1;
|
|
250
|
+
if (result.kind === "failed")
|
|
251
|
+
return 3;
|
|
252
|
+
result = result.value;
|
|
253
|
+
}
|
|
91
254
|
if (typeof result === "object" && result !== null && "issues" in result)
|
|
92
255
|
return result.issues.length === 0 ? 0 : 1;
|
|
93
256
|
if (typeof result === "object" && result !== null && "items" in result) {
|
|
@@ -2,6 +2,12 @@ export type TextRenderContext = Readonly<{
|
|
|
2
2
|
columns: number;
|
|
3
3
|
color: boolean;
|
|
4
4
|
}>;
|
|
5
|
+
export type GitShortStat = Readonly<{
|
|
6
|
+
filesChanged: number;
|
|
7
|
+
insertions: number;
|
|
8
|
+
deletions: number;
|
|
9
|
+
}>;
|
|
10
|
+
export declare function gitShortStat(stat: GitShortStat): string;
|
|
5
11
|
export declare function displayColumns(value: string): number;
|
|
6
12
|
export declare function takeDisplayColumns(value: string, maximum: number): Readonly<{
|
|
7
13
|
text: string;
|
|
@@ -19,5 +25,6 @@ export declare function renderBoundedTextBlock(value: string, input: Readonly<{
|
|
|
19
25
|
export declare function safeText(value: string): string;
|
|
20
26
|
export declare function renderFacts(primary: string, facts: readonly string[], columns: number): readonly string[];
|
|
21
27
|
export declare function renderTextBlock(value: string, indent: string, columns: number): readonly string[];
|
|
28
|
+
export declare function renderOpaqueBlock(value: string, indent: string, columns: number): readonly string[];
|
|
22
29
|
export declare function renderVoiceRuler(left: string, right: string, columns: number): string;
|
|
23
30
|
export declare function tone(value: string, kind: "dim" | "alert", color: boolean): string;
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
export function gitShortStat(stat) {
|
|
2
|
+
const files = stat.filesChanged === 1 ? "1 file changed" : `${stat.filesChanged} files changed`;
|
|
3
|
+
const parts = [files];
|
|
4
|
+
if (stat.insertions === 1)
|
|
5
|
+
parts.push("1 insertion(+)");
|
|
6
|
+
else if (stat.insertions !== 0)
|
|
7
|
+
parts.push(`${stat.insertions} insertions(+)`);
|
|
8
|
+
if (stat.deletions === 1)
|
|
9
|
+
parts.push("1 deletion(-)");
|
|
10
|
+
else if (stat.deletions !== 0)
|
|
11
|
+
parts.push(`${stat.deletions} deletions(-)`);
|
|
12
|
+
return parts.join(", ");
|
|
13
|
+
}
|
|
1
14
|
const GRAPHEMES = new Intl.Segmenter("und", { granularity: "grapheme" });
|
|
2
15
|
const WIDE_RANGES = [
|
|
3
16
|
[0x1100, 0x115f], [0x2329, 0x232a], [0x2e80, 0xa4cf], [0xac00, 0xd7a3],
|
|
@@ -137,6 +150,39 @@ export function renderTextBlock(value, indent, columns) {
|
|
|
137
150
|
lines.push(current);
|
|
138
151
|
return lines;
|
|
139
152
|
}
|
|
153
|
+
export function renderOpaqueBlock(value, indent, columns) {
|
|
154
|
+
let rest = safeText(value);
|
|
155
|
+
if (rest.length === 0)
|
|
156
|
+
return [indent.trimEnd()];
|
|
157
|
+
const continuation = `${indent} `;
|
|
158
|
+
const lines = [];
|
|
159
|
+
let prefix = indent;
|
|
160
|
+
while (rest.length > 0) {
|
|
161
|
+
const budget = columns - displayColumns(prefix);
|
|
162
|
+
if (budget <= 0) {
|
|
163
|
+
if (prefix === continuation) {
|
|
164
|
+
lines.push(`${prefix}${rest}`);
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
lines.push(prefix.trimEnd());
|
|
168
|
+
prefix = continuation;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (displayColumns(rest) <= budget) {
|
|
172
|
+
lines.push(`${prefix}${rest}`);
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
const taken = takeDisplayColumns(rest, budget);
|
|
176
|
+
if (taken.text.length === 0) {
|
|
177
|
+
lines.push(`${prefix}${rest}`);
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
lines.push(`${prefix}${taken.text}`);
|
|
181
|
+
rest = taken.rest;
|
|
182
|
+
prefix = continuation;
|
|
183
|
+
}
|
|
184
|
+
return lines;
|
|
185
|
+
}
|
|
140
186
|
export function renderVoiceRuler(left, right, columns) {
|
|
141
187
|
const width = Math.max(20, Math.min(80, columns));
|
|
142
188
|
const occupied = displayColumns(left) + displayColumns(right) + 2;
|
|
@@ -3,6 +3,7 @@ import { renderAccepted, renderRetry } from "./contract.js";
|
|
|
3
3
|
import { renderKanshiText } from "./kanshi.js";
|
|
4
4
|
import { renderRefusal } from "./refusal.js";
|
|
5
5
|
import { renderCatalogText } from "./catalog.js";
|
|
6
|
+
import { renderRegionText } from "./region.js";
|
|
6
7
|
export function renderText(result, context) {
|
|
7
8
|
if (result.kind === "guidance")
|
|
8
9
|
return result.guidance;
|
|
@@ -10,11 +11,13 @@ export function renderText(result, context) {
|
|
|
10
11
|
return renderKanshiText(result.report, context, result.selection);
|
|
11
12
|
if (result.kind === "catalog")
|
|
12
13
|
return renderCatalogText(result.catalog);
|
|
14
|
+
if (result.kind === "region")
|
|
15
|
+
return renderRegionText(result.region);
|
|
13
16
|
if (result.kind === "accepted")
|
|
14
|
-
return renderAccepted(result);
|
|
17
|
+
return renderAccepted(result, context);
|
|
15
18
|
if (result.kind === "refused")
|
|
16
|
-
return renderRefusal(result);
|
|
19
|
+
return renderRefusal(result, context);
|
|
17
20
|
if (result.kind === "retry")
|
|
18
|
-
return renderRetry(result);
|
|
21
|
+
return renderRetry(result, context);
|
|
19
22
|
return renderObservation(result);
|
|
20
23
|
}
|