@astrosheep/keiyaku 4.5.26 → 4.5.28

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.
Files changed (98) hide show
  1. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
  2. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
  3. package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
  4. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -3
  5. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +82 -162
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +153 -76
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +68 -64
  8. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +115 -146
  9. package/build/src/akuma/akuma-errors.d.ts +6 -0
  10. package/build/src/akuma/akuma-errors.js +11 -0
  11. package/build/src/akuma/akuma-handle.d.ts +54 -1
  12. package/build/src/akuma/akuma-handle.js +79 -8
  13. package/build/src/akuma/akuma-instance.js +6 -22
  14. package/build/src/akuma/akuma-observe.d.ts +6 -0
  15. package/build/src/akuma/akuma-observe.js +3 -1
  16. package/build/src/akuma/akuma-probe.d.ts +20 -1
  17. package/build/src/akuma/akuma-probe.js +20 -3
  18. package/build/src/akuma/akuma.d.ts +13 -0
  19. package/build/src/akuma/akuma.js +1 -0
  20. package/build/src/akuma/allowed.d.ts +2 -1
  21. package/build/src/akuma/allowed.js +9 -4
  22. package/build/src/akuma/archetype.js +3 -3
  23. package/build/src/akuma/body.js +8 -3
  24. package/build/src/akuma/fleet-execution.d.ts +13 -2
  25. package/build/src/akuma/fleet-execution.js +45 -0
  26. package/build/src/akuma/fleet-observation.d.ts +241 -0
  27. package/build/src/akuma/fleet-observation.js +13 -0
  28. package/build/src/akuma/fleet-owner-port.d.ts +12 -0
  29. package/build/src/akuma/fleet-owner-port.js +46 -0
  30. package/build/src/akuma/fleet-request.d.ts +55 -4
  31. package/build/src/akuma/fleet-request.js +101 -6
  32. package/build/src/akuma/heart/index.d.ts +1 -0
  33. package/build/src/akuma/heart/index.js +4 -1
  34. package/build/src/akuma/heart/rows.d.ts +1 -0
  35. package/build/src/akuma/heart/rows.js +8 -0
  36. package/build/src/akuma/heart/soul.js +2 -2
  37. package/build/src/akuma/identity.js +11 -9
  38. package/build/src/akuma/projection.d.ts +36 -0
  39. package/build/src/akuma/projection.js +2 -1
  40. package/build/src/akuma/provider.d.ts +14 -0
  41. package/build/src/akuma/provider.js +66 -4
  42. package/build/src/akuma/providers/acp/events.js +16 -8
  43. package/build/src/akuma/providers/claude/events.js +5 -7
  44. package/build/src/akuma/providers/opencode-sdk/events.js +9 -5
  45. package/build/src/akuma/providers/pi/events.js +4 -3
  46. package/build/src/akuma/request-lifecycle.js +10 -1
  47. package/build/src/akuma-body.js +1 -33
  48. package/build/src/alias/index.js +3 -3
  49. package/build/src/cli/commands/akuma-invoke.d.ts +8 -0
  50. package/build/src/cli/commands/akuma-invoke.js +67 -6
  51. package/build/src/cli/commands/akuma.d.ts +1 -0
  52. package/build/src/cli/commands/akuma.js +19 -30
  53. package/build/src/cli/commands/contract-help.d.ts +1 -0
  54. package/build/src/cli/commands/contract-help.js +9 -5
  55. package/build/src/cli/invoke.js +1 -1
  56. package/build/src/cli/render/akuma-activity.d.ts +7 -1
  57. package/build/src/cli/render/akuma-activity.js +164 -50
  58. package/build/src/cli/render/akuma-tool.d.ts +5 -0
  59. package/build/src/cli/render/akuma-tool.js +118 -14
  60. package/build/src/cli/render/akuma.d.ts +12 -1
  61. package/build/src/cli/render/akuma.js +74 -2
  62. package/build/src/cli/render/catalog.js +2 -3
  63. package/build/src/cli/render/contract-observation.d.ts +1 -0
  64. package/build/src/cli/render/contract-observation.js +20 -1
  65. package/build/src/cli/render/contract.js +4 -4
  66. package/build/src/cli/render/execution-progress.d.ts +1 -0
  67. package/build/src/cli/render/execution-progress.js +77 -3
  68. package/build/src/cli/render/kanshi.js +5 -19
  69. package/build/src/cli/render/terminal.js +3 -1
  70. package/build/src/cli/runtime.d.ts +6 -0
  71. package/build/src/cli/runtime.js +35 -17
  72. package/build/src/core/facts/offer.d.ts +1 -2
  73. package/build/src/core/verbs/abandon.js +1 -1
  74. package/build/src/core/verbs/amend.js +1 -1
  75. package/build/src/core/verbs/arc.js +1 -1
  76. package/build/src/core/verbs/attestation.js +1 -1
  77. package/build/src/core/verbs/bind.js +1 -1
  78. package/build/src/core/verbs/deliver.js +1 -1
  79. package/build/src/core/verbs/placement.js +1 -1
  80. package/build/src/core/verbs/reintegrate.js +1 -1
  81. package/build/src/git/admission.js +18 -7
  82. package/build/src/identity/coordinates.js +1 -1
  83. package/build/src/identity/normalize.d.ts +3 -0
  84. package/build/src/identity/normalize.js +10 -0
  85. package/build/src/identity/selector.d.ts +1 -0
  86. package/build/src/identity/selector.js +15 -4
  87. package/build/src/library/address.d.ts +33 -3
  88. package/build/src/library/address.js +90 -29
  89. package/build/src/library/akuma-creation.d.ts +1 -1
  90. package/build/src/library/akuma-creation.js +10 -52
  91. package/build/src/library/composition.d.ts +14 -1
  92. package/build/src/library/fleet.d.ts +13 -2
  93. package/build/src/library/fleet.js +142 -48
  94. package/build/src/library/keiyaku.d.ts +14 -1
  95. package/build/src/plugin/public.d.ts +2 -0
  96. package/build/src/protocol/completion.js +9 -2
  97. package/build/src/runtime/proc/windows-launch.exe +0 -0
  98. package/package.json +1 -1
@@ -1,8 +1,20 @@
1
- const AKUMA_ALIAS_PATTERN = /^@[a-z][a-z0-9-]{0,63}$/u;
1
+ import { MAX_AKUMA_NAME_BYTES, normalizeIdentityStem, validateAkumaName } from "./normalize.js";
2
2
  const AKUMA_GLOB_SUFFIX = /^[0-9a-f*]+$/u;
3
+ const LEGACY_AKUMA_ALIAS_PATTERN = /^@[a-z][a-z0-9-]{0,63}$/u;
4
+ // Old alias spellings remain readable, but new bindings use canonical Akuma names.
5
+ export function parseReadableAkumaAlias(value) {
6
+ if (LEGACY_AKUMA_ALIAS_PATTERN.test(value))
7
+ return value;
8
+ return parseAkumaAlias(value);
9
+ }
3
10
  export function parseAkumaAlias(value) {
4
- if (!AKUMA_ALIAS_PATTERN.test(value)) {
5
- throw new TypeError("Akuma alias must match ^@[a-z][a-z0-9-]{0,63}$");
11
+ if (!value.startsWith("@"))
12
+ throw new TypeError("Akuma alias selector must start with @");
13
+ try {
14
+ validateAkumaName(value.slice(1));
15
+ }
16
+ catch {
17
+ throw new TypeError(`Akuma alias name must be a normalized Akuma name of at most ${MAX_AKUMA_NAME_BYTES} UTF-8 bytes`);
6
18
  }
7
19
  return value;
8
20
  }
@@ -26,4 +38,3 @@ export function matchesAkumaGlob(glob, value) {
26
38
  .replaceAll("*", "[^/]*");
27
39
  return new RegExp(`^${pattern}$`, "u").test(value);
28
40
  }
29
- import { normalizeIdentityStem } from "./normalize.js";
@@ -28,6 +28,17 @@ export type AkumaWorldScopeRefusal = Readonly<{
28
28
  ids: readonly AkuId[];
29
29
  world: WorldRoot;
30
30
  }>;
31
+ export type AkumaAddressRefusal = Readonly<{
32
+ kind: "akuma-alias-not-found";
33
+ alias: AkumaAlias;
34
+ }> | Readonly<{
35
+ kind: "invalid-akuma";
36
+ selector: string;
37
+ }>;
38
+ export declare class AkumaAddressError extends Error {
39
+ readonly refusal: AkumaAddressRefusal;
40
+ constructor(refusal: AkumaAddressRefusal);
41
+ }
31
42
  export declare class AkumaWorldScopeError extends TypeError {
32
43
  readonly refusal: AkumaWorldScopeRefusal;
33
44
  constructor(refusal: AkumaWorldScopeRefusal);
@@ -45,15 +56,34 @@ export type NamedAddressInput = Readonly<{
45
56
  aliases: Section<readonly AliasBinding[]>;
46
57
  }>;
47
58
  export declare function resolveNamedAddress(input: NamedAddressInput): NamedAddress;
48
- export declare function addressAkuma(input: UncheckedAkumaAddressInput): Promise<Readonly<{
59
+ type AddressedAkuma = Readonly<{
49
60
  path: WorldRoot;
50
61
  id: AkuId;
62
+ }>;
63
+ /**
64
+ * Resolves one selector to a complete identity without proving it born. The
65
+ * caller is a forwarding boundary: the parent Fleet answers for the target, so
66
+ * this process must not read its own Heart files to decide.
67
+ */
68
+ export declare function resolveAkuma(input: UncheckedAkumaAddressInput): Promise<AddressedAkuma>;
69
+ /**
70
+ * Resolves one selector against this World, where a local caller is answered
71
+ * for the target's birth by the one addressability normalization.
72
+ */
73
+ export declare function addressAkuma(input: UncheckedAkumaAddressInput): Promise<AddressedAkuma>;
74
+ /**
75
+ * Resolves a selector set to complete identities without proving any born. The
76
+ * caller is a forwarding boundary, the parent Fleet owns the answer, and no
77
+ * member's Heart is read here.
78
+ */
79
+ export declare function resolveAkumaSet(input: UncheckedAkumaAddressInput): Promise<Readonly<{
80
+ path: WorldRoot;
81
+ ids: readonly AkuId[];
82
+ orderedIds: readonly AkuId[];
51
83
  }>>;
52
84
  export declare function addressAkumaSet(input: UncheckedAkumaAddressInput): Promise<Readonly<{
53
85
  path: WorldRoot;
54
- /** The complete selected set in canonical order. */
55
86
  ids: readonly AkuId[];
56
- /** The same set in the caller's selector order, for surfaces that name the selection as chosen. */
57
87
  orderedIds: readonly AkuId[];
58
88
  }>>;
59
89
  export {};
@@ -1,14 +1,24 @@
1
1
  /** @architectureCompositionRoot */
2
2
  import { readAliases } from "../alias/index.js";
3
3
  import { createAkumaProduct } from "../akuma/akuma-product.js";
4
- import { probeBornAkuma } from "../akuma/akuma-probe.js";
4
+ import { akumaAddressability, requireBornAkuma } from "../akuma/akuma-probe.js";
5
5
  import { parseAkuId } from "../akuma/identity.js";
6
6
  import { contractId } from "../core/facts/types.js";
7
7
  import { readDispatches } from "../dispatch/index.js";
8
- import { matchesAkumaGlob, parseAkumaAlias, parseAkumaGlob, } from "../identity/selector.js";
8
+ import { matchesAkumaGlob, parseReadableAkumaAlias, parseAkumaGlob, } from "../identity/selector.js";
9
9
  import { World } from "../world.js";
10
10
  import { requireInput } from "./input.js";
11
11
  import { scopeForRepo } from "./repo.js";
12
+ export class AkumaAddressError extends Error {
13
+ refusal;
14
+ constructor(refusal) {
15
+ super(refusal.kind === "akuma-alias-not-found"
16
+ ? `unknown Akuma alias: ${refusal.alias}`
17
+ : `invalid Akuma: ${refusal.selector}`);
18
+ this.refusal = refusal;
19
+ this.name = "AkumaAddressError";
20
+ }
21
+ }
12
22
  export class AkumaWorldScopeError extends TypeError {
13
23
  refusal;
14
24
  constructor(refusal) {
@@ -22,23 +32,43 @@ function nonblank(value, label) {
22
32
  throw new TypeError(`${label} must be a nonblank string`);
23
33
  return value;
24
34
  }
35
+ function parseAddressAlias(selector) {
36
+ try {
37
+ return parseReadableAkumaAlias(selector);
38
+ }
39
+ catch (error) {
40
+ if (!(error instanceof TypeError))
41
+ throw error;
42
+ throw new AkumaAddressError({ kind: "invalid-akuma", selector });
43
+ }
44
+ }
45
+ function parseAddressId(selector) {
46
+ try {
47
+ return parseAkuId(selector);
48
+ }
49
+ catch (error) {
50
+ if (!(error instanceof TypeError))
51
+ throw error;
52
+ throw new AkumaAddressError({ kind: "invalid-akuma", selector });
53
+ }
54
+ }
25
55
  async function directId(path, selector) {
26
56
  if (selector.startsWith("@")) {
27
- const alias = parseAkumaAlias(selector);
57
+ const alias = parseAddressAlias(selector);
28
58
  const resolved = (await readAliases(path)).find((binding) => binding.alias === alias)?.akuId ?? null;
29
59
  if (resolved === null)
30
- throw new TypeError(`unknown Akuma alias: ${alias}`);
60
+ throw new AkumaAddressError({ kind: "akuma-alias-not-found", alias });
31
61
  return resolved;
32
62
  }
33
- return parseAkuId(selector).id;
63
+ return parseAddressId(selector).id;
34
64
  }
35
65
  export function resolveNamedAddress(input) {
36
66
  const selector = nonblank(input.selector, "selector");
37
67
  if (selector.startsWith("kei/"))
38
68
  return { kind: "contract", id: contractId(selector) };
39
69
  if (selector.startsWith("aku/"))
40
- return { kind: "akuma", id: parseAkuId(selector).id };
41
- const alias = parseAkumaAlias(selector);
70
+ return { kind: "akuma", id: parseAddressId(selector).id };
71
+ const alias = parseAddressAlias(selector);
42
72
  const contractMatches = (input.report.contracts.kind === "present" ? input.report.contracts.value.rows : []).filter((row) => row.disposition === "active" &&
43
73
  row.workspace === "worktree" &&
44
74
  row.worktreePath !== null &&
@@ -62,9 +92,14 @@ export function resolveNamedAddress(input) {
62
92
  if (input.aliases.kind === "failed") {
63
93
  throw new TypeError("cannot resolve a named selector while Alias authority is failed");
64
94
  }
65
- throw new TypeError(`unknown selector: ${selector}`);
95
+ throw new AkumaAddressError({ kind: "akuma-alias-not-found", alias });
66
96
  }
67
- export async function addressAkuma(input) {
97
+ /**
98
+ * Resolves one selector to a complete identity without proving it born. The
99
+ * caller is a forwarding boundary: the parent Fleet answers for the target, so
100
+ * this process must not read its own Heart files to decide.
101
+ */
102
+ export async function resolveAkuma(input) {
68
103
  const values = requireInput(input, "Akuma address input");
69
104
  for (const key of Object.keys(values)) {
70
105
  if (!["path", "akuma", "repo"].includes(key)) {
@@ -74,7 +109,17 @@ export async function addressAkuma(input) {
74
109
  if (values.repo !== undefined)
75
110
  scopeForRepo(values.repo);
76
111
  const path = await World.prove(nonblank(values.path, "path"));
77
- return { path, id: await directId(path, nonblank(values.akuma, "akuma")) };
112
+ const id = await directId(path, nonblank(values.akuma, "akuma"));
113
+ return { path, id };
114
+ }
115
+ /**
116
+ * Resolves one selector against this World, where a local caller is answered
117
+ * for the target's birth by the one addressability normalization.
118
+ */
119
+ export async function addressAkuma(input) {
120
+ const addressed = await resolveAkuma(input);
121
+ await requireBornAkuma(addressed.path, addressed.id);
122
+ return addressed;
78
123
  }
79
124
  function parseSetSelector(raw) {
80
125
  const selector = nonblank(raw, "akuma selector");
@@ -83,13 +128,13 @@ function parseSetSelector(raw) {
83
128
  if (selector.includes("*"))
84
129
  return { kind: "glob", value: parseAkumaGlob(selector) };
85
130
  if (selector.startsWith("@"))
86
- return { kind: "alias", value: parseAkumaAlias(selector) };
87
- return { kind: "direct", value: parseAkuId(selector).id };
131
+ return { kind: "alias", value: parseAddressAlias(selector) };
132
+ return { kind: "direct", value: parseAddressId(selector).id };
88
133
  }
89
134
  function hasSelectorKind(selectors, kind) {
90
135
  return selectors.some((selector) => selector.kind === kind);
91
136
  }
92
- function addSelectorIds(selector, sources, selected, contractMembers) {
137
+ function addSelectorIds(selector, sources, selected, contractMembers, explicit) {
93
138
  if (selector.kind === "contract") {
94
139
  for (const dispatch of sources.dispatches) {
95
140
  if (dispatch.contractId !== selector.value)
@@ -108,20 +153,18 @@ function addSelectorIds(selector, sources, selected, contractMembers) {
108
153
  if (selector.kind === "alias") {
109
154
  const id = sources.aliases.get(selector.value);
110
155
  if (id === undefined)
111
- throw new TypeError(`unknown Akuma alias: ${selector.value}`);
156
+ throw new AkumaAddressError({ kind: "akuma-alias-not-found", alias: selector.value });
112
157
  selected.add(id);
158
+ explicit.add(id);
113
159
  return;
114
160
  }
115
161
  selected.add(selector.value);
162
+ explicit.add(selector.value);
116
163
  }
117
164
  async function contractMemberInWorld(path, id) {
118
- try {
119
- return await probeBornAkuma(path, id);
120
- }
121
- catch {
122
- // A dispatched physical member remains selected when its Heart cannot be read.
123
- return true;
124
- }
165
+ // A dispatched physical member stays selected when its Heart cannot be read:
166
+ // the World, not this reader, remains the authority on its membership.
167
+ return (await akumaAddressability(path, id)).kind !== "absent";
125
168
  }
126
169
  async function refuseForeignContractMembers(path, ids, contractMembers) {
127
170
  const foreign = [];
@@ -132,7 +175,13 @@ async function refuseForeignContractMembers(path, ids, contractMembers) {
132
175
  if (foreign.length > 0)
133
176
  throw new AkumaWorldScopeError({ kind: "akuma-not-in-world", ids: foreign, world: path });
134
177
  }
135
- export async function addressAkumaSet(input) {
178
+ function canonicalAkumaOrder(selected) {
179
+ const ids = [...selected].sort((left, right) => Buffer.compare(Buffer.from(left), Buffer.from(right)));
180
+ if (ids.length === 0)
181
+ throw new TypeError("Akuma selector snapshot is empty");
182
+ return ids;
183
+ }
184
+ async function readAkumaSet(input) {
136
185
  const values = requireInput(input, "Akuma set address input");
137
186
  for (const key of Object.keys(values)) {
138
187
  if (!["path", "akuma", "repo"].includes(key)) {
@@ -157,13 +206,25 @@ export async function addressAkumaSet(input) {
157
206
  : [];
158
207
  const selected = new Set();
159
208
  const contractMembers = new Set();
209
+ const explicit = new Set();
160
210
  const sources = { fleetIds, aliases, dispatches };
161
211
  for (const selector of selectors)
162
- addSelectorIds(selector, sources, selected, contractMembers);
163
- const orderedIds = [...selected];
164
- const ids = [...selected].sort((left, right) => Buffer.compare(Buffer.from(left), Buffer.from(right)));
165
- if (ids.length === 0)
166
- throw new TypeError("Akuma selector snapshot is empty");
167
- await refuseForeignContractMembers(path, ids, contractMembers);
168
- return { path, ids, orderedIds };
212
+ addSelectorIds(selector, sources, selected, contractMembers, explicit);
213
+ return { path, orderedIds: [...selected], ids: canonicalAkumaOrder(selected), contractMembers, explicit };
214
+ }
215
+ /**
216
+ * Resolves a selector set to complete identities without proving any born. The
217
+ * caller is a forwarding boundary, the parent Fleet owns the answer, and no
218
+ * member's Heart is read here.
219
+ */
220
+ export async function resolveAkumaSet(input) {
221
+ const resolved = await readAkumaSet(input);
222
+ return { path: resolved.path, ids: resolved.ids, orderedIds: resolved.orderedIds };
223
+ }
224
+ export async function addressAkumaSet(input) {
225
+ const resolved = await readAkumaSet(input);
226
+ for (const id of resolved.explicit)
227
+ await requireBornAkuma(resolved.path, id);
228
+ await refuseForeignContractMembers(resolved.path, resolved.ids, resolved.contractMembers);
229
+ return { path: resolved.path, ids: resolved.ids, orderedIds: resolved.orderedIds };
169
230
  }
@@ -73,7 +73,7 @@ export type CallResult = Readonly<{
73
73
  readonly?: ReadonlyRestraint;
74
74
  execution: Readonly<{
75
75
  cwd: string;
76
- source: "input" | "contract-worktree" | "caller" | "process" | "world";
76
+ source: "input" | "caller" | "process" | "world";
77
77
  }>;
78
78
  dispatch: DispatchStage;
79
79
  alias: AliasStage;
@@ -9,7 +9,6 @@ import { AuthorityCorruptionError } from "../core/facts/errors.js";
9
9
  import { publishDispatch, readDispatch } from "../dispatch/index.js";
10
10
  import { parseAkumaAlias } from "../identity/selector.js";
11
11
  import { emitCalledPluginSignal } from "../plugin/akuma-signals.js";
12
- import { readManagedWorktreeAppointment } from "../workspace-place.js";
13
12
  import { World } from "../world.js";
14
13
  import { Akuma as PublicAkuma } from "../akuma/akuma-instance.js";
15
14
  import { requestForwardedFleetTellAnswer } from "../akuma/fleet-request.js";
@@ -17,7 +16,6 @@ import { localExecutionContext } from "../akuma/requests.js";
17
16
  import { callReadonly, canonicalBirthCwd } from "../akuma/call-input.js";
18
17
  import { requireInput } from "./input.js";
19
18
  import { addressAkuma } from "./address.js";
20
- import { KeiyakuRefused } from "./contract.js";
21
19
  import { seatForKeiyaku } from "./contract-handle.js";
22
20
  import { scopeForRepo } from "./repo.js";
23
21
  function nonblank(value, label) {
@@ -67,10 +65,10 @@ function integrationFailure(error) {
67
65
  };
68
66
  }
69
67
  function callMode(value) {
70
- if (value === undefined || value === "wait")
71
- return "wait";
72
- if (value === "detach")
68
+ if (value === undefined || value === "detach")
73
69
  return "detach";
70
+ if (value === "wait")
71
+ return "wait";
74
72
  throw new TypeError("mode must be wait or detach");
75
73
  }
76
74
  function callTimeout(value, mode) {
@@ -196,49 +194,13 @@ async function forkDispatchStage(input) {
196
194
  return { kind: "failed", failure: integrationFailure(error) };
197
195
  }
198
196
  }
199
- function unavailableWorkspace(contractId, detail) {
200
- return new Error(`Contract workspace is unavailable: ${contractId} ${detail}`);
201
- }
202
- async function currentManagedContract(contract, contractId) {
203
- let state;
204
- try {
205
- state = await contract.state();
206
- }
207
- catch (error) {
208
- if (error instanceof Error && error.message === `contract does not exist: ${contractId}`) {
209
- throw new KeiyakuRefused({ kind: "contract-missing", contractId });
210
- }
211
- throw error;
212
- }
213
- if (state.terminal !== null)
214
- throw new KeiyakuRefused({ kind: "terminal", contractId: state.id });
215
- return state;
216
- }
217
197
  async function resolveCallExecution(input) {
218
- if (input.cwd !== undefined) {
219
- return {
220
- cwd: await canonicalBirthCwd(input.cwd),
221
- source: "input",
222
- };
223
- }
224
- if (input.contract !== undefined) {
225
- const seat = seatForKeiyaku(input.contract);
226
- if (seat === null)
227
- throw new TypeError("contract must be a Keiyaku");
228
- const state = await currentManagedContract(input.contract, seat.id);
229
- const appointment = await readManagedWorktreeAppointment(seat.scope, state.id);
230
- if (appointment.kind === "unappointed") {
231
- throw unavailableWorkspace(state.id, "is unappointed; use reconcile");
232
- }
233
- if (appointment.kind === "failed") {
234
- throw new Error(`${appointment.diagnostic}; use reconcile`);
235
- }
236
- return {
237
- cwd: await canonicalBirthCwd(appointment.path, `Contract workspace is unavailable: ${appointment.path}`),
238
- source: "contract-worktree",
239
- };
240
- }
241
- return undefined;
198
+ if (input.cwd === undefined)
199
+ return undefined;
200
+ return {
201
+ cwd: await canonicalBirthCwd(input.cwd),
202
+ source: "input",
203
+ };
242
204
  }
243
205
  async function resolveAliasStage(path, alias, dispatch, akuma) {
244
206
  if (alias === undefined)
@@ -326,11 +288,7 @@ function schemaTell(input) {
326
288
  }
327
289
  async function prepareCall(input, context) {
328
290
  const parsed = await parseCallInput(input);
329
- const execution = await resolveCallExecution({
330
- path: parsed.path,
331
- ...(parsed.cwd === undefined ? {} : { cwd: parsed.cwd }),
332
- ...(parsed.seat === undefined ? {} : { contract: parsed.values.contract }),
333
- });
291
+ const execution = await resolveCallExecution(parsed.cwd === undefined ? {} : { cwd: parsed.cwd });
334
292
  const world = akumaWorld(parsed.path, parsed.home, parsed.settings, context);
335
293
  const { born, akuma } = await admitCall({
336
294
  path: parsed.path,
@@ -16,7 +16,7 @@ export declare function composeLibrary(context?: ExecutionContext, composition?:
16
16
  readonly?: import("../akuma/provider-recipe.js").ReadonlyRestraint;
17
17
  execution: Readonly<{
18
18
  cwd: string;
19
- source: "input" | "contract-worktree" | "caller" | "process" | "world";
19
+ source: "input" | "caller" | "process" | "world";
20
20
  }>;
21
21
  dispatch: import("./akuma-creation.js").DispatchStage;
22
22
  alias: import("./akuma-creation.js").AliasStage;
@@ -191,6 +191,10 @@ export declare function composeLibrary(context?: ExecutionContext, composition?:
191
191
  } | {
192
192
  kind: "other";
193
193
  display: string;
194
+ input?: {
195
+ json: string;
196
+ truncated: boolean;
197
+ } | undefined;
194
198
  };
195
199
  state: "active";
196
200
  truncated?: true | undefined;
@@ -227,6 +231,10 @@ export declare function composeLibrary(context?: ExecutionContext, composition?:
227
231
  } | {
228
232
  kind: "other";
229
233
  display: string;
234
+ input?: {
235
+ json: string;
236
+ truncated: boolean;
237
+ } | undefined;
230
238
  };
231
239
  state: {
232
240
  status: "error" | "ok";
@@ -317,6 +325,10 @@ export declare function composeLibrary(context?: ExecutionContext, composition?:
317
325
  } | {
318
326
  kind: "other";
319
327
  display: string;
328
+ input?: {
329
+ json: string;
330
+ truncated: boolean;
331
+ } | undefined;
320
332
  };
321
333
  state: {
322
334
  status: "error" | "ok";
@@ -345,6 +357,7 @@ export declare function composeLibrary(context?: ExecutionContext, composition?:
345
357
  };
346
358
  } | undefined;
347
359
  };
360
+ cwd?: string | undefined;
348
361
  readonly?: {
349
362
  enforcement: "native";
350
363
  } | {
@@ -1,10 +1,11 @@
1
1
  /** @architectureCompositionRoot */
2
2
  import { type ActivityHistory, type OutcomeRow, type AkumaStatus, type InterruptReceipt } from "../akuma/akuma.js";
3
3
  import { type ExecutionContext } from "../akuma/requests.js";
4
- import type { WaitObserver } from "../akuma/fleet-execution.js";
4
+ import type { TellWaitObserver, WaitObserver } from "../akuma/fleet-execution.js";
5
5
  import { type DispatchAssociation } from "../dispatch/index.js";
6
+ import { type Schema } from "../akuma/schema.js";
6
7
  import { type AkumaAddressInput, type AkumaSetAddressInput } from "./address.js";
7
- import { type AkumaKillResult, type AkumaObservation, type AkumaObservationStage, type AkumaTellResult, type AkumaWaitResult } from "../akuma/fleet-observation.js";
8
+ import { type AkumaKillResult, type AkumaObservation, type AkumaObservationStage, type AkumaTellResult, type AkumaTellWaitResult, type AkumaWaitResult } from "../akuma/fleet-observation.js";
8
9
  export type AkumaWaitInput = AkumaSetAddressInput & Readonly<{
9
10
  completion?: "any" | "all";
10
11
  timeoutMs?: number;
@@ -15,6 +16,15 @@ export type AkumaTellInput = AkumaAddressInput & Readonly<{
15
16
  initiator?: string;
16
17
  signal?: AbortSignal;
17
18
  }>;
19
+ export type AkumaTellWaitInput = AkumaAddressInput & Readonly<{
20
+ body: string;
21
+ timeoutMs: number;
22
+ schema?: Schema<unknown>;
23
+ interrupt?: boolean;
24
+ initiator?: string;
25
+ signal?: AbortSignal;
26
+ observe?: TellWaitObserver;
27
+ }>;
18
28
  export type { TellResult, TellWake } from "../akuma/akuma.js";
19
29
  export type { CreatedTaskObservation } from "../task/created-observation.js";
20
30
  export type { DispatchAssociation } from "../dispatch/association.js";
@@ -68,5 +78,6 @@ export declare function statusAkuma(input: AkumaAddressInput): Promise<AkumaObse
68
78
  export declare function waitAkuma(input: AkumaWaitInput, execution?: ExecutionContext, observer?: WaitObserver): Promise<AkumaWaitResult>;
69
79
  export declare function killAkuma(input: AkumaKillInput, execution?: ExecutionContext): Promise<AkumaKillResult>;
70
80
  export declare function tellAkuma(input: AkumaTellInput, execution?: ExecutionContext): Promise<AkumaTellResult>;
81
+ export declare function tellWaitAkuma(input: AkumaTellWaitInput, execution?: ExecutionContext): Promise<AkumaTellWaitResult>;
71
82
  export declare function interruptAkuma(input: AkumaInterruptInput): Promise<AkumaInterruptResult>;
72
83
  export declare function historyAkuma(input: AkumaHistoryInput): Promise<AkumaHistoryResult>;