@astrosheep/keiyaku 4.1.0 → 4.1.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 +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +3 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +3 -6
- package/build/src/akuma/akuma-errors.d.ts +6 -0
- package/build/src/akuma/akuma-errors.js +9 -0
- package/build/src/akuma/akuma-handle.d.ts +39 -0
- package/build/src/akuma/akuma-handle.js +263 -0
- package/build/src/akuma/akuma-observe.d.ts +19 -0
- package/build/src/akuma/akuma-observe.js +74 -0
- package/build/src/akuma/akuma-product-symbols.d.ts +1 -0
- package/build/src/akuma/akuma-product-symbols.js +1 -0
- package/build/src/akuma/akuma-product.d.ts +18 -0
- package/build/src/akuma/akuma-product.js +154 -0
- package/build/src/akuma/akuma.d.ts +37 -81
- package/build/src/akuma/akuma.js +39 -447
- package/build/src/akuma/allowed.d.ts +1 -0
- package/build/src/akuma/allowed.js +6 -0
- package/build/src/akuma/archetype.js +8 -5
- package/build/src/akuma/body-supervisor.d.ts +26 -0
- package/build/src/akuma/body-supervisor.js +89 -0
- package/build/src/akuma/body.d.ts +45 -4
- package/build/src/akuma/body.js +145 -35
- package/build/src/akuma/coordinate.js +17 -7
- package/build/src/akuma/heart/facts.js +1 -1
- package/build/src/akuma/heart/index.d.ts +1 -1
- package/build/src/akuma/heart/index.js +2 -4
- package/build/src/akuma/heart/request-authority.js +4 -4
- package/build/src/akuma/heart/request-rows.js +27 -16
- package/build/src/akuma/heart/rows.js +79 -41
- package/build/src/akuma/heart/soul.js +1 -1
- package/build/src/akuma/heart/storage.d.ts +1 -0
- package/build/src/akuma/heart/storage.js +76 -11
- package/build/src/akuma/heart/tells.js +35 -18
- package/build/src/akuma/heart/timeline.js +19 -11
- package/build/src/akuma/identity.d.ts +1 -0
- package/build/src/akuma/identity.js +1 -0
- package/build/src/akuma/index.d.ts +3 -3
- package/build/src/akuma/index.js +1 -1
- package/build/src/akuma/nuke.js +106 -14
- package/build/src/akuma/projection-read.d.ts +17 -0
- package/build/src/akuma/projection-read.js +135 -0
- package/build/src/akuma/projection.d.ts +1 -16
- package/build/src/akuma/projection.js +77 -154
- package/build/src/akuma/provider-recipe.js +11 -5
- package/build/src/akuma/provider.js +105 -62
- package/build/src/akuma/providers/acp/config.js +5 -6
- package/build/src/akuma/providers/acp/core.js +17 -10
- package/build/src/akuma/providers/acp/events.js +38 -29
- package/build/src/akuma/providers/acp/index.js +13 -9
- package/build/src/akuma/providers/claude/events.js +8 -12
- package/build/src/akuma/providers/claude/index.d.ts +1 -0
- package/build/src/akuma/providers/claude/index.js +55 -26
- package/build/src/akuma/providers/claude/input.js +6 -2
- package/build/src/akuma/providers/codex-app-server/events.js +61 -36
- package/build/src/akuma/providers/codex-app-server/index.js +25 -13
- package/build/src/akuma/providers/grok-build/index.js +22 -25
- package/build/src/akuma/providers/index.js +2 -18
- package/build/src/akuma/providers/opencode-sdk/events.js +32 -18
- package/build/src/akuma/providers/opencode-sdk/index.js +26 -17
- package/build/src/akuma/providers/opencode-sdk/session.js +21 -5
- package/build/src/akuma/providers/pi/events.js +26 -19
- package/build/src/akuma/providers/pi/index.js +58 -40
- package/build/src/akuma/publication.js +9 -9
- package/build/src/akuma/request-execution.d.ts +6 -0
- package/build/src/akuma/request-execution.js +86 -0
- package/build/src/akuma/request-serve.d.ts +12 -1
- package/build/src/akuma/request-serve.js +19 -122
- package/build/src/akuma/request-wire.d.ts +2 -2
- package/build/src/akuma/request-wire.js +75 -102
- package/build/src/akuma/requests.js +2 -2
- package/build/src/akuma/{body-turn.d.ts → turn-drive.d.ts} +2 -25
- package/build/src/akuma/{body-turn.js → turn-drive.js} +20 -103
- package/build/src/akuma-body.js +6 -5
- package/build/src/body/amend.d.ts +4 -1
- package/build/src/body/amend.js +14 -6
- package/build/src/body/decode.js +2 -4
- package/build/src/body/envelope.js +2 -4
- package/build/src/body/region.d.ts +1 -2
- package/build/src/body/region.js +2 -70
- package/build/src/body/render.js +17 -12
- package/build/src/body/shape.js +1 -7
- package/build/src/cli/accepted.d.ts +1 -1
- package/build/src/cli/accepted.js +8 -1
- package/build/src/cli/commands/akuma-invoke.js +18 -6
- package/build/src/cli/commands/akuma.d.ts +0 -6
- package/build/src/cli/commands/akuma.js +11 -24
- package/build/src/cli/commands/amend.d.ts +2 -2
- package/build/src/cli/commands/amend.js +2 -4
- package/build/src/cli/commands/bind.d.ts +4 -4
- package/build/src/cli/commands/bind.js +16 -6
- package/build/src/cli/commands/contract-invoke.d.ts +25 -0
- package/build/src/cli/commands/contract-invoke.js +193 -0
- package/build/src/cli/commands/contract.d.ts +109 -10
- package/build/src/cli/commands/contract.js +339 -16
- package/build/src/cli/commands/install.d.ts +1 -1
- package/build/src/cli/commands/install.js +23 -15
- package/build/src/cli/commands/task-invoke.js +187 -67
- package/build/src/cli/commands/task-query.js +48 -24
- package/build/src/cli/commands/task.js +150 -38
- package/build/src/cli/coordinates.js +2 -4
- package/build/src/cli/invoke.js +92 -208
- package/build/src/cli/main.js +4 -2
- package/build/src/cli/parse.d.ts +3 -90
- package/build/src/cli/parse.js +27 -233
- package/build/src/cli/render/akuma-activity.d.ts +38 -0
- package/build/src/cli/render/akuma-activity.js +362 -0
- package/build/src/cli/render/akuma-tool-command.js +6 -7
- package/build/src/cli/render/akuma-tool.js +10 -8
- package/build/src/cli/render/akuma.d.ts +1 -1
- package/build/src/cli/render/akuma.js +61 -353
- package/build/src/cli/render/audit.js +5 -15
- package/build/src/cli/render/board.d.ts +1 -0
- package/build/src/cli/render/board.js +17 -0
- package/build/src/cli/render/catalog.js +81 -8
- package/build/src/cli/render/contract-history.d.ts +2 -0
- package/build/src/cli/render/contract-history.js +83 -0
- package/build/src/cli/render/contract-observation.d.ts +10 -0
- package/build/src/cli/render/contract-observation.js +58 -0
- package/build/src/cli/render/contract.d.ts +1 -2
- package/build/src/cli/render/contract.js +41 -142
- package/build/src/cli/render/kanshi.js +239 -215
- package/build/src/cli/render/receipt.js +2 -9
- package/build/src/cli/render/refusal.js +10 -15
- package/build/src/cli/render/region.js +22 -6
- package/build/src/cli/render/settings.js +4 -4
- package/build/src/cli/render/task.js +34 -14
- package/build/src/cli/render/terminal.js +16 -5
- package/build/src/cli/result.d.ts +3 -3
- package/build/src/cli/runtime.d.ts +6 -1
- package/build/src/cli/runtime.js +84 -63
- package/build/src/cli/selectors.js +2 -4
- package/build/src/cli/usage.js +6 -5
- package/build/src/contract-worktree.d.ts +1 -23
- package/build/src/contract-worktree.js +79 -155
- package/build/src/coordination/durable-file.js +7 -3
- package/build/src/coordination/sqlite-transaction-lock.js +29 -12
- package/build/src/core/facts/codec.js +7 -3
- package/build/src/core/facts/types.d.ts +1 -1
- package/build/src/core/subject.js +16 -9
- package/build/src/core/verbs/abandon.d.ts +1 -1
- package/build/src/core/verbs/abandon.js +1 -1
- package/build/src/core/verbs/amend.d.ts +1 -1
- package/build/src/core/verbs/amend.js +7 -7
- package/build/src/core/verbs/attestation.js +4 -1
- package/build/src/core/verbs/bind.d.ts +1 -1
- package/build/src/core/verbs/bind.js +1 -1
- package/build/src/core/verbs/placement.d.ts +1 -1
- package/build/src/core/verbs/placement.js +10 -8
- package/build/src/dispatch/index.js +8 -6
- package/build/src/duration.js +5 -1
- package/build/src/git/admission.js +5 -3
- package/build/src/git/hooks.d.ts +8 -0
- package/build/src/git/hooks.js +63 -14
- package/build/src/git/identity.js +1 -4
- package/build/src/git/integration.d.ts +2 -3
- package/build/src/git/integration.js +32 -39
- package/build/src/git/nuke.d.ts +1 -1
- package/build/src/git/nuke.js +110 -57
- package/build/src/git/observe.d.ts +13 -1
- package/build/src/git/observe.js +51 -44
- package/build/src/git/process.js +4 -2
- package/build/src/git/read-observation.js +10 -8
- package/build/src/git/reconcile.d.ts +22 -2
- package/build/src/git/reconcile.js +38 -274
- package/build/src/git/repository.d.ts +2 -0
- package/build/src/git/repository.js +13 -22
- package/build/src/git/scratch.d.ts +8 -5
- package/build/src/git/scratch.js +29 -2
- package/build/src/git/target-placement.d.ts +9 -10
- package/build/src/git/target-placement.js +59 -62
- package/build/src/git/tender.js +13 -46
- package/build/src/git/terminal-reconcile.d.ts +21 -0
- package/build/src/git/terminal-reconcile.js +278 -0
- package/build/src/git/terminal-seal.js +15 -12
- package/build/src/git/tree.js +5 -2
- package/build/src/git/workspace.d.ts +24 -2
- package/build/src/git/workspace.js +120 -16
- package/build/src/identity/coordinates.js +3 -1
- package/build/src/identity/selector.js +6 -3
- package/build/src/kanshi/fleet.d.ts +6 -0
- package/build/src/kanshi/fleet.js +27 -0
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/read.js +60 -48
- package/build/src/kanshi/report.d.ts +11 -23
- package/build/src/kanshi/select.js +25 -24
- package/build/src/library/address.d.ts +2 -1
- package/build/src/library/address.js +7 -8
- package/build/src/library/akuma-creation.js +20 -12
- package/build/src/library/audit.d.ts +0 -1
- package/build/src/library/audit.js +1 -2
- package/build/src/library/bind.d.ts +53 -5
- package/build/src/library/bind.js +98 -22
- package/build/src/library/catalog.d.ts +1 -0
- package/build/src/library/catalog.js +6 -3
- package/build/src/library/configuration.js +3 -1
- package/build/src/library/continuation.d.ts +15 -4
- package/build/src/library/continuation.js +24 -16
- package/build/src/library/contract-bind.d.ts +26 -0
- package/build/src/library/contract-bind.js +106 -0
- package/build/src/library/contract-operations.d.ts +77 -0
- package/build/src/library/contract-operations.js +130 -0
- package/build/src/library/contract-types.d.ts +95 -0
- package/build/src/library/contract-types.js +1 -0
- package/build/src/library/contract.d.ts +19 -154
- package/build/src/library/contract.js +46 -261
- package/build/src/library/fleet.d.ts +1 -1
- package/build/src/library/fleet.js +19 -11
- package/build/src/library/input.d.ts +2 -0
- package/build/src/library/input.js +14 -0
- package/build/src/library/keiyaku.d.ts +8 -7
- package/build/src/library/keiyaku.js +3 -3
- package/build/src/library/nuke.js +14 -5
- package/build/src/library/reconcile.d.ts +9 -4
- package/build/src/library/reconcile.js +30 -24
- package/build/src/library/refusal.d.ts +13 -5
- package/build/src/library/refusal.js +7 -0
- package/build/src/library/region.d.ts +8 -7
- package/build/src/library/region.js +31 -11
- package/build/src/library/repo.js +2 -2
- package/build/src/markdown/lex.js +9 -2
- package/build/src/markdown/parse.js +11 -7
- package/build/src/markdown/query.js +4 -2
- package/build/src/protocol/amend.js +3 -1
- package/build/src/protocol/attempt.d.ts +7 -3
- package/build/src/protocol/attempt.js +9 -5
- package/build/src/protocol/audit.d.ts +1 -1
- package/build/src/protocol/audit.js +4 -14
- package/build/src/protocol/bind.d.ts +19 -6
- package/build/src/protocol/bind.js +28 -13
- package/build/src/protocol/completion.d.ts +0 -1
- package/build/src/protocol/completion.js +1 -3
- package/build/src/protocol/deliver.d.ts +1 -3
- package/build/src/protocol/deliver.js +15 -39
- package/build/src/protocol/intent.d.ts +1 -0
- package/build/src/protocol/intent.js +9 -7
- package/build/src/protocol/operations.d.ts +3 -7
- package/build/src/protocol/operations.js +5 -3
- package/build/src/protocol/placement.d.ts +0 -1
- package/build/src/protocol/placement.js +6 -6
- package/build/src/protocol/read/observation.d.ts +11 -0
- package/build/src/protocol/read/observation.js +37 -0
- package/build/src/protocol/read/status.d.ts +23 -12
- package/build/src/protocol/read/status.js +90 -72
- package/build/src/protocol/reconcile.d.ts +1 -0
- package/build/src/protocol/reconcile.js +2 -3
- package/build/src/protocol/reintegrate.js +1 -1
- package/build/src/protocol/review.d.ts +0 -1
- package/build/src/protocol/review.js +15 -22
- package/build/src/protocol/run.d.ts +1 -0
- package/build/src/protocol/run.js +4 -5
- package/build/src/runtime/proc/launch.d.ts +33 -0
- package/build/src/runtime/proc/launch.js +98 -0
- package/build/src/runtime/proc/line-rpc.js +9 -3
- package/build/src/runtime/proc/run.d.ts +12 -6
- package/build/src/runtime/proc/run.js +78 -21
- package/build/src/runtime/proc/stdio.js +7 -10
- package/build/src/settings.js +6 -2
- package/build/src/settlement/holder.js +13 -10
- package/build/src/settlement/settle.js +39 -6
- package/build/src/task/board.js +12 -6
- package/build/src/task/compose.js +85 -22
- package/build/src/task/context.js +21 -8
- package/build/src/task/document.js +46 -10
- package/build/src/task/identity.js +5 -2
- package/build/src/task/index.d.ts +0 -1
- package/build/src/task/index.js +119 -34
- package/build/src/task/input.js +29 -7
- package/build/src/task/mutation.js +61 -19
- package/build/src/task/operations.d.ts +6 -1
- package/build/src/task/operations.js +83 -29
- package/build/src/task/query.js +55 -26
- package/build/src/task/store.d.ts +3 -1
- package/build/src/task/store.js +81 -17
- package/build/src/verification/execution.js +14 -11
- package/build/src/workspace-place.js +19 -7
- package/build/src/world.js +16 -6
- package/package.json +8 -3
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
import { isMap, parseDocument, stringify } from "yaml";
|
|
2
2
|
import { formatTaskId, parseTaskId } from "./identity.js";
|
|
3
3
|
export class TaskAuthorityCorruptionError extends Error {
|
|
4
|
-
constructor(message, options) {
|
|
4
|
+
constructor(message, options) {
|
|
5
|
+
super(message, options);
|
|
6
|
+
this.name = "TaskAuthorityCorruptionError";
|
|
7
|
+
}
|
|
5
8
|
}
|
|
6
9
|
const STATES = new Set(["open", "in_progress", "on_hold", "done", "drop"]);
|
|
7
|
-
const REQUIRED_STORED_KEYS = [
|
|
10
|
+
const REQUIRED_STORED_KEYS = [
|
|
11
|
+
"id",
|
|
12
|
+
"title",
|
|
13
|
+
"state",
|
|
14
|
+
"priority",
|
|
15
|
+
"needs",
|
|
16
|
+
"parent",
|
|
17
|
+
"supersedes",
|
|
18
|
+
"relates",
|
|
19
|
+
"note",
|
|
20
|
+
"createdAt",
|
|
21
|
+
"updatedAt",
|
|
22
|
+
];
|
|
8
23
|
const STORED_KEYS = [...REQUIRED_STORED_KEYS, "createdBy"];
|
|
9
24
|
const CREATION_KEYS = ["title", "state", "priority", "needs", "parent", "supersedes", "relates", "note"];
|
|
10
25
|
function frontMatter(markdown, fail) {
|
|
@@ -92,7 +107,9 @@ function fields(value, body, fail) {
|
|
|
92
107
|
};
|
|
93
108
|
}
|
|
94
109
|
export function parseTaskDocument(bytes, expected) {
|
|
95
|
-
const fail = (message, cause) => {
|
|
110
|
+
const fail = (message, cause) => {
|
|
111
|
+
throw new TaskAuthorityCorruptionError(message, cause === undefined ? {} : { cause });
|
|
112
|
+
};
|
|
96
113
|
const { value, body } = frontMatter(Buffer.from(bytes).toString("utf8"), fail);
|
|
97
114
|
closed(value, STORED_KEYS, REQUIRED_STORED_KEYS, fail);
|
|
98
115
|
const id = taskId(value.id, "id", fail);
|
|
@@ -102,27 +119,46 @@ export function parseTaskDocument(bytes, expected) {
|
|
|
102
119
|
if (Date.parse(updatedAt) < Date.parse(createdAt))
|
|
103
120
|
fail("updatedAt must not precede createdAt");
|
|
104
121
|
return {
|
|
105
|
-
id,
|
|
122
|
+
id,
|
|
123
|
+
state: state(value.state, fail),
|
|
124
|
+
createdAt,
|
|
125
|
+
updatedAt,
|
|
126
|
+
...fields(value, body, fail),
|
|
106
127
|
...(Object.hasOwn(value, "createdBy") ? { createdBy: createdBy(value.createdBy, fail) } : {}),
|
|
107
128
|
};
|
|
108
129
|
}
|
|
109
130
|
export function parseTaskCreationDocument(markdown) {
|
|
110
|
-
const fail = (message) => {
|
|
131
|
+
const fail = (message) => {
|
|
132
|
+
throw new TypeError(message);
|
|
133
|
+
};
|
|
111
134
|
const { value, body } = frontMatter(markdown, fail);
|
|
112
135
|
closed(value, CREATION_KEYS, ["title"], fail);
|
|
113
136
|
const complete = {
|
|
114
|
-
state: "open",
|
|
137
|
+
state: "open",
|
|
138
|
+
priority: 2,
|
|
139
|
+
needs: [],
|
|
140
|
+
parent: null,
|
|
141
|
+
supersedes: [],
|
|
142
|
+
relates: [],
|
|
143
|
+
note: "",
|
|
115
144
|
...value,
|
|
116
145
|
};
|
|
117
146
|
return { state: state(complete.state, fail), ...fields(complete, body, fail) };
|
|
118
147
|
}
|
|
119
148
|
export function serializeTaskDocument(document) {
|
|
120
149
|
const value = {
|
|
121
|
-
id: document.id,
|
|
122
|
-
|
|
123
|
-
|
|
150
|
+
id: document.id,
|
|
151
|
+
title: document.title,
|
|
152
|
+
state: document.state,
|
|
153
|
+
priority: document.priority,
|
|
154
|
+
needs: [...document.needs],
|
|
155
|
+
parent: document.parent,
|
|
156
|
+
supersedes: [...document.supersedes],
|
|
157
|
+
relates: [...document.relates],
|
|
158
|
+
note: document.note,
|
|
124
159
|
...(document.createdBy === undefined ? {} : { createdBy: document.createdBy }),
|
|
125
|
-
createdAt: document.createdAt,
|
|
160
|
+
createdAt: document.createdAt,
|
|
161
|
+
updatedAt: document.updatedAt,
|
|
126
162
|
};
|
|
127
163
|
return Buffer.from(`---\n${stringify(value, { lineWidth: 0 })}---\n${document.body}`);
|
|
128
164
|
}
|
|
@@ -3,8 +3,11 @@ import { identityCoordinate, identitySegments } from "../identity/coordinates.js
|
|
|
3
3
|
import { normalizeIdentityStem } from "../identity/normalize.js";
|
|
4
4
|
const STEM_CODE_POINTS = 32;
|
|
5
5
|
export function isTaskSegment(value) {
|
|
6
|
-
return value.length > 0 &&
|
|
7
|
-
|
|
6
|
+
return (value.length > 0 &&
|
|
7
|
+
value !== "." &&
|
|
8
|
+
value !== ".." &&
|
|
9
|
+
!value.includes("/") &&
|
|
10
|
+
normalizeIdentityStem({ source: value }) === value);
|
|
8
11
|
}
|
|
9
12
|
export function parseTaskId(value) {
|
|
10
13
|
let segments;
|
|
@@ -19,7 +19,6 @@ export type TaskDoctorReport = Readonly<{
|
|
|
19
19
|
export type TaskDecompositionTree = TaskOutcome<TaskTreeNode>;
|
|
20
20
|
export type { AddTaskDocumentInput, AddTaskInput, BlockedTaskRow, TaskBatchResult, TaskCompositionResult, TaskDoctorIssue, TaskId, TaskMutationResult, TaskOutcome, TaskPriority, TaskRef, TaskRefusal, TaskRetry, TaskRow, TaskState, TaskTreeNode, TaskUpdateResult, TaskView, UpdateTaskInput, TaskPage, TaskQueryExpression, TaskQueryPredicate, TaskQueryRow, TaskQuerySort, TaskRelationPredicateField, };
|
|
21
21
|
export { TaskAuthorityCorruptionError, TASK_RELATION_PREDICATE_FIELDS };
|
|
22
|
-
export declare function observeTaskDetails(world: WorldRoot, ids: readonly TaskId[]): Promise<TaskOutcome<readonly TaskDetail[]>>;
|
|
23
22
|
declare class TaskHandle {
|
|
24
23
|
readonly id: TaskId;
|
|
25
24
|
private readonly world;
|
package/build/src/task/index.js
CHANGED
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import { buildTree, createTaskRelations, diagnoseBoard, projectDetailFacts, } from "./board.js";
|
|
2
2
|
import { composeTasks } from "./compose.js";
|
|
3
3
|
import { TaskAuthorityCorruptionError } from "./document.js";
|
|
4
|
-
import { addTask, addTaskDocument, batchTasks, blockedTasks, lifecycleTask, listTasks, queryTasks,
|
|
4
|
+
import { addTask, addTaskDocument, batchTasks, blockedTasks, lifecycleTask, listTasks, queryTasks, readyTasks, taskView, updateTask, } from "./operations.js";
|
|
5
5
|
import { readBoard } from "./store.js";
|
|
6
6
|
import { actor, addInput, closed, limit, namespace, record, signal, sort, taskId as id, taskIds, text, updateInput, } from "./input.js";
|
|
7
7
|
import { normalizeTaskQuery, TASK_RELATION_PREDICATE_FIELDS, DEFAULT_TASK_LIMIT, } from "./query.js";
|
|
8
8
|
export { TaskAuthorityCorruptionError, TASK_RELATION_PREDICATE_FIELDS };
|
|
9
|
-
export async function observeTaskDetails(world, ids) {
|
|
10
|
-
const observed = await readTaskDetails(world, ids);
|
|
11
|
-
if (observed.kind !== "accepted")
|
|
12
|
-
return observed;
|
|
13
|
-
return { kind: "accepted", value: observed.value.map((facts) => ({ ...facts, task: taskView(facts.task) })) };
|
|
14
|
-
}
|
|
15
9
|
class TaskHandle {
|
|
16
10
|
id;
|
|
17
11
|
world;
|
|
@@ -29,21 +23,37 @@ class TaskHandle {
|
|
|
29
23
|
throw new TypeError("tree accepts no input");
|
|
30
24
|
const board = (await readBoard(this.world)).board;
|
|
31
25
|
const node = buildTree(board, this.id, createTaskRelations(board));
|
|
32
|
-
return node === null
|
|
26
|
+
return node === null
|
|
27
|
+
? { kind: "refused", refusal: { kind: "task-missing", taskId: this.id } }
|
|
28
|
+
: { kind: "accepted", value: node };
|
|
29
|
+
}
|
|
30
|
+
update(input) {
|
|
31
|
+
return updateTask(this.world, this.id, updateInput(input));
|
|
33
32
|
}
|
|
34
|
-
update(input) { return updateTask(this.world, this.id, updateInput(input)); }
|
|
35
33
|
lifecycle(verb, input) {
|
|
36
34
|
const value = record(input ?? {}, `${verb} input`);
|
|
37
35
|
closed(value, verb === "drop" || verb === "done" ? ["note", "signal"] : ["signal"], `${verb} input`);
|
|
38
36
|
const note = verb === "drop" || verb === "done" ? text(value.note, "note") : undefined;
|
|
39
37
|
return lifecycleTask(this.world, this.id, verb, signal(value.signal), note);
|
|
40
38
|
}
|
|
41
|
-
start(input) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
39
|
+
start(input) {
|
|
40
|
+
return this.lifecycle("start", input);
|
|
41
|
+
}
|
|
42
|
+
stop(input) {
|
|
43
|
+
return this.lifecycle("stop", input);
|
|
44
|
+
}
|
|
45
|
+
hold(input) {
|
|
46
|
+
return this.lifecycle("hold", input);
|
|
47
|
+
}
|
|
48
|
+
resume(input) {
|
|
49
|
+
return this.lifecycle("resume", input);
|
|
50
|
+
}
|
|
51
|
+
done(input) {
|
|
52
|
+
return this.lifecycle("done", input);
|
|
53
|
+
}
|
|
54
|
+
drop(input) {
|
|
55
|
+
return this.lifecycle("drop", input);
|
|
56
|
+
}
|
|
47
57
|
}
|
|
48
58
|
class TasksHandle {
|
|
49
59
|
world;
|
|
@@ -52,25 +62,100 @@ class TasksHandle {
|
|
|
52
62
|
this.world = world;
|
|
53
63
|
this.root = world;
|
|
54
64
|
}
|
|
55
|
-
task(input) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
65
|
+
task(input) {
|
|
66
|
+
const v = record(input, "task input");
|
|
67
|
+
closed(v, ["id"], "task input");
|
|
68
|
+
return new TaskHandle(id(v.id), this.world);
|
|
69
|
+
}
|
|
70
|
+
add(input) {
|
|
71
|
+
return addTask(this.world, addInput(input));
|
|
72
|
+
}
|
|
73
|
+
addDocument(input) {
|
|
74
|
+
const v = record(input, "addDocument input");
|
|
75
|
+
closed(v, ["markdown", "namespace", "actor", "signal"], "addDocument input");
|
|
76
|
+
const markdown = text(v.markdown, "markdown");
|
|
77
|
+
if (markdown === undefined)
|
|
78
|
+
throw new TypeError("markdown is required");
|
|
79
|
+
const ns = namespace(v.namespace), createdBy = actor(v.actor), abort = signal(v.signal);
|
|
80
|
+
return addTaskDocument(this.world, {
|
|
81
|
+
markdown,
|
|
82
|
+
...(ns === undefined ? {} : { namespace: ns }),
|
|
83
|
+
...(createdBy === undefined ? {} : { actor: createdBy }),
|
|
84
|
+
...(abort === undefined ? {} : { signal: abort }),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
async list(input = {}) {
|
|
88
|
+
const v = record(input, "list input");
|
|
89
|
+
closed(v, ["selection", "scope", "namespace", "limit"], "list input");
|
|
90
|
+
if (v.selection !== undefined && v.selection !== "active" && v.selection !== "closed" && v.selection !== "all")
|
|
91
|
+
throw new TypeError("selection must be active, closed, or all");
|
|
92
|
+
if (v.scope !== undefined && v.scope !== "namespace" && v.scope !== "world")
|
|
93
|
+
throw new TypeError("scope must be namespace or world");
|
|
94
|
+
return listTasks(this.world, namespace(v.namespace), v.selection ?? "active", v.scope, limit(v.limit) ?? DEFAULT_TASK_LIMIT);
|
|
95
|
+
}
|
|
96
|
+
async ready(input = {}) {
|
|
97
|
+
const v = record(input, "ready input");
|
|
98
|
+
closed(v, ["scope", "namespace", "parent", "limit"], "ready input");
|
|
99
|
+
if (v.scope !== undefined && v.scope !== "namespace" && v.scope !== "world")
|
|
100
|
+
throw new TypeError("scope must be namespace or world");
|
|
101
|
+
const parent = v.parent === undefined ? undefined : id(v.parent);
|
|
102
|
+
return readyTasks(this.world, namespace(v.namespace), v.scope, parent, limit(v.limit) ?? DEFAULT_TASK_LIMIT);
|
|
103
|
+
}
|
|
104
|
+
async blocked(input = {}) {
|
|
105
|
+
const v = record(input, "blocked input");
|
|
106
|
+
closed(v, ["scope", "namespace", "parent", "limit"], "blocked input");
|
|
107
|
+
if (v.scope !== undefined && v.scope !== "namespace" && v.scope !== "world")
|
|
108
|
+
throw new TypeError("scope must be namespace or world");
|
|
109
|
+
const parent = v.parent === undefined ? undefined : id(v.parent);
|
|
110
|
+
return blockedTasks(this.world, namespace(v.namespace), v.scope, parent, limit(v.limit) ?? DEFAULT_TASK_LIMIT);
|
|
111
|
+
}
|
|
112
|
+
async query(input = {}) {
|
|
113
|
+
const v = record(input, "query input");
|
|
114
|
+
closed(v, ["where", "scope", "namespace", "sort", "limit"], "query input");
|
|
115
|
+
if (v.scope !== undefined && v.scope !== "namespace" && v.scope !== "world")
|
|
116
|
+
throw new TypeError("scope must be namespace or world");
|
|
117
|
+
const expression = v.where === undefined
|
|
118
|
+
? {
|
|
119
|
+
kind: "and",
|
|
120
|
+
terms: [
|
|
121
|
+
{ kind: "predicate", predicate: { field: "state", operator: "!=", value: "done" } },
|
|
122
|
+
{ kind: "predicate", predicate: { field: "state", operator: "!=", value: "drop" } },
|
|
123
|
+
],
|
|
124
|
+
}
|
|
125
|
+
: normalizeTaskQuery(v.where);
|
|
126
|
+
const selected = namespace(v.namespace);
|
|
127
|
+
return queryTasks({
|
|
128
|
+
world: this.world,
|
|
129
|
+
...(selected === undefined ? {} : { namespace: selected }),
|
|
130
|
+
expression,
|
|
131
|
+
...(v.scope === undefined ? {} : { scope: v.scope }),
|
|
132
|
+
sort: sort(v.sort) ?? "priority",
|
|
133
|
+
limit: limit(v.limit) ?? DEFAULT_TASK_LIMIT,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
async doctor() {
|
|
137
|
+
return { issues: diagnoseBoard((await readBoard(this.world)).board) };
|
|
138
|
+
}
|
|
139
|
+
batch(input) {
|
|
140
|
+
const v = record(input, "batch input");
|
|
141
|
+
closed(v, ["verb", "ids", "note", "signal"], "batch input");
|
|
142
|
+
const verb = v.verb;
|
|
143
|
+
if (verb !== "done" && verb !== "drop" && verb !== "hold")
|
|
144
|
+
throw new TypeError("batch verb is invalid");
|
|
145
|
+
const note = text(v.note, "note");
|
|
146
|
+
if (note !== undefined && verb !== "done" && verb !== "drop")
|
|
147
|
+
throw new TypeError("batch note is valid only for done or drop");
|
|
148
|
+
return batchTasks(this.world, verb, taskIds(v.ids, "ids") ?? [], signal(v.signal), note);
|
|
149
|
+
}
|
|
150
|
+
compose(input) {
|
|
151
|
+
const v = record(input, "compose input");
|
|
152
|
+
closed(v, ["markdown", "namespace", "actor", "signal"], "compose input");
|
|
153
|
+
const markdown = text(v.markdown, "markdown");
|
|
154
|
+
if (markdown === undefined)
|
|
155
|
+
throw new TypeError("markdown is required");
|
|
156
|
+
const selected = namespace(v.namespace);
|
|
157
|
+
return composeTasks(this.world, markdown, signal(v.signal), actor(v.actor), selected);
|
|
158
|
+
}
|
|
74
159
|
}
|
|
75
160
|
export const Tasks = Object.freeze({
|
|
76
161
|
of(world) {
|
package/build/src/task/input.js
CHANGED
|
@@ -90,8 +90,7 @@ export function sort(value) {
|
|
|
90
90
|
export function state(value) {
|
|
91
91
|
if (value === undefined)
|
|
92
92
|
return undefined;
|
|
93
|
-
if (value !== "open" && value !== "in_progress" && value !== "on_hold"
|
|
94
|
-
&& value !== "done" && value !== "drop") {
|
|
93
|
+
if (value !== "open" && value !== "in_progress" && value !== "on_hold" && value !== "done" && value !== "drop") {
|
|
95
94
|
throw new TypeError("state is invalid");
|
|
96
95
|
}
|
|
97
96
|
return value;
|
|
@@ -102,8 +101,18 @@ function nullableId(value) {
|
|
|
102
101
|
export function addInput(input) {
|
|
103
102
|
const value = record(input, "add input");
|
|
104
103
|
closed(value, [
|
|
105
|
-
"title",
|
|
106
|
-
"
|
|
104
|
+
"title",
|
|
105
|
+
"namespace",
|
|
106
|
+
"body",
|
|
107
|
+
"note",
|
|
108
|
+
"state",
|
|
109
|
+
"priority",
|
|
110
|
+
"needs",
|
|
111
|
+
"parent",
|
|
112
|
+
"supersedes",
|
|
113
|
+
"relates",
|
|
114
|
+
"actor",
|
|
115
|
+
"signal",
|
|
107
116
|
], "add input");
|
|
108
117
|
const title = text(value.title, "title");
|
|
109
118
|
if (title === undefined || title.trim() === "")
|
|
@@ -137,9 +146,22 @@ export function addInput(input) {
|
|
|
137
146
|
export function updateInput(input) {
|
|
138
147
|
const value = record(input, "update input");
|
|
139
148
|
closed(value, [
|
|
140
|
-
"title",
|
|
141
|
-
"
|
|
142
|
-
"
|
|
149
|
+
"title",
|
|
150
|
+
"body",
|
|
151
|
+
"appendBody",
|
|
152
|
+
"note",
|
|
153
|
+
"priority",
|
|
154
|
+
"needs",
|
|
155
|
+
"addNeeds",
|
|
156
|
+
"dropNeeds",
|
|
157
|
+
"parent",
|
|
158
|
+
"supersedes",
|
|
159
|
+
"addSupersedes",
|
|
160
|
+
"dropSupersedes",
|
|
161
|
+
"relates",
|
|
162
|
+
"addRelates",
|
|
163
|
+
"dropRelates",
|
|
164
|
+
"signal",
|
|
143
165
|
], "update input");
|
|
144
166
|
if (value.body !== undefined && value.appendBody !== undefined) {
|
|
145
167
|
throw new TypeError("body and appendBody are mutually exclusive");
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import { addInput, closed, namespace, record, taskId, taskIds, text, updateInput } from "./input.js";
|
|
2
2
|
export const TASK_MUTATION_ACTIONS = Object.freeze([
|
|
3
|
-
"task.add",
|
|
4
|
-
"task.
|
|
3
|
+
"task.add",
|
|
4
|
+
"task.addDocument",
|
|
5
|
+
"task.compose",
|
|
6
|
+
"task.done",
|
|
7
|
+
"task.drop",
|
|
8
|
+
"task.hold",
|
|
9
|
+
"task.resume",
|
|
10
|
+
"task.start",
|
|
11
|
+
"task.stop",
|
|
12
|
+
"task.update",
|
|
5
13
|
]);
|
|
6
14
|
const TASK_MUTATION_ACTION_SET = new Set(TASK_MUTATION_ACTIONS);
|
|
7
15
|
export function isTaskMutationAction(value) {
|
|
@@ -16,9 +24,7 @@ export function decodeTaskMutationRequest(action, value) {
|
|
|
16
24
|
switch (action) {
|
|
17
25
|
case "task.add": {
|
|
18
26
|
const input = mutationObject(value, ["input"], "task.add request");
|
|
19
|
-
const raw = mutationObject(input.input, [
|
|
20
|
-
"title", "namespace", "body", "note", "state", "priority", "needs", "parent", "supersedes", "relates",
|
|
21
|
-
], "task.add input");
|
|
27
|
+
const raw = mutationObject(input.input, ["title", "namespace", "body", "note", "state", "priority", "needs", "parent", "supersedes", "relates"], "task.add input");
|
|
22
28
|
const decoded = addInput(raw);
|
|
23
29
|
if (decoded.namespace === undefined)
|
|
24
30
|
throw new TypeError("task.add request namespace is required");
|
|
@@ -48,8 +54,21 @@ export function decodeTaskMutationRequest(action, value) {
|
|
|
48
54
|
case "task.update": {
|
|
49
55
|
const request = mutationObject(value, ["id", "input"], "task.update request");
|
|
50
56
|
const raw = mutationObject(request.input, [
|
|
51
|
-
"title",
|
|
52
|
-
"
|
|
57
|
+
"title",
|
|
58
|
+
"body",
|
|
59
|
+
"appendBody",
|
|
60
|
+
"note",
|
|
61
|
+
"priority",
|
|
62
|
+
"needs",
|
|
63
|
+
"addNeeds",
|
|
64
|
+
"dropNeeds",
|
|
65
|
+
"parent",
|
|
66
|
+
"supersedes",
|
|
67
|
+
"addSupersedes",
|
|
68
|
+
"dropSupersedes",
|
|
69
|
+
"relates",
|
|
70
|
+
"addRelates",
|
|
71
|
+
"dropRelates",
|
|
53
72
|
], "task.update input");
|
|
54
73
|
return { action, id: taskId(request.id), input: updateInput(raw) };
|
|
55
74
|
}
|
|
@@ -77,17 +96,40 @@ export async function executeTaskMutation(input) {
|
|
|
77
96
|
const { request, signal } = input;
|
|
78
97
|
const withSignal = signal === undefined ? {} : { signal };
|
|
79
98
|
switch (request.action) {
|
|
80
|
-
case "task.add":
|
|
81
|
-
|
|
82
|
-
case "task.
|
|
83
|
-
|
|
84
|
-
case "task.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
99
|
+
case "task.add":
|
|
100
|
+
return await tasks.add({ ...request.input, actor: input.requester, ...withSignal });
|
|
101
|
+
case "task.addDocument":
|
|
102
|
+
return await tasks.addDocument({ ...request.input, actor: input.requester, ...withSignal });
|
|
103
|
+
case "task.compose":
|
|
104
|
+
return await tasks.compose({
|
|
105
|
+
markdown: request.markdown,
|
|
106
|
+
namespace: request.namespace,
|
|
107
|
+
actor: input.requester,
|
|
108
|
+
...withSignal,
|
|
109
|
+
});
|
|
110
|
+
case "task.update":
|
|
111
|
+
return await tasks.task({ id: request.id }).update({ ...request.input, ...withSignal });
|
|
112
|
+
case "task.start":
|
|
113
|
+
return await tasks.task({ id: request.id }).start(withSignal);
|
|
114
|
+
case "task.stop":
|
|
115
|
+
return await tasks.task({ id: request.id }).stop(withSignal);
|
|
116
|
+
case "task.resume":
|
|
117
|
+
return await tasks.task({ id: request.id }).resume(withSignal);
|
|
118
|
+
case "task.hold":
|
|
119
|
+
return await tasks.batch({ verb: "hold", ids: request.ids, ...withSignal });
|
|
120
|
+
case "task.done":
|
|
121
|
+
return await tasks.batch({
|
|
122
|
+
verb: "done",
|
|
123
|
+
ids: request.ids,
|
|
124
|
+
...withSignal,
|
|
125
|
+
...(request.note === undefined ? {} : { note: request.note }),
|
|
126
|
+
});
|
|
127
|
+
case "task.drop":
|
|
128
|
+
return await tasks.batch({
|
|
129
|
+
verb: "drop",
|
|
130
|
+
ids: request.ids,
|
|
131
|
+
...withSignal,
|
|
132
|
+
...(request.note === undefined ? {} : { note: request.note }),
|
|
133
|
+
});
|
|
92
134
|
}
|
|
93
135
|
}
|
|
@@ -6,7 +6,9 @@ import { type TaskPage, type TaskQueryExpression, type TaskQueryRow, type TaskQu
|
|
|
6
6
|
export type TaskView = Readonly<TaskDocument & {
|
|
7
7
|
namespace: readonly string[];
|
|
8
8
|
}>;
|
|
9
|
-
export declare function nukeTask(world: WorldRoot
|
|
9
|
+
export declare function nukeTask(world: WorldRoot, options?: Readonly<{
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
}>): Promise<void>;
|
|
10
12
|
export type TaskRefusal = Readonly<{
|
|
11
13
|
kind: "task-missing";
|
|
12
14
|
taskId: TaskId;
|
|
@@ -116,6 +118,9 @@ export declare function batchTasks(world: WorldRoot, verb: "done" | "drop" | "ho
|
|
|
116
118
|
export declare function settleTask(world: WorldRoot, id: TaskId): Promise<SettledTaskResult>;
|
|
117
119
|
export declare function listTasks(world: WorldRoot, namespace: readonly string[] | undefined, selection: "active" | "closed" | "all", scope?: "namespace" | "world", limit?: number): Promise<TaskOutcome<TaskPage<TaskRow>>>;
|
|
118
120
|
export declare function readTaskDetails(world: WorldRoot, ids: readonly TaskId[]): Promise<TaskOutcome<readonly TaskDetailFacts[]>>;
|
|
121
|
+
export declare function observeTaskDetails(world: WorldRoot, ids: readonly TaskId[]): Promise<TaskOutcome<readonly (Omit<TaskDetailFacts, "task"> & Readonly<{
|
|
122
|
+
task: TaskView;
|
|
123
|
+
}>)[]>>;
|
|
119
124
|
export declare function readyTasks(world: WorldRoot, namespace: readonly string[] | undefined, scope?: "namespace" | "world", parent?: TaskId, limit?: number): Promise<TaskOutcome<TaskPage<TaskRow>>>;
|
|
120
125
|
export declare function blockedTasks(world: WorldRoot, namespace: readonly string[] | undefined, scope?: "namespace" | "world", parent?: TaskId, limit?: number): Promise<TaskOutcome<TaskPage<BlockedTaskRow>>>;
|
|
121
126
|
export declare function queryTasks(input: Readonly<{
|