@astrosheep/keiyaku 2.9.8 → 2.9.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 +50 -182
- package/build/.tsbuildinfo +1 -1
- package/build/agents/harness/control-types.js +18 -1
- package/build/agents/harness/index.js +2 -0
- package/build/agents/harness/outcome-error.js +81 -0
- package/build/agents/harness/projection.js +10 -7
- package/build/agents/harness/router.js +5 -1
- package/build/agents/providers/claude-agent-sdk/adapter.js +18 -4
- package/build/agents/providers/claude-agent-sdk/registration.js +11 -1
- package/build/agents/providers/claude-agent-sdk/session.js +19 -5
- package/build/agents/providers/codex-app-server/adapter.js +11 -6
- package/build/agents/providers/codex-app-server/events.js +67 -6
- package/build/agents/providers/codex-app-server/registration.js +11 -1
- package/build/agents/providers/opencode-sdk/adapter.js +8 -1
- package/build/agents/providers/opencode-sdk/events.js +24 -2
- package/build/agents/providers/opencode-sdk/registration.js +11 -1
- package/build/agents/providers/pi/checkpoint.js +9 -1
- package/build/agents/providers/pi/events.js +2 -0
- package/build/agents/providers/pi/registration.js +14 -1
- package/build/cli/commands/akuma/akuma/handler.js +1 -1
- package/build/cli/commands/akuma/akuma/meta.js +3 -3
- package/build/cli/commands/akuma/catalog.js +2 -2
- package/build/cli/commands/akuma/{view → show}/handler.js +5 -5
- package/build/cli/commands/akuma/{view → show}/meta.js +3 -3
- package/build/cli/commands/akuma.js +1 -1
- package/build/cli/commands/contract/amend/handler.js +5 -4
- package/build/cli/commands/contract/arc/handler.js +5 -4
- package/build/cli/commands/contract/audit/handler.js +2 -2
- package/build/cli/commands/contract/bind/handler.js +12 -3
- package/build/cli/commands/contract/bind/meta.js +45 -15
- package/build/cli/commands/contract/forfeit/handler.js +9 -5
- package/build/cli/commands/contract/log/handler.js +2 -2
- package/build/cli/commands/contract/petition/handler.js +34 -7
- package/build/cli/commands/contract/renew/handler.js +7 -7
- package/build/cli/commands/contract/renew/meta.js +3 -3
- package/build/cli/commands/metadata.js +10 -6
- package/build/cli/commands/projection/call/meta.js +1 -1
- package/build/cli/commands/projection/catalog.js +2 -0
- package/build/cli/commands/projection/history/handler.js +21 -0
- package/build/cli/commands/projection/history/meta.js +9 -0
- package/build/cli/commands/projection/shared.js +3 -4
- package/build/cli/commands/projection/status/handler.js +3 -3
- package/build/cli/commands/projection/wait/handler.js +20 -11
- package/build/cli/commands/task/add/handler.js +14 -5
- package/build/cli/commands/task/add/meta.js +2 -2
- package/build/cli/commands/task/catalog.js +4 -0
- package/build/cli/commands/task/done/handler.js +1 -4
- package/build/cli/commands/task/done/meta.js +1 -1
- package/build/cli/commands/task/drop/meta.js +1 -1
- package/build/cli/commands/task/hold/handler.js +3 -0
- package/build/cli/commands/task/hold/meta.js +8 -0
- package/build/cli/commands/task/log/handler.js +1 -1
- package/build/cli/commands/task/log/meta.js +2 -2
- package/build/cli/commands/task/resume/handler.js +3 -0
- package/build/cli/commands/task/resume/meta.js +8 -0
- package/build/cli/commands/task/shared.js +39 -14
- package/build/cli/commands/task/show/handler.js +1 -1
- package/build/cli/commands/task/show/meta.js +1 -1
- package/build/cli/commands/task/start/meta.js +1 -1
- package/build/cli/commands/task/stop/handler.js +1 -4
- package/build/cli/commands/task/stop/meta.js +1 -1
- package/build/cli/commands/task/update/handler.js +11 -3
- package/build/cli/commands/task/update/meta.js +3 -3
- package/build/cli/completion.js +3 -2
- package/build/cli/flags.js +51 -14
- package/build/cli/help.js +4 -1
- package/build/cli/index.js +40 -25
- package/build/cli/parse-flags.js +40 -7
- package/build/cli/parse-metadata.js +5 -2
- package/build/cli/parse-selectors.js +2 -3
- package/build/cli/parse.js +40 -6
- package/build/cli/projection-address.js +12 -10
- package/build/cli/render/amendment-warning.js +8 -0
- package/build/cli/render/arc.js +6 -2
- package/build/cli/render/audit.js +400 -81
- package/build/cli/render/kanshi.js +242 -79
- package/build/cli/render/lifecycle.js +56 -0
- package/build/cli/render/misc.js +24 -28
- package/build/cli/render/petition.js +5 -0
- package/build/cli/render/projection-activity.js +65 -29
- package/build/cli/render/projection-history.js +64 -0
- package/build/cli/render/shared.js +23 -9
- package/build/cli/render/status.js +13 -35
- package/build/cli/render/task.js +51 -26
- package/build/cli/render/terminal-failure.js +3 -1
- package/build/cli/render/wait.js +45 -69
- package/build/cli/subagent-guard.js +1 -1
- package/build/cli/types.js +1 -1
- package/build/config/env-keys.js +3 -1
- package/build/config/env.js +24 -1
- package/build/config/settings/schema.js +3 -1
- package/build/core/address-carrier.js +89 -0
- package/build/core/addressing.js +255 -196
- package/build/core/amend.js +115 -38
- package/build/core/amendment-criteria.js +17 -0
- package/build/core/amendment-warning.js +10 -0
- package/build/core/arc.js +184 -83
- package/build/core/audit/candidate.js +110 -9
- package/build/core/audit/coordinates.js +120 -65
- package/build/core/audit/evidence.js +19 -23
- package/build/core/audit/facade.js +34 -11
- package/build/core/audit/report.js +5 -5
- package/build/core/bind-reconciliation.js +390 -0
- package/build/core/bind-workspace.js +12 -20
- package/build/core/bind.js +242 -273
- package/build/core/call/call.js +1 -0
- package/build/core/call/context.js +46 -71
- package/build/core/call/prompt.js +6 -3
- package/build/core/context.js +49 -35
- package/build/core/contract-carrier-runtime.js +408 -0
- package/build/core/contract-carrier.js +270 -0
- package/build/core/contract-view.js +33 -27
- package/build/core/contract.js +5 -1
- package/build/core/derived-replay.js +207 -0
- package/build/core/draft.js +125 -57
- package/build/core/forfeit.js +113 -56
- package/build/core/identifier-slug.js +63 -13
- package/build/core/ids.js +4 -4
- package/build/core/lifecycle-history.js +35 -0
- package/build/core/lifecycle-recovery.js +117 -0
- package/build/core/lifecycle-runner.js +377 -0
- package/build/core/log.js +37 -11
- package/build/core/outcome-base.js +181 -0
- package/build/core/process-group.js +139 -0
- package/build/core/projection/generation/database.js +82 -7
- package/build/core/projection/generation/model.js +9 -36
- package/build/core/projection/generation/projection-generation-continuation.js +10 -22
- package/build/core/projection/generation/projection-generation-execution.js +13 -6
- package/build/core/projection/index.js +5 -4
- package/build/core/projection/projection-activity.js +29 -8
- package/build/core/projection/projection-alias.js +23 -10
- package/build/core/projection/projection-core.js +21 -7
- package/build/core/projection/projection-execution-observer.js +91 -39
- package/build/core/projection/projection-history.js +474 -0
- package/build/core/projection/projection-runner-lock.js +12 -0
- package/build/core/projection/projection-status-observation.js +365 -0
- package/build/core/projection/projection-status.js +35 -337
- package/build/core/projection/projection-terminal-failure.js +13 -8
- package/build/core/projection/projection-wait.js +7 -2
- package/build/core/projection/tell/launch-store.js +244 -0
- package/build/core/projection/tell/model.js +3 -3
- package/build/core/projection/tell/store.js +70 -118
- package/build/core/registry.js +22 -87
- package/build/core/renew-build.js +424 -0
- package/build/core/renew-plan.js +239 -0
- package/build/core/renew-rewrite.js +77 -0
- package/build/core/renew.js +295 -520
- package/build/core/repository-ledger/accepted-fold-read.js +19 -0
- package/build/core/repository-ledger/accepted-tail.js +116 -0
- package/build/core/repository-ledger/admission.js +38 -0
- package/build/core/repository-ledger/authoritative-transaction.js +1 -0
- package/build/core/repository-ledger/claim-evidence.js +147 -0
- package/build/core/repository-ledger/codec.js +297 -0
- package/build/core/repository-ledger/current-state-store.js +853 -0
- package/build/core/repository-ledger/fold-repository.js +375 -0
- package/build/core/repository-ledger/fold.js +248 -0
- package/build/core/repository-ledger/git-object-store.js +243 -0
- package/build/core/repository-ledger/history-read.js +15 -0
- package/build/core/repository-ledger/incremental-read.js +153 -0
- package/build/core/repository-ledger/index.js +15 -0
- package/build/core/repository-ledger/inventory-plan.js +75 -0
- package/build/core/repository-ledger/inventory.js +310 -0
- package/build/core/repository-ledger/publication-admission.js +125 -0
- package/build/core/repository-ledger/publication.js +353 -0
- package/build/core/repository-ledger/read-model.js +469 -0
- package/build/core/repository-ledger/transaction-membership.js +78 -0
- package/build/core/repository-ledger/traversal.js +404 -0
- package/build/core/repository-ledger/write-transaction.js +339 -0
- package/build/core/seal.js +168 -161
- package/build/core/settlement/claim-delivery.js +42 -215
- package/build/core/settlement/claim.js +235 -153
- package/build/core/settlement/index.js +4 -4
- package/build/core/settlement/petition-claim-gates.js +52 -33
- package/build/core/settlement/petition-forfeit.js +12 -5
- package/build/core/settlement/petition-head-guard.js +8 -5
- package/build/core/settlement/petition-preview.js +68 -56
- package/build/core/settlement/petition-window.js +50 -0
- package/build/core/settlement/petition.js +252 -131
- package/build/core/settlement/queue-read-model.js +72 -95
- package/build/core/settlement/queue-seat-allocation.js +35 -126
- package/build/core/settlement/queue.js +1 -1
- package/build/core/settlement/settlement.js +172 -80
- package/build/core/settlement/verdict.js +112 -66
- package/build/core/settlement/verification-coordination.js +305 -0
- package/build/core/settlement/verification-supervisor.js +275 -0
- package/build/core/settlement/verification.js +398 -31
- package/build/core/status/board.js +125 -127
- package/build/core/status/lifecycle.js +7 -80
- package/build/core/structured-query.js +23 -0
- package/build/core/target-ref.js +1 -1
- package/build/core/task/board.js +59 -24
- package/build/core/task/commands.js +181 -33
- package/build/core/task/coordinate.js +56 -0
- package/build/core/task/document.js +25 -9
- package/build/core/task/index.js +7 -4
- package/build/core/task/query.js +17 -27
- package/build/core/task/settlement-git.js +164 -179
- package/build/core/task/settlement-policy.js +15 -11
- package/build/core/task/source-board.js +31 -13
- package/build/core/task/task-bind-preparation.js +193 -0
- package/build/core/task/task-contract.js +102 -193
- package/build/core/task/task-file-transaction.js +171 -0
- package/build/core/task/task-git-runtime.js +76 -14
- package/build/core/task/task-git-store.js +68 -169
- package/build/core/task/task-store-repository.js +13 -6
- package/build/core/task/task-worktree.js +6 -33
- package/build/core/task/task.js +1 -1
- package/build/core/task/tree.js +3 -3
- package/build/core/task/validation.js +4 -3
- package/build/core/transcripts.js +93 -1
- package/build/core/worktree-bootstrap.js +44 -36
- package/build/core/worktree-path.js +210 -77
- package/build/flow-error.js +7 -7
- package/build/generated/version.js +2 -2
- package/build/git/core.js +76 -13
- package/build/git/refs.js +168 -46
- package/build/git/streaming-batch.js +73 -13
- package/package.json +1 -1
- package/skills/keiyaku/SKILL.md +1 -1
- package/skills/keiyaku-akuma/SKILL.md +3 -3
- package/skills/keiyaku-task/SKILL.md +4 -2
- package/skills/keiyaku-workflow/SKILL.md +88 -203
- package/build/core/entry.js +0 -305
- package/build/core/ledger-batch.js +0 -194
- package/build/core/ledger.js +0 -84
- package/build/core/projection/leash.js +0 -87
- package/build/core/ref-log.js +0 -119
- package/build/core/renew-session.js +0 -128
- package/build/core/status/ledger-batch.js +0 -1
- package/build/core/status/reconciliation.js +0 -137
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { readProjectionHistoryAddress, readProjectionHistory, selectProjectionHistory, } from "../../../../core/projection/index.js";
|
|
2
|
+
import { FlowError } from "../../../../flow-error.js";
|
|
3
|
+
import { projectionHistoryJson, renderProjectionHistoryDetail, renderProjectionHistoryList } from "../../../render/projection-history.js";
|
|
4
|
+
import { textResponse } from "../../../render/shared.js";
|
|
5
|
+
import { projectDirectory } from "../../shared.js";
|
|
6
|
+
export const handler = async (_stdin, flags, _signal, positional) => {
|
|
7
|
+
const cwd = await projectDirectory(flags, "history");
|
|
8
|
+
const [address] = positional;
|
|
9
|
+
if (!address) {
|
|
10
|
+
const runs = selectProjectionHistory(await readProjectionHistory(cwd), {
|
|
11
|
+
filters: flags.taskFilters,
|
|
12
|
+
sort: flags.taskSort,
|
|
13
|
+
nowMs: Date.now(),
|
|
14
|
+
});
|
|
15
|
+
return textResponse(flags.json ? projectionHistoryJson(runs) : renderProjectionHistoryList(runs));
|
|
16
|
+
}
|
|
17
|
+
const detail = await readProjectionHistoryAddress(cwd, address);
|
|
18
|
+
if (!detail)
|
|
19
|
+
throw new FlowError("PROJECTION_HISTORY_NOT_FOUND", `history has no retained run for '${address}'`);
|
|
20
|
+
return textResponse(flags.json ? projectionHistoryJson(detail) : renderProjectionHistoryDetail(detail));
|
|
21
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const meta = {
|
|
2
|
+
command: "history",
|
|
3
|
+
summary: "Discover retained Akuma runs or inspect one run",
|
|
4
|
+
usage: ["keiyaku history [PROJECTION|ALIAS|ARTIFACT] [-C|--cwd DIR] [--filter EXPR] [--sort KEYS] [--json]"],
|
|
5
|
+
stdin: { mode: "argument" },
|
|
6
|
+
flags: ["cwd", "repo", "filter", "sort", "json"],
|
|
7
|
+
purpose: "Read retained projection history and the public response-file path without reading response content.",
|
|
8
|
+
completionRank: 15,
|
|
9
|
+
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { resolveContractAddress, withResolvedAddress, } from "../../../core/addressing.js";
|
|
2
|
-
import { projectionDir } from "../../../core/projection/index.js";
|
|
3
2
|
import { resolveProjectionAddress, } from "../../projection-address.js";
|
|
4
3
|
import { projectDirectory, repositoryDirectory } from "../shared.js";
|
|
5
4
|
/** Resolve cwd + optional contract address, then run the verb under that carrier. */
|
|
@@ -13,16 +12,16 @@ export async function runProjectionCommand(flags, verb, operation) {
|
|
|
13
12
|
const run = () => operation({ cwd, address });
|
|
14
13
|
return address ? await withResolvedAddress(address, run) : await run();
|
|
15
14
|
}
|
|
16
|
-
export function resolveProjectionCommandAddress(ctx, projectionAddress, verb) {
|
|
15
|
+
export function resolveProjectionCommandAddress(ctx, projectionAddress, verb, coordinate) {
|
|
17
16
|
return resolveProjectionAddress({
|
|
18
17
|
cwd: ctx.cwd,
|
|
19
18
|
address: projectionAddress,
|
|
20
19
|
scope: ctx.address,
|
|
20
|
+
coordinate,
|
|
21
21
|
verb,
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
24
|
export async function resolveProjectionCommandTarget(ctx, projectionAddress, verb) {
|
|
25
25
|
const projection = await resolveProjectionCommandAddress(ctx, projectionAddress, verb);
|
|
26
|
-
|
|
27
|
-
return { ...projection, directory };
|
|
26
|
+
return projection;
|
|
28
27
|
}
|
|
@@ -3,7 +3,7 @@ import { normalizeTargetRef } from "../../../../core/target-ref.js";
|
|
|
3
3
|
import { isProjectionId } from "../../../../core/projection/index.js";
|
|
4
4
|
import { FlowError } from "../../../../flow-error.js";
|
|
5
5
|
import { renderProjectionFilteredStatus, renderStatusBoard } from "../../../render/status.js";
|
|
6
|
-
import {
|
|
6
|
+
import { coreTextResponse } from "../../../render/shared.js";
|
|
7
7
|
import { projectDirectory, repositoryDirectory } from "../../shared.js";
|
|
8
8
|
export const handler = async (_stdin, flags, _signal, positional) => {
|
|
9
9
|
const [projectionId] = positional;
|
|
@@ -21,6 +21,6 @@ export const handler = async (_stdin, flags, _signal, positional) => {
|
|
|
21
21
|
...(projectionId === undefined ? {} : { projectionId }),
|
|
22
22
|
});
|
|
23
23
|
if (projectionId === undefined)
|
|
24
|
-
return
|
|
25
|
-
return
|
|
24
|
+
return coreTextResponse(renderStatusBoard(board), board);
|
|
25
|
+
return coreTextResponse(renderProjectionFilteredStatus(board, projectionId), board);
|
|
26
26
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { snapshotCommissionProjectionIds, waitForProjection, waitForProjectionSet } from "../../../../core/projection/index.js";
|
|
1
|
+
import { projectionDirAtCoordinate, resolveProjectionCoordinate, snapshotCommissionProjectionIdsAtCoordinate, waitForProjection, waitForProjectionSet, } from "../../../../core/projection/index.js";
|
|
3
2
|
import { FlowError } from "../../../../flow-error.js";
|
|
4
3
|
import { prependAddressReceipt } from "../../../render/address.js";
|
|
5
4
|
import { buildProjectionWaitSetResponse, buildWaitResponse } from "../../../render/wait.js";
|
|
@@ -15,30 +14,40 @@ export const handler = async (_stdin, flags, signal, positional) => runProjectio
|
|
|
15
14
|
signal,
|
|
16
15
|
}), { alias: projection.alias }), ctx.address, { projectionId: projection.id, projectionAlias: projection.alias });
|
|
17
16
|
}
|
|
18
|
-
const selected =
|
|
17
|
+
const selected = new Map();
|
|
18
|
+
let coordinate;
|
|
19
|
+
if (ctx.address) {
|
|
20
|
+
coordinate = {
|
|
21
|
+
physicalRoot: ctx.address.repo.stableRoot,
|
|
22
|
+
authority: { kind: "repository", stableRoot: ctx.address.repo.stableRoot },
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
coordinate = await resolveProjectionCoordinate(ctx.cwd);
|
|
27
|
+
}
|
|
19
28
|
if (positional.length === 0) {
|
|
20
29
|
if (ctx.address?.binding.kind === "commission") {
|
|
21
|
-
|
|
30
|
+
for (const id of await snapshotCommissionProjectionIdsAtCoordinate(coordinate, ctx.address.binding.commissionId)) {
|
|
31
|
+
selected.set(id, { id, projectionDirectory: projectionDirAtCoordinate(coordinate, id) });
|
|
32
|
+
}
|
|
22
33
|
}
|
|
23
34
|
}
|
|
24
35
|
else {
|
|
25
36
|
// Resolve in argument order so multiple bad coordinates have one stable failure.
|
|
26
37
|
for (const projectionAddress of positional) {
|
|
27
|
-
|
|
38
|
+
const projection = await resolveProjectionCommandAddress(ctx, projectionAddress, "wait", coordinate);
|
|
39
|
+
selected.set(projection.id, { id: projection.id, projectionDirectory: projection.directory });
|
|
28
40
|
}
|
|
29
41
|
}
|
|
30
|
-
const
|
|
31
|
-
if (
|
|
42
|
+
const projections = [...selected.values()].sort((left, right) => left.id.localeCompare(right.id));
|
|
43
|
+
if (projections.length === 0) {
|
|
32
44
|
throw new FlowError("EMPTY_PARAM", "wait commission snapshot contains no projections");
|
|
33
45
|
}
|
|
34
46
|
if (!flags.any && !flags.all) {
|
|
35
47
|
throw new FlowError("EMPTY_PARAM", WAIT_SET_SELECTION_ERROR);
|
|
36
48
|
}
|
|
37
49
|
return prependAddressReceipt(buildProjectionWaitSetResponse(await waitForProjectionSet({
|
|
38
|
-
projections
|
|
39
|
-
id,
|
|
40
|
-
projectionDirectory: await projectionDir(ctx.cwd, id),
|
|
41
|
-
}))),
|
|
50
|
+
projections,
|
|
42
51
|
selection: flags.any ? "any" : "all",
|
|
43
52
|
timeoutMs: flags.timeoutMs,
|
|
44
53
|
signal,
|
|
@@ -1,13 +1,22 @@
|
|
|
1
|
-
import { createTask, resolveTaskCreator, } from "../../../../core/task/index.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { createTask, openTaskMutationContext, resolveTaskCreator, } from "../../../../core/task/index.js";
|
|
2
|
+
import { renderTaskMutationRow } from "../../../render/task.js";
|
|
3
|
+
import { textResponse } from "../../../render/shared.js";
|
|
4
|
+
import { effectiveDirectory } from "../../shared.js";
|
|
5
|
+
import { parseTaskAddInput } from "../shared.js";
|
|
6
|
+
export const handler = async (stdin, flags, signal) => {
|
|
4
7
|
const input = parseTaskAddInput(stdin);
|
|
5
|
-
|
|
8
|
+
const cwd = effectiveDirectory(flags);
|
|
9
|
+
const context = await openTaskMutationContext(cwd, signal);
|
|
10
|
+
const task = await createTask(context.repository, {
|
|
6
11
|
...input,
|
|
12
|
+
namespace: context.namespace,
|
|
7
13
|
creator: await resolveTaskCreator(cwd),
|
|
8
14
|
...(flags.taskPri === undefined ? {} : { pri: flags.taskPri }),
|
|
9
15
|
needs: flags.taskNeeds ?? [],
|
|
10
16
|
parent: flags.taskParent ?? null,
|
|
11
17
|
from: flags.taskFrom ?? [],
|
|
12
|
-
|
|
18
|
+
supersedes: flags.taskSupersedes ?? [],
|
|
19
|
+
relatesTo: flags.taskRelatesTo ?? [],
|
|
20
|
+
}, { now: () => new Date() });
|
|
21
|
+
return textResponse(renderTaskMutationRow(task));
|
|
13
22
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const TASK_ADD_USAGE_PREFIX = "keiyaku task add [-C|--cwd DIR] [--needs
|
|
1
|
+
const TASK_ADD_USAGE_PREFIX = "keiyaku task add [-C|--cwd DIR] [--needs COORDINATE]... [--parent COORDINATE] [--from COORDINATE]... [--supersedes COORDINATE]... [--relates-to COORDINATE]... [--pri 0-3]";
|
|
2
2
|
export const meta = {
|
|
3
3
|
command: "task add",
|
|
4
4
|
summary: "Add a task",
|
|
@@ -10,7 +10,7 @@ export const meta = {
|
|
|
10
10
|
mode: "argument",
|
|
11
11
|
selector: { kind: "positional", index: 0, required: true, rejectBlank: true },
|
|
12
12
|
},
|
|
13
|
-
flags: ["cwd", "needs", "parent", "from", "pri"],
|
|
13
|
+
flags: ["cwd", "needs", "parent", "from", "supersedes", "relates-to", "pri"],
|
|
14
14
|
purpose: "Create a lightweight task from a title and optional body.",
|
|
15
15
|
notes: [
|
|
16
16
|
"<BODY> and literal - are mutually exclusive body selectors. Use literal - with stdin for multiline prose.",
|
|
@@ -5,6 +5,8 @@ import { meta as lsMeta } from "./ls/meta.js";
|
|
|
5
5
|
import { meta as logMeta } from "./log/meta.js";
|
|
6
6
|
import { meta as startMeta } from "./start/meta.js";
|
|
7
7
|
import { meta as stopMeta } from "./stop/meta.js";
|
|
8
|
+
import { meta as holdMeta } from "./hold/meta.js";
|
|
9
|
+
import { meta as resumeMeta } from "./resume/meta.js";
|
|
8
10
|
import { meta as doneMeta } from "./done/meta.js";
|
|
9
11
|
import { meta as dropMeta } from "./drop/meta.js";
|
|
10
12
|
import { meta as updateMeta } from "./update/meta.js";
|
|
@@ -17,6 +19,8 @@ export const taskCatalog = [
|
|
|
17
19
|
{ meta: logMeta, load: () => import("./log/handler.js") },
|
|
18
20
|
{ meta: startMeta, load: () => import("./start/handler.js") },
|
|
19
21
|
{ meta: stopMeta, load: () => import("./stop/handler.js") },
|
|
22
|
+
{ meta: holdMeta, load: () => import("./hold/handler.js") },
|
|
23
|
+
{ meta: resumeMeta, load: () => import("./resume/handler.js") },
|
|
20
24
|
{ meta: doneMeta, load: () => import("./done/handler.js") },
|
|
21
25
|
{ meta: dropMeta, load: () => import("./drop/handler.js") },
|
|
22
26
|
{ meta: updateMeta, load: () => import("./update/handler.js") },
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { doneTask } from "../../../../core/task/index.js";
|
|
2
|
-
import {
|
|
3
|
-
import { mutationSelectionMessage, rejectBareContractTaskState, runTaskMutationCommand } from "../shared.js";
|
|
2
|
+
import { mutationSelectionMessage, runTaskMutationCommand } from "../shared.js";
|
|
4
3
|
export const handler = async (_stdin, flags, _signal, positional) => {
|
|
5
4
|
try {
|
|
6
|
-
if (positional[0] === undefined)
|
|
7
|
-
await rejectBareContractTaskState(effectiveDirectory(flags), "done");
|
|
8
5
|
return await runTaskMutationCommand(flags, (repository) => doneTask(repository, positional[0]));
|
|
9
6
|
}
|
|
10
7
|
catch (error) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const meta = {
|
|
2
2
|
command: "task done",
|
|
3
3
|
summary: "Complete a task",
|
|
4
|
-
usage: ["keiyaku task done [-C|--cwd DIR] [
|
|
4
|
+
usage: ["keiyaku task done [-C|--cwd DIR] [COORDINATE]"],
|
|
5
5
|
stdin: { mode: "argument" },
|
|
6
6
|
flags: ["cwd"],
|
|
7
7
|
purpose: "Complete an open or in-progress task.",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const meta = {
|
|
2
2
|
command: "task drop",
|
|
3
3
|
summary: "Drop a task",
|
|
4
|
-
usage: ["keiyaku task drop [-C|--cwd DIR]
|
|
4
|
+
usage: ["keiyaku task drop [-C|--cwd DIR] COORDINATE"],
|
|
5
5
|
stdin: { mode: "argument" },
|
|
6
6
|
flags: ["cwd"],
|
|
7
7
|
purpose: "Abandon an open or in-progress task.",
|
|
@@ -7,6 +7,6 @@ export const handler = async (_stdin, flags, _signal, positional) => withTaskCom
|
|
|
7
7
|
const task = board.byId.get(resolveTaskReadId(board, positional[0]));
|
|
8
8
|
if (!task)
|
|
9
9
|
throw new FlowError("INTERNAL_STATE", "resolved task disappeared from the board");
|
|
10
|
-
const rows = await readTaskHistory(cwd, task.
|
|
10
|
+
const rows = await readTaskHistory(cwd, task.coordinate);
|
|
11
11
|
return textResponse(rows.map(({ timestamp, actor, subject }) => `${timestamp}\t${actor}\t${subject}`).join("\n"));
|
|
12
12
|
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export const meta = {
|
|
2
2
|
command: "task log",
|
|
3
3
|
summary: "Show one task's Git history",
|
|
4
|
-
usage: ["keiyaku task log [-C|--cwd DIR]
|
|
4
|
+
usage: ["keiyaku task log [-C|--cwd DIR] COORDINATE"],
|
|
5
5
|
stdin: { mode: "argument" },
|
|
6
6
|
flags: ["cwd"],
|
|
7
|
-
purpose: "Read the current
|
|
7
|
+
purpose: "Read the current checkout branch's task micro-commit history.",
|
|
8
8
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import * as path from "node:path";
|
|
2
1
|
import { FlowError } from "../../../flow-error.js";
|
|
3
|
-
import {
|
|
2
|
+
import { openTaskCommandRepository, parseTaskDocument, readTaskDoctor, taskCoordinateFromSourcePath, } from "../../../core/task/index.js";
|
|
4
3
|
import { deriveTaskDisplay, renderTaskList, renderTaskMutationRow, } from "../../render/task.js";
|
|
5
4
|
import { textResponse } from "../../render/shared.js";
|
|
6
5
|
import { effectiveDirectory } from "../shared.js";
|
|
@@ -46,7 +45,7 @@ function taskDocumentsById(sources) {
|
|
|
46
45
|
for (const source of sources) {
|
|
47
46
|
try {
|
|
48
47
|
const document = parseTaskDocument(source);
|
|
49
|
-
documents.set(
|
|
48
|
+
documents.set(taskCoordinateFromSourcePath(source.path).coordinate, document);
|
|
50
49
|
}
|
|
51
50
|
catch {
|
|
52
51
|
// Invalid documents are reported from board diseases.
|
|
@@ -59,9 +58,13 @@ function renderTaskDiseaseRows(diseases, documents) {
|
|
|
59
58
|
const renderedCycles = new Set();
|
|
60
59
|
for (const disease of diseases) {
|
|
61
60
|
if (disease.code === "invalid_document") {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
rows.push(`! ${
|
|
61
|
+
try {
|
|
62
|
+
const coordinate = taskCoordinateFromSourcePath(disease.path).coordinate;
|
|
63
|
+
rows.push(`! ${coordinate} invalid front matter — quarantined`);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// A malformed non-coordinate path has no copyable task identity to render.
|
|
67
|
+
}
|
|
65
68
|
continue;
|
|
66
69
|
}
|
|
67
70
|
if (disease.code === "needs_cycle" && disease.id && disease.relatedIds) {
|
|
@@ -90,6 +93,28 @@ function renderTaskDiseaseRows(diseases, documents) {
|
|
|
90
93
|
rows.push(`! cycle detected: ${cycle.join(" → ")}`);
|
|
91
94
|
continue;
|
|
92
95
|
}
|
|
96
|
+
if (disease.code === "supersedes_cycle" && disease.id && disease.relatedIds) {
|
|
97
|
+
const cycleKey = `supersedes\0${disease.relatedIds.join("\0")}`;
|
|
98
|
+
if (renderedCycles.has(cycleKey))
|
|
99
|
+
continue;
|
|
100
|
+
renderedCycles.add(cycleKey);
|
|
101
|
+
const members = new Set(disease.relatedIds);
|
|
102
|
+
const start = [...members].sort()[0];
|
|
103
|
+
const cycle = [start];
|
|
104
|
+
let current = start;
|
|
105
|
+
for (let count = 0; count <= members.size; count += 1) {
|
|
106
|
+
const next = documents.get(current)?.supersedes.filter((id) => members.has(id)).sort()[0];
|
|
107
|
+
if (!next)
|
|
108
|
+
break;
|
|
109
|
+
cycle.push(next);
|
|
110
|
+
if (next === start)
|
|
111
|
+
break;
|
|
112
|
+
current = next;
|
|
113
|
+
}
|
|
114
|
+
if (cycle.at(-1) === start)
|
|
115
|
+
rows.push(`! supersedes cycle detected: ${cycle.join(" → ")}`);
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
93
118
|
if (disease.code === "missing_reference" && disease.id && disease.relatedIds) {
|
|
94
119
|
const document = documents.get(disease.id);
|
|
95
120
|
if (!document)
|
|
@@ -99,6 +124,10 @@ function renderTaskDiseaseRows(diseases, documents) {
|
|
|
99
124
|
rows.push(`! ${disease.id} needs missing task ${related}`);
|
|
100
125
|
if (document.parent === related)
|
|
101
126
|
rows.push(`? ${disease.id} parent ${related} does not exist`);
|
|
127
|
+
if (document.supersedes.includes(related))
|
|
128
|
+
rows.push(`! ${disease.id} supersedes missing task ${related}`);
|
|
129
|
+
if (document.relatesTo.includes(related))
|
|
130
|
+
rows.push(`! ${disease.id} relates to missing task ${related}`);
|
|
102
131
|
}
|
|
103
132
|
}
|
|
104
133
|
}
|
|
@@ -108,11 +137,13 @@ export async function renderTaskDoctor(cwd) {
|
|
|
108
137
|
const result = await readTaskDoctor(cwd);
|
|
109
138
|
const board = result.board;
|
|
110
139
|
const tasks = board.tasks;
|
|
111
|
-
const counts = { inProgress: 0, ready: 0, blocked: 0, done: 0, dropped: 0, bound: 0 };
|
|
140
|
+
const counts = { inProgress: 0, onHold: 0, ready: 0, blocked: 0, done: 0, dropped: 0, bound: 0 };
|
|
112
141
|
for (const task of tasks) {
|
|
113
142
|
const display = deriveTaskDisplay(task);
|
|
114
143
|
if (display === "in_progress")
|
|
115
144
|
counts.inProgress += 1;
|
|
145
|
+
else if (display === "on_hold")
|
|
146
|
+
counts.onHold += 1;
|
|
116
147
|
else if (display === "ready")
|
|
117
148
|
counts.ready += 1;
|
|
118
149
|
else if (display === "blocked")
|
|
@@ -126,7 +157,7 @@ export async function renderTaskDoctor(cwd) {
|
|
|
126
157
|
}
|
|
127
158
|
const lines = [
|
|
128
159
|
`tasks · ${tasks.length} total`,
|
|
129
|
-
`${counts.inProgress} in_progress · ${counts.ready} ready · ${counts.blocked} blocked · ${counts.done} done · ${counts.dropped} dropped · ${counts.bound} bound`,
|
|
160
|
+
`${counts.inProgress} in_progress · ${counts.onHold} on hold · ${counts.ready} ready · ${counts.blocked} blocked · ${counts.done} done · ${counts.dropped} dropped · ${counts.bound} bound`,
|
|
130
161
|
...renderTaskDiseaseRows(board.diseases, taskDocumentsById(result.sources)),
|
|
131
162
|
...result.orphans.map(({ taskId, contractId }) => `! ${taskId} points at contract ${contractId} which has no ledger entry — rolling back`),
|
|
132
163
|
];
|
|
@@ -134,9 +165,3 @@ export async function renderTaskDoctor(cwd) {
|
|
|
134
165
|
lines.push("× board lock currently held by a live writer");
|
|
135
166
|
return lines.join("\n");
|
|
136
167
|
}
|
|
137
|
-
export async function rejectBareContractTaskState(cwd, verb) {
|
|
138
|
-
const contractId = await taskCommandContractId(cwd);
|
|
139
|
-
if (contractId) {
|
|
140
|
-
throw new FlowError("UNSUPPORTED_POLICY", `task ${verb} is not available in a contract worktree; task state follows the contract (${contractId})`);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
@@ -8,6 +8,6 @@ export const handler = async (_stdin, flags, _signal, positional) => withTaskCom
|
|
|
8
8
|
const task = board.byId.get(resolveTaskReadId(board, positional[0]));
|
|
9
9
|
if (!task)
|
|
10
10
|
throw new FlowError("INTERNAL_STATE", "resolved task disappeared from the board");
|
|
11
|
-
const tree = buildTaskTree(board, task.
|
|
11
|
+
const tree = buildTaskTree(board, task.coordinate);
|
|
12
12
|
return textResponse(flags.json ? taskJsonText(renderTaskShowJson(task, tree)) : renderTaskShow(task, tree));
|
|
13
13
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const meta = {
|
|
2
2
|
command: "task show",
|
|
3
3
|
summary: "Show one task and its children tree",
|
|
4
|
-
usage: ["keiyaku task show [-C|--cwd DIR]
|
|
4
|
+
usage: ["keiyaku task show [-C|--cwd DIR] COORDINATE [--json]"],
|
|
5
5
|
stdin: { mode: "argument" },
|
|
6
6
|
flags: ["cwd", "json"],
|
|
7
7
|
purpose: "Read one task and every descendant linked by parent edges.",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const meta = {
|
|
2
2
|
command: "task start",
|
|
3
3
|
summary: "Start a task",
|
|
4
|
-
usage: ["keiyaku task start [-C|--cwd DIR]
|
|
4
|
+
usage: ["keiyaku task start [-C|--cwd DIR] COORDINATE"],
|
|
5
5
|
stdin: { mode: "argument" },
|
|
6
6
|
flags: ["cwd"],
|
|
7
7
|
purpose: "Move an open task to in_progress.",
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { stopTask } from "../../../../core/task/index.js";
|
|
2
|
-
import {
|
|
3
|
-
import { mutationSelectionMessage, rejectBareContractTaskState, runTaskMutationCommand } from "../shared.js";
|
|
2
|
+
import { mutationSelectionMessage, runTaskMutationCommand } from "../shared.js";
|
|
4
3
|
export const handler = async (_stdin, flags, _signal, positional) => {
|
|
5
4
|
try {
|
|
6
|
-
if (positional[0] === undefined)
|
|
7
|
-
await rejectBareContractTaskState(effectiveDirectory(flags), "stop");
|
|
8
5
|
return await runTaskMutationCommand(flags, (repository) => stopTask(repository, positional[0]));
|
|
9
6
|
}
|
|
10
7
|
catch (error) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const meta = {
|
|
2
2
|
command: "task stop",
|
|
3
3
|
summary: "Stop a task",
|
|
4
|
-
usage: ["keiyaku task stop [-C|--cwd DIR] [
|
|
4
|
+
usage: ["keiyaku task stop [-C|--cwd DIR] [COORDINATE]"],
|
|
5
5
|
stdin: { mode: "argument" },
|
|
6
6
|
flags: ["cwd"],
|
|
7
7
|
purpose: "Return an in-progress task to open.",
|
|
@@ -1,13 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { updateTaskWithReceipt } from "../../../../core/task/index.js";
|
|
2
|
+
import { renderTaskUpdate, renderTaskUpdateJson } from "../../../render/task.js";
|
|
3
|
+
import { textResponse } from "../../../render/shared.js";
|
|
4
|
+
import { withTaskCommandRepository } from "../shared.js";
|
|
3
5
|
export const handler = async (_stdin, flags, _signal, positional) => {
|
|
4
|
-
|
|
6
|
+
const result = await withTaskCommandRepository(flags, (repository) => updateTaskWithReceipt(repository, positional[0], {
|
|
5
7
|
...(flags.taskTitle === undefined ? {} : { title: flags.taskTitle }),
|
|
6
8
|
...(flags.taskBody === undefined ? {} : { body: flags.taskBody }),
|
|
9
|
+
...(flags.taskAppend === undefined ? {} : { appendBody: flags.taskAppend }),
|
|
7
10
|
...(flags.taskPri === undefined ? {} : { pri: flags.taskPri }),
|
|
8
11
|
...(flags.taskNeeds === undefined ? {} : { addNeeds: flags.taskNeeds }),
|
|
9
12
|
...(flags.taskDropNeeds === undefined ? {} : { dropNeeds: flags.taskDropNeeds }),
|
|
10
13
|
...(flags.taskParent !== undefined ? { parent: flags.taskParent } : flags.taskNoParent ? { parent: null } : {}),
|
|
11
14
|
...(flags.taskFrom === undefined ? {} : { from: flags.taskFrom }),
|
|
15
|
+
...(flags.taskSupersedes === undefined ? {} : { addSupersedes: flags.taskSupersedes }),
|
|
16
|
+
...(flags.taskDropSupersedes === undefined ? {} : { dropSupersedes: flags.taskDropSupersedes }),
|
|
17
|
+
...(flags.taskRelatesTo === undefined ? {} : { addRelatesTo: flags.taskRelatesTo }),
|
|
18
|
+
...(flags.taskDropRelatesTo === undefined ? {} : { dropRelatesTo: flags.taskDropRelatesTo }),
|
|
12
19
|
}));
|
|
20
|
+
return textResponse(flags.json ? renderTaskUpdateJson(result) : renderTaskUpdate(result));
|
|
13
21
|
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export const meta = {
|
|
2
2
|
command: "task update",
|
|
3
3
|
summary: "Update task facts",
|
|
4
|
-
usage: ["keiyaku task update [-C|--cwd DIR]
|
|
4
|
+
usage: ["keiyaku task update [-C|--cwd DIR] COORDINATE [--title TEXT] [--body TEXT|-|--append TEXT|-] [--pri 0-3] [--needs COORDINATE] [--drop-needs COORDINATE] [--parent COORDINATE|--no-parent] [--from COORDINATE] [--supersedes COORDINATE] [--drop-supersedes COORDINATE] [--relates-to COORDINATE] [--drop-relates-to COORDINATE] [--json]"],
|
|
5
5
|
stdin: {
|
|
6
6
|
mode: "argument",
|
|
7
|
-
selector: { kind: "flag",
|
|
7
|
+
selector: { kind: "flag", names: ["taskBody", "taskAppend"], required: false, rejectBlank: false },
|
|
8
8
|
},
|
|
9
|
-
flags: ["cwd", "title", "body", "pri", "needs", "drop-needs", "parent", "no-parent", "from"],
|
|
9
|
+
flags: ["cwd", "title", "body", "append", "pri", "needs", "drop-needs", "parent", "no-parent", "from", "supersedes", "drop-supersedes", "relates-to", "drop-relates-to", "json"],
|
|
10
10
|
purpose: "Change mutable task facts.",
|
|
11
11
|
};
|
package/build/cli/completion.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { assertSettingsKnobUsable } from "../config/settings/disease.js";
|
|
2
2
|
import { loadKeiyakuSettings } from "../config/settings/loader.js";
|
|
3
3
|
import { loadAkumaCatalog } from "../config/akuma-loader.js";
|
|
4
|
-
import {
|
|
4
|
+
import { readRepositoryLifecycle } from "../core/repository-ledger/read-model.js";
|
|
5
5
|
import { TASK_FILTER_COMPLETION } from "../core/task/query.js";
|
|
6
6
|
import { allCommandMetadata, getCommandMetadata } from "./commands/metadata.js";
|
|
7
7
|
function topLevelCommands() {
|
|
@@ -27,7 +27,8 @@ function filterPrefix(items, word) {
|
|
|
27
27
|
return items.filter((item) => item.startsWith(word));
|
|
28
28
|
}
|
|
29
29
|
async function contractAddressCandidates(cwd, word) {
|
|
30
|
-
|
|
30
|
+
const read = await readRepositoryLifecycle(cwd);
|
|
31
|
+
return filterPrefix(read.contracts.map((model) => `@${model.contract}`), word);
|
|
31
32
|
}
|
|
32
33
|
async function akumaCandidates(cwd, word) {
|
|
33
34
|
const loaded = await loadKeiyakuSettings(cwd);
|