@songsid/agend 2.3.2-beta.9 → 2.3.3-beta.1
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 +6 -0
- package/README.zh-TW.md +6 -0
- package/dist/agent-cli-instructions.md +2 -2
- package/dist/agent-cli.js +48 -0
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.js +6 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/agent-whats-new.d.ts +21 -0
- package/dist/agent-whats-new.js +53 -21
- package/dist/agent-whats-new.js.map +1 -1
- package/dist/auth-api.js +2 -0
- package/dist/auth-api.js.map +1 -1
- package/dist/backend/claude-code.d.ts +13 -1
- package/dist/backend/claude-code.js +43 -2
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex-session-lookup.d.ts +15 -0
- package/dist/backend/codex-session-lookup.js +58 -0
- package/dist/backend/codex-session-lookup.js.map +1 -1
- package/dist/backend/codex.js +15 -4
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/kiro-classic-archive.d.ts +57 -0
- package/dist/backend/kiro-classic-archive.js +622 -0
- package/dist/backend/kiro-classic-archive.js.map +1 -0
- package/dist/backend/kiro-classic-links.d.ts +24 -0
- package/dist/backend/kiro-classic-links.js +135 -0
- package/dist/backend/kiro-classic-links.js.map +1 -0
- package/dist/backend/kiro-identity.d.ts +100 -1
- package/dist/backend/kiro-identity.js +262 -31
- package/dist/backend/kiro-identity.js.map +1 -1
- package/dist/backend/kiro-migration-verify.d.ts +10 -0
- package/dist/backend/kiro-migration-verify.js +52 -0
- package/dist/backend/kiro-migration-verify.js.map +1 -0
- package/dist/backend/kiro-reconcile-store.d.ts +27 -0
- package/dist/backend/kiro-reconcile-store.js +351 -0
- package/dist/backend/kiro-reconcile-store.js.map +1 -0
- package/dist/backend/kiro-v2-store-worker.js +35 -1
- package/dist/backend/kiro-v2-store-worker.js.map +1 -1
- package/dist/backend/kiro-v2-store.d.ts +31 -1
- package/dist/backend/kiro-v2-store.js +22 -12
- package/dist/backend/kiro-v2-store.js.map +1 -1
- package/dist/backend/kiro.d.ts +124 -6
- package/dist/backend/kiro.js +553 -39
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/types.d.ts +109 -4
- package/dist/backend/types.js +9 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/cache-service.d.ts +13 -1
- package/dist/cache-service.js +45 -2
- package/dist/cache-service.js.map +1 -1
- package/dist/channel/ipc-timeouts.js +3 -0
- package/dist/channel/ipc-timeouts.js.map +1 -1
- package/dist/channel/mcp-tools.js +40 -5
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/tool-router.js +2 -1
- package/dist/channel/tool-router.js.map +1 -1
- package/dist/classic-channel-manager.d.ts +6 -0
- package/dist/classic-channel-manager.js +25 -0
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli.js +52 -6
- package/dist/cli.js.map +1 -1
- package/dist/config-validator.d.ts +7 -1
- package/dist/config-validator.js +20 -9
- package/dist/config-validator.js.map +1 -1
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -1
- package/dist/cross-instance-envelope.d.ts +10 -5
- package/dist/cross-instance-envelope.js +20 -17
- package/dist/cross-instance-envelope.js.map +1 -1
- package/dist/daemon.d.ts +125 -63
- package/dist/daemon.js +694 -330
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard-permissions.d.ts +15 -4
- package/dist/dashboard-permissions.js +49 -23
- package/dist/dashboard-permissions.js.map +1 -1
- package/dist/delivery-outbox.d.ts +27 -22
- package/dist/delivery-outbox.js +109 -161
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/delivery-outbox.test.js +10 -25
- package/dist/delivery-outbox.test.js.map +1 -1
- package/dist/doctor.js +2 -1
- package/dist/doctor.js.map +1 -1
- package/dist/fleet-control-audit.d.ts +1 -1
- package/dist/fleet-control-audit.js +3 -0
- package/dist/fleet-control-audit.js.map +1 -1
- package/dist/fleet-manager.d.ts +94 -15
- package/dist/fleet-manager.js +597 -133
- package/dist/fleet-manager.js.map +1 -1
- package/dist/forged-envelope-scan.d.ts +9 -0
- package/dist/forged-envelope-scan.js +30 -5
- package/dist/forged-envelope-scan.js.map +1 -1
- package/dist/general-instance.d.ts +24 -0
- package/dist/general-instance.js +53 -0
- package/dist/general-instance.js.map +1 -1
- package/dist/general-knowledge/skills/delegation-playbook/SKILL.md +1 -1
- package/dist/general-knowledge/skills/docker-install/SKILL.md +25 -0
- package/dist/general-knowledge/skills/fleet-config/SKILL.md +5 -3
- package/dist/general-knowledge/skills/fleet-restart/SKILL.md +1 -1
- package/dist/general-knowledge/skills/kiro-engine-migration/SKILL.md +34 -0
- package/dist/general-knowledge/skills/session-management/SKILL.md +2 -2
- package/dist/general-knowledge/skills/tui-effort/SKILL.md +1 -1
- package/dist/general-knowledge/skills/web-appearance/SKILL.canvas-worker-off.md +32 -0
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +32 -0
- package/dist/general-knowledge/skills/web-dashboard/SKILL.canvas-worker-off.md +57 -17
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +57 -17
- package/dist/instance-config-impact.js +3 -2
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +4 -0
- package/dist/instance-lifecycle.js +28 -5
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instructions.js +6 -7
- package/dist/instructions.js.map +1 -1
- package/dist/kiro-migrate.d.ts +19 -2
- package/dist/kiro-migrate.js +133 -35
- package/dist/kiro-migrate.js.map +1 -1
- package/dist/kiro-reconcile.d.ts +21 -0
- package/dist/kiro-reconcile.js +88 -0
- package/dist/kiro-reconcile.js.map +1 -0
- package/dist/kiro-session-proof.d.ts +41 -0
- package/dist/kiro-session-proof.js +89 -0
- package/dist/kiro-session-proof.js.map +1 -0
- package/dist/kiro-tui-forensic.d.ts +19 -0
- package/dist/kiro-tui-forensic.js +124 -0
- package/dist/kiro-tui-forensic.js.map +1 -0
- package/dist/locale.js +202 -16
- package/dist/locale.js.map +1 -1
- package/dist/log-service.js +3 -3
- package/dist/log-service.js.map +1 -1
- package/dist/needs-you.d.ts +3 -1
- package/dist/needs-you.js +4 -2
- package/dist/needs-you.js.map +1 -1
- package/dist/office-levels.d.ts +64 -0
- package/dist/office-levels.js +66 -0
- package/dist/office-levels.js.map +1 -0
- package/dist/office-share-page.d.ts +3 -1
- package/dist/office-share-page.js +8 -3
- package/dist/office-share-page.js.map +1 -1
- package/dist/office-share-service.d.ts +6 -3
- package/dist/office-share-service.js +12 -8
- package/dist/office-share-service.js.map +1 -1
- package/dist/office-share.d.ts +45 -8
- package/dist/office-share.js +75 -15
- package/dist/office-share.js.map +1 -1
- package/dist/outbound-handlers.js +21 -2
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +47 -2
- package/dist/outbound-schemas.js +42 -3
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/public-web-gateway.js +1 -1
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/quickstart-api.d.ts +39 -1
- package/dist/quickstart-api.js +115 -17
- package/dist/quickstart-api.js.map +1 -1
- package/dist/remote-card-answer.d.ts +83 -0
- package/dist/remote-card-answer.js +208 -0
- package/dist/remote-card-answer.js.map +1 -0
- package/dist/remote-card-prompt.d.ts +38 -0
- package/dist/remote-card-prompt.js +86 -0
- package/dist/remote-card-prompt.js.map +1 -0
- package/dist/scheduler/task-board.d.ts +44 -17
- package/dist/scheduler/task-board.js +95 -36
- package/dist/scheduler/task-board.js.map +1 -1
- package/dist/sd-notify.d.ts +13 -14
- package/dist/sd-notify.js +62 -28
- package/dist/sd-notify.js.map +1 -1
- package/dist/service-installer.d.ts +13 -0
- package/dist/service-installer.js +15 -0
- package/dist/service-installer.js.map +1 -1
- package/dist/service-owner.d.ts +25 -0
- package/dist/service-owner.js +43 -2
- package/dist/service-owner.js.map +1 -1
- package/dist/settings-api.d.ts +2 -1
- package/dist/settings-api.js +19 -26
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-change.js +10 -5
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-effect.js +7 -6
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-instance-patch.js +1 -1
- package/dist/settings-instance-patch.js.map +1 -1
- package/dist/setup-form.d.ts +2 -2
- package/dist/setup-form.js +139 -93
- package/dist/setup-form.js.map +1 -1
- package/dist/setup-i18n.d.ts +25 -0
- package/dist/setup-i18n.js +226 -0
- package/dist/setup-i18n.js.map +1 -0
- package/dist/task-board-waker.d.ts +40 -1
- package/dist/task-board-waker.js +115 -9
- package/dist/task-board-waker.js.map +1 -1
- package/dist/tmux-control.d.ts +1 -1
- package/dist/tmux-control.js +3 -2
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-manager.js +18 -16
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tmux-read.d.ts +2 -0
- package/dist/tmux-read.js +7 -1
- package/dist/tmux-read.js.map +1 -1
- package/dist/tool-permissions.js +18 -0
- package/dist/tool-permissions.js.map +1 -1
- package/dist/topic-commands.d.ts +2 -0
- package/dist/topic-commands.js +2 -1
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-sources.d.ts +1 -0
- package/dist/transcript-sources.js +20 -3
- package/dist/transcript-sources.js.map +1 -1
- package/dist/types.d.ts +11 -5
- package/dist/ui/backend-signin.js +4 -3
- package/dist/ui/chat-store.js +3 -2
- package/dist/ui/chat-strings.js +2 -2
- package/dist/ui/fleet-office-card.js +114 -0
- package/dist/ui/fleet-office-editor.js +81 -9
- package/dist/ui/fleet-office-layout.js +56 -11
- package/dist/ui/fleet-office-levels.js +105 -0
- package/dist/ui/fleet-office-model.js +9 -1
- package/dist/ui/fleet-office-pack.d.ts +15 -3
- package/dist/ui/fleet-office-pack.js +177 -23
- package/dist/ui/fleet-office-skin.js +39 -3
- package/dist/ui/fleet-office-store.js +74 -3
- package/dist/ui/fleet-office-view.js +8 -0
- package/dist/ui/fleet-office-zones.js +102 -19
- package/dist/ui/fleet-office.js +308 -44
- package/dist/ui/fleet-org.js +2 -0
- package/dist/ui/fleet-task-card.js +2 -2
- package/dist/ui/fleet-task-common.js +30 -7
- package/dist/ui/fleet-task-work.js +2 -2
- package/dist/ui/fleet-tasks.js +10 -11
- package/dist/ui/office-share-dialog.js +31 -7
- package/dist/ui/office-share-page.js +1 -0
- package/dist/ui/panel-chat.js +14 -2
- package/dist/ui/panel-log.js +6 -6
- package/dist/ui/panel-needs.js +1 -1
- package/dist/ui/panel-settings.js +16 -8
- package/dist/ui/settings-appearance.js +3 -35
- package/dist/ui/settings-discord.js +3 -2
- package/dist/ui/settings-guests.js +17 -7
- package/dist/ui/settings-model.js +17 -9
- package/dist/ui/settings-registry.js +1 -1
- package/dist/ui/settings-strings.js +18 -6
- package/dist/ui/settings-token.js +3 -2
- package/dist/ui/settings-wizard.js +25 -9
- package/dist/ui/shared/app-i18n.js +2 -2
- package/dist/ui/shared/app-stream.js +1 -1
- package/dist/ui/shared/app.css +70 -2
- package/dist/ui/shared/setup-host-text.js +107 -0
- package/dist/ui/structured-signin.js +89 -38
- package/dist/update-check.d.ts +13 -4
- package/dist/update-check.js +17 -4
- package/dist/update-check.js.map +1 -1
- package/dist/usage-rollup.d.ts +34 -3
- package/dist/usage-rollup.js +56 -3
- package/dist/usage-rollup.js.map +1 -1
- package/dist/web-api.d.ts +10 -1
- package/dist/web-api.js +207 -17
- package/dist/web-api.js.map +1 -1
- package/dist/web-auth.js +1 -1
- package/dist/web-auth.js.map +1 -1
- package/dist/web-experimental.d.ts +6 -2
- package/dist/web-experimental.js +8 -4
- package/dist/web-experimental.js.map +1 -1
- package/dist/web-office-acts.d.ts +5 -2
- package/dist/web-office-acts.js +9 -4
- package/dist/web-office-acts.js.map +1 -1
- package/dist/web-office-pack-read.d.ts +35 -0
- package/dist/web-office-pack-read.js +252 -0
- package/dist/web-office-pack-read.js.map +1 -0
- package/dist/web-office-pack-tools.d.ts +241 -0
- package/dist/web-office-pack-tools.js +785 -0
- package/dist/web-office-pack-tools.js.map +1 -0
- package/dist/web-office-skins.d.ts +68 -4
- package/dist/web-office-skins.js +324 -33
- package/dist/web-office-skins.js.map +1 -1
- package/dist/web-office-store.d.ts +47 -4
- package/dist/web-office-store.js +124 -23
- package/dist/web-office-store.js.map +1 -1
- package/dist/web-settings-patch.d.ts +3 -2
- package/dist/web-settings-patch.js +7 -5
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/workflow-templates/default.md +3 -3
- package/dist/working-recovery.d.ts +0 -2
- package/dist/working-recovery.js +2 -23
- package/dist/working-recovery.js.map +1 -1
- package/package.json +2 -2
- package/templates/windows-shortcuts.ps1 +18 -17
- package/dist/upgrade-notices.d.ts +0 -17
- package/dist/upgrade-notices.js +0 -93
- package/dist/upgrade-notices.js.map +0 -1
|
@@ -157,6 +157,10 @@ export interface ProjectStats {
|
|
|
157
157
|
/** A card as the dashboard draws it: references by card number. */
|
|
158
158
|
export interface CardView {
|
|
159
159
|
id: string;
|
|
160
|
+
/** #2080: in review needing the person's confirmation, or blocked on a question theirs (waitsForPerson): Waiting for you. */
|
|
161
|
+
waitsForPerson: boolean;
|
|
162
|
+
/** #2080: the instance that confirms it in review (its dispatcher, else its assignee); null when the person does. */
|
|
163
|
+
confirmer: string | null;
|
|
160
164
|
uuid: string;
|
|
161
165
|
kind: CardKind;
|
|
162
166
|
projectId: number | null;
|
|
@@ -218,13 +222,15 @@ export interface CardEvent {
|
|
|
218
222
|
}
|
|
219
223
|
/**
|
|
220
224
|
* Why an instance hears about one of its cards (step 2's wakes, task-board-waker.ts): someone else assigned it,
|
|
221
|
-
* started it, sent it back, answered its blocked question,
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
225
|
+
* started it, sent it back, answered its blocked question, or finished the last card it waited for; it is blocked and
|
|
226
|
+
* the instance handed it out (decide); it went to the person for confirmation and the instance handed it out, so it
|
|
227
|
+
* tells them (to_confirm); a main task went to the person by itself before its owner wrapped it up (wrap_up); or
|
|
228
|
+
* someone else cancelled it — a main task's cancel takes its unfinished sub tasks down with it, and their assignees
|
|
229
|
+
* hear (cancelled). #2801: only a change of status or assignee is news, and only to the one instance that acts on it
|
|
230
|
+
* next — a comment, and a confirmation (the work is finished), wake nobody; but for the answer to its blocked question
|
|
231
|
+
* that waits on the card while its assignee is busy with another (#2303), which it acts on next (answer_kept).
|
|
226
232
|
*/
|
|
227
|
-
export type WakeReason = "assigned" | "start" | "sent_back" | "answered" | "
|
|
233
|
+
export type WakeReason = "assigned" | "start" | "sent_back" | "answered" | "answer_kept" | "ready" | "decide" | "to_confirm" | "confirm_own" | "wrap_up" | "cancelled";
|
|
228
234
|
/** One card's news for one instance from one committed write. Never sent to a page (it carries titles and text). */
|
|
229
235
|
export interface Wake {
|
|
230
236
|
instance: string;
|
|
@@ -248,6 +254,8 @@ export interface BoardChange {
|
|
|
248
254
|
projects: boolean;
|
|
249
255
|
/** Whom to wake about what (the fleet's waker); a page is sent the rest. */
|
|
250
256
|
wakes: Wake[];
|
|
257
|
+
/** #2801: the cards whose status or assignee this write changed (an older notice about them no longer stands). */
|
|
258
|
+
changed: string[];
|
|
251
259
|
}
|
|
252
260
|
export interface CardDetail {
|
|
253
261
|
card: CardView;
|
|
@@ -371,6 +379,11 @@ export interface SearchHit {
|
|
|
371
379
|
export declare const personConfirms: (card: Pick<Card, "dispatcher">) => boolean;
|
|
372
380
|
/** Who that is, in words (an error, the card's text). */
|
|
373
381
|
export declare function confirmerOf(card: Pick<Card, "dispatcher" | "assignee">): string;
|
|
382
|
+
/**
|
|
383
|
+
* #2080: the instance that confirms a card in review (`confirms`' rule), or null when it is the person's — handed out by
|
|
384
|
+
* them, or by an instance deleted since (`gone`), or nobody's at all.
|
|
385
|
+
*/
|
|
386
|
+
export declare function confirmingInstance(card: Pick<Card, "dispatcher" | "assignee" | "createdBy">, gone?: GoneDispatcher): string | null;
|
|
374
387
|
/** "m3", "M - 3" → "M-3"; null when it is not a card number. */
|
|
375
388
|
export declare function cardCode(raw: string): string | null;
|
|
376
389
|
/**
|
|
@@ -438,6 +451,8 @@ export declare class TaskBoard {
|
|
|
438
451
|
private checkProjectName;
|
|
439
452
|
/** A new main task's project: the one asked for (not archived), or none. */
|
|
440
453
|
private projectForMain;
|
|
454
|
+
/** #2801: when the card's status or assignee last changed (ISO), or null — a notice older than that is stale. */
|
|
455
|
+
lastChangeAt(uuid: string): string | null;
|
|
441
456
|
/** A card by number (M-3), uuid, or a unique uuid prefix of at least 8 hex digits. */
|
|
442
457
|
findCard(ref: string): Card | undefined;
|
|
443
458
|
getCard(ref: string): Card;
|
|
@@ -462,10 +477,11 @@ export declare class TaskBoard {
|
|
|
462
477
|
/**
|
|
463
478
|
* Each project's numbers (by id; "none" for No project) over all its cards, finished ones included: main tasks,
|
|
464
479
|
* work units (a main task's sub tasks, or one unit for a main task without them; a done main task counts all its
|
|
465
|
-
* units done), cards waiting for the person and blocked, and the last change. One pass over the table.
|
|
480
|
+
* units done), cards waiting for the person and blocked, and the last change. One pass over the table. #2080: waiting
|
|
481
|
+
* counts only the cards in review the person confirms (waitsForPerson, `gone` as for Needs you), never an agent's.
|
|
466
482
|
*/
|
|
467
|
-
projectStats(): Record<string, ProjectStats>;
|
|
468
|
-
view(card: Card, scope?: ReadScope): CardView;
|
|
483
|
+
projectStats(gone?: GoneDispatcher): Record<string, ProjectStats>;
|
|
484
|
+
view(card: Card, scope?: ReadScope, gone?: GoneDispatcher): CardView;
|
|
469
485
|
/** ` AND <column> NOT IN (…)` for a scope's left-out authors, with its values (empty when none). */
|
|
470
486
|
private notBy;
|
|
471
487
|
/**
|
|
@@ -474,8 +490,13 @@ export declare class TaskBoard {
|
|
|
474
490
|
* queries per card: a board read stays a handful of statements however many cards it has (it runs on the fleet's
|
|
475
491
|
* event loop). Same answers as progress(), unmetDeps() and newComments() card by card.
|
|
476
492
|
*/
|
|
477
|
-
views(cards: Card[], scope?: ReadScope): CardView[];
|
|
478
|
-
detail(ref: string, scope?: ReadScope): CardDetail;
|
|
493
|
+
views(cards: Card[], scope?: ReadScope, gone?: GoneDispatcher): CardView[];
|
|
494
|
+
detail(ref: string, scope?: ReadScope, gone?: GoneDispatcher): CardDetail;
|
|
495
|
+
/**
|
|
496
|
+
* #2757 review: the instance dispatchers on the board that `gone` says are gone, as one string — what a cached read
|
|
497
|
+
* that names waitsForPerson / confirmer must also be keyed by (a dispatcher deleted changes them, the revision not).
|
|
498
|
+
*/
|
|
499
|
+
goneDispatchers(gone?: GoneDispatcher): string;
|
|
479
500
|
/** The latest `limit` entries of a card, oldest first. */
|
|
480
501
|
entries(uuid: string, kinds: EntryKind[], limit?: number): Entry[];
|
|
481
502
|
/** Comments and rejections by others that the assignee has not acted on yet. */
|
|
@@ -615,6 +636,13 @@ export declare class TaskBoard {
|
|
|
615
636
|
result?: string;
|
|
616
637
|
priority?: CardPriority;
|
|
617
638
|
}): Card;
|
|
639
|
+
/**
|
|
640
|
+
* #2080: review for an instance's own confirmation is done. An instance moving a card to review that it confirms itself
|
|
641
|
+
* (nobody else handed it out, or it handed it to itself) would wait for nobody but itself — and sat there unnoticed,
|
|
642
|
+
* in the person's Waiting for you too: it finishes instead (the checks for review are the ones for done). A person's
|
|
643
|
+
* move, and a card someone else confirms, stay as asked.
|
|
644
|
+
*/
|
|
645
|
+
private ownReview;
|
|
618
646
|
/**
|
|
619
647
|
* Cards moved by hand: sub tasks, and main tasks that have no sub tasks. `comment` is the move's own comment (a
|
|
620
648
|
* dispatcher's answer); `finishing`: a claim on the way to done (the `task` tool's done of an open card).
|
|
@@ -688,12 +716,11 @@ export declare class TaskBoard {
|
|
|
688
716
|
private wakeReady;
|
|
689
717
|
/**
|
|
690
718
|
* What of a wake still stands now (at the end of its write, and again when the fleet sends it): a finished card is
|
|
691
|
-
* news only as a
|
|
692
|
-
*
|
|
693
|
-
*
|
|
694
|
-
*
|
|
695
|
-
*
|
|
696
|
-
* read it (its own write since showed it, as the `task` tool's answer). null when nothing is left.
|
|
719
|
+
* news only as a cancel; a card that is no longer the instance's is not; a question only while the card is blocked
|
|
720
|
+
* and the instance still handed it out; a wrap-up only while it waits unfinished; and an assignment only once the
|
|
721
|
+
* card can start (its "ready" wakes it then). What asks the instance to act holds only while it still can (#2303
|
|
722
|
+
* review): "ready" while the card is open with nothing left to wait for, "start" and "answered" while it is in
|
|
723
|
+
* progress, "sent back" while it is back with the instance. null when nothing is left.
|
|
697
724
|
*/
|
|
698
725
|
wakeHolds(wake: Wake): Wake | null;
|
|
699
726
|
/**
|
|
@@ -120,6 +120,17 @@ export function confirmerOf(card) {
|
|
|
120
120
|
return card.dispatcher.name;
|
|
121
121
|
return card.assignee ?? "its assignee";
|
|
122
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* #2080: the instance that confirms a card in review (`confirms`' rule), or null when it is the person's — handed out by
|
|
125
|
+
* them, or by an instance deleted since (`gone`), or nobody's at all.
|
|
126
|
+
*/
|
|
127
|
+
export function confirmingInstance(card, gone) {
|
|
128
|
+
if (personConfirms(card) || orphaned(card, gone))
|
|
129
|
+
return null;
|
|
130
|
+
if (card.dispatcher?.kind === "instance")
|
|
131
|
+
return card.dispatcher.name;
|
|
132
|
+
return card.assignee ?? (card.createdBy || null);
|
|
133
|
+
}
|
|
123
134
|
function normalizeAssignee(raw) {
|
|
124
135
|
const v = raw?.trim() ?? "";
|
|
125
136
|
if (v === "" || v.toLowerCase() === "none")
|
|
@@ -436,6 +447,11 @@ export class TaskBoard {
|
|
|
436
447
|
return project.id;
|
|
437
448
|
}
|
|
438
449
|
// ── Reading ─────────────────────────────────────────────
|
|
450
|
+
/** #2801: when the card's status or assignee last changed (ISO), or null — a notice older than that is stale. */
|
|
451
|
+
lastChangeAt(uuid) {
|
|
452
|
+
const r = this.db.prepare("SELECT MAX(at) AS at FROM task_events WHERE task_id = ? AND type IN ('created', 'moved', 'assigned')").get(uuid);
|
|
453
|
+
return r?.at ?? null;
|
|
454
|
+
}
|
|
439
455
|
/** A card by number (M-3), uuid, or a unique uuid prefix of at least 8 hex digits. */
|
|
440
456
|
findCard(ref) {
|
|
441
457
|
const text = (ref ?? "").trim();
|
|
@@ -518,10 +534,11 @@ export class TaskBoard {
|
|
|
518
534
|
/**
|
|
519
535
|
* Each project's numbers (by id; "none" for No project) over all its cards, finished ones included: main tasks,
|
|
520
536
|
* work units (a main task's sub tasks, or one unit for a main task without them; a done main task counts all its
|
|
521
|
-
* units done), cards waiting for the person and blocked, and the last change. One pass over the table.
|
|
537
|
+
* units done), cards waiting for the person and blocked, and the last change. One pass over the table. #2080: waiting
|
|
538
|
+
* counts only the cards in review the person confirms (waitsForPerson, `gone` as for Needs you), never an agent's.
|
|
522
539
|
*/
|
|
523
|
-
projectStats() {
|
|
524
|
-
const rows = this.db.prepare("SELECT id, kind, status, project_id, parent_id, updated_at FROM tasks").all();
|
|
540
|
+
projectStats(gone) {
|
|
541
|
+
const rows = this.db.prepare("SELECT id, kind, status, project_id, parent_id, updated_at, needs_review, dispatcher, dispatcher_kind FROM tasks").all();
|
|
525
542
|
const subs = new Map();
|
|
526
543
|
for (const r of rows) {
|
|
527
544
|
if (r.kind !== "sub" || !r.parent_id || r.status === "cancelled")
|
|
@@ -540,7 +557,8 @@ export class TaskBoard {
|
|
|
540
557
|
const status = r.status;
|
|
541
558
|
if (status === "cancelled")
|
|
542
559
|
continue;
|
|
543
|
-
if (status === "review")
|
|
560
|
+
if (status === "review" && waitsForPerson({ status, needsReview: Number(r.needs_review) === 1,
|
|
561
|
+
dispatcher: r.dispatcher ? { kind: r.dispatcher_kind === "person" ? "person" : "instance", name: r.dispatcher } : null }, gone))
|
|
544
562
|
st.waiting++;
|
|
545
563
|
if (status === "blocked")
|
|
546
564
|
st.blocked++;
|
|
@@ -565,8 +583,8 @@ export class TaskBoard {
|
|
|
565
583
|
st.percent = st.units.total ? Math.round((st.units.done / st.units.total) * 100) : 0;
|
|
566
584
|
return out;
|
|
567
585
|
}
|
|
568
|
-
view(card, scope = {}) {
|
|
569
|
-
return this.views([card], scope)[0];
|
|
586
|
+
view(card, scope = {}, gone) {
|
|
587
|
+
return this.views([card], scope, gone)[0];
|
|
570
588
|
}
|
|
571
589
|
/** ` AND <column> NOT IN (…)` for a scope's left-out authors, with its values (empty when none). */
|
|
572
590
|
notBy(scope, column) {
|
|
@@ -579,7 +597,7 @@ export class TaskBoard {
|
|
|
579
597
|
* queries per card: a board read stays a handful of statements however many cards it has (it runs on the fleet's
|
|
580
598
|
* event loop). Same answers as progress(), unmetDeps() and newComments() card by card.
|
|
581
599
|
*/
|
|
582
|
-
views(cards, scope = {}) {
|
|
600
|
+
views(cards, scope = {}, gone) {
|
|
583
601
|
if (!cards.length)
|
|
584
602
|
return [];
|
|
585
603
|
const all = new Map();
|
|
@@ -618,6 +636,8 @@ export class TaskBoard {
|
|
|
618
636
|
const c = comments.get(card.uuid);
|
|
619
637
|
return {
|
|
620
638
|
id: card.code,
|
|
639
|
+
waitsForPerson: waitsForPerson(card, gone),
|
|
640
|
+
confirmer: confirmingInstance(card, gone),
|
|
621
641
|
uuid: card.uuid,
|
|
622
642
|
kind: card.kind,
|
|
623
643
|
projectId: card.projectId,
|
|
@@ -653,18 +673,28 @@ export class TaskBoard {
|
|
|
653
673
|
};
|
|
654
674
|
});
|
|
655
675
|
}
|
|
656
|
-
detail(ref, scope = {}) {
|
|
676
|
+
detail(ref, scope = {}, gone) {
|
|
657
677
|
const card = this.getCard(ref);
|
|
658
678
|
const parent = card.parent ? this.byUuid(card.parent) : undefined;
|
|
659
679
|
return {
|
|
660
|
-
card: this.view(card, scope),
|
|
680
|
+
card: this.view(card, scope, gone),
|
|
661
681
|
parent: parent ? { id: parent.code, title: parent.title, status: parent.status } : null,
|
|
662
|
-
children: this.views(this.children(card.uuid), scope),
|
|
682
|
+
children: this.views(this.children(card.uuid), scope, gone),
|
|
663
683
|
comments: this.entries(card.uuid, ["comment", "reject", "approve"], 200),
|
|
664
684
|
logs: this.entries(card.uuid, ["log"], 200),
|
|
665
685
|
history: this.events(card.uuid, 200).filter((e) => e.type !== "reordered"),
|
|
666
686
|
};
|
|
667
687
|
}
|
|
688
|
+
/**
|
|
689
|
+
* #2757 review: the instance dispatchers on the board that `gone` says are gone, as one string — what a cached read
|
|
690
|
+
* that names waitsForPerson / confirmer must also be keyed by (a dispatcher deleted changes them, the revision not).
|
|
691
|
+
*/
|
|
692
|
+
goneDispatchers(gone) {
|
|
693
|
+
if (!gone)
|
|
694
|
+
return "";
|
|
695
|
+
const rows = this.db.prepare("SELECT DISTINCT dispatcher FROM tasks WHERE dispatcher IS NOT NULL AND (dispatcher_kind IS NULL OR dispatcher_kind != 'person')").all();
|
|
696
|
+
return rows.map((r) => r.dispatcher).filter((n) => gone(n)).sort().join("\u0000");
|
|
697
|
+
}
|
|
668
698
|
/** The latest `limit` entries of a card, oldest first. */
|
|
669
699
|
entries(uuid, kinds, limit = 20) {
|
|
670
700
|
const rows = this.db.prepare(`SELECT * FROM task_entries WHERE task_id = ? AND kind IN (${kinds.map(() => "?").join(", ")}) ORDER BY id DESC LIMIT ?`)
|
|
@@ -1236,7 +1266,8 @@ export class TaskBoard {
|
|
|
1236
1266
|
if (busy.length) {
|
|
1237
1267
|
const text = checkText("the comment", comment, CARD_LIMITS.comment);
|
|
1238
1268
|
this.entry(card, "comment", actor, text);
|
|
1239
|
-
|
|
1269
|
+
// #2801 review: the one comment that is news — the answer its assignee waits for (`kept`).
|
|
1270
|
+
this.event(actor, card, "commented", { text, kept: true });
|
|
1240
1271
|
card.version++;
|
|
1241
1272
|
card.updatedAt = this.nowIso();
|
|
1242
1273
|
this.save(card);
|
|
@@ -1249,7 +1280,7 @@ export class TaskBoard {
|
|
|
1249
1280
|
this.checkDerivedMove(card, actor, to, reason, { comment });
|
|
1250
1281
|
else
|
|
1251
1282
|
this.checkManualMove(card, actor, to, reason, { comment });
|
|
1252
|
-
this.applyMove(card, actor, to, reason, comment);
|
|
1283
|
+
this.applyMove(card, actor, this.ownReview(card, actor, to, reason), reason, comment);
|
|
1253
1284
|
return { card, from, ...this.spoken() };
|
|
1254
1285
|
});
|
|
1255
1286
|
}
|
|
@@ -1429,6 +1460,8 @@ export class TaskBoard {
|
|
|
1429
1460
|
if (held && to !== card.status)
|
|
1430
1461
|
this.checkManualMove(card, actor, to, "");
|
|
1431
1462
|
}
|
|
1463
|
+
// #2757 review: a derived main task too; a card off the board (not held) keeps the tool's old, unchecked finish.
|
|
1464
|
+
to = this.ownReview(card, actor, to, "", held);
|
|
1432
1465
|
}
|
|
1433
1466
|
if (to !== card.status) {
|
|
1434
1467
|
this.applyMove(card, actor, to, "");
|
|
@@ -1447,6 +1480,21 @@ export class TaskBoard {
|
|
|
1447
1480
|
});
|
|
1448
1481
|
}
|
|
1449
1482
|
// ── Rules ───────────────────────────────────────────────
|
|
1483
|
+
/**
|
|
1484
|
+
* #2080: review for an instance's own confirmation is done. An instance moving a card to review that it confirms itself
|
|
1485
|
+
* (nobody else handed it out, or it handed it to itself) would wait for nobody but itself — and sat there unnoticed,
|
|
1486
|
+
* in the person's Waiting for you too: it finishes instead (the checks for review are the ones for done). A person's
|
|
1487
|
+
* move, and a card someone else confirms, stay as asked.
|
|
1488
|
+
*/
|
|
1489
|
+
ownReview(card, actor, to, reason = "", check = true) {
|
|
1490
|
+
if (to !== "review" || isPerson(actor) || card.status === "review" || !confirms(card, actor))
|
|
1491
|
+
return to;
|
|
1492
|
+
// #2757 review: finished as done is, whichever way it came (a derived main task's review checks less).
|
|
1493
|
+
if (check)
|
|
1494
|
+
this.checkFinish(card, true, reason);
|
|
1495
|
+
this.say("own_review", [card.code], `${card.code} waits for nobody else's confirmation (you confirm it): done, not review`);
|
|
1496
|
+
return "done";
|
|
1497
|
+
}
|
|
1450
1498
|
/**
|
|
1451
1499
|
* Cards moved by hand: sub tasks, and main tasks that have no sub tasks. `comment` is the move's own comment (a
|
|
1452
1500
|
* dispatcher's answer); `finishing`: a claim on the way to done (the `task` tool's done of an open card).
|
|
@@ -1628,6 +1676,13 @@ export class TaskBoard {
|
|
|
1628
1676
|
return;
|
|
1629
1677
|
}
|
|
1630
1678
|
if (ai) {
|
|
1679
|
+
// #2080: a main task in review by itself (its sub tasks done) is finished by the instance that confirms it.
|
|
1680
|
+
if (from === "review" && to === "done" && confirms(card, actor)) {
|
|
1681
|
+
if (reason)
|
|
1682
|
+
this.entry(card, "approve", actor, reason);
|
|
1683
|
+
this.checkFinish(card, ai, reason);
|
|
1684
|
+
return;
|
|
1685
|
+
}
|
|
1631
1686
|
if (from === "claimed" && to === "review") {
|
|
1632
1687
|
if (!own)
|
|
1633
1688
|
throw notOwner();
|
|
@@ -1886,10 +1941,16 @@ export class TaskBoard {
|
|
|
1886
1941
|
w.by[reason] = by.name;
|
|
1887
1942
|
out.set(key, w);
|
|
1888
1943
|
};
|
|
1944
|
+
// The answer to a blocked question is the comment that came with it (#2801: a comment alone wakes nobody).
|
|
1889
1945
|
const comments = new Map();
|
|
1890
1946
|
for (const e of events)
|
|
1891
1947
|
if (e.type === "commented")
|
|
1892
1948
|
comments.set(e.uuid, String(e.data.text ?? ""));
|
|
1949
|
+
for (const e of events) {
|
|
1950
|
+
const card = e.type === "commented" && e.data.kept === true ? this.byUuid(e.uuid) : undefined;
|
|
1951
|
+
if (card)
|
|
1952
|
+
add(card, card.assignee, "answer_kept", e.actor, String(e.data.text ?? ""));
|
|
1953
|
+
}
|
|
1893
1954
|
for (const e of events) {
|
|
1894
1955
|
const card = this.byUuid(e.uuid);
|
|
1895
1956
|
if (!card)
|
|
@@ -1905,8 +1966,6 @@ export class TaskBoard {
|
|
|
1905
1966
|
if (this.isOnBoard(card))
|
|
1906
1967
|
add(card, d.to ?? null, "assigned", e.actor);
|
|
1907
1968
|
}
|
|
1908
|
-
else if (e.type === "commented")
|
|
1909
|
-
add(card, card.assignee, "comment", e.actor, d.text);
|
|
1910
1969
|
else if (e.type === "moved") {
|
|
1911
1970
|
if (d.to === "done")
|
|
1912
1971
|
this.wakeReady(card, e.actor, add);
|
|
@@ -1919,10 +1978,16 @@ export class TaskBoard {
|
|
|
1919
1978
|
}
|
|
1920
1979
|
// An agent's card waits for its instance dispatcher to confirm it (#2434: its own to confirm, nobody to ask). A
|
|
1921
1980
|
// person's card has no instance dispatcher, so no notice: the person has it in Needs you.
|
|
1922
|
-
|
|
1923
|
-
|
|
1981
|
+
const toConfirm = d.to === "review" && !isPerson(e.actor) && requiresReview(card) ? dispatcherOf() : null;
|
|
1982
|
+
if (toConfirm)
|
|
1983
|
+
add(card, toConfirm, "to_confirm", e.actor);
|
|
1984
|
+
// #2080: a card its own assignee confirms, in review by itself (its sub tasks done) or by someone else's move:
|
|
1985
|
+
// nobody else will confirm it, so its assignee is told it is theirs.
|
|
1986
|
+
if (d.to === "review" && card.assignee && confirmingInstance(card) === card.assignee)
|
|
1987
|
+
add(card, card.assignee, "confirm_own", e.actor);
|
|
1924
1988
|
if (d.auto) {
|
|
1925
|
-
|
|
1989
|
+
// #2801: one change, one instance — the dispatcher's confirmation already says what it lacks.
|
|
1990
|
+
if (d.to === "review" && card.kind === "main" && wrapUpGap(card) && !toConfirm)
|
|
1926
1991
|
add(card, card.assignee, "wrap_up", e.actor);
|
|
1927
1992
|
continue;
|
|
1928
1993
|
}
|
|
@@ -1932,10 +1997,6 @@ export class TaskBoard {
|
|
|
1932
1997
|
add(card, card.assignee, "answered", e.actor, comments.get(card.uuid));
|
|
1933
1998
|
else if (d.from === "review" && (d.to === "claimed" || d.to === "open"))
|
|
1934
1999
|
add(card, card.assignee, "sent_back", e.actor, d.reason);
|
|
1935
|
-
else if (d.from === "review" && d.to === "done") {
|
|
1936
|
-
add(card, card.assignee, "approved", e.actor, d.reason);
|
|
1937
|
-
add(card, dispatcherOf(), "approved", e.actor, d.reason);
|
|
1938
|
-
}
|
|
1939
2000
|
if (d.to === "blocked" && !isPerson(e.actor))
|
|
1940
2001
|
add(card, dispatcherOf(), "decide", e.actor, d.reason);
|
|
1941
2002
|
}
|
|
@@ -1952,12 +2013,11 @@ export class TaskBoard {
|
|
|
1952
2013
|
}
|
|
1953
2014
|
/**
|
|
1954
2015
|
* What of a wake still stands now (at the end of its write, and again when the fleet sends it): a finished card is
|
|
1955
|
-
* news only as a
|
|
1956
|
-
*
|
|
1957
|
-
*
|
|
1958
|
-
*
|
|
1959
|
-
*
|
|
1960
|
-
* read it (its own write since showed it, as the `task` tool's answer). null when nothing is left.
|
|
2016
|
+
* news only as a cancel; a card that is no longer the instance's is not; a question only while the card is blocked
|
|
2017
|
+
* and the instance still handed it out; a wrap-up only while it waits unfinished; and an assignment only once the
|
|
2018
|
+
* card can start (its "ready" wakes it then). What asks the instance to act holds only while it still can (#2303
|
|
2019
|
+
* review): "ready" while the card is open with nothing left to wait for, "start" and "answered" while it is in
|
|
2020
|
+
* progress, "sent back" while it is back with the instance. null when nothing is left.
|
|
1961
2021
|
*/
|
|
1962
2022
|
wakeHolds(wake) {
|
|
1963
2023
|
const card = this.byUuid(wake.uuid);
|
|
@@ -1967,8 +2027,6 @@ export class TaskBoard {
|
|
|
1967
2027
|
const own = card.assignee === wake.instance;
|
|
1968
2028
|
const waiting = this.unmetDeps(card).length > 0;
|
|
1969
2029
|
let reasons = wake.reasons.filter((r) => {
|
|
1970
|
-
if (r === "approved")
|
|
1971
|
-
return card.status === "done" && (own || handedOut);
|
|
1972
2030
|
if (r === "cancelled")
|
|
1973
2031
|
return card.status === "cancelled" && own;
|
|
1974
2032
|
if (isFinished(card))
|
|
@@ -1980,25 +2038,25 @@ export class TaskBoard {
|
|
|
1980
2038
|
return handedOut && card.status === "review" && requiresReview(card);
|
|
1981
2039
|
if (!own)
|
|
1982
2040
|
return false;
|
|
2041
|
+
if (r === "confirm_own")
|
|
2042
|
+
return card.status === "review" && confirmingInstance(card) === wake.instance;
|
|
1983
2043
|
if (r === "wrap_up")
|
|
1984
2044
|
return card.status === "review" && wrapUpGap(card) !== null;
|
|
1985
2045
|
if (r === "assigned")
|
|
1986
2046
|
return !waiting;
|
|
1987
|
-
if (r === "comment")
|
|
1988
|
-
return !waiting && this.newComments(card).length > 0;
|
|
1989
2047
|
if (r === "ready")
|
|
1990
2048
|
return card.status === "open" && !waiting;
|
|
1991
2049
|
if (r === "start" || r === "answered")
|
|
1992
2050
|
return card.status === "claimed";
|
|
2051
|
+
if (r === "answer_kept")
|
|
2052
|
+
return card.status === "blocked";
|
|
1993
2053
|
if (r === "sent_back")
|
|
1994
2054
|
return card.status === "claimed" || card.status === "open";
|
|
1995
2055
|
return true;
|
|
1996
2056
|
});
|
|
1997
|
-
// One piece of news says it all:
|
|
1998
|
-
if (reasons.includes("answered"))
|
|
1999
|
-
reasons = reasons.filter((r) => r !== "comment");
|
|
2057
|
+
// One piece of news says it all: a send-back outweighs the rest.
|
|
2000
2058
|
if (reasons.includes("sent_back"))
|
|
2001
|
-
reasons = reasons.filter((r) => r !== "
|
|
2059
|
+
reasons = reasons.filter((r) => r !== "start");
|
|
2002
2060
|
if (reasons.includes("assigned"))
|
|
2003
2061
|
reasons = reasons.filter((r) => r !== "start" && r !== "ready");
|
|
2004
2062
|
if (reasons.includes("cancelled"))
|
|
@@ -2032,7 +2090,8 @@ export class TaskBoard {
|
|
|
2032
2090
|
const touched = this.pending;
|
|
2033
2091
|
const projects = this.projectsChanged;
|
|
2034
2092
|
if (touched.length || projects) {
|
|
2035
|
-
const
|
|
2093
|
+
const changed = [...new Set(touched.filter((e) => e.type === "moved" || e.type === "assigned").map((e) => e.uuid))];
|
|
2094
|
+
const change = { rev: this.revision(), ids: [...new Set(touched.map((e) => e.code))], actors: [...new Set(touched.map((e) => e.actor.name))], projects, wakes, changed };
|
|
2036
2095
|
for (const listener of this.listeners) {
|
|
2037
2096
|
try {
|
|
2038
2097
|
listener(change);
|