@astrosheep/keiyaku 4.0.3 → 4.0.5

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 (238) 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 +4 -4
  5. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +1 -1
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +15 -1
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +3 -1
  8. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +34 -13
  9. package/build/src/akuma/akuma.d.ts +34 -12
  10. package/build/src/akuma/akuma.js +118 -63
  11. package/build/src/akuma/allowed.d.ts +7 -0
  12. package/build/src/akuma/allowed.js +33 -0
  13. package/build/src/akuma/archetype.d.ts +7 -4
  14. package/build/src/akuma/archetype.js +15 -16
  15. package/build/src/akuma/body.d.ts +6 -1
  16. package/build/src/akuma/body.js +36 -27
  17. package/build/src/akuma/heart/facts.d.ts +82 -14
  18. package/build/src/akuma/heart/index.d.ts +5 -18
  19. package/build/src/akuma/heart/index.js +14 -84
  20. package/build/src/akuma/heart/request-authority.d.ts +12 -0
  21. package/build/src/akuma/heart/request-authority.js +119 -0
  22. package/build/src/akuma/heart/request-rows.d.ts +16 -0
  23. package/build/src/akuma/heart/request-rows.js +88 -0
  24. package/build/src/akuma/heart/rows.d.ts +1 -26
  25. package/build/src/akuma/heart/rows.js +0 -50
  26. package/build/src/akuma/heart/schema.d.ts +1 -1
  27. package/build/src/akuma/heart/schema.js +22 -10
  28. package/build/src/akuma/heart/soul.js +2 -36
  29. package/build/src/akuma/heart/storage.d.ts +1 -0
  30. package/build/src/akuma/heart/storage.js +15 -0
  31. package/build/src/akuma/heart/timeline.d.ts +1 -5
  32. package/build/src/akuma/heart/timeline.js +8 -17
  33. package/build/src/akuma/index.d.ts +5 -2
  34. package/build/src/akuma/index.js +1 -0
  35. package/build/src/akuma/projection.d.ts +17 -3
  36. package/build/src/akuma/projection.js +40 -3
  37. package/build/src/akuma/provider-recipe.js +1 -11
  38. package/build/src/akuma/provider.d.ts +2 -7
  39. package/build/src/akuma/provider.js +2 -1
  40. package/build/src/akuma/providers/acp/core.d.ts +3 -1
  41. package/build/src/akuma/providers/acp/core.js +10 -6
  42. package/build/src/akuma/providers/acp/events.d.ts +11 -3
  43. package/build/src/akuma/providers/acp/events.js +78 -4
  44. package/build/src/akuma/providers/acp/index.js +0 -1
  45. package/build/src/akuma/providers/claude/events.js +62 -3
  46. package/build/src/akuma/providers/claude/index.d.ts +0 -4
  47. package/build/src/akuma/providers/claude/index.js +7 -3
  48. package/build/src/akuma/providers/codex-app-server/events.js +1 -13
  49. package/build/src/akuma/providers/codex-app-server/index.d.ts +2 -27
  50. package/build/src/akuma/providers/codex-app-server/index.js +0 -2
  51. package/build/src/akuma/providers/grok-build/index.d.ts +2 -1
  52. package/build/src/akuma/providers/grok-build/index.js +72 -3
  53. package/build/src/akuma/providers/opencode-sdk/events.js +71 -6
  54. package/build/src/akuma/providers/opencode-sdk/index.d.ts +2 -28
  55. package/build/src/akuma/providers/opencode-sdk/index.js +8 -4
  56. package/build/src/akuma/providers/opencode-sdk/session.d.ts +1 -1
  57. package/build/src/akuma/providers/opencode-sdk/session.js +1 -1
  58. package/build/src/akuma/providers/pi/events.js +17 -3
  59. package/build/src/akuma/providers/pi/index.js +11 -4
  60. package/build/src/akuma/providers/unified-patch.d.ts +4 -0
  61. package/build/src/akuma/providers/unified-patch.js +14 -0
  62. package/build/src/akuma/publication.d.ts +1 -1
  63. package/build/src/akuma/publication.js +1 -1
  64. package/build/src/akuma/request-serve.d.ts +87 -0
  65. package/build/src/akuma/request-serve.js +484 -0
  66. package/build/src/akuma/request-wire.d.ts +124 -0
  67. package/build/src/akuma/request-wire.js +380 -0
  68. package/build/src/akuma/requests.d.ts +41 -41
  69. package/build/src/akuma/requests.js +75 -374
  70. package/build/src/akuma-body.d.ts +8 -0
  71. package/build/src/akuma-body.js +84 -0
  72. package/build/src/body/arc.js +4 -29
  73. package/build/src/body/decode.js +5 -39
  74. package/build/src/body/envelope.d.ts +7 -0
  75. package/build/src/body/envelope.js +37 -0
  76. package/build/src/cli/accepted.d.ts +4 -1
  77. package/build/src/cli/accepted.js +39 -9
  78. package/build/src/cli/commands/akuma-invoke.d.ts +8 -7
  79. package/build/src/cli/commands/akuma-invoke.js +18 -10
  80. package/build/src/cli/commands/akuma.d.ts +11 -2
  81. package/build/src/cli/commands/akuma.js +67 -28
  82. package/build/src/cli/commands/amend.d.ts +1 -1
  83. package/build/src/cli/commands/amend.js +1 -1
  84. package/build/src/cli/commands/contract.d.ts +8 -8
  85. package/build/src/cli/commands/contract.js +3 -3
  86. package/build/src/cli/commands/install.js +2 -2
  87. package/build/src/cli/commands/task-invoke.js +98 -9
  88. package/build/src/cli/commands/task-query.d.ts +1 -1
  89. package/build/src/cli/commands/task-query.js +11 -5
  90. package/build/src/cli/coordinates.d.ts +2 -0
  91. package/build/src/cli/coordinates.js +12 -5
  92. package/build/src/cli/invoke.d.ts +1 -0
  93. package/build/src/cli/invoke.js +116 -75
  94. package/build/src/cli/main.d.ts +2 -0
  95. package/build/src/cli/main.js +29 -4
  96. package/build/src/cli/parse.d.ts +3 -2
  97. package/build/src/cli/parse.js +25 -8
  98. package/build/src/cli/render/akuma.d.ts +2 -2
  99. package/build/src/cli/render/akuma.js +138 -24
  100. package/build/src/cli/render/audit.js +18 -8
  101. package/build/src/cli/render/contract.d.ts +2 -0
  102. package/build/src/cli/render/contract.js +243 -36
  103. package/build/src/cli/render/kanshi.js +64 -29
  104. package/build/src/cli/render/receipt.d.ts +2 -1
  105. package/build/src/cli/render/receipt.js +37 -2
  106. package/build/src/cli/render/terminal.d.ts +0 -2
  107. package/build/src/cli/render/terminal.js +0 -29
  108. package/build/src/cli/render/text.js +3 -1
  109. package/build/src/cli/result.d.ts +52 -9
  110. package/build/src/cli/selectors.d.ts +1 -0
  111. package/build/src/cli/selectors.js +9 -6
  112. package/build/src/contract-worktree.d.ts +1 -2
  113. package/build/src/contract-worktree.js +7 -9
  114. package/build/src/core/facts/codec.js +9 -0
  115. package/build/src/core/facts/fold.js +13 -1
  116. package/build/src/core/facts/types.d.ts +8 -1
  117. package/build/src/core/subject.js +4 -3
  118. package/build/src/core/verbs/placement.d.ts +9 -1
  119. package/build/src/core/verbs/placement.js +24 -6
  120. package/build/src/core/verbs/reintegrate.d.ts +13 -0
  121. package/build/src/core/verbs/reintegrate.js +24 -0
  122. package/build/src/dispatch/index.d.ts +1 -1
  123. package/build/src/dispatch/index.js +50 -39
  124. package/build/src/git/admission.d.ts +2 -1
  125. package/build/src/git/hooks.d.ts +0 -4
  126. package/build/src/git/hooks.js +0 -36
  127. package/build/src/git/integration.d.ts +7 -8
  128. package/build/src/git/integration.js +62 -9
  129. package/build/src/git/observe.d.ts +2 -1
  130. package/build/src/git/observe.js +6 -5
  131. package/build/src/git/process.d.ts +26 -0
  132. package/build/src/git/process.js +94 -0
  133. package/build/src/git/read-observation.d.ts +2 -1
  134. package/build/src/git/read-observation.js +3 -2
  135. package/build/src/git/reconcile.d.ts +8 -2
  136. package/build/src/git/reconcile.js +63 -14
  137. package/build/src/git/repository.d.ts +2 -29
  138. package/build/src/git/repository.js +4 -118
  139. package/build/src/git/scratch.d.ts +1 -1
  140. package/build/src/git/scratch.js +1 -1
  141. package/build/src/git/target-placement.d.ts +1 -1
  142. package/build/src/git/target-placement.js +9 -7
  143. package/build/src/git/tender.d.ts +20 -5
  144. package/build/src/git/tender.js +45 -13
  145. package/build/src/git/terminal-seal.d.ts +16 -2
  146. package/build/src/git/terminal-seal.js +15 -5
  147. package/build/src/git/workspace.d.ts +2 -1
  148. package/build/src/git/workspace.js +13 -5
  149. package/build/src/index.d.ts +1 -2
  150. package/build/src/index.js +1 -1
  151. package/build/src/kanshi/index.d.ts +1 -1
  152. package/build/src/kanshi/index.js +1 -1
  153. package/build/src/kanshi/read.d.ts +9 -1
  154. package/build/src/kanshi/read.js +91 -37
  155. package/build/src/kanshi/report.d.ts +1 -0
  156. package/build/src/library/address.d.ts +5 -14
  157. package/build/src/library/address.js +27 -23
  158. package/build/src/library/akuma-creation.d.ts +4 -2
  159. package/build/src/library/akuma-creation.js +43 -26
  160. package/build/src/library/audit.d.ts +2 -1
  161. package/build/src/library/audit.js +1 -1
  162. package/build/src/library/bind.d.ts +2 -1
  163. package/build/src/library/bind.js +4 -4
  164. package/build/src/library/catalog.d.ts +1 -2
  165. package/build/src/library/catalog.js +11 -6
  166. package/build/src/library/configuration.d.ts +5 -1
  167. package/build/src/library/configuration.js +71 -18
  168. package/build/src/library/contract.d.ts +70 -3
  169. package/build/src/library/contract.js +213 -27
  170. package/build/src/library/delivery.d.ts +1 -1
  171. package/build/src/library/fleet.d.ts +70 -12
  172. package/build/src/library/fleet.js +236 -56
  173. package/build/src/library/input.d.ts +0 -1
  174. package/build/src/library/input.js +1 -5
  175. package/build/src/library/keiyaku.d.ts +4 -4
  176. package/build/src/library/keiyaku.js +1 -2
  177. package/build/src/library/mutation.d.ts +2 -1
  178. package/build/src/library/reconcile.d.ts +2 -1
  179. package/build/src/library/reconcile.js +3 -1
  180. package/build/src/library/region.d.ts +1 -1
  181. package/build/src/library/repo.d.ts +3 -1
  182. package/build/src/library/repo.js +8 -4
  183. package/build/src/protocol/abandon.d.ts +9 -0
  184. package/build/src/protocol/abandon.js +15 -0
  185. package/build/src/protocol/amend.d.ts +16 -0
  186. package/build/src/protocol/amend.js +77 -0
  187. package/build/src/protocol/arc.d.ts +6 -0
  188. package/build/src/protocol/arc.js +12 -0
  189. package/build/src/protocol/attempt.d.ts +2 -1
  190. package/build/src/protocol/audit.d.ts +53 -0
  191. package/build/src/protocol/audit.js +140 -0
  192. package/build/src/protocol/bind.d.ts +2 -3
  193. package/build/src/protocol/bind.js +2 -16
  194. package/build/src/protocol/completion.d.ts +32 -0
  195. package/build/src/protocol/completion.js +130 -0
  196. package/build/src/protocol/deliver.d.ts +37 -0
  197. package/build/src/protocol/deliver.js +160 -0
  198. package/build/src/protocol/intent.d.ts +1 -1
  199. package/build/src/protocol/intent.js +1 -1
  200. package/build/src/protocol/operations.d.ts +65 -198
  201. package/build/src/protocol/operations.js +21 -634
  202. package/build/src/protocol/placement.d.ts +4 -13
  203. package/build/src/protocol/placement.js +3 -15
  204. package/build/src/protocol/read/status.d.ts +4 -2
  205. package/build/src/protocol/read/status.js +27 -15
  206. package/build/src/protocol/reconcile.d.ts +35 -0
  207. package/build/src/protocol/reconcile.js +41 -0
  208. package/build/src/protocol/reintegrate.d.ts +31 -0
  209. package/build/src/protocol/reintegrate.js +74 -0
  210. package/build/src/protocol/review.d.ts +33 -0
  211. package/build/src/protocol/review.js +148 -0
  212. package/build/src/protocol/run.d.ts +1 -1
  213. package/build/src/runtime/proc/run.d.ts +1 -0
  214. package/build/src/runtime/proc/run.js +9 -2
  215. package/build/src/settlement/fence.d.ts +1 -1
  216. package/build/src/settlement/holder.d.ts +1 -1
  217. package/build/src/settlement/settle.d.ts +2 -1
  218. package/build/src/settlement/settle.js +4 -1
  219. package/build/src/task/board.d.ts +18 -4
  220. package/build/src/task/board.js +73 -29
  221. package/build/src/task/compose.d.ts +1 -1
  222. package/build/src/task/compose.js +11 -4
  223. package/build/src/task/index.d.ts +4 -4
  224. package/build/src/task/index.js +8 -131
  225. package/build/src/task/input.d.ts +18 -0
  226. package/build/src/task/input.js +189 -0
  227. package/build/src/task/mutation.d.ts +39 -0
  228. package/build/src/task/mutation.js +85 -0
  229. package/build/src/task/operations.d.ts +4 -19
  230. package/build/src/task/operations.js +64 -18
  231. package/build/src/task/query.d.ts +9 -2
  232. package/build/src/task/query.js +32 -64
  233. package/build/src/task/store.js +0 -2
  234. package/build/src/verification/execution.d.ts +1 -1
  235. package/build/src/verification/execution.js +2 -1
  236. package/build/src/workspace-place.d.ts +1 -4
  237. package/build/src/workspace-place.js +0 -15
  238. package/package.json +5 -3
@@ -1,6 +1,6 @@
1
1
  import type { SnapshotId } from "../core/facts/types.js";
2
2
  import { type GitObjectId } from "./identity.js";
3
- import { type GitRepository } from "./repository.js";
3
+ import { type GitRepository } from "./process.js";
4
4
  export type WorkspaceChanges = Readonly<{
5
5
  staged: readonly string[];
6
6
  unstaged: readonly string[];
@@ -10,6 +10,7 @@ export type WorkspaceChanges = Readonly<{
10
10
  export type WorkspaceTree = Readonly<{
11
11
  tree: GitObjectId;
12
12
  head: SnapshotId;
13
+ at: string;
13
14
  dirty: boolean;
14
15
  changes: WorkspaceChanges;
15
16
  }>;
@@ -2,7 +2,7 @@ import { mkdtemp, rm } from "node:fs/promises";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join, resolve } from "node:path";
4
4
  import { gitObjectId, mintSnapshotId } from "./identity.js";
5
- import { runGit, runGitWithEnvironment } from "./repository.js";
5
+ import { runGit, runGitWithEnvironment } from "./process.js";
6
6
  const WORKTREE_DIRECTORY = ["keiyaku", "wt"];
7
7
  export function worktreePath(repository, place) {
8
8
  return resolve(repository.commonDirectory, ...WORKTREE_DIRECTORY, place);
@@ -114,24 +114,32 @@ export async function observeTargetLag(repository, workspace, head) {
114
114
  }
115
115
  /** Capture tracked and untracked workspace bytes without changing its real index. */
116
116
  export async function captureWorkspaceTree(repository, workspace) {
117
- const identities = (await runGit(repository, ["-C", workspace, "show", "-s", "--format=%H%n%T", "HEAD"]))
117
+ const identities = (await runGit(repository, ["-C", workspace, "show", "-s", "--format=%H%n%T%n%cI", "HEAD"]))
118
118
  .toString("utf8")
119
119
  .split("\n");
120
- if (identities.length !== 3 || identities[0] === undefined || identities[1] === undefined || identities[2] !== "") {
121
- throw new Error("workspace HEAD/tree resolution did not return exactly two object IDs");
120
+ if (identities.length !== 4
121
+ || identities[0] === undefined
122
+ || identities[1] === undefined
123
+ || identities[2] === undefined
124
+ || identities[3] !== "") {
125
+ throw new Error("workspace HEAD/tree/time resolution returned an unexpected shape");
122
126
  }
123
127
  const head = mintSnapshotId(identities[0]);
124
128
  const tree = gitObjectId(identities[1], "workspace tree");
129
+ const at = identities[2];
130
+ if (Number.isNaN(Date.parse(at)))
131
+ throw new Error("workspace HEAD has an invalid committer timestamp");
125
132
  const changes = await workspaceChanges(repository, workspace);
126
133
  const dirty = changes.staged.length > 0 || changes.unstaged.length > 0 || changes.untracked.length > 0;
127
134
  if (!dirty)
128
- return { tree, head, dirty, changes };
135
+ return { tree, head, at, dirty, changes };
129
136
  return await withPrivateGitIndex(async (environment) => {
130
137
  await runGitWithEnvironment(repository, ["-C", workspace, "read-tree", "HEAD"], undefined, environment);
131
138
  await runGitWithEnvironment(repository, ["-C", workspace, "add", "--all"], undefined, environment);
132
139
  return {
133
140
  tree: gitObjectId((await runGitWithEnvironment(repository, ["-C", workspace, "write-tree"], undefined, environment)).toString("utf8").trim(), "workspace tree"),
134
141
  head,
142
+ at,
135
143
  dirty,
136
144
  changes,
137
145
  };
@@ -1,6 +1,5 @@
1
- export { AuthorityCorruptionError, AkumaWorldScopeError, Delivery, gatesFrom, Keiyaku, KeiyakuRefused, KeiyakuRetry, NoGitWorldError, Repo, requireBranchesToBeUpToDateFrom, SettingsError, worktreeHooksFrom } from "./library/keiyaku.js";
1
+ export * from "./library/keiyaku.js";
2
2
  export { settings } from "./settings.js";
3
3
  export { World, WorldError } from "./world.js";
4
4
  export type { WorldResolution, WorldResolutionInput, WorldRoot } from "./world.js";
5
5
  export type { Settings, SettingsEntry, SettingsInput, SettingsNamespaceFailure, SettingsNamespaceView, SettingsScope, SettingsScopeState, } from "./settings.js";
6
- export type { AttestationVerdict, AbandonInput, ActorId, AkuId, AkumaAddressInput, AkumaAlias, AkumaGlob, AkumaHistoryInput, AkumaHistoryResult, AkumaInterruptInput, AkumaInterruptResult, AkumaKillResult, AkumaSetAddressInput, AkumaStatus, AkumaStatusView, AkumaTellInput, AkumaTellResult, AkumaWaitInput, AkumaWaitResult, AkumaWorldScopeRefusal, AliasBinding, AliasStage, AmendResult, AmendInput, ArcInput, AuditReport, DeliveryPreparationRefusal, BindInput, BindResult, CallInput, CallObservation, CallResult, Catalog, CatalogInput, CatalogQuery, ChangeId, ContractId, ContractState, ContractBoard, ContractDisposition, ContractGateCurrent, ContractGateReport, ContractListInput, ContractObservation, ContractObservationInput, ContractPhase, ContractRow, DeliverInput, Fact, FactKind, Dispatch, DispatchFailure, DispatchStage, DirectAkumaSelector, Gate, GatesFromInput, HookCommand, RequireBranchesToBeUpToDateFromInput, KeiyakuOfInput, KeiyakuRefusal, KeiyakuRetryReason, ForkInput, ForkResult, IntegrationFailure, Lag, MutationResult, PlacementStop, RegionOverlap, ReconcileInput, RepoReconcileReport, Review, ReconcileReport, ReviewInput, RepoAtInput, AuditInput, SnapshotId, SettlementAction, SettlementLag, SettlementReport, SetAkumaSelector, TaskId, TopologyEffect, VerificationReuse, VerificationStop, WorktreeHooks, } from "./library/keiyaku.js";
@@ -1,3 +1,3 @@
1
- export { AuthorityCorruptionError, AkumaWorldScopeError, Delivery, gatesFrom, Keiyaku, KeiyakuRefused, KeiyakuRetry, NoGitWorldError, Repo, requireBranchesToBeUpToDateFrom, SettingsError, worktreeHooksFrom } from "./library/keiyaku.js";
1
+ export * from "./library/keiyaku.js";
2
2
  export { settings } from "./settings.js";
3
3
  export { World, WorldError } from "./world.js";
@@ -1,4 +1,4 @@
1
- export { kanshi } from "./read.js";
1
+ export { kanshi, observeKanshi } from "./read.js";
2
2
  export { selectKanshi, selectRegion } from "./select.js";
3
3
  export type { KanshiInput } from "./read.js";
4
4
  export type { AkumaKanshiRow, AkumaKanshiWorld, ContractEndpointObservation, ContractHolderObservation, ContractKanshiBoard, ContractKanshiRow, KanshiReport, Section, TaskKanshiRow, TaskKanshiWorld, KanshiRegionSelection, RegionDeclaration, RegionIntersection, RegionPathMatch, RegionRead, } from "./report.js";
@@ -1,2 +1,2 @@
1
- export { kanshi } from "./read.js";
1
+ export { kanshi, observeKanshi } from "./read.js";
2
2
  export { selectKanshi, selectRegion } from "./select.js";
@@ -1,9 +1,17 @@
1
1
  import { Repo } from "../library/repo.js";
2
- import type { KanshiReport, KanshiRegionSelection } from "./report.js";
2
+ import type { ContractBoard } from "../library/contract.js";
3
+ import { type AliasBinding } from "../alias/index.js";
4
+ import type { KanshiReport, Section, KanshiRegionSelection } from "./report.js";
3
5
  import type { WorldRoot } from "../world.js";
4
6
  export type KanshiInput = Readonly<{
5
7
  world: WorldRoot | null;
6
8
  repo?: Repo;
7
9
  region?: KanshiRegionSelection;
10
+ contract?: ContractBoard["rows"][number]["id"];
8
11
  }>;
12
+ export type KanshiObservation = Readonly<{
13
+ report: KanshiReport;
14
+ aliases: Section<readonly AliasBinding[]>;
15
+ }>;
16
+ export declare function observeKanshi(input: KanshiInput): Promise<KanshiObservation>;
9
17
  export declare function kanshi(input: KanshiInput): Promise<KanshiReport>;
@@ -1,6 +1,7 @@
1
1
  import { Repo } from "../library/repo.js";
2
2
  import { scopeForRepo } from "../library/repo.js";
3
- import { observeTaskStatusRows } from "../task/operations.js";
3
+ import { observeTaskBoard } from "../task/operations.js";
4
+ import { contractNamespace } from "../settlement/settle.js";
4
5
  import { Akuma } from "../akuma/index.js";
5
6
  import { readAliases } from "../alias/index.js";
6
7
  import { readDispatchesAt } from "../dispatch/index.js";
@@ -10,7 +11,7 @@ import { withGitDecodeChannel, withGitReadObservation } from "../git/read-observ
10
11
  import { readDocuments } from "../protocol/read/documents.js";
11
12
  import { readRegionDeclarations, validateRegionPath } from "../library/region.js";
12
13
  import { contractId } from "../core/facts/types.js";
13
- import { selectRegion } from "./select.js";
14
+ import { selectKanshi, selectRegion } from "./select.js";
14
15
  function diagnostic(error) {
15
16
  let source;
16
17
  if (error instanceof Error)
@@ -85,15 +86,21 @@ function regionSelection(value) {
85
86
  function coordinate(input) {
86
87
  if (typeof input !== "object" || input === null || Array.isArray(input))
87
88
  throw new TypeError("kanshi input must be an object");
88
- for (const key of Object.keys(input))
89
- if (key !== "world" && key !== "repo" && key !== "region")
89
+ for (const key of Object.keys(input)) {
90
+ if (!["world", "repo", "region", "contract"].includes(key)) {
90
91
  throw new TypeError(`kanshi input has unknown field: ${key}`);
92
+ }
93
+ }
91
94
  if (input.world !== null && (typeof input.world !== "string" || input.world.trim().length === 0)) {
92
95
  throw new TypeError("kanshi world must be a WorldRoot or null");
93
96
  }
94
97
  if (input.repo !== undefined && !(input.repo instanceof Repo))
95
98
  throw new TypeError("kanshi repo must be a Repo");
96
- return input.region === undefined ? input : { ...input, region: regionSelection(input.region) };
99
+ return {
100
+ ...input,
101
+ ...(input.region === undefined ? {} : { region: regionSelection(input.region) }),
102
+ ...(input.contract === undefined ? {} : { contract: contractId(input.contract) }),
103
+ };
97
104
  }
98
105
  async function readRegion(observation, selection) {
99
106
  try {
@@ -114,9 +121,9 @@ async function readBranch(repo) {
114
121
  return null;
115
122
  }
116
123
  }
117
- async function readContracts(observation) {
124
+ async function readContracts(observation, selected) {
118
125
  try {
119
- return { kind: "present", value: await readContractBoard(observation) };
126
+ return { kind: "present", value: await readContractBoard(observation, selected) };
120
127
  }
121
128
  catch (error) {
122
129
  return { kind: "failed", failure: { message: diagnostic(error) } };
@@ -151,7 +158,7 @@ function attachFleet(contracts, akuma) {
151
158
  },
152
159
  };
153
160
  }
154
- function decorateContracts(contracts, holders) {
161
+ function decorateContracts(contracts, holders, namespaceTasks) {
155
162
  if (contracts.kind !== "present")
156
163
  return contracts;
157
164
  return {
@@ -159,12 +166,15 @@ function decorateContracts(contracts, holders) {
159
166
  value: {
160
167
  ...contracts.value,
161
168
  rows: contracts.value.rows.map((row) => {
162
- if (holders.kind === "failed")
163
- return { ...row, holder: { kind: "unavailable" }, fleet: [] };
169
+ const selected = namespaceTasks(row.id);
170
+ if (holders.kind === "failed") {
171
+ return { ...row, holder: { kind: "unavailable" }, fleet: [], namespaceTasks: selected };
172
+ }
164
173
  const holder = holders.kind === "present" ? holders.value.get(row.id) : undefined;
165
174
  return {
166
175
  ...row,
167
176
  fleet: [],
177
+ namespaceTasks: selected,
168
178
  holder: holder?.disposition === "held"
169
179
  ? { kind: "held", taskId: holder.taskId }
170
180
  : { kind: "none" },
@@ -192,25 +202,42 @@ function joinTasks(rows, holders, observeContract) {
192
202
  return { ...row, contract: { id: contractId, observed: observeContract(contractId) } };
193
203
  });
194
204
  }
195
- async function readTasks(path, holders, observeContract) {
196
- if (holders.kind === "failed")
197
- return { kind: "failed", failure: holders.failure };
205
+ async function readTaskWorld(path) {
206
+ if (path === null)
207
+ return { kind: "absent" };
198
208
  try {
199
- return {
200
- kind: "present",
201
- value: { root: path, rows: joinTasks(await observeTaskStatusRows(path), holders, observeContract) },
202
- };
209
+ return { kind: "present", observation: await observeTaskBoard(path) };
203
210
  }
204
211
  catch (error) {
205
212
  return { kind: "failed", failure: { message: diagnostic(error) } };
206
213
  }
207
214
  }
208
- async function joinAkuma(path, observeContract, dispatches) {
215
+ function namespaceTaskSection(board, id) {
216
+ if (board.kind === "absent")
217
+ return { kind: "absent" };
218
+ if (board.kind === "failed")
219
+ return { kind: "failed", failure: board.failure };
220
+ return { kind: "present", value: board.observation.selectNamespace(contractNamespace(id)) };
221
+ }
222
+ function readTasks(path, board, holders, observeContract) {
223
+ if (holders.kind === "failed")
224
+ return { kind: "failed", failure: holders.failure };
225
+ if (board.kind === "failed")
226
+ return { kind: "failed", failure: board.failure };
227
+ if (board.kind === "absent")
228
+ return { kind: "absent" };
229
+ return {
230
+ kind: "present",
231
+ value: { root: path, rows: joinTasks(board.observation.statusRows, holders, observeContract) },
232
+ };
233
+ }
234
+ async function joinAkuma(path, observeContract, dispatches, aliases) {
235
+ if (aliases.kind !== "present")
236
+ return aliases;
209
237
  try {
210
238
  const source = await Akuma.of(path).list();
211
- const aliases = await readAliases(path);
212
239
  const aliasById = new Map();
213
- for (const binding of aliases)
240
+ for (const binding of aliases.value)
214
241
  aliasById.set(binding.akuId, [...(aliasById.get(binding.akuId) ?? []), binding]);
215
242
  const dispatchById = new Map(dispatches.map((dispatch) => [dispatch.akuId, dispatch]));
216
243
  return {
@@ -237,6 +264,14 @@ async function joinAkuma(path, observeContract, dispatches) {
237
264
  return { kind: "failed", failure: { message: diagnostic(error) } };
238
265
  }
239
266
  }
267
+ async function readAliasBindings(path) {
268
+ try {
269
+ return { kind: "present", value: await readAliases(path) };
270
+ }
271
+ catch (error) {
272
+ return { kind: "failed", failure: { message: diagnostic(error) } };
273
+ }
274
+ }
240
275
  async function readDispatches(observation) {
241
276
  try {
242
277
  return { kind: "present", value: await readDispatchesAt(observation) };
@@ -245,7 +280,7 @@ async function readDispatches(observation) {
245
280
  return { kind: "failed", failure: { message: diagnostic(error) } };
246
281
  }
247
282
  }
248
- export async function kanshi(input) {
283
+ export async function observeKanshi(input) {
249
284
  const observedAt = new Date().toISOString();
250
285
  const { world, repo } = coordinate(input);
251
286
  const branch = await readBranch(repo);
@@ -253,28 +288,35 @@ export async function kanshi(input) {
253
288
  const contracts = { kind: "absent" };
254
289
  const holders = { kind: "absent" };
255
290
  const observeContract = contractEndpointObserver(contracts);
256
- const tasks = world === null ? { kind: "absent" } : await readTasks(world, holders, observeContract);
257
- const akuma = world === null ? { kind: "absent" } : await joinAkuma(world, observeContract, []);
258
- return { root: world, observedAt, branch, contracts, tasks, akuma, ...(input.region === undefined ? {} : { region: { kind: "absent" } }) };
291
+ const board = await readTaskWorld(world);
292
+ const tasks = world === null ? { kind: "absent" } : readTasks(world, board, holders, observeContract);
293
+ const aliases = world === null ? { kind: "absent" } : await readAliasBindings(world);
294
+ const akuma = world === null ? { kind: "absent" } : await joinAkuma(world, observeContract, [], aliases);
295
+ return {
296
+ report: { root: world, observedAt, branch, contracts, tasks, akuma, ...(input.region === undefined ? {} : { region: { kind: "absent" } }) },
297
+ aliases,
298
+ };
259
299
  }
260
300
  try {
261
301
  const repository = scopeForRepo(repo);
262
302
  return await withGitDecodeChannel(repository, (channel) => withGitReadObservation(repository, channel, async (observation) => {
263
- const [contractSection, holders, dispatches, region] = await Promise.all([
264
- readContracts(observation),
303
+ const [contractSection, holders, dispatches, region, board] = await Promise.all([
304
+ readContracts(observation, input.contract),
265
305
  readHolders(observation),
266
306
  readDispatches(observation),
267
307
  input.region === undefined ? Promise.resolve(undefined) : readRegion(observation, input.region),
308
+ readTaskWorld(world),
268
309
  ]);
269
- const contracts = decorateContracts(contractSection, holders);
310
+ const contracts = decorateContracts(contractSection, holders, (id) => namespaceTaskSection(board, id));
270
311
  const observeContract = contractEndpointObserver(contracts);
271
- const tasks = world === null ? { kind: "absent" } : await readTasks(world, holders, observeContract);
312
+ const aliases = world === null ? { kind: "absent" } : await readAliasBindings(world);
313
+ const tasks = world === null ? { kind: "absent" } : readTasks(world, board, holders, observeContract);
272
314
  const akuma = world === null
273
315
  ? { kind: "absent" }
274
316
  : dispatches.kind === "failed"
275
317
  ? dispatches
276
- : await joinAkuma(world, observeContract, dispatches.value);
277
- return {
318
+ : await joinAkuma(world, observeContract, dispatches.value, aliases);
319
+ const report = {
278
320
  root: world,
279
321
  observedAt,
280
322
  branch,
@@ -283,18 +325,30 @@ export async function kanshi(input) {
283
325
  akuma,
284
326
  ...(region === undefined ? {} : { region }),
285
327
  };
328
+ return {
329
+ report: input.contract === undefined
330
+ ? report
331
+ : selectKanshi({ report, contract: input.contract }),
332
+ aliases,
333
+ };
286
334
  }));
287
335
  }
288
336
  catch (error) {
289
337
  const failure = { kind: "failed", failure: { message: diagnostic(error) } };
290
338
  return {
291
- root: world,
292
- observedAt,
293
- branch,
294
- contracts: failure,
295
- tasks: world === null ? { kind: "absent" } : failure,
296
- akuma: world === null ? { kind: "absent" } : failure,
297
- ...(input.region === undefined ? {} : { region: failure }),
339
+ report: {
340
+ root: world,
341
+ observedAt,
342
+ branch,
343
+ contracts: failure,
344
+ tasks: world === null ? { kind: "absent" } : failure,
345
+ akuma: world === null ? { kind: "absent" } : failure,
346
+ ...(input.region === undefined ? {} : { region: failure }),
347
+ },
348
+ aliases: world === null ? { kind: "absent" } : failure,
298
349
  };
299
350
  }
300
351
  }
352
+ export async function kanshi(input) {
353
+ return (await observeKanshi(input)).report;
354
+ }
@@ -31,6 +31,7 @@ export type ContractFleetAttachment = Readonly<{
31
31
  export type ContractKanshiRow = ContractBoard["rows"][number] & Readonly<{
32
32
  holder: ContractHolderObservation;
33
33
  fleet: readonly ContractFleetAttachment[];
34
+ namespaceTasks: Section<readonly TaskRow[]>;
34
35
  }>;
35
36
  export type ContractKanshiBoard = Omit<ContractBoard, "rows"> & Readonly<{
36
37
  rows: readonly ContractKanshiRow[];
@@ -1,20 +1,19 @@
1
+ import { type AliasBinding } from "../alias/index.js";
1
2
  import { type AkuId } from "../akuma/identity.js";
2
3
  import { type AkumaAlias, type AkumaGlob } from "../identity/selector.js";
3
- import type { Settings } from "../settings.js";
4
4
  import type { WorldRoot } from "../world.js";
5
+ import type { KanshiReport, Section } from "../kanshi/index.js";
5
6
  import { type Repo } from "./repo.js";
6
7
  export type DirectAkumaSelector = AkuId | AkumaAlias;
7
8
  export type SetAkumaSelector = DirectAkumaSelector | AkumaGlob | `kei/${string}`;
8
9
  export type AkumaAddressInput = Readonly<{
9
10
  path: WorldRoot;
10
11
  akuma: string;
11
- settings?: Settings;
12
12
  repo?: Repo;
13
13
  }>;
14
14
  export type AkumaSetAddressInput = Readonly<{
15
15
  path: WorldRoot;
16
16
  akuma: readonly string[];
17
- settings?: Settings;
18
17
  repo?: Repo;
19
18
  }>;
20
19
  export type AkumaWorldScopeRefusal = Readonly<{
@@ -26,12 +25,6 @@ export declare class AkumaWorldScopeError extends TypeError {
26
25
  readonly refusal: AkumaWorldScopeRefusal;
27
26
  constructor(refusal: AkumaWorldScopeRefusal);
28
27
  }
29
- export type NamedAddressContract = Readonly<{
30
- id: string;
31
- disposition: "active" | "terminal";
32
- workspace: "worktree" | "here";
33
- worktreePath: string | null;
34
- }>;
35
28
  export type NamedAddress = Readonly<{
36
29
  kind: "contract";
37
30
  id: string;
@@ -40,18 +33,16 @@ export type NamedAddress = Readonly<{
40
33
  id: AkuId;
41
34
  }>;
42
35
  export type NamedAddressInput = Readonly<{
43
- path: WorldRoot | null;
44
36
  selector: string;
45
- contracts: readonly NamedAddressContract[];
37
+ report: KanshiReport;
38
+ aliases: Section<readonly AliasBinding[]>;
46
39
  }>;
47
- export declare function resolveNamedAddress(input: NamedAddressInput): Promise<NamedAddress>;
40
+ export declare function resolveNamedAddress(input: NamedAddressInput): NamedAddress;
48
41
  export declare function addressAkuma(input: AkumaAddressInput): Promise<Readonly<{
49
42
  path: WorldRoot;
50
43
  id: AkuId;
51
- settings?: Settings;
52
44
  }>>;
53
45
  export declare function addressAkumaSet(input: AkumaSetAddressInput): Promise<Readonly<{
54
46
  path: WorldRoot;
55
47
  ids: readonly AkuId[];
56
- settings?: Settings;
57
48
  }>>;
@@ -20,16 +20,8 @@ function nonblank(value, label) {
20
20
  throw new TypeError(`${label} must be a nonblank string`);
21
21
  return value;
22
22
  }
23
- function settingsOption(value) {
24
- if (value === undefined)
25
- return undefined;
26
- if (typeof value !== "object" || value === null || typeof value.namespace !== "function") {
27
- throw new TypeError("settings must be a Settings");
28
- }
29
- return value;
30
- }
31
- function world(path, settings) {
32
- return Akuma.of(path, settings);
23
+ function world(path) {
24
+ return Akuma.of(path);
33
25
  }
34
26
  async function directId(path, selector) {
35
27
  if (selector.startsWith("@")) {
@@ -41,19 +33,25 @@ async function directId(path, selector) {
41
33
  }
42
34
  return parseAkuId(selector).id;
43
35
  }
44
- export async function resolveNamedAddress(input) {
36
+ export function resolveNamedAddress(input) {
45
37
  const selector = nonblank(input.selector, "selector");
46
38
  if (selector.startsWith("kei/"))
47
39
  return { kind: "contract", id: contractId(selector) };
48
40
  if (selector.startsWith("aku/"))
49
41
  return { kind: "akuma", id: parseAkuId(selector).id };
50
42
  const alias = parseAkumaAlias(selector);
51
- const contractMatches = input.contracts.filter((row) => row.disposition === "active"
43
+ if (input.report.contracts.kind === "failed") {
44
+ throw new TypeError("cannot resolve a named selector while the Contract world is failed");
45
+ }
46
+ if (input.aliases.kind === "failed") {
47
+ throw new TypeError("cannot resolve a named selector while Alias authority is failed");
48
+ }
49
+ const contractMatches = (input.report.contracts.kind === "present" ? input.report.contracts.value.rows : []).filter((row) => row.disposition === "active"
52
50
  && row.workspace === "worktree" && row.worktreePath !== null
53
51
  && `@${row.id.slice("kei/".length)}` === alias);
54
- const aliasId = input.path === null
55
- ? null
56
- : (await readAliases(input.path)).find((binding) => binding.alias === alias)?.akuId ?? null;
52
+ const aliasId = input.aliases.kind === "present"
53
+ ? input.aliases.value.find((binding) => binding.alias === alias)?.akuId ?? null
54
+ : null;
57
55
  if (contractMatches.length > 0 && aliasId !== null)
58
56
  throw new TypeError(`ambiguous selector matches Contract and Akuma: ${selector}`);
59
57
  if (contractMatches.length === 1)
@@ -67,14 +65,14 @@ export async function resolveNamedAddress(input) {
67
65
  export async function addressAkuma(input) {
68
66
  const values = requireInput(input, "Akuma address input");
69
67
  for (const key of Object.keys(values)) {
70
- if (!["path", "akuma", "settings", "repo"].includes(key))
68
+ if (!["path", "akuma", "repo"].includes(key)) {
71
69
  throw new TypeError(`Akuma address input has unknown field: ${key}`);
70
+ }
72
71
  }
73
72
  if (values.repo !== undefined)
74
73
  scopeForRepo(values.repo);
75
74
  const path = nonblank(values.path, "path");
76
- const settings = settingsOption(values.settings);
77
- return { path, id: await directId(path, nonblank(values.akuma, "akuma")), ...(settings === undefined ? {} : { settings }) };
75
+ return { path, id: await directId(path, nonblank(values.akuma, "akuma")) };
78
76
  }
79
77
  function idsFromFleet(fleet) {
80
78
  return fleet.rows.map((row) => row.id);
@@ -118,7 +116,13 @@ function addSelectorIds(selector, sources, selected, contractMembers) {
118
116
  selected.add(selector.value);
119
117
  }
120
118
  async function contractMemberInWorld(path, id) {
121
- return await probeBornAkuma(path, id);
119
+ try {
120
+ return await probeBornAkuma(path, id);
121
+ }
122
+ catch {
123
+ // A dispatched physical member remains selected when its Heart cannot be read.
124
+ return true;
125
+ }
122
126
  }
123
127
  async function refuseForeignContractMembers(path, ids, contractMembers) {
124
128
  const foreign = [];
@@ -132,19 +136,19 @@ async function refuseForeignContractMembers(path, ids, contractMembers) {
132
136
  export async function addressAkumaSet(input) {
133
137
  const values = requireInput(input, "Akuma set address input");
134
138
  for (const key of Object.keys(values)) {
135
- if (!["path", "akuma", "settings", "repo"].includes(key))
139
+ if (!["path", "akuma", "repo"].includes(key)) {
136
140
  throw new TypeError(`Akuma set address input has unknown field: ${key}`);
141
+ }
137
142
  }
138
143
  if (!Array.isArray(values.akuma) || values.akuma.length === 0)
139
144
  throw new TypeError("akuma must be a nonempty selector array");
140
145
  const path = nonblank(values.path, "path");
141
- const settings = settingsOption(values.settings);
142
146
  const selectors = values.akuma.map(parseSetSelector);
143
147
  if (hasSelectorKind(selectors, "contract") && values.repo === undefined) {
144
148
  throw new TypeError("Contract Akuma selector requires repo");
145
149
  }
146
150
  const fleetIds = hasSelectorKind(selectors, "glob")
147
- ? idsFromFleet(await world(path, settings).list())
151
+ ? idsFromFleet(await world(path).list())
148
152
  : [];
149
153
  const aliases = hasSelectorKind(selectors, "alias")
150
154
  ? new Map((await readAliases(path)).map((binding) => [binding.alias, binding.akuId]))
@@ -161,5 +165,5 @@ export async function addressAkumaSet(input) {
161
165
  if (ids.length === 0)
162
166
  throw new TypeError("Akuma selector snapshot is empty");
163
167
  await refuseForeignContractMembers(path, ids, contractMembers);
164
- return { path, ids, ...(settings === undefined ? {} : { settings }) };
168
+ return { path, ids };
165
169
  }
@@ -5,6 +5,7 @@ import { type Dispatch, type DispatchFailure } from "../dispatch/index.js";
5
5
  import { type AkumaAlias } from "../identity/selector.js";
6
6
  import type { Settings } from "../settings.js";
7
7
  import type { WorldRoot } from "../world.js";
8
+ import type { AllowedAction } from "../akuma/allowed.js";
8
9
  import { type Keiyaku } from "./contract.js";
9
10
  import { type Repo } from "./repo.js";
10
11
  export type { AkumaStatus } from "../akuma/akuma.js";
@@ -41,9 +42,11 @@ export type CallInput = Readonly<{
41
42
  cwd?: string;
42
43
  mode?: "wait" | "detach";
43
44
  timeoutMs?: number;
45
+ home?: string;
44
46
  settings?: Settings;
45
47
  contract?: Keiyaku;
46
48
  alias?: AkumaAlias;
49
+ allowed?: readonly AllowedAction[];
47
50
  }>;
48
51
  export type CallObservation = Readonly<{
49
52
  kind: "detached";
@@ -60,7 +63,7 @@ export type CallResult = Readonly<{
60
63
  readonly?: ReadonlyRestraint;
61
64
  execution: Readonly<{
62
65
  cwd: string;
63
- source: "input" | "world" | "contract-worktree";
66
+ source: "input" | "contract-worktree" | "caller" | "process" | "world";
64
67
  }>;
65
68
  dispatch: DispatchStage;
66
69
  alias: AliasStage;
@@ -70,7 +73,6 @@ export type ForkInput = Readonly<{
70
73
  path: WorldRoot;
71
74
  akuma: string;
72
75
  at: string;
73
- settings?: Settings;
74
76
  repo?: Repo;
75
77
  }>;
76
78
  export type ForkResult = Readonly<{