@astrosheep/keiyaku 4.6.8 → 4.6.10
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 +40 -14
- package/build/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/build/plugins/claude/skills/keiyaku/SKILL.md +5 -6
- package/build/plugins/claude/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/plugins/claude/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/plugins/claude/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/claude/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/plugins/claude/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/plugins/claude/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/plugins/codex/.codex-plugin/plugin.json +1 -1
- package/build/plugins/codex/skills/keiyaku/SKILL.md +5 -6
- package/build/plugins/codex/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/plugins/codex/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/plugins/codex/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/codex/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/plugins/codex/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/plugins/codex/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/plugins/opencode/index.js +1 -1
- package/build/plugins/opencode/skills/keiyaku/SKILL.md +5 -6
- package/build/plugins/opencode/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/plugins/opencode/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/plugins/opencode/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/opencode/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/plugins/opencode/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/plugins/opencode/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/skills/keiyaku/SKILL.md +5 -6
- package/build/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/src/akuma/akuma-instance.d.ts +2 -0
- package/build/src/akuma/akuma-instance.js +10 -0
- package/build/src/akuma/akuma-observe.d.ts +33 -8
- package/build/src/akuma/akuma-observe.js +88 -64
- package/build/src/akuma/akuma-owner.d.ts +11 -2
- package/build/src/akuma/akuma-owner.js +45 -35
- package/build/src/akuma/akuma-selection-execution.js +9 -1
- package/build/src/akuma/akuma-stream.d.ts +22 -0
- package/build/src/akuma/akuma-stream.js +116 -0
- package/build/src/akuma/akuma-wait.d.ts +1 -40
- package/build/src/akuma/akuma-wait.js +23 -84
- package/build/src/akuma/akuma.d.ts +17 -11
- package/build/src/akuma/akuma.js +2 -0
- package/build/src/akuma/allowed.d.ts +7 -12
- package/build/src/akuma/allowed.js +13 -4
- package/build/src/akuma/body-supervisor.d.ts +5 -5
- package/build/src/akuma/body-supervisor.js +22 -20
- package/build/src/akuma/body.js +28 -1
- package/build/src/akuma/call-request.d.ts +12 -22
- package/build/src/akuma/heart/activity-schema.d.ts +12 -0
- package/build/src/akuma/heart/activity-schema.js +6 -0
- package/build/src/akuma/heart/index.d.ts +59 -2
- package/build/src/akuma/heart/index.js +87 -8
- package/build/src/akuma/heart/rows.js +5 -3
- package/build/src/akuma/heart/soul.d.ts +9 -0
- package/build/src/akuma/heart/soul.js +29 -0
- package/build/src/akuma/heart/storage.d.ts +15 -0
- package/build/src/akuma/heart/storage.js +55 -0
- package/build/src/akuma/heart/timeline.d.ts +7 -0
- package/build/src/akuma/heart/timeline.js +10 -0
- package/build/src/akuma/index.d.ts +1 -0
- package/build/src/akuma/projection.d.ts +25 -0
- package/build/src/akuma/projection.js +24 -7
- package/build/src/akuma/provider-recipe.d.ts +11 -0
- package/build/src/akuma/provider-recipe.js +23 -0
- package/build/src/akuma/provider.d.ts +25 -0
- package/build/src/akuma/provider.js +99 -7
- package/build/src/akuma/providers/acp/events.js +25 -2
- package/build/src/akuma/providers/claude/events.js +76 -10
- package/build/src/akuma/providers/claude/index.js +2 -5
- package/build/src/akuma/providers/codex-app-server/events.js +17 -2
- package/build/src/akuma/providers/codex-app-server/index.js +15 -9
- package/build/src/akuma/providers/decode.d.ts +8 -0
- package/build/src/akuma/providers/decode.js +21 -0
- package/build/src/akuma/providers/grok-build/index.js +10 -26
- package/build/src/akuma/providers/opencode-sdk/event-stream.d.ts +3 -3
- package/build/src/akuma/providers/opencode-sdk/event-stream.js +2 -25
- package/build/src/akuma/providers/opencode-sdk/events.d.ts +7 -43
- package/build/src/akuma/providers/opencode-sdk/events.js +147 -284
- package/build/src/akuma/providers/opencode-sdk/index.js +267 -421
- package/build/src/akuma/providers/opencode-sdk/native-http.d.ts +9 -0
- package/build/src/akuma/providers/opencode-sdk/native-http.js +69 -0
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +42 -36
- package/build/src/akuma/providers/opencode-sdk/session.js +75 -82
- package/build/src/akuma/providers/paseo/events.d.ts +8 -0
- package/build/src/akuma/providers/paseo/events.js +58 -11
- package/build/src/akuma/providers/paseo/index.js +11 -7
- package/build/src/akuma/providers/pi/events.d.ts +2 -0
- package/build/src/akuma/providers/pi/events.js +32 -24
- package/build/src/akuma/providers/pi/index.js +21 -35
- package/build/src/akuma/request-lifecycle.d.ts +1 -2
- package/build/src/akuma/request-lifecycle.js +2 -8
- package/build/src/akuma/request-rendezvous.js +38 -55
- package/build/src/akuma/request-serve.d.ts +1 -1
- package/build/src/akuma/request-serve.js +77 -113
- package/build/src/akuma/selection-observation.d.ts +57 -51
- package/build/src/akuma/selection-observation.js +3 -3
- package/build/src/akuma/turn-drive.d.ts +3 -0
- package/build/src/akuma/turn-drive.js +26 -5
- package/build/src/akuma-body.js +12 -22
- package/build/src/cli/akuma-caller.js +10 -0
- package/build/src/cli/commands/akuma-grammar.js +3 -4
- package/build/src/cli/commands/akuma.js +13 -51
- package/build/src/cli/commands/contract-grammar.d.ts +7 -6
- package/build/src/cli/commands/contract-grammar.js +27 -32
- package/build/src/cli/commands/contract-help.d.ts +16 -7
- package/build/src/cli/commands/contract-help.js +20 -11
- package/build/src/cli/commands/contract.js +11 -11
- package/build/src/cli/commands/debt-grammar.d.ts +19 -0
- package/build/src/cli/commands/debt-grammar.js +323 -0
- package/build/src/cli/commands/debt-query.d.ts +5 -0
- package/build/src/cli/commands/{task-query.js → debt-query.js} +9 -9
- package/build/src/cli/commands/{task.d.ts → debt.d.ts} +2 -2
- package/build/src/cli/commands/{task.js → debt.js} +83 -143
- package/build/src/cli/coordinates.d.ts +1 -1
- package/build/src/cli/coordinates.js +1 -1
- package/build/src/cli/parse.d.ts +4 -4
- package/build/src/cli/parse.js +17 -16
- package/build/src/cli/render/akuma-activity.d.ts +11 -83
- package/build/src/cli/render/akuma-activity.js +20 -382
- package/build/src/cli/render/catalog.d.ts +2 -2
- package/build/src/cli/render/catalog.js +5 -5
- package/build/src/cli/render/contract.js +2 -2
- package/build/src/cli/render/debt.d.ts +28 -0
- package/build/src/cli/render/{task.js → debt.js} +51 -112
- package/build/src/cli/render/kanshi.js +28 -28
- package/build/src/cli/render/marks.d.ts +5 -5
- package/build/src/cli/render/marks.js +4 -10
- package/build/src/cli/render/nuke.js +1 -1
- package/build/src/cli/runtime.js +3 -3
- package/build/src/cli/scan.d.ts +1 -1
- package/build/src/cli/usage.d.ts +1 -1
- package/build/src/cli/usage.js +4 -4
- package/build/src/contract-worktree.js +3 -3
- package/build/src/debt/board.d.ts +160 -0
- package/build/src/{task → debt}/board.js +89 -89
- package/build/src/debt/catalog.d.ts +11 -0
- package/build/src/debt/catalog.js +59 -0
- package/build/src/{task → debt}/context.d.ts +1 -1
- package/build/src/{task → debt}/context.js +1 -1
- package/build/src/{task → debt}/created-observation.d.ts +6 -10
- package/build/src/{task → debt}/created-observation.js +7 -7
- package/build/src/debt/document.d.ts +37 -0
- package/build/src/{task → debt}/document.js +37 -37
- package/build/src/debt/identity.d.ts +21 -0
- package/build/src/{task → debt}/identity.js +35 -35
- package/build/src/debt/index.d.ts +111 -0
- package/build/src/debt/index.js +203 -0
- package/build/src/{task → debt}/input.d.ts +8 -8
- package/build/src/{task → debt}/input.js +21 -21
- package/build/src/debt/lifecycle-operations.d.ts +6 -0
- package/build/src/{task → debt}/lifecycle-operations.js +27 -31
- package/build/src/debt/mutation-result.d.ts +981 -0
- package/build/src/debt/mutation-result.js +109 -0
- package/build/src/debt/mutation.d.ts +424 -0
- package/build/src/debt/mutation.js +223 -0
- package/build/src/debt/operation-types.d.ts +71 -0
- package/build/src/debt/operations.d.ts +28 -0
- package/build/src/{task → debt}/operations.js +59 -60
- package/build/src/debt/query.d.ts +76 -0
- package/build/src/{task → debt}/query.js +55 -55
- package/build/src/{task → debt}/store.d.ts +13 -13
- package/build/src/{task → debt}/store.js +58 -49
- package/build/src/debt/view.d.ts +4 -0
- package/build/src/debt/view.js +7 -0
- package/build/src/identity/coordinates.d.ts +1 -1
- package/build/src/index.d.ts +13 -13
- package/build/src/index.js +9 -9
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/read.js +33 -33
- package/build/src/kanshi/report.d.ts +7 -7
- package/build/src/kanshi/select.js +4 -4
- package/build/src/library/akumas.d.ts +2 -3
- package/build/src/library/bind.d.ts +3 -3
- package/build/src/library/bind.js +5 -5
- package/build/src/library/contract-creation.js +5 -5
- package/build/src/library/contract-execution.js +4 -4
- package/build/src/library/contract-types.d.ts +2 -2
- package/build/src/library/input.d.ts +2 -2
- package/build/src/library/input.js +5 -5
- package/build/src/library/invocation.js +2 -2
- package/build/src/library/nuke.js +3 -3
- package/build/src/library/outcome.d.ts +126 -126
- package/build/src/library/outcome.js +3 -3
- package/build/src/library/selection.d.ts +1 -4
- package/build/src/library/selection.js +11 -62
- package/build/src/plugin/public.d.ts +5 -0
- package/build/src/plugin/runtime.js +3 -1
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/settlement/fence.d.ts +3 -3
- package/build/src/settlement/fence.js +4 -4
- package/build/src/settlement/holder.d.ts +16 -16
- package/build/src/settlement/holder.js +69 -63
- package/build/src/settlement/settle.d.ts +5 -5
- package/build/src/settlement/settle.js +53 -53
- package/package.json +12 -6
- package/plugins/paseo/plugin/index.server.ts +17 -0
- package/plugins/paseo/plugin/paseo-plugin.json +4 -0
- package/plugins/paseo/plugin/server/attach.ts +52 -0
- package/plugins/paseo/plugin/server/keiyaku.ts +44 -0
- package/plugins/paseo/plugin/server/message.ts +60 -0
- package/plugins/paseo/plugin/server/mirror.ts +193 -0
- package/plugins/paseo/plugin/server/model.ts +14 -0
- package/plugins/paseo/plugin/server/provider.ts +276 -0
- package/plugins/paseo/plugin/server/sdk-worker.ts +237 -0
- package/plugins/paseo/plugin/server/sdk.ts +289 -0
- package/plugins/paseo/plugin/server/stop.ts +26 -0
- package/plugins/paseo/plugin/server/transport.ts +35 -0
- package/plugins/paseo/plugin/shared/attach-rpc.ts +10 -0
- package/plugins/paseo/plugin/shared/refresh-rpc.ts +6 -0
- package/plugins/paseo/plugin/tsconfig.json +6 -0
- package/skills/keiyaku/SKILL.md +5 -6
- package/skills/keiyaku-akuma/SKILL.md +1 -1
- package/skills/keiyaku-akuma/references/automation.md +8 -8
- package/skills/keiyaku-babysit/SKILL.md +1 -1
- package/skills/keiyaku-bind/SKILL.md +9 -9
- package/skills/keiyaku-debt/SKILL.md +91 -0
- package/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/plugins/claude/skills/keiyaku-task/SKILL.md +0 -104
- package/build/plugins/codex/skills/keiyaku-task/SKILL.md +0 -104
- package/build/plugins/opencode/skills/keiyaku-task/SKILL.md +0 -104
- package/build/skills/keiyaku-task/SKILL.md +0 -104
- package/build/src/cli/commands/task-grammar.d.ts +0 -19
- package/build/src/cli/commands/task-grammar.js +0 -384
- package/build/src/cli/commands/task-query.d.ts +0 -5
- package/build/src/cli/render/task.d.ts +0 -39
- package/build/src/task/board.d.ts +0 -168
- package/build/src/task/catalog.d.ts +0 -11
- package/build/src/task/catalog.js +0 -59
- package/build/src/task/compose-language.d.ts +0 -57
- package/build/src/task/compose-language.js +0 -364
- package/build/src/task/compose-parser.d.ts +0 -32
- package/build/src/task/compose-parser.js +0 -180
- package/build/src/task/compose.d.ts +0 -16
- package/build/src/task/compose.js +0 -189
- package/build/src/task/document.d.ts +0 -39
- package/build/src/task/identity.d.ts +0 -21
- package/build/src/task/index.d.ts +0 -138
- package/build/src/task/index.js +0 -269
- package/build/src/task/lifecycle-operations.d.ts +0 -6
- package/build/src/task/mutation-result.d.ts +0 -1726
- package/build/src/task/mutation-result.js +0 -198
- package/build/src/task/mutation.d.ts +0 -590
- package/build/src/task/mutation.js +0 -262
- package/build/src/task/operation-types.d.ts +0 -71
- package/build/src/task/operations.d.ts +0 -28
- package/build/src/task/query.d.ts +0 -76
- package/build/src/task/view.d.ts +0 -4
- package/build/src/task/view.js +0 -7
- package/skills/keiyaku-task/SKILL.md +0 -104
- /package/build/src/{task → debt}/operation-types.js +0 -0
|
@@ -1,384 +0,0 @@
|
|
|
1
|
-
import { CliUsageError, TASK_FAMILY_USAGE_GUIDE, unknownCommandGuide } from "../usage.js";
|
|
2
|
-
import { scanArgs } from "../scan.js";
|
|
3
|
-
import { parseTaskNamespaceSelector } from "../../task/catalog.js";
|
|
4
|
-
import { parseTaskId } from "../../task/identity.js";
|
|
5
|
-
import { parseTaskQueryExpression, validateTaskLimit, validateTaskParent, } from "./task-query.js";
|
|
6
|
-
const COMMON = { json: "boolean" };
|
|
7
|
-
const TASK_COMMAND_SPECS = {
|
|
8
|
-
add: {
|
|
9
|
-
arity: [0, 1],
|
|
10
|
-
stdin: "document",
|
|
11
|
-
flags: {
|
|
12
|
-
...COMMON,
|
|
13
|
-
namespace: "value",
|
|
14
|
-
state: "value",
|
|
15
|
-
priority: "value",
|
|
16
|
-
needs: "repeat",
|
|
17
|
-
parent: "value",
|
|
18
|
-
supersedes: "repeat",
|
|
19
|
-
relates: "repeat",
|
|
20
|
-
body: "value",
|
|
21
|
-
note: "value",
|
|
22
|
-
actor: "value",
|
|
23
|
-
},
|
|
24
|
-
usage: `task add <TITLE> [--namespace <ns>] [--priority 0..3]
|
|
25
|
-
[--state open|in_progress|on_hold|done|drop]
|
|
26
|
-
[--note <text>] [--actor <actor>]
|
|
27
|
-
[--needs <TaskId>]... [--parent <TaskId>]
|
|
28
|
-
[--supersedes <TaskId>]... [--relates <TaskId>]...
|
|
29
|
-
[--body <text>]
|
|
30
|
-
task add [--namespace <ns>] [--actor <actor>] -`,
|
|
31
|
-
purpose: "Create a Task from flags or a Task document on stdin.",
|
|
32
|
-
details: "The stdin document is YAML front matter (title, state, priority, needs, parent, supersedes, relates, note) followed by a Markdown body.",
|
|
33
|
-
},
|
|
34
|
-
show: {
|
|
35
|
-
arity: [1, Number.POSITIVE_INFINITY],
|
|
36
|
-
flags: COMMON,
|
|
37
|
-
usage: "task show <TaskId>...",
|
|
38
|
-
purpose: "Read one or more Tasks and their relationships.",
|
|
39
|
-
},
|
|
40
|
-
ls: {
|
|
41
|
-
arity: [0, 1],
|
|
42
|
-
flags: { ...COMMON, closed: "boolean", all: "boolean", world: "boolean", limit: "value" },
|
|
43
|
-
usage: "task ls [<namespace-selector>] [--closed | --all] [--world] [--limit <n>]",
|
|
44
|
-
purpose: "List Tasks in the selected namespace.",
|
|
45
|
-
details: [
|
|
46
|
-
"With no selector, lists the current directory Task context.",
|
|
47
|
-
"task/ selects the root namespace; --world lists every namespace in the current Task world.",
|
|
48
|
-
].join("\n"),
|
|
49
|
-
},
|
|
50
|
-
ready: {
|
|
51
|
-
arity: [0, 0],
|
|
52
|
-
flags: { ...COMMON, world: "boolean", parent: "value", limit: "value" },
|
|
53
|
-
usage: "task ready [--world] [--parent <TaskId>] [--limit <n>]",
|
|
54
|
-
purpose: "List open Tasks whose every dependency is complete or dropped.",
|
|
55
|
-
details: "--world lists every namespace in the current Task world.",
|
|
56
|
-
},
|
|
57
|
-
blocked: {
|
|
58
|
-
arity: [0, 0],
|
|
59
|
-
flags: { ...COMMON, world: "boolean", parent: "value", limit: "value" },
|
|
60
|
-
usage: "task blocked [--world] [--parent <TaskId>] [--limit <n>]",
|
|
61
|
-
purpose: "List Tasks with unmet dependencies.",
|
|
62
|
-
details: "--world lists every namespace in the current Task world.",
|
|
63
|
-
},
|
|
64
|
-
query: {
|
|
65
|
-
arity: [0, 0],
|
|
66
|
-
flags: {
|
|
67
|
-
...COMMON,
|
|
68
|
-
where: "value",
|
|
69
|
-
world: "boolean",
|
|
70
|
-
closed: "boolean",
|
|
71
|
-
all: "boolean",
|
|
72
|
-
sort: "value",
|
|
73
|
-
limit: "value",
|
|
74
|
-
},
|
|
75
|
-
usage: `task query [--where <expression>] [--closed | --all] [--world]
|
|
76
|
-
[--sort priority|created|updated|id] [--limit <n>]`,
|
|
77
|
-
purpose: "Filter and sort Tasks with a boolean expression.",
|
|
78
|
-
details: [
|
|
79
|
-
"fields: state priority title id parent under needs blocks ready blocked created updated",
|
|
80
|
-
"operators: = != < > <= >= ~ and or not ( )",
|
|
81
|
-
"sort: priority and created ascend; updated descends; id is lexical. Default: priority.",
|
|
82
|
-
"--world lists every namespace in the current Task world.",
|
|
83
|
-
"By default only active Tasks match; --closed selects terminal Tasks, --all includes both.",
|
|
84
|
-
"examples:",
|
|
85
|
-
" keiyaku task query --where 'priority <= 1 and ready' --world",
|
|
86
|
-
" keiyaku task query --where 'updated < 2026-08-06T00:00:00.000Z' --world",
|
|
87
|
-
].join("\n"),
|
|
88
|
-
},
|
|
89
|
-
tree: {
|
|
90
|
-
arity: [1, 1],
|
|
91
|
-
flags: COMMON,
|
|
92
|
-
usage: "task tree <TaskId>",
|
|
93
|
-
purpose: "Show a Task and its parent/child breakdown.",
|
|
94
|
-
},
|
|
95
|
-
doctor: {
|
|
96
|
-
arity: [0, 0],
|
|
97
|
-
flags: COMMON,
|
|
98
|
-
usage: "task doctor",
|
|
99
|
-
purpose: "Check Tasks for inconsistencies without changing them.",
|
|
100
|
-
},
|
|
101
|
-
update: {
|
|
102
|
-
arity: [1, 1],
|
|
103
|
-
flags: {
|
|
104
|
-
...COMMON,
|
|
105
|
-
title: "value",
|
|
106
|
-
body: "value",
|
|
107
|
-
append: "value",
|
|
108
|
-
note: "value",
|
|
109
|
-
priority: "value",
|
|
110
|
-
needs: "repeat",
|
|
111
|
-
"drop-needs": "repeat",
|
|
112
|
-
parent: "value",
|
|
113
|
-
"no-parent": "boolean",
|
|
114
|
-
supersedes: "repeat",
|
|
115
|
-
"drop-supersedes": "repeat",
|
|
116
|
-
relates: "repeat",
|
|
117
|
-
"drop-relates": "repeat",
|
|
118
|
-
},
|
|
119
|
-
usage: `task update <TaskId> [--title <text>] [--body <text>|- | --append <text>]
|
|
120
|
-
[--note <text>]
|
|
121
|
-
[--priority 0..3] [--needs <TaskId>]... [--drop-needs <TaskId>]...
|
|
122
|
-
[--parent <TaskId> | --no-parent]
|
|
123
|
-
[--supersedes <TaskId>]... [--drop-supersedes <TaskId>]...
|
|
124
|
-
[--relates <TaskId>]... [--drop-relates <TaskId>]...`,
|
|
125
|
-
purpose: "Change a Task's fields and relationships.",
|
|
126
|
-
details: [
|
|
127
|
-
"--body replaces the body; --append adds text after it, separated by a newline when needed.",
|
|
128
|
-
"--body - reads replacement body text from stdin.",
|
|
129
|
-
].join("\n"),
|
|
130
|
-
},
|
|
131
|
-
start: {
|
|
132
|
-
arity: [1, Number.POSITIVE_INFINITY],
|
|
133
|
-
flags: COMMON,
|
|
134
|
-
usage: "task start <TaskId>...",
|
|
135
|
-
purpose: "Move one or more open Tasks into progress.",
|
|
136
|
-
},
|
|
137
|
-
stop: {
|
|
138
|
-
arity: [1, Number.POSITIVE_INFINITY],
|
|
139
|
-
flags: COMMON,
|
|
140
|
-
usage: "task stop <TaskId>...",
|
|
141
|
-
purpose: "Return one or more in-progress Tasks to open.",
|
|
142
|
-
},
|
|
143
|
-
hold: {
|
|
144
|
-
arity: [1, Number.POSITIVE_INFINITY],
|
|
145
|
-
flags: COMMON,
|
|
146
|
-
usage: "task hold <TaskId>...",
|
|
147
|
-
purpose: "Put one or more Tasks on hold.",
|
|
148
|
-
},
|
|
149
|
-
resume: {
|
|
150
|
-
arity: [1, Number.POSITIVE_INFINITY],
|
|
151
|
-
flags: COMMON,
|
|
152
|
-
usage: "task resume <TaskId>...",
|
|
153
|
-
purpose: "Return one or more held Tasks to open.",
|
|
154
|
-
},
|
|
155
|
-
done: {
|
|
156
|
-
arity: [1, Number.POSITIVE_INFINITY],
|
|
157
|
-
flags: { ...COMMON, note: "value" },
|
|
158
|
-
usage: "task done <TaskId>... [--note <text>]",
|
|
159
|
-
purpose: "Mark one or more Tasks done.",
|
|
160
|
-
},
|
|
161
|
-
drop: {
|
|
162
|
-
arity: [1, Number.POSITIVE_INFINITY],
|
|
163
|
-
flags: { ...COMMON, note: "value" },
|
|
164
|
-
usage: "task drop <TaskId>... [--note <text>]",
|
|
165
|
-
purpose: "Mark one or more Tasks as no longer needed.",
|
|
166
|
-
},
|
|
167
|
-
context: {
|
|
168
|
-
arity: [0, 1],
|
|
169
|
-
flags: COMMON,
|
|
170
|
-
usage: "task context [<namespace>]",
|
|
171
|
-
purpose: "Set or read the default Task namespace for this directory.",
|
|
172
|
-
details: "Omit <namespace> to read the current context; use / to reset it to the root namespace.",
|
|
173
|
-
},
|
|
174
|
-
compose: {
|
|
175
|
-
arity: [0, 0],
|
|
176
|
-
stdin: "compose",
|
|
177
|
-
flags: { ...COMMON, actor: "value", plan: "boolean" },
|
|
178
|
-
usage: "task compose [--actor <actor>] [--plan] -",
|
|
179
|
-
purpose: "Create or update several Tasks from one document, with an optional preview.",
|
|
180
|
-
details: [
|
|
181
|
-
"nodes: + <Title> creates; @task/<id> modifies a pre-existing Task",
|
|
182
|
-
"properties: as = <alias>; state = open|in_progress|on_hold|done|drop; pri = 0..3; parent = <ref>|empty",
|
|
183
|
-
"relations: needs|supersedes|relates with =, +=, or -=",
|
|
184
|
-
"references: @task/... is pre-existing; ^alias is new in this document",
|
|
185
|
-
"body: body = clears; body <<TOKEN reads exact content to TOKEN",
|
|
186
|
-
"TOKEN: [A-Z][A-Z0-9_]* with length 3..32",
|
|
187
|
-
"example:",
|
|
188
|
-
" ns=feature",
|
|
189
|
-
" + Parent",
|
|
190
|
-
" as = parent",
|
|
191
|
-
" pri = 1",
|
|
192
|
-
" body <<BODY",
|
|
193
|
-
" Exact body bytes.",
|
|
194
|
-
" BODY",
|
|
195
|
-
" + Child",
|
|
196
|
-
" parent = ^parent",
|
|
197
|
-
].join("\n"),
|
|
198
|
-
},
|
|
199
|
-
};
|
|
200
|
-
export function isTaskAction(value) {
|
|
201
|
-
return value !== undefined && Object.hasOwn(TASK_COMMAND_SPECS, value);
|
|
202
|
-
}
|
|
203
|
-
export function renderTaskHelp(action) {
|
|
204
|
-
if (action !== undefined) {
|
|
205
|
-
const spec = TASK_COMMAND_SPECS[action];
|
|
206
|
-
return `${spec.purpose}\n\n${renderTaskUsage(action)}${spec.details === undefined ? "" : `\n\n${spec.details}`}`;
|
|
207
|
-
}
|
|
208
|
-
const nameWidth = Math.max(...Object.keys(TASK_COMMAND_SPECS).map((name) => name.length));
|
|
209
|
-
return [
|
|
210
|
-
"usage keiyaku task <command> ...",
|
|
211
|
-
" keiyaku task <command> --help shows that command's complete usage",
|
|
212
|
-
"",
|
|
213
|
-
...Object.entries(TASK_COMMAND_SPECS).map(([name, spec]) => ` ${name.padEnd(nameWidth)} ${spec.purpose}`),
|
|
214
|
-
].join("\n");
|
|
215
|
-
}
|
|
216
|
-
function renderTaskUsage(action) {
|
|
217
|
-
return TASK_COMMAND_SPECS[action].usage
|
|
218
|
-
.split("\n")
|
|
219
|
-
.map((line, index) => {
|
|
220
|
-
if (index === 0 || line.trimStart().startsWith("task ")) {
|
|
221
|
-
const command = line.trimStart().startsWith("task ") ? `keiyaku ${line.trim()}` : `keiyaku ${line}`;
|
|
222
|
-
return `${index === 0 ? "usage " : " "}${command}`;
|
|
223
|
-
}
|
|
224
|
-
return ` ${line.trim()}`;
|
|
225
|
-
})
|
|
226
|
-
.join("\n");
|
|
227
|
-
}
|
|
228
|
-
function taskUsage(action) {
|
|
229
|
-
const lines = TASK_COMMAND_SPECS[action].usage.split("\n");
|
|
230
|
-
return lines
|
|
231
|
-
.map((line, index) => {
|
|
232
|
-
if (index === 0 || line.trimStart().startsWith("task "))
|
|
233
|
-
return `keiyaku ${line.trim()}`;
|
|
234
|
-
return ` ${line.trim()}`;
|
|
235
|
-
})
|
|
236
|
-
.join("\n");
|
|
237
|
-
}
|
|
238
|
-
export function taskUsageGuide(action) {
|
|
239
|
-
return {
|
|
240
|
-
scope: `keiyaku task ${action}`,
|
|
241
|
-
accepts: taskUsage(action),
|
|
242
|
-
help: `keiyaku task ${action} --help`,
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
/** One scan spec per Task action: `-` reads the document, or `--body -` replaces an update body. */
|
|
246
|
-
function scanSpec(action, spec) {
|
|
247
|
-
return {
|
|
248
|
-
subject: `task ${action}`,
|
|
249
|
-
flags: spec.flags,
|
|
250
|
-
...(spec.stdin === undefined ? {} : { stdin: spec.stdin }),
|
|
251
|
-
stdinRefusal: "stdin marker '-' is not valid here",
|
|
252
|
-
...(action === "update" ? { stdinValue: "body" } : {}),
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
function validateUpdate(scanned, fail) {
|
|
256
|
-
const flags = scanned.flags;
|
|
257
|
-
if (flags.body !== undefined && flags.append !== undefined)
|
|
258
|
-
fail("--body and --append are mutually exclusive");
|
|
259
|
-
if (flags.parent !== undefined && flags["no-parent"] === true)
|
|
260
|
-
fail("--parent and --no-parent are mutually exclusive");
|
|
261
|
-
if (Object.keys(flags).every((name) => name === "json"))
|
|
262
|
-
fail("task update requires at least one patch option");
|
|
263
|
-
}
|
|
264
|
-
function validateTaskReadFlags(action, flags, fail) {
|
|
265
|
-
if ((action === "ls" || action === "query") && flags.closed === true && flags.all === true)
|
|
266
|
-
fail("--closed and --all are mutually exclusive");
|
|
267
|
-
if (action === "ls" && flags.world === true) {
|
|
268
|
-
// An explicit selector is checked below, after positional shape is known.
|
|
269
|
-
}
|
|
270
|
-
if (typeof flags.limit === "string") {
|
|
271
|
-
try {
|
|
272
|
-
validateTaskLimit(flags.limit);
|
|
273
|
-
}
|
|
274
|
-
catch (error) {
|
|
275
|
-
fail(error instanceof Error ? error.message : String(error));
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
if (typeof flags.sort === "string" &&
|
|
279
|
-
flags.sort !== "priority" &&
|
|
280
|
-
flags.sort !== "created" &&
|
|
281
|
-
flags.sort !== "updated" &&
|
|
282
|
-
flags.sort !== "id") {
|
|
283
|
-
fail("--sort must be priority, created, updated, or id");
|
|
284
|
-
}
|
|
285
|
-
if ((action === "ready" || action === "blocked") && typeof flags.parent === "string") {
|
|
286
|
-
try {
|
|
287
|
-
validateTaskParent(flags.parent);
|
|
288
|
-
}
|
|
289
|
-
catch (error) {
|
|
290
|
-
fail(error instanceof Error ? error.message : String(error));
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
/** Actions whose positionals are all addressed TaskIds validated by the native owner. */
|
|
295
|
-
const TASK_ID_ACTIONS = new Set([
|
|
296
|
-
"show",
|
|
297
|
-
"tree",
|
|
298
|
-
"update",
|
|
299
|
-
"start",
|
|
300
|
-
"stop",
|
|
301
|
-
"hold",
|
|
302
|
-
"resume",
|
|
303
|
-
"done",
|
|
304
|
-
"drop",
|
|
305
|
-
]);
|
|
306
|
-
/** Validate every addressed TaskId positional through the native owner before any read or write. */
|
|
307
|
-
function validateTaskIdPositionals(positionals, fail) {
|
|
308
|
-
for (const taskId of positionals) {
|
|
309
|
-
try {
|
|
310
|
-
parseTaskId(taskId);
|
|
311
|
-
}
|
|
312
|
-
catch (error) {
|
|
313
|
-
fail(error instanceof Error ? error.message : String(error));
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
/** Validate an explicit `task ls` namespace selector through the native owner. */
|
|
318
|
-
function validateListSelector(selector, fail) {
|
|
319
|
-
if (selector !== "task/" && (!selector.startsWith("task/") || !selector.endsWith("/")))
|
|
320
|
-
fail(`invalid Task namespace selector: ${selector}`);
|
|
321
|
-
if (selector === "task/")
|
|
322
|
-
return;
|
|
323
|
-
try {
|
|
324
|
-
parseTaskNamespaceSelector(selector);
|
|
325
|
-
}
|
|
326
|
-
catch (error) {
|
|
327
|
-
fail(error instanceof Error ? error.message : String(error));
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
function validateTaskScan(action, scanned, fail) {
|
|
331
|
-
const spec = TASK_COMMAND_SPECS[action], { positionals, flags, stdin } = scanned;
|
|
332
|
-
if (positionals.length < spec.arity[0])
|
|
333
|
-
fail(spec.arity[1] === 1 ? `task ${action} requires a TaskId` : `task ${action} requires at least one TaskId`);
|
|
334
|
-
if (positionals.length > spec.arity[1])
|
|
335
|
-
fail(spec.arity[1] === 0
|
|
336
|
-
? `task ${action} accepts no positional arguments`
|
|
337
|
-
: `task ${action} accepts at most ${spec.arity[1]} positional argument${spec.arity[1] === 1 ? "" : "s"}`);
|
|
338
|
-
if (action === "add" && (stdin === "document") === (positionals.length === 1))
|
|
339
|
-
fail("task add requires either TITLE or '-' input");
|
|
340
|
-
if (action === "add" &&
|
|
341
|
-
stdin === "document" &&
|
|
342
|
-
Object.keys(flags).some((name) => name !== "json" && name !== "namespace" && name !== "actor"))
|
|
343
|
-
fail("task add document input owns its creation fields");
|
|
344
|
-
if (action === "compose" && stdin !== "compose")
|
|
345
|
-
fail("task compose requires '-' input");
|
|
346
|
-
if (TASK_ID_ACTIONS.has(action))
|
|
347
|
-
validateTaskIdPositionals(positionals, fail);
|
|
348
|
-
if (action === "ls" && positionals.length === 1) {
|
|
349
|
-
validateListSelector(positionals[0], fail);
|
|
350
|
-
if (flags.world === true)
|
|
351
|
-
fail("--world cannot be combined with an explicit Task namespace selector");
|
|
352
|
-
}
|
|
353
|
-
validateTaskReadFlags(action, flags, fail);
|
|
354
|
-
if (action === "update")
|
|
355
|
-
validateUpdate(scanned, fail);
|
|
356
|
-
}
|
|
357
|
-
export function parseTaskCommand(argv) {
|
|
358
|
-
const candidate = argv[0];
|
|
359
|
-
if (!isTaskAction(candidate)) {
|
|
360
|
-
throw new CliUsageError(`unknown task command: ${candidate ?? ""}`, unknownCommandGuide(TASK_FAMILY_USAGE_GUIDE, candidate ?? ""));
|
|
361
|
-
}
|
|
362
|
-
const action = candidate;
|
|
363
|
-
const fail = (message) => {
|
|
364
|
-
throw new CliUsageError(message, taskUsageGuide(action));
|
|
365
|
-
};
|
|
366
|
-
const scanned = scanArgs(argv, scanSpec(action, TASK_COMMAND_SPECS[action]), fail);
|
|
367
|
-
validateTaskScan(action, scanned, fail);
|
|
368
|
-
let where;
|
|
369
|
-
if (action === "query" && typeof scanned.flags.where === "string") {
|
|
370
|
-
try {
|
|
371
|
-
where = parseTaskQueryExpression(scanned.flags.where);
|
|
372
|
-
}
|
|
373
|
-
catch (error) {
|
|
374
|
-
fail(error instanceof Error ? error.message : String(error));
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
return {
|
|
378
|
-
command: "task",
|
|
379
|
-
action,
|
|
380
|
-
output: scanned.flags.json === true ? "json" : "text",
|
|
381
|
-
...scanned,
|
|
382
|
-
...(where === undefined ? {} : { where }),
|
|
383
|
-
};
|
|
384
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { type TaskQueryExpression } from "../../task/query.js";
|
|
2
|
-
export type { TaskQueryExpression } from "../../task/query.js";
|
|
3
|
-
export declare function parseTaskQueryExpression(source: string): TaskQueryExpression;
|
|
4
|
-
export declare function validateTaskLimit(source: string): void;
|
|
5
|
-
export declare function validateTaskParent(source: string): void;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { BlockedTaskList, TaskBatchResult, TaskCompositionResult, TaskContextResult, TaskDecompositionTree, TaskDetail, TaskDoctorReport, TaskList, TaskMutationResult, TaskQueryResult, TaskUpdateResult } from "../../task/index.js";
|
|
2
|
-
import { type TextRenderContext } from "./terminal.js";
|
|
3
|
-
export { taskMark } from "./marks.js";
|
|
4
|
-
type TaskListOutcome = TaskList | BlockedTaskList | TaskQueryResult;
|
|
5
|
-
/** One addressed show selection: native details, or a refusal naming a missing addressed read. */
|
|
6
|
-
export type TaskShowResult = TaskDetail | TaskDetail[] | Extract<TaskMutationResult, {
|
|
7
|
-
kind: "refused";
|
|
8
|
-
}>;
|
|
9
|
-
/** Presentation-only list scope the leaf acquired; never part of a product value. */
|
|
10
|
-
export type TaskListScope = "world" | "current" | Readonly<{
|
|
11
|
-
namespace: string;
|
|
12
|
-
}>;
|
|
13
|
-
/** The union of native Task SDK answers one leaf renders directly; the CLI adds no result envelope. */
|
|
14
|
-
type TaskNativeResult = TaskMutationResult | TaskUpdateResult | TaskBatchResult | TaskCompositionResult | TaskShowResult | TaskList | BlockedTaskList | TaskQueryResult | TaskDecompositionTree | TaskDoctorReport | TaskContextResult;
|
|
15
|
-
type TaskFailure = Extract<TaskMutationResult, {
|
|
16
|
-
kind: "refused" | "retry";
|
|
17
|
-
}> | Extract<TaskContextResult, {
|
|
18
|
-
kind: "refused" | "retry";
|
|
19
|
-
}> | Extract<TaskCompositionResult, {
|
|
20
|
-
kind: "refused";
|
|
21
|
-
}>;
|
|
22
|
-
/** Task dispositions and relation states are snake_case facts; people read them as words. */
|
|
23
|
-
export declare function dispositionText(word: string): string;
|
|
24
|
-
export declare function taskFrameHead(view: string, scope: string): string;
|
|
25
|
-
export declare function renderTaskList(action: "ls" | "ready" | "blocked" | "query", scope: TaskListScope, result: TaskListOutcome, context?: TextRenderContext): string;
|
|
26
|
-
export declare function renderTaskShow(result: TaskShowResult, context?: TextRenderContext): string;
|
|
27
|
-
export declare function renderDoctor(report: TaskDoctorReport): string;
|
|
28
|
-
export declare function renderTaskUpdate(result: TaskUpdateResult, context?: TextRenderContext): string;
|
|
29
|
-
export declare function renderTaskCompose(result: TaskCompositionResult, context?: TextRenderContext): string;
|
|
30
|
-
export declare function renderTaskTree(result: TaskDecompositionTree, context?: TextRenderContext): string;
|
|
31
|
-
export declare function renderTaskContext(result: TaskContextResult, context?: TextRenderContext): string;
|
|
32
|
-
/** One single-Task mutation answer; `verb` is the literal action the leaf invoked. */
|
|
33
|
-
export declare function renderTaskMutation(verb: string, result: TaskMutationResult, context?: TextRenderContext): string;
|
|
34
|
-
/** One lifecycle answer: a single mutation or a plural batch, both native shapes. */
|
|
35
|
-
export declare function renderTaskLifecycle(verb: string, result: TaskMutationResult | TaskBatchResult, context?: TextRenderContext): string;
|
|
36
|
-
/** A native refusal the CLI edge raised for one action, through the shared refusal grammar. */
|
|
37
|
-
export declare function renderTaskFailure(verb: string, result: TaskFailure, context?: TextRenderContext): string;
|
|
38
|
-
export declare function renderTaskIncompleteDiagnostic(result: TaskCompositionResult): string;
|
|
39
|
-
export declare function taskExitCode(result: TaskNativeResult): number;
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import { type TaskDocument, type TaskPriority, type TaskState } from "./document.js";
|
|
2
|
-
import { type TaskId } from "./identity.js";
|
|
3
|
-
import { z } from "zod";
|
|
4
|
-
import { type BoundedList } from "../bounded-list.js";
|
|
5
|
-
export type TaskRef = Readonly<{
|
|
6
|
-
id: TaskId;
|
|
7
|
-
title: string | null;
|
|
8
|
-
state: TaskState | "missing";
|
|
9
|
-
}>;
|
|
10
|
-
export declare const taskRowSchema: z.ZodObject<{
|
|
11
|
-
id: z.ZodPipe<z.ZodString, z.ZodTransform<`task/${string}`, string>>;
|
|
12
|
-
title: z.ZodString;
|
|
13
|
-
state: z.ZodEnum<{
|
|
14
|
-
open: "open";
|
|
15
|
-
in_progress: "in_progress";
|
|
16
|
-
on_hold: "on_hold";
|
|
17
|
-
done: "done";
|
|
18
|
-
drop: "drop";
|
|
19
|
-
}>;
|
|
20
|
-
priority: z.ZodUnion<readonly [z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>;
|
|
21
|
-
disposition: z.ZodEnum<{
|
|
22
|
-
in_progress: "in_progress";
|
|
23
|
-
on_hold: "on_hold";
|
|
24
|
-
done: "done";
|
|
25
|
-
drop: "drop";
|
|
26
|
-
ready: "ready";
|
|
27
|
-
blocked: "blocked";
|
|
28
|
-
}>;
|
|
29
|
-
updatedAt: z.ZodString;
|
|
30
|
-
bodyPresent: z.ZodBoolean;
|
|
31
|
-
children: z.ZodOptional<z.ZodObject<{
|
|
32
|
-
live: z.ZodNumber;
|
|
33
|
-
total: z.ZodNumber;
|
|
34
|
-
}, z.core.$strict>>;
|
|
35
|
-
}, z.core.$strict>;
|
|
36
|
-
export declare const taskRowsSchema: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
37
|
-
id: z.ZodPipe<z.ZodString, z.ZodTransform<`task/${string}`, string>>;
|
|
38
|
-
title: z.ZodString;
|
|
39
|
-
state: z.ZodEnum<{
|
|
40
|
-
open: "open";
|
|
41
|
-
in_progress: "in_progress";
|
|
42
|
-
on_hold: "on_hold";
|
|
43
|
-
done: "done";
|
|
44
|
-
drop: "drop";
|
|
45
|
-
}>;
|
|
46
|
-
priority: z.ZodUnion<readonly [z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>;
|
|
47
|
-
disposition: z.ZodEnum<{
|
|
48
|
-
in_progress: "in_progress";
|
|
49
|
-
on_hold: "on_hold";
|
|
50
|
-
done: "done";
|
|
51
|
-
drop: "drop";
|
|
52
|
-
ready: "ready";
|
|
53
|
-
blocked: "blocked";
|
|
54
|
-
}>;
|
|
55
|
-
updatedAt: z.ZodString;
|
|
56
|
-
bodyPresent: z.ZodBoolean;
|
|
57
|
-
children: z.ZodOptional<z.ZodObject<{
|
|
58
|
-
live: z.ZodNumber;
|
|
59
|
-
total: z.ZodNumber;
|
|
60
|
-
}, z.core.$strict>>;
|
|
61
|
-
}, z.core.$strict>>>;
|
|
62
|
-
export type TaskDisposition = z.infer<typeof taskRowSchema>["disposition"];
|
|
63
|
-
export type TaskRow = z.infer<typeof taskRowSchema>;
|
|
64
|
-
export type BlockedTaskRow = TaskRow & Readonly<{
|
|
65
|
-
blockers: readonly TaskRef[];
|
|
66
|
-
}>;
|
|
67
|
-
export type TaskDetailFacts = Readonly<{
|
|
68
|
-
task: TaskDocument;
|
|
69
|
-
needs: readonly (TaskRef & Readonly<{
|
|
70
|
-
released: boolean;
|
|
71
|
-
}>)[];
|
|
72
|
-
blockers: readonly TaskRef[];
|
|
73
|
-
blocks: readonly TaskRef[];
|
|
74
|
-
parent: TaskRef | null;
|
|
75
|
-
children: readonly TaskRef[];
|
|
76
|
-
supersedes: readonly TaskRef[];
|
|
77
|
-
supersededBy: readonly TaskRef[];
|
|
78
|
-
related: readonly TaskRef[];
|
|
79
|
-
}>;
|
|
80
|
-
export type TaskTreeNode = Readonly<{
|
|
81
|
-
task: TaskRef & Readonly<{
|
|
82
|
-
priority: TaskPriority | null;
|
|
83
|
-
}>;
|
|
84
|
-
cycle?: true;
|
|
85
|
-
children: readonly TaskTreeNode[];
|
|
86
|
-
}>;
|
|
87
|
-
export type TaskBoard = Readonly<{
|
|
88
|
-
tasks: ReadonlyMap<TaskId, TaskDocument>;
|
|
89
|
-
}>;
|
|
90
|
-
/** The local ids occupied across one namespace of the current board. */
|
|
91
|
-
export declare function occupiedLocalIds(board: TaskBoard, namespace: readonly string[]): Set<string>;
|
|
92
|
-
type TaskRelation = "needs" | "parent" | "supersedes" | "relates";
|
|
93
|
-
export type TaskDoctorIssue = Readonly<{
|
|
94
|
-
kind: "missing-target";
|
|
95
|
-
taskId: TaskId;
|
|
96
|
-
relation: TaskRelation;
|
|
97
|
-
target: TaskId;
|
|
98
|
-
}> | Readonly<{
|
|
99
|
-
kind: "self-relation";
|
|
100
|
-
taskId: TaskId;
|
|
101
|
-
relation: TaskRelation;
|
|
102
|
-
}> | Readonly<{
|
|
103
|
-
kind: "cycle";
|
|
104
|
-
relation: "needs" | "parent" | "supersedes";
|
|
105
|
-
tasks: readonly TaskId[];
|
|
106
|
-
}>;
|
|
107
|
-
export declare function taskRef(board: TaskBoard, id: TaskId): TaskRef;
|
|
108
|
-
export type TaskRelationProjection = Readonly<{
|
|
109
|
-
children(id: TaskId): readonly TaskRef[];
|
|
110
|
-
blocks(id: TaskId): readonly TaskRef[];
|
|
111
|
-
supersededBy(id: TaskId): readonly TaskRef[];
|
|
112
|
-
related(id: TaskId): readonly TaskRef[];
|
|
113
|
-
}>;
|
|
114
|
-
export declare function createTaskRelations(board: TaskBoard): TaskRelationProjection;
|
|
115
|
-
export declare function taskDisposition(board: TaskBoard, task: TaskDocument): TaskDisposition;
|
|
116
|
-
export declare function taskBlocked(board: TaskBoard, task: TaskDocument): boolean;
|
|
117
|
-
export declare function projectOwnedDetailFacts(board: TaskBoard, id: TaskId): TaskDetailFacts | null;
|
|
118
|
-
export declare function projectDetailFacts(board: TaskBoard, id: TaskId, relations: TaskRelationProjection): TaskDetailFacts | null;
|
|
119
|
-
export declare function projectTaskRow(board: TaskBoard, relations: TaskRelationProjection, task: TaskDocument): TaskRow;
|
|
120
|
-
export declare function projectRows(board: TaskBoard, relations: TaskRelationProjection, scope: readonly string[] | null, selection: "active" | "closed" | "all"): readonly TaskRow[];
|
|
121
|
-
/**
|
|
122
|
-
* Rows for the identities that created work, grouped by creator. Only documents a
|
|
123
|
-
* requested identity created reach row projection, and each group keeps the
|
|
124
|
-
* established row order.
|
|
125
|
-
*/
|
|
126
|
-
export declare function projectCreatedByRows(board: TaskBoard, relations: TaskRelationProjection, createdByIds: readonly string[]): ReadonlyMap<string, readonly TaskRow[]>;
|
|
127
|
-
export declare function projectBlocked(board: TaskBoard, scope: readonly string[] | null, relations: TaskRelationProjection): readonly BlockedTaskRow[];
|
|
128
|
-
export declare function projectStatusRows(board: TaskBoard, relations: TaskRelationProjection, scope: readonly string[] | null): ({
|
|
129
|
-
id: `task/${string}`;
|
|
130
|
-
title: string;
|
|
131
|
-
state: "open" | "in_progress" | "on_hold" | "done" | "drop";
|
|
132
|
-
priority: 0 | 1 | 2 | 3;
|
|
133
|
-
disposition: "in_progress" | "on_hold" | "done" | "drop" | "ready" | "blocked";
|
|
134
|
-
updatedAt: string;
|
|
135
|
-
bodyPresent: boolean;
|
|
136
|
-
children?: {
|
|
137
|
-
live: number;
|
|
138
|
-
total: number;
|
|
139
|
-
} | undefined;
|
|
140
|
-
} | {
|
|
141
|
-
blockers: readonly Readonly<{
|
|
142
|
-
id: TaskId;
|
|
143
|
-
title: string | null;
|
|
144
|
-
state: TaskState | "missing";
|
|
145
|
-
}>[];
|
|
146
|
-
id: `task/${string}`;
|
|
147
|
-
title: string;
|
|
148
|
-
state: "open" | "in_progress" | "on_hold" | "done" | "drop";
|
|
149
|
-
priority: 0 | 1 | 2 | 3;
|
|
150
|
-
disposition: "in_progress" | "on_hold" | "done" | "drop" | "ready" | "blocked";
|
|
151
|
-
updatedAt: string;
|
|
152
|
-
bodyPresent: boolean;
|
|
153
|
-
children?: {
|
|
154
|
-
live: number;
|
|
155
|
-
total: number;
|
|
156
|
-
} | undefined;
|
|
157
|
-
})[];
|
|
158
|
-
export type TaskBoardObservation = Readonly<{
|
|
159
|
-
statusRows: ReturnType<typeof projectStatusRows>;
|
|
160
|
-
selectRecentStatus(limit?: number): BoundedList<ReturnType<typeof projectStatusRows>[number]>;
|
|
161
|
-
selectNamespace(namespace: readonly string[]): readonly TaskRow[];
|
|
162
|
-
selectCreatedBy(createdBy: string): readonly TaskRow[];
|
|
163
|
-
}>;
|
|
164
|
-
export declare function projectTaskBoardObservation(board: TaskBoard): TaskBoardObservation;
|
|
165
|
-
export declare function relationProblem(board: TaskBoard, before: TaskDocument | null, after: TaskDocument): string | null;
|
|
166
|
-
export declare function diagnoseBoard(board: TaskBoard): readonly TaskDoctorIssue[];
|
|
167
|
-
export declare function buildTree(board: TaskBoard, root: TaskId, relations: TaskRelationProjection): TaskTreeNode | null;
|
|
168
|
-
export {};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { BoundedList } from "../bounded-list.js";
|
|
2
|
-
import type { TaskRef, TaskRow } from "./board.js";
|
|
3
|
-
import type { WorldRoot } from "../world.js";
|
|
4
|
-
export declare function parseTaskNamespaceSelector(value: string): readonly string[];
|
|
5
|
-
export type RecentTaskStatusRow = TaskRow & Readonly<{
|
|
6
|
-
blockers?: readonly TaskRef[];
|
|
7
|
-
}>;
|
|
8
|
-
export declare function observeRecentTaskStatus(world: WorldRoot, input?: Readonly<{
|
|
9
|
-
namespace?: readonly string[];
|
|
10
|
-
limit?: number;
|
|
11
|
-
}>): Promise<BoundedList<RecentTaskStatusRow>>;
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { isTaskSegment, parseTaskId } from "./identity.js";
|
|
2
|
-
import { readRecentTaskDocuments, readTaskDocument } from "./store.js";
|
|
3
|
-
export function parseTaskNamespaceSelector(value) {
|
|
4
|
-
if (value === "task/")
|
|
5
|
-
return [];
|
|
6
|
-
if (!value.startsWith("task/") || !value.endsWith("/")) {
|
|
7
|
-
throw new TypeError(`invalid Task namespace selector: ${value}`);
|
|
8
|
-
}
|
|
9
|
-
const body = value.slice("task/".length, -1);
|
|
10
|
-
const segments = body.split("/");
|
|
11
|
-
if (body.length === 0 || !segments.every(isTaskSegment)) {
|
|
12
|
-
throw new TypeError(`invalid Task namespace selector: ${value}`);
|
|
13
|
-
}
|
|
14
|
-
return parseTaskId(`task/${body}/placeholder`).namespace;
|
|
15
|
-
}
|
|
16
|
-
function terminal(task) {
|
|
17
|
-
return task?.state === "done" || task?.state === "drop";
|
|
18
|
-
}
|
|
19
|
-
async function catalogRow(world, task, documents) {
|
|
20
|
-
const needs = await Promise.all(task.needs.map(async (id) => documents.get(id) ?? (await readTaskDocument(world, id))));
|
|
21
|
-
const blockers = [];
|
|
22
|
-
if (task.state === "open" || task.state === "in_progress") {
|
|
23
|
-
for (const [index, need] of needs.entries()) {
|
|
24
|
-
if (terminal(need))
|
|
25
|
-
continue;
|
|
26
|
-
blockers.push({ id: task.needs[index], title: need?.title ?? null, state: need?.state ?? "missing" });
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return {
|
|
30
|
-
id: task.id,
|
|
31
|
-
title: task.title,
|
|
32
|
-
state: task.state,
|
|
33
|
-
priority: task.priority,
|
|
34
|
-
disposition: task.state === "open" && needs.some((need) => !terminal(need))
|
|
35
|
-
? "blocked"
|
|
36
|
-
: task.state === "open"
|
|
37
|
-
? "ready"
|
|
38
|
-
: task.state,
|
|
39
|
-
updatedAt: task.updatedAt,
|
|
40
|
-
bodyPresent: task.body.length > 0,
|
|
41
|
-
...(blockers.length === 0 ? {} : { blockers }),
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
export async function observeRecentTaskStatus(world, input = {}) {
|
|
45
|
-
const { namespace } = input;
|
|
46
|
-
if (namespace !== undefined && !namespace.every(isTaskSegment)) {
|
|
47
|
-
throw new TypeError("namespace must contain canonical segments");
|
|
48
|
-
}
|
|
49
|
-
const documents = await readRecentTaskDocuments(world, {
|
|
50
|
-
...(namespace === undefined ? {} : { namespace }),
|
|
51
|
-
selection: "active",
|
|
52
|
-
...(input.limit === undefined ? {} : { limit: input.limit }),
|
|
53
|
-
});
|
|
54
|
-
const known = new Map(documents.rows.map((document) => [document.id, document]));
|
|
55
|
-
return {
|
|
56
|
-
rows: await Promise.all(documents.rows.map((document) => catalogRow(world, document, known))),
|
|
57
|
-
hasMore: documents.hasMore,
|
|
58
|
-
};
|
|
59
|
-
}
|