@songsid/agend 2.3.0-beta.25 → 2.3.0-beta.27
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 +7 -5
- package/README.zh-TW.md +7 -5
- package/dist/adapter-world.js.map +1 -1
- package/dist/agend-home.d.ts +5 -0
- package/dist/agend-home.js +7 -0
- package/dist/agend-home.js.map +1 -0
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.js +8 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/agent-file-read.js +1 -1
- package/dist/agent-file-read.js.map +1 -1
- package/dist/agent-whats-new.js +12 -2
- package/dist/agent-whats-new.js.map +1 -1
- package/dist/apply-job.js.map +1 -1
- package/dist/atomic-write.js.map +1 -1
- package/dist/auth-api.d.ts +5 -0
- package/dist/auth-api.js +21 -0
- package/dist/auth-api.js.map +1 -1
- package/dist/authority/authority-state.d.ts +4 -0
- package/dist/authority/authority-state.js +17 -8
- package/dist/authority/authority-state.js.map +1 -1
- package/dist/authority/session-authorizations.js.map +1 -1
- package/dist/authority/web-authority.d.ts +14 -6
- package/dist/authority/web-authority.js +19 -5
- package/dist/authority/web-authority.js.map +1 -1
- package/dist/backend/antigravity.d.ts +2 -2
- package/dist/backend/antigravity.js +2 -1
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex-package.js.map +1 -1
- package/dist/backend/codex-session-lookup.js.map +1 -1
- package/dist/backend/codex.js +1 -1
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/effort-metadata.js.map +1 -1
- package/dist/backend/grok.js.map +1 -1
- package/dist/backend/kiro-engine-ledger.js.map +1 -1
- package/dist/backend/kiro-kas-store.js.map +1 -1
- package/dist/backend/kiro-v2-store.js.map +1 -1
- package/dist/backend/kiro-v3-identity.js.map +1 -1
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/launch-effort.js.map +1 -1
- package/dist/backend/mock.js.map +1 -1
- package/dist/backend/muse.js.map +1 -1
- package/dist/backend/opencode-permission.js.map +1 -1
- package/dist/backend/opencode.js.map +1 -1
- package/dist/backend/session-signals.js.map +1 -1
- package/dist/backend-availability.js.map +1 -1
- package/dist/backend-command.js.map +1 -1
- package/dist/backend-outage.js.map +1 -1
- package/dist/binary-probe.js.map +1 -1
- package/dist/bug-report.js.map +1 -1
- package/dist/bundled-skills.js.map +1 -1
- package/dist/cache-service.js +1 -1
- package/dist/cache-service.js.map +1 -1
- package/dist/channel/adapters/discord.d.ts +2 -0
- package/dist/channel/adapters/discord.js +40 -5
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +6 -0
- package/dist/channel/adapters/telegram.js +54 -14
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/mcp-server.js +10 -1
- package/dist/channel/mcp-server.js.map +1 -1
- package/dist/channel/mcp-tools.js +2 -2
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/message-queue.js.map +1 -1
- package/dist/channel/sticker-download.js.map +1 -1
- package/dist/channel/tool-router.js.map +1 -1
- package/dist/classic-channel-manager.js +3 -2
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli-entry.js.map +1 -1
- package/dist/cli-flags.js.map +1 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +44 -9
- package/dist/cli.js.map +1 -1
- package/dist/command-table.js.map +1 -1
- package/dist/compact-watch.js.map +1 -1
- package/dist/completion-install.js.map +1 -1
- package/dist/completion.js.map +1 -1
- package/dist/config-validator.js +22 -6
- package/dist/config-validator.js.map +1 -1
- package/dist/config.js +8 -2
- package/dist/config.js.map +1 -1
- package/dist/connection-secrets.js.map +1 -1
- package/dist/context-guardian.js.map +1 -1
- package/dist/coredump-filter.js.map +1 -1
- package/dist/cpu-profile.js.map +1 -1
- package/dist/cross-instance-envelope.js.map +1 -1
- package/dist/daemon.d.ts +3 -0
- package/dist/daemon.js +76 -4
- package/dist/daemon.js.map +1 -1
- package/dist/daily-summary.js.map +1 -1
- package/dist/darwin-memory.js.map +1 -1
- package/dist/dashboard-live.d.ts +8 -0
- package/dist/dashboard-live.js +35 -0
- package/dist/dashboard-live.js.map +1 -0
- package/dist/dashboard-permissions.d.ts +69 -0
- package/dist/dashboard-permissions.js +138 -0
- package/dist/dashboard-permissions.js.map +1 -0
- package/dist/decision-list.js.map +1 -1
- package/dist/delivery-consumed-watch.js.map +1 -1
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/delivery-outbox.test.js.map +1 -1
- package/dist/delivery-reconciliation.test.js.map +1 -1
- package/dist/diagnostic-redaction.js.map +1 -1
- package/dist/doctor.d.ts +3 -0
- package/dist/doctor.js +10 -0
- package/dist/doctor.js.map +1 -1
- package/dist/e2e-isolation.js.map +1 -1
- package/dist/event-log.js.map +1 -1
- package/dist/export-import.js +3 -2
- package/dist/export-import.js.map +1 -1
- package/dist/fleet-control-audit.js.map +1 -1
- package/dist/fleet-label.js.map +1 -1
- package/dist/fleet-lock.js +3 -2
- package/dist/fleet-lock.js.map +1 -1
- package/dist/fleet-manager.d.ts +84 -7
- package/dist/fleet-manager.js +562 -158
- package/dist/fleet-manager.js.map +1 -1
- package/dist/fleet-process-handlers.js +3 -2
- package/dist/fleet-process-handlers.js.map +1 -1
- package/dist/fleet-startup.d.ts +14 -0
- package/dist/fleet-startup.js +30 -0
- package/dist/fleet-startup.js.map +1 -0
- package/dist/fleet-traffic.js.map +1 -1
- package/dist/forged-envelope-scan.d.ts +0 -20
- package/dist/forged-envelope-scan.js +3 -2
- package/dist/forged-envelope-scan.js.map +1 -1
- package/dist/full-restart.js.map +1 -1
- package/dist/general-knowledge/skills/web-appearance/SKILL.canvas-worker-off.md +2 -0
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +2 -0
- package/dist/general-knowledge/skills/web-dashboard/SKILL.canvas-worker-off.md +43 -21
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +52 -23
- package/dist/host-memory.js.map +1 -1
- package/dist/idle-gate-log.d.ts +19 -0
- package/dist/idle-gate-log.js +15 -0
- package/dist/idle-gate-log.js.map +1 -0
- package/dist/instance-config-impact.js +6 -0
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.js +1 -1
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instructions.d.ts +2 -0
- package/dist/instructions.js +6 -2
- package/dist/instructions.js.map +1 -1
- package/dist/kiro-compact-pane.js.map +1 -1
- package/dist/kiro-db-reader.js.map +1 -1
- package/dist/kiro-engine-status.js.map +1 -1
- package/dist/kiro-log-gate.js.map +1 -1
- package/dist/kiro-transcript-lane.js.map +1 -1
- package/dist/locale.js +40 -6
- package/dist/locale.js.map +1 -1
- package/dist/log-service.js.map +1 -1
- package/dist/log-steps.js.map +1 -1
- package/dist/logger.js +3 -2
- package/dist/logger.js.map +1 -1
- package/dist/login-controller.js.map +1 -1
- package/dist/login-manager.js.map +1 -1
- package/dist/login-shell.js.map +1 -1
- package/dist/memory-pressure.js.map +1 -1
- package/dist/muse-usage-relay.js.map +1 -1
- package/dist/needs-you-hub.js.map +1 -1
- package/dist/needs-you-live.js.map +1 -1
- package/dist/network-family.js.map +1 -1
- package/dist/operator-control-paths.js +3 -4
- package/dist/operator-control-paths.js.map +1 -1
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +68 -68
- package/dist/outbound-schemas.js +1 -1
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/outbox-open-error.js.map +1 -1
- package/dist/pane-context-cache.js.map +1 -1
- package/dist/paths.js.map +1 -1
- package/dist/private-dir.js.map +1 -1
- package/dist/probe-worker-pool.js.map +1 -1
- package/dist/profile-control.js.map +1 -1
- package/dist/prompt-file-ref.js.map +1 -1
- package/dist/provider-probe.js.map +1 -1
- package/dist/provider-secret-registry.js.map +1 -1
- package/dist/public-link-auto-open.d.ts +32 -0
- package/dist/public-link-auto-open.js +86 -0
- package/dist/public-link-auto-open.js.map +1 -0
- package/dist/public-link-owner.d.ts +10 -0
- package/dist/public-link-owner.js +36 -0
- package/dist/public-link-owner.js.map +1 -0
- package/dist/public-link-progress.js.map +1 -1
- package/dist/public-preview.js.map +1 -1
- package/dist/public-web-gateway.js +7 -2
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/public-web-link.d.ts +35 -1
- package/dist/public-web-link.js +142 -43
- package/dist/public-web-link.js.map +1 -1
- package/dist/quickstart-api.js.map +1 -1
- package/dist/quickstart.d.ts +5 -0
- package/dist/quickstart.js +25 -16
- package/dist/quickstart.js.map +1 -1
- package/dist/reply-buttons-controller.js.map +1 -1
- package/dist/reply-dedup.js.map +1 -1
- package/dist/resource-report.js.map +1 -1
- package/dist/restart-guard.js.map +1 -1
- package/dist/restart-progress.js.map +1 -1
- package/dist/rollout-index.js.map +1 -1
- package/dist/runtime-cpu-profile.js.map +1 -1
- package/dist/scheduler/db.js.map +1 -1
- package/dist/scheduler/scheduler.js.map +1 -1
- package/dist/scheduler/task-board-text.js +16 -11
- package/dist/scheduler/task-board-text.js.map +1 -1
- package/dist/scheduler/task-board.d.ts +39 -11
- package/dist/scheduler/task-board.js +123 -45
- package/dist/scheduler/task-board.js.map +1 -1
- package/dist/scheduler/types.d.ts +1 -1
- package/dist/sd-notify.js.map +1 -1
- package/dist/search/search-index.js.map +1 -1
- package/dist/secret-file.js.map +1 -1
- package/dist/secret-store.js.map +1 -1
- package/dist/service-installer.d.ts +7 -1
- package/dist/service-installer.js +13 -1
- package/dist/service-installer.js.map +1 -1
- package/dist/service-plan.d.ts +33 -4
- package/dist/service-plan.js +177 -8
- package/dist/service-plan.js.map +1 -1
- package/dist/session-oom.d.ts +21 -0
- package/dist/session-oom.js +139 -0
- package/dist/session-oom.js.map +1 -0
- package/dist/settings-api.js +3 -1
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-baseline.js.map +1 -1
- package/dist/settings-change.d.ts +5 -0
- package/dist/settings-change.js +71 -1
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-confirmation.d.ts +4 -0
- package/dist/settings-confirmation.js +2 -0
- package/dist/settings-confirmation.js.map +1 -1
- package/dist/settings-control.js.map +1 -1
- package/dist/settings-effect.js +4 -1
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-http-confirmation.js +1 -0
- package/dist/settings-http-confirmation.js.map +1 -1
- package/dist/settings-instance-patch.js +13 -1
- package/dist/settings-instance-patch.js.map +1 -1
- package/dist/settings-transaction.js.map +1 -1
- package/dist/setup-auth.js.map +1 -1
- package/dist/setup-host.d.ts +5 -1
- package/dist/setup-host.js +8 -1
- package/dist/setup-host.js.map +1 -1
- package/dist/setup-wizard.js +5 -2
- package/dist/setup-wizard.js.map +1 -1
- package/dist/spawn-gate.d.ts +4 -0
- package/dist/spawn-gate.js +15 -5
- package/dist/spawn-gate.js.map +1 -1
- package/dist/start-attempt.d.ts +1 -0
- package/dist/start-attempt.js +18 -0
- package/dist/start-attempt.js.map +1 -0
- package/dist/start-failure-notice.d.ts +4 -0
- package/dist/start-failure-notice.js +20 -0
- package/dist/start-failure-notice.js.map +1 -0
- package/dist/start-failure.d.ts +147 -0
- package/dist/start-failure.js +281 -0
- package/dist/start-failure.js.map +1 -0
- package/dist/startup-memory-deadline.d.ts +23 -0
- package/dist/startup-memory-deadline.js +55 -0
- package/dist/startup-memory-deadline.js.map +1 -0
- package/dist/statusline-watcher.js.map +1 -1
- package/dist/storm-window.js.map +1 -1
- package/dist/systemd-peer-bus.js.map +1 -1
- package/dist/target-queue-worker.js.map +1 -1
- package/dist/task-board-summary.js.map +1 -1
- package/dist/task-board-tool.js +3 -2
- package/dist/task-board-tool.js.map +1 -1
- package/dist/task-board-waker.js +8 -4
- package/dist/task-board-waker.js.map +1 -1
- package/dist/tips.js.map +1 -1
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-exec-helper.js.map +1 -1
- package/dist/tmux-manager.d.ts +1 -0
- package/dist/tmux-manager.js +2 -1
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tmux-read.js +1 -1
- package/dist/tmux-read.js.map +1 -1
- package/dist/tool-permissions.js.map +1 -1
- package/dist/tool-progress.js.map +1 -1
- package/dist/topic-archiver.js.map +1 -1
- package/dist/topic-commands.js.map +1 -1
- package/dist/topic-link.js.map +1 -1
- package/dist/transcript-delta-reader.js.map +1 -1
- package/dist/transcript-jsonl.js.map +1 -1
- package/dist/transcript-monitor.js.map +1 -1
- package/dist/transcript-sources.js.map +1 -1
- package/dist/tunnel/cloudflared-install.js.map +1 -1
- package/dist/tunnel/cloudflared.js.map +1 -1
- package/dist/tunnel/lease.js +3 -2
- package/dist/tunnel/lease.js.map +1 -1
- package/dist/tunnel/manager.js.map +1 -1
- package/dist/tunnel/public-fetch.js.map +1 -1
- package/dist/tunnel/purpose-lane.js.map +1 -1
- package/dist/tunnel/types.js.map +1 -1
- package/dist/types.d.ts +22 -1
- package/dist/ui/chat-render.js +7 -17
- package/dist/ui/chat-store.js +171 -61
- package/dist/ui/chat-strings.js +9 -4
- package/dist/ui/chat-thread.js +48 -1
- package/dist/ui/fleet-canvas-layout.js +3 -0
- package/dist/ui/fleet-canvas.js +23 -20
- package/dist/ui/fleet-office-editor.js +149 -0
- package/dist/ui/fleet-office-model.js +358 -0
- package/dist/ui/fleet-office-pack.js +199 -0
- package/dist/ui/fleet-office-skin.js +474 -0
- package/dist/ui/fleet-office-store.js +49 -0
- package/dist/ui/fleet-office-zones.js +177 -0
- package/dist/ui/fleet-office.js +434 -0
- package/dist/ui/fleet-org.js +18 -5
- package/dist/ui/guest-refused.html +41 -0
- package/dist/ui/image-lightbox.js +9 -3
- package/dist/ui/panel-chat.js +35 -22
- package/dist/ui/panel-settings.js +24 -7
- package/dist/ui/settings-dialogs.js +11 -2
- package/dist/ui/settings-model.js +20 -0
- package/dist/ui/settings-strings.js +36 -0
- package/dist/ui/settings-web-authority.js +7 -2
- package/dist/ui/shared/agend-auth.js +2 -0
- package/dist/ui/shared/app-i18n.js +2 -2
- package/dist/ui/shared/app-prefs.js +2 -0
- package/dist/ui/shared/app-shell.js +62 -9
- package/dist/ui/shared/app-store.js +1 -0
- package/dist/ui/shared/app-stream.js +2 -1
- package/dist/ui/shared/app.css +164 -15
- package/dist/ui/shared/guest-refused.js +35 -0
- package/dist/ui/shared/header-tools.js +2 -2
- package/dist/ui/shared/instance-nav.js +25 -8
- package/dist/ui/shared/tokens.css +4 -0
- package/dist/ui/shared/ui-dialog.js +2 -2
- package/dist/ui/shared/usage-dialog.js +152 -6
- package/dist/ui/shared/view-strings.js +20 -0
- package/dist/ui/shared/web-authorize.js +3 -1
- package/dist/update-check.js.map +1 -1
- package/dist/update-dispatch.js.map +1 -1
- package/dist/update-install.js.map +1 -1
- package/dist/update-launch.js.map +1 -1
- package/dist/update-marker.js.map +1 -1
- package/dist/update-preflight.js.map +1 -1
- package/dist/update-progress.d.ts +3 -1
- package/dist/update-progress.js +3 -1
- package/dist/update-progress.js.map +1 -1
- package/dist/usage/format-rich.js.map +1 -1
- package/dist/usage/providers.d.ts +8 -0
- package/dist/usage/providers.js +6 -2
- package/dist/usage/providers.js.map +1 -1
- package/dist/usage/statusline-usage.js.map +1 -1
- package/dist/usage/usage-api.js +2 -1
- package/dist/usage/usage-api.js.map +1 -1
- package/dist/usage-report.js.map +1 -1
- package/dist/usage-rollup.js +1 -1
- package/dist/usage-rollup.js.map +1 -1
- package/dist/user-systemd.js.map +1 -1
- package/dist/view-api.js +1 -1
- package/dist/view-api.js.map +1 -1
- package/dist/wake-coordinator.js.map +1 -1
- package/dist/web-ambient.js.map +1 -1
- package/dist/web-api.d.ts +19 -2
- package/dist/web-api.js +180 -28
- package/dist/web-api.js.map +1 -1
- package/dist/web-app-icon.js.map +1 -1
- package/dist/web-appearance-policy.js.map +1 -1
- package/dist/web-appearance-tools.js.map +1 -1
- package/dist/web-appearance-view.js.map +1 -1
- package/dist/web-appearance.js.map +1 -1
- package/dist/web-auth.js +5 -4
- package/dist/web-auth.js.map +1 -1
- package/dist/web-backend-login.js.map +1 -1
- package/dist/web-card.js.map +1 -1
- package/dist/web-channel-echo.js.map +1 -1
- package/dist/web-chat-history.d.ts +41 -11
- package/dist/web-chat-history.js +93 -22
- package/dist/web-chat-history.js.map +1 -1
- package/dist/web-commands.js.map +1 -1
- package/dist/web-effect-bundle.d.ts +2 -2
- package/dist/web-effect-library.js.map +1 -1
- package/dist/web-effect-playback.js.map +1 -1
- package/dist/web-effect-profiles.d.ts +16 -16
- package/dist/web-effect-profiles.js +3 -2
- package/dist/web-effect-profiles.js.map +1 -1
- package/dist/web-effect-service.js.map +1 -1
- package/dist/web-effect-tools.js.map +1 -1
- package/dist/web-effect-trials.js.map +1 -1
- package/dist/web-effect-upload.js.map +1 -1
- package/dist/web-effect.d.ts +7 -7
- package/dist/web-effect.js.map +1 -1
- package/dist/web-experimental.js.map +1 -1
- package/dist/web-guest-access.js +1 -1
- package/dist/web-guest-access.js.map +1 -1
- package/dist/web-guest-rooms.js.map +1 -1
- package/dist/web-host-guard.js.map +1 -1
- package/dist/web-icons.js.map +1 -1
- package/dist/web-identity-color.js.map +1 -1
- package/dist/web-images.js.map +1 -1
- package/dist/web-libavoid.js.map +1 -1
- package/dist/web-login.js.map +1 -1
- package/dist/web-mentions.js.map +1 -1
- package/dist/web-mod-agent.js.map +1 -1
- package/dist/web-mod-store.js.map +1 -1
- package/dist/web-office-store.d.ts +104 -0
- package/dist/web-office-store.js +236 -0
- package/dist/web-office-store.js.map +1 -0
- package/dist/web-owner-css-store.js.map +1 -1
- package/dist/web-owner-css.js.map +1 -1
- package/dist/web-png.js.map +1 -1
- package/dist/web-prefs.js +2 -0
- package/dist/web-prefs.js.map +1 -1
- package/dist/web-profile.js.map +1 -1
- package/dist/web-reactions.d.ts +2 -1
- package/dist/web-request-context.d.ts +5 -0
- package/dist/web-request-context.js.map +1 -1
- package/dist/web-returning-device.js +1 -1
- package/dist/web-returning-device.js.map +1 -1
- package/dist/web-schedules.js.map +1 -1
- package/dist/web-send-dedupe.d.ts +36 -0
- package/dist/web-send-dedupe.js +69 -0
- package/dist/web-send-dedupe.js.map +1 -0
- package/dist/web-session-authorization.js.map +1 -1
- package/dist/web-session.js +1 -1
- package/dist/web-session.js.map +1 -1
- package/dist/web-settings-patch.d.ts +1 -0
- package/dist/web-settings-patch.js +6 -4
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/web-settings-tools.js.map +1 -1
- package/dist/web-terminal-http.js.map +1 -1
- package/dist/web-terminal.js.map +1 -1
- package/dist/web-theme-store.js.map +1 -1
- package/dist/web-upload.d.ts +5 -1
- package/dist/web-upload.js +6 -4
- package/dist/web-upload.js.map +1 -1
- package/dist/web-widget.js.map +1 -1
- package/dist/webhook-emitter.js.map +1 -1
- package/dist/windows-shortcuts.js +1 -1
- package/dist/windows-shortcuts.js.map +1 -1
- package/dist/workflow-templates/default.md +1 -1
- package/dist/ws-server.js.map +1 -1
- package/dist/yaml-shared-nodes.js.map +1 -1
- package/launcher/agend-install.cjs +281 -6
- package/launcher/private-home.cjs +43 -0
- package/package.json +3 -2
- package/templates/windows-shortcuts.ps1 +1 -1
|
@@ -112,6 +112,11 @@ export interface Card {
|
|
|
112
112
|
priority: CardPriority;
|
|
113
113
|
size: CardSize | null;
|
|
114
114
|
needsReview: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* #2434: opened on the board (createCards), not the `task` tool's own plain task. Before #2434 a main task's default
|
|
117
|
+
* "needs review" marked it; an agent's main task no longer waits for review, so the board says so on its own.
|
|
118
|
+
*/
|
|
119
|
+
onBoard: boolean;
|
|
115
120
|
/** uuids of the cards to finish first (what the fleet's `task` tool has always stored). */
|
|
116
121
|
deps: string[];
|
|
117
122
|
goal: string;
|
|
@@ -358,14 +363,28 @@ export interface SearchHit {
|
|
|
358
363
|
text: string;
|
|
359
364
|
} | null;
|
|
360
365
|
}
|
|
366
|
+
/**
|
|
367
|
+
* #2434: who confirms a card in review. The person confirms the cards they handed out (#2426's rule for a blocked card,
|
|
368
|
+
* for review too); an agent's card is the agents' own business: its instance dispatcher confirms it, and one nobody
|
|
369
|
+
* handed out its assignee (or the instance that opened it). A person may still confirm any card.
|
|
370
|
+
*/
|
|
371
|
+
export declare const personConfirms: (card: Pick<Card, "dispatcher">) => boolean;
|
|
372
|
+
/** Who that is, in words (an error, the card's text). */
|
|
373
|
+
export declare function confirmerOf(card: Pick<Card, "dispatcher" | "assignee">): string;
|
|
361
374
|
/** "m3", "M - 3" → "M-3"; null when it is not a card number. */
|
|
362
375
|
export declare function cardCode(raw: string): string | null;
|
|
363
|
-
/**
|
|
376
|
+
/**
|
|
377
|
+
* An instance dispatcher that is no longer in the fleet (deleted): `gone(name)`, asked of the fleet. Its cards have no one
|
|
378
|
+
* left to answer or confirm them but the person. Unknown (no `gone`): every dispatcher is there.
|
|
379
|
+
*/
|
|
380
|
+
export type GoneDispatcher = (name: string) => boolean;
|
|
364
381
|
/**
|
|
365
382
|
* #2425: whether a card waits for the person — in review needing their confirmation, or blocked on a question the person
|
|
366
|
-
* owns
|
|
383
|
+
* owns; both only when they handed it out (#2434: an agent's card in review is its dispatcher's to confirm), or when the
|
|
384
|
+
* instance that handed it out was deleted since (`gone`: nobody else is left to answer it). The one rule for
|
|
385
|
+
* waitingForPerson's query, Needs you and a button's route.
|
|
367
386
|
*/
|
|
368
|
-
export declare function waitsForPerson(card: Pick<Card, "status" | "needsReview" | "dispatcher"
|
|
387
|
+
export declare function waitsForPerson(card: Pick<Card, "status" | "needsReview" | "dispatcher">, gone?: GoneDispatcher): boolean;
|
|
369
388
|
export declare function requiresReview(card: Pick<Card, "needsReview">): boolean;
|
|
370
389
|
/**
|
|
371
390
|
* What a finished card still lacks for the person's confirmation: unchecked acceptance items, no result. A main task
|
|
@@ -483,7 +502,10 @@ export declare class TaskBoard {
|
|
|
483
502
|
cards: Card[];
|
|
484
503
|
total: number;
|
|
485
504
|
};
|
|
486
|
-
/**
|
|
505
|
+
/**
|
|
506
|
+
* On the board's terms: opened on it (#2434), in a project, a sub task, one with sub tasks, or one that waits for
|
|
507
|
+
* review (every main task opened on the board before #2434 did).
|
|
508
|
+
*/
|
|
487
509
|
isOnBoard(card: Card): boolean;
|
|
488
510
|
/**
|
|
489
511
|
* An instance's work, for `task mine`: what it is doing, what is blocked or waits for the person, what it can start
|
|
@@ -493,6 +515,10 @@ export declare class TaskBoard {
|
|
|
493
515
|
/** Who holds a live card (open, in progress, blocked, waiting for the person): the instances, and any other name. */
|
|
494
516
|
liveAssignees(): string[];
|
|
495
517
|
myWork(name: string): MyWork;
|
|
518
|
+
/** #2434: whether `actor` confirms `card` (finishes it from review): the person their cards, an agent's its dispatcher. */
|
|
519
|
+
confirms(card: Card, actor: Actor): boolean;
|
|
520
|
+
/** #2434: the cards an instance handed out that wait in review for its confirmation (its `task mine`). */
|
|
521
|
+
toConfirm(name: string): Card[];
|
|
496
522
|
/**
|
|
497
523
|
* What waits for the person (step 3: Needs you, and the daily summary): cards in review that need their confirmation,
|
|
498
524
|
* and blocked cards whose question is theirs to answer — oldest first, each with when it started waiting (its last
|
|
@@ -502,9 +528,11 @@ export declare class TaskBoard {
|
|
|
502
528
|
* out is that instance's to decide (step 2's wakes: its question goes there, not here). One with no dispatcher is an
|
|
503
529
|
* instance's own "I'm waiting" — every card the `task` tool kept before the board, an agent's card for itself, a
|
|
504
530
|
* reviewer's "waiting on the author" — and is no question to the person: 2.3.0-beta.24 listed 28 such cards, weeks
|
|
505
|
-
* old, as "stuck, asking you" (#2425). Nothing is changed on the cards; they stay on the board as they are.
|
|
531
|
+
* old, as "stuck, asking you" (#2425). Nothing is changed on the cards; they stay on the board as they are. One an
|
|
532
|
+
* instance handed out that was deleted since (`gone`) has nobody else to answer or confirm it: it falls back to the
|
|
533
|
+
* person.
|
|
506
534
|
*/
|
|
507
|
-
waitingForPerson(): Array<{
|
|
535
|
+
waitingForPerson(gone?: GoneDispatcher): Array<{
|
|
508
536
|
card: Card;
|
|
509
537
|
since: string;
|
|
510
538
|
}>;
|
|
@@ -521,7 +549,7 @@ export declare class TaskBoard {
|
|
|
521
549
|
* Step 3, the daily summary (task-board-summary.ts): what waits for the person now, what got done and what was
|
|
522
550
|
* opened in [since, until) (not cancelled), and every live main task's project and assignee.
|
|
523
551
|
*/
|
|
524
|
-
summaryRead(since: string, until: string): {
|
|
552
|
+
summaryRead(since: string, until: string, gone?: GoneDispatcher): {
|
|
525
553
|
waiting: Card[];
|
|
526
554
|
done: Card[];
|
|
527
555
|
created: Card[];
|
|
@@ -571,8 +599,8 @@ export declare class TaskBoard {
|
|
|
571
599
|
*/
|
|
572
600
|
legacyClaim(actor: Actor, uuid: string, assignee: string): Card;
|
|
573
601
|
/**
|
|
574
|
-
* `task done`: from open or claimed. A card that needs
|
|
575
|
-
*
|
|
602
|
+
* `task done`: from open or claimed. A card that needs confirmation goes to review instead, so no instance finishes
|
|
603
|
+
* one it does not confirm alone; the one who confirms it finishes it, from review too (#2434). On the board, an instance finishes as it would there: its own card, with a result
|
|
576
604
|
* (an open one is claimed first, under the same rules).
|
|
577
605
|
*/
|
|
578
606
|
legacyComplete(actor: Actor, uuid: string, result?: string): Card;
|
|
@@ -627,8 +655,8 @@ export declare class TaskBoard {
|
|
|
627
655
|
private applyMove;
|
|
628
656
|
/**
|
|
629
657
|
* A main task with sub tasks follows them: open until something starts, in progress while they run, and when they
|
|
630
|
-
* are all done, review (or done, for one that
|
|
631
|
-
* to done. A blocked or cancelled main task is left alone, and so is one without sub tasks (it is moved by hand).
|
|
658
|
+
* are all done, review (or done, for one that needs no confirmation). Only whoever confirms it (#2434) moves it
|
|
659
|
+
* from review to done. A blocked or cancelled main task is left alone, and so is one without sub tasks (it is moved by hand).
|
|
632
660
|
*/
|
|
633
661
|
/** What a main task's sub tasks make its status (its own, when it is blocked, cancelled or has none). */
|
|
634
662
|
private derivedStatus;
|
|
@@ -97,6 +97,29 @@ function toDispatcher(input, actor) {
|
|
|
97
97
|
*/
|
|
98
98
|
const openedForItself = (c) => c.assignee !== null && c.createdBy === c.assignee && c.dispatcher === null;
|
|
99
99
|
const isDispatcher = (card, actor) => card.dispatcher?.kind === "instance" && !isPerson(actor) && card.dispatcher.name === actor.name;
|
|
100
|
+
/**
|
|
101
|
+
* #2434: who confirms a card in review. The person confirms the cards they handed out (#2426's rule for a blocked card,
|
|
102
|
+
* for review too); an agent's card is the agents' own business: its instance dispatcher confirms it, and one nobody
|
|
103
|
+
* handed out its assignee (or the instance that opened it). A person may still confirm any card.
|
|
104
|
+
*/
|
|
105
|
+
export const personConfirms = (card) => card.dispatcher?.kind === "person";
|
|
106
|
+
function confirms(card, actor) {
|
|
107
|
+
if (isPerson(actor))
|
|
108
|
+
return true;
|
|
109
|
+
if (personConfirms(card))
|
|
110
|
+
return false;
|
|
111
|
+
if (card.dispatcher?.kind === "instance")
|
|
112
|
+
return card.dispatcher.name === actor.name;
|
|
113
|
+
return card.assignee === actor.name || (card.assignee === null && card.createdBy === actor.name);
|
|
114
|
+
}
|
|
115
|
+
/** Who that is, in words (an error, the card's text). */
|
|
116
|
+
export function confirmerOf(card) {
|
|
117
|
+
if (card.dispatcher?.kind === "person")
|
|
118
|
+
return "the person";
|
|
119
|
+
if (card.dispatcher?.kind === "instance")
|
|
120
|
+
return card.dispatcher.name;
|
|
121
|
+
return card.assignee ?? "its assignee";
|
|
122
|
+
}
|
|
100
123
|
function normalizeAssignee(raw) {
|
|
101
124
|
const v = raw?.trim() ?? "";
|
|
102
125
|
if (v === "" || v.toLowerCase() === "none")
|
|
@@ -110,13 +133,15 @@ export function cardCode(raw) {
|
|
|
110
133
|
const m = CODE_RE.exec(raw);
|
|
111
134
|
return m ? `${m[1].toUpperCase()}-${Number(m[2])}` : null;
|
|
112
135
|
}
|
|
113
|
-
|
|
136
|
+
const orphaned = (card, gone) => !!gone && card.dispatcher?.kind === "instance" && gone(card.dispatcher.name);
|
|
114
137
|
/**
|
|
115
138
|
* #2425: whether a card waits for the person — in review needing their confirmation, or blocked on a question the person
|
|
116
|
-
* owns
|
|
139
|
+
* owns; both only when they handed it out (#2434: an agent's card in review is its dispatcher's to confirm), or when the
|
|
140
|
+
* instance that handed it out was deleted since (`gone`: nobody else is left to answer it). The one rule for
|
|
141
|
+
* waitingForPerson's query, Needs you and a button's route.
|
|
117
142
|
*/
|
|
118
|
-
export function waitsForPerson(card) {
|
|
119
|
-
return (card.status === "review" && card.needsReview) ||
|
|
143
|
+
export function waitsForPerson(card, gone) {
|
|
144
|
+
return (personConfirms(card) || orphaned(card, gone)) && ((card.status === "review" && card.needsReview) || card.status === "blocked");
|
|
120
145
|
}
|
|
121
146
|
export function requiresReview(card) {
|
|
122
147
|
return card.needsReview;
|
|
@@ -155,6 +180,7 @@ function toCard(r) {
|
|
|
155
180
|
priority: r.priority ?? "normal",
|
|
156
181
|
size: r.size ?? null,
|
|
157
182
|
needsReview: Number(r.needs_review) === 1,
|
|
183
|
+
onBoard: Number(r.on_board) === 1,
|
|
158
184
|
deps: parseJsonArray(r.depends_on, []).filter((d) => typeof d === "string"),
|
|
159
185
|
goal: r.description ?? "",
|
|
160
186
|
scope: r.scope ?? "",
|
|
@@ -257,6 +283,7 @@ export class TaskBoard {
|
|
|
257
283
|
add("seen_entry_id", "INTEGER NOT NULL DEFAULT 0");
|
|
258
284
|
add("dispatcher", "TEXT");
|
|
259
285
|
add("dispatcher_kind", "TEXT");
|
|
286
|
+
add("on_board", "INTEGER NOT NULL DEFAULT 0"); // #2434; a row before it: its needs_review says so
|
|
260
287
|
this.db.exec(`
|
|
261
288
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_tasks_code ON tasks(code);
|
|
262
289
|
CREATE INDEX IF NOT EXISTS idx_tasks_parent ON tasks(parent_id);
|
|
@@ -760,9 +787,12 @@ export class TaskBoard {
|
|
|
760
787
|
const rows = this.db.prepare(`SELECT * ${from} ORDER BY CASE kind WHEN 'main' THEN 0 ELSE 1 END, ${STATUS_ORDER}, ${PRIORITY_ORDER}, sort LIMIT ?`).all(...params, limit);
|
|
761
788
|
return { cards: rows.map(toCard), total: n };
|
|
762
789
|
}
|
|
763
|
-
/**
|
|
790
|
+
/**
|
|
791
|
+
* On the board's terms: opened on it (#2434), in a project, a sub task, one with sub tasks, or one that waits for
|
|
792
|
+
* review (every main task opened on the board before #2434 did).
|
|
793
|
+
*/
|
|
764
794
|
isOnBoard(card) {
|
|
765
|
-
return card.projectId !== null || card.kind === "sub" || card.needsReview || this.activeSubs(card.uuid).length > 0;
|
|
795
|
+
return card.onBoard || card.projectId !== null || card.kind === "sub" || card.needsReview || this.activeSubs(card.uuid).length > 0;
|
|
766
796
|
}
|
|
767
797
|
/**
|
|
768
798
|
* An instance's work, for `task mine`: what it is doing, what is blocked or waits for the person, what it can start
|
|
@@ -807,6 +837,13 @@ export class TaskBoard {
|
|
|
807
837
|
mains: coordinating.map((card) => ({ card, progress: this.progress(card) })),
|
|
808
838
|
};
|
|
809
839
|
}
|
|
840
|
+
/** #2434: whether `actor` confirms `card` (finishes it from review): the person their cards, an agent's its dispatcher. */
|
|
841
|
+
confirms(card, actor) { return confirms(card, actor); }
|
|
842
|
+
/** #2434: the cards an instance handed out that wait in review for its confirmation (its `task mine`). */
|
|
843
|
+
toConfirm(name) {
|
|
844
|
+
return this.db.prepare("SELECT * FROM tasks WHERE status = 'review' AND needs_review = 1 AND (dispatcher_kind IS NULL OR dispatcher_kind != 'person') AND dispatcher = ? AND (assignee IS NULL OR assignee != ?) ORDER BY updated_at")
|
|
845
|
+
.all(name, name).map(toCard);
|
|
846
|
+
}
|
|
810
847
|
/**
|
|
811
848
|
* What waits for the person (step 3: Needs you, and the daily summary): cards in review that need their confirmation,
|
|
812
849
|
* and blocked cards whose question is theirs to answer — oldest first, each with when it started waiting (its last
|
|
@@ -816,10 +853,17 @@ export class TaskBoard {
|
|
|
816
853
|
* out is that instance's to decide (step 2's wakes: its question goes there, not here). One with no dispatcher is an
|
|
817
854
|
* instance's own "I'm waiting" — every card the `task` tool kept before the board, an agent's card for itself, a
|
|
818
855
|
* reviewer's "waiting on the author" — and is no question to the person: 2.3.0-beta.24 listed 28 such cards, weeks
|
|
819
|
-
* old, as "stuck, asking you" (#2425). Nothing is changed on the cards; they stay on the board as they are.
|
|
856
|
+
* old, as "stuck, asking you" (#2425). Nothing is changed on the cards; they stay on the board as they are. One an
|
|
857
|
+
* instance handed out that was deleted since (`gone`) has nobody else to answer or confirm it: it falls back to the
|
|
858
|
+
* person.
|
|
820
859
|
*/
|
|
821
|
-
waitingForPerson() {
|
|
822
|
-
const
|
|
860
|
+
waitingForPerson(gone) {
|
|
861
|
+
const waiting = "((status = 'review' AND needs_review = 1) OR status = 'blocked')";
|
|
862
|
+
const rows = [
|
|
863
|
+
...this.db.prepare(`SELECT * FROM tasks WHERE dispatcher_kind = 'person' AND ${waiting}`).all().map(toCard),
|
|
864
|
+
...(gone ? this.db.prepare(`SELECT * FROM tasks WHERE dispatcher IS NOT NULL AND (dispatcher_kind IS NULL OR dispatcher_kind != 'person') AND ${waiting}`).all()
|
|
865
|
+
.map(toCard).filter((card) => orphaned(card, gone)) : []),
|
|
866
|
+
];
|
|
823
867
|
const moved = this.db.prepare("SELECT at FROM task_events WHERE task_id = ? AND type = 'moved' AND json_extract(data, '$.to') = ? ORDER BY id DESC LIMIT 1");
|
|
824
868
|
return rows.map((card) => {
|
|
825
869
|
const at = moved.get(card.uuid, card.status)?.at;
|
|
@@ -913,10 +957,10 @@ export class TaskBoard {
|
|
|
913
957
|
* Step 3, the daily summary (task-board-summary.ts): what waits for the person now, what got done and what was
|
|
914
958
|
* opened in [since, until) (not cancelled), and every live main task's project and assignee.
|
|
915
959
|
*/
|
|
916
|
-
summaryRead(since, until) {
|
|
960
|
+
summaryRead(since, until, gone) {
|
|
917
961
|
const between = (sql) => this.db.prepare(sql).all(since, until).map(toCard);
|
|
918
962
|
return {
|
|
919
|
-
waiting: this.waitingForPerson().map((w) => w.card),
|
|
963
|
+
waiting: this.waitingForPerson(gone).map((w) => w.card),
|
|
920
964
|
done: between("SELECT * FROM tasks WHERE status = 'done' AND done_at >= ? AND done_at < ? ORDER BY sort"),
|
|
921
965
|
created: between("SELECT * FROM tasks WHERE status != 'cancelled' AND created_at >= ? AND created_at < ? ORDER BY sort"),
|
|
922
966
|
mains: this.db.prepare("SELECT project_id, assignee FROM tasks WHERE kind = 'main' AND status != 'cancelled'").all()
|
|
@@ -958,13 +1002,14 @@ export class TaskBoard {
|
|
|
958
1002
|
const acceptance = checkAcceptance(spec.acceptance ?? []);
|
|
959
1003
|
if (acceptance.length > CARD_LIMITS.acceptanceItems)
|
|
960
1004
|
throw new TaskBoardError("too_long", `at most ${CARD_LIMITS.acceptanceItems} acceptance items`, "acceptance_max", [CARD_LIMITS.acceptanceItems]);
|
|
961
|
-
const needsReview = spec.needsReview ?? kind === "main";
|
|
962
|
-
if (!needsReview && kind === "main" && !isPerson(actor))
|
|
963
|
-
throw new TaskBoardError("forbidden", "only a person can open a main task that skips their confirmation");
|
|
964
1005
|
const now = this.nowIso();
|
|
965
1006
|
const assignee = spec.assignee !== undefined ? normalizeAssignee(spec.assignee) : isPerson(actor) ? null : actor.name;
|
|
966
1007
|
const opener = isPerson(actor) ? { kind: "person", name: actor.name }
|
|
967
1008
|
: actor.kind === "instance" && assignee && assignee !== actor.name ? { kind: "instance", name: actor.name } : null;
|
|
1009
|
+
const dispatcher = spec.dispatcher !== undefined ? toDispatcher(spec.dispatcher, actor) : (parent?.dispatcher ?? opener);
|
|
1010
|
+
// #2434: a main task waits for the person's confirmation when the person handed it out; an agent's needs none
|
|
1011
|
+
// unless it asks for one (its dispatcher then confirms it).
|
|
1012
|
+
const needsReview = spec.needsReview ?? (kind === "main" && dispatcher?.kind === "person");
|
|
968
1013
|
const card = {
|
|
969
1014
|
uuid: randomUUID(),
|
|
970
1015
|
code: this.nextCode(kind === "main" ? "M" : "S"),
|
|
@@ -974,10 +1019,11 @@ export class TaskBoard {
|
|
|
974
1019
|
title,
|
|
975
1020
|
status: "open",
|
|
976
1021
|
assignee,
|
|
977
|
-
dispatcher
|
|
1022
|
+
dispatcher,
|
|
978
1023
|
priority: spec.priority ?? "normal",
|
|
979
1024
|
size: spec.size ?? null,
|
|
980
1025
|
needsReview,
|
|
1026
|
+
onBoard: true,
|
|
981
1027
|
deps: this.checkDeps({ uuid: null, kind, parent: parent?.uuid ?? null }, (spec.dependsOn ?? []).map((d) => this.resolveRef(d, created))),
|
|
982
1028
|
goal: checkText("the goal", spec.goal ?? "", CARD_LIMITS.goal),
|
|
983
1029
|
scope: checkText("the scope", spec.scope ?? "", CARD_LIMITS.scope),
|
|
@@ -1064,11 +1110,24 @@ export class TaskBoard {
|
|
|
1064
1110
|
set("size", patch.size);
|
|
1065
1111
|
if (patch.priority !== undefined)
|
|
1066
1112
|
set("priority", patch.priority);
|
|
1067
|
-
if (patch.dispatcher !== undefined)
|
|
1068
|
-
|
|
1113
|
+
if (patch.dispatcher !== undefined) {
|
|
1114
|
+
const next = toDispatcher(patch.dispatcher, actor);
|
|
1115
|
+
// #2434: the person's card stays theirs — an instance re-dispatching it would take it out of their confirmation.
|
|
1116
|
+
const moved = JSON.stringify(next) !== JSON.stringify(card.dispatcher);
|
|
1117
|
+
if (ai && personConfirms(card) && moved) {
|
|
1118
|
+
throw new TaskBoardError("forbidden", `${card.code} was handed out by the person; only they hand it to someone else`);
|
|
1119
|
+
}
|
|
1120
|
+
// #2436 review: nor an agent's card that waits for its dispatcher's confirmation — dropping or replacing the
|
|
1121
|
+
// dispatcher would let its assignee confirm it itself. Only that dispatcher (or a person) hands it on.
|
|
1122
|
+
if (ai && moved && card.needsReview && card.dispatcher?.kind === "instance" && card.dispatcher.name !== actor.name) {
|
|
1123
|
+
throw new TaskBoardError("forbidden", `${card.code} waits for ${card.dispatcher.name}'s confirmation; only they hand it to someone else`);
|
|
1124
|
+
}
|
|
1125
|
+
set("dispatcher", next, "dispatcher", (d) => d?.name ?? null);
|
|
1126
|
+
}
|
|
1069
1127
|
if (patch.needsReview !== undefined) {
|
|
1070
|
-
if (ai && card.needsReview && !patch.needsReview)
|
|
1071
|
-
throw new TaskBoardError("forbidden", "only a person can clear \"needs review\"");
|
|
1128
|
+
if (ai && card.needsReview && !patch.needsReview && !confirms(card, actor)) {
|
|
1129
|
+
throw new TaskBoardError("forbidden", personConfirms(card) ? "only a person can clear \"needs review\"" : `only ${confirmerOf(card)} can clear "needs review" on ${card.code}`);
|
|
1130
|
+
}
|
|
1072
1131
|
set("needsReview", patch.needsReview);
|
|
1073
1132
|
}
|
|
1074
1133
|
if (patch.dependsOn !== undefined) {
|
|
@@ -1236,7 +1295,7 @@ export class TaskBoard {
|
|
|
1236
1295
|
const now = this.nowIso();
|
|
1237
1296
|
const card = {
|
|
1238
1297
|
uuid: randomUUID(), code: this.nextCode("M"), kind: "main", projectId: null, parent: null, title: params.title, status: "open",
|
|
1239
|
-
assignee: params.assignee ?? null, priority: params.priority ?? "normal", size: null, needsReview: false,
|
|
1298
|
+
assignee: params.assignee ?? null, priority: params.priority ?? "normal", size: null, needsReview: false, onBoard: false,
|
|
1240
1299
|
// Opened for another instance: the opener handed it out (its blocked question goes to it).
|
|
1241
1300
|
dispatcher: actor.kind === "instance" && params.assignee && params.assignee !== actor.name ? { kind: "instance", name: actor.name } : null,
|
|
1242
1301
|
deps: this.checkDeps({ uuid: null, kind: "main", parent: null }, params.depends_on ?? []),
|
|
@@ -1289,8 +1348,8 @@ export class TaskBoard {
|
|
|
1289
1348
|
});
|
|
1290
1349
|
}
|
|
1291
1350
|
/**
|
|
1292
|
-
* `task done`: from open or claimed. A card that needs
|
|
1293
|
-
*
|
|
1351
|
+
* `task done`: from open or claimed. A card that needs confirmation goes to review instead, so no instance finishes
|
|
1352
|
+
* one it does not confirm alone; the one who confirms it finishes it, from review too (#2434). On the board, an instance finishes as it would there: its own card, with a result
|
|
1294
1353
|
* (an open one is claimed first, under the same rules).
|
|
1295
1354
|
*/
|
|
1296
1355
|
legacyComplete(actor, uuid, result) {
|
|
@@ -1298,8 +1357,10 @@ export class TaskBoard {
|
|
|
1298
1357
|
const card = this.byUuid(uuid);
|
|
1299
1358
|
if (!card)
|
|
1300
1359
|
throw new Error(`Task "${uuid}" not found`);
|
|
1301
|
-
|
|
1302
|
-
|
|
1360
|
+
// #2434: a card in review is finished by whoever confirms it (an agent's card: its dispatcher).
|
|
1361
|
+
const confirming = card.status === "review" && confirms(card, actor);
|
|
1362
|
+
if (card.status !== "claimed" && card.status !== "open" && !confirming) {
|
|
1363
|
+
throw new Error(`Task "${uuid}" is ${card.status}, cannot complete (must be open or claimed${card.status === "review" ? `; it waits for ${confirmerOf(card)}'s confirmation` : ""})`);
|
|
1303
1364
|
}
|
|
1304
1365
|
const open = this.children(card.uuid).filter((k) => !isFinished(k));
|
|
1305
1366
|
if (open.length)
|
|
@@ -1308,7 +1369,7 @@ export class TaskBoard {
|
|
|
1308
1369
|
this.event(actor, card, "updated", { changes: { result: { from: card.result, to: result } } });
|
|
1309
1370
|
card.result = result;
|
|
1310
1371
|
}
|
|
1311
|
-
const to = requiresReview(card) && !
|
|
1372
|
+
const to = requiresReview(card) && !confirms(card, actor) ? "review" : "done";
|
|
1312
1373
|
if (this.heldToBoardRules(card, actor)) {
|
|
1313
1374
|
if (card.status === "open") {
|
|
1314
1375
|
this.checkManualMove(card, actor, "claimed", "", { finishing: true });
|
|
@@ -1361,9 +1422,9 @@ export class TaskBoard {
|
|
|
1361
1422
|
if (derived)
|
|
1362
1423
|
this.checkDerivedMove(card, actor, to, "");
|
|
1363
1424
|
else {
|
|
1364
|
-
if (card.status === "review" && to === "done")
|
|
1365
|
-
throw new Error(`Task "${card.code}" is waiting for
|
|
1366
|
-
if (to === "done" && requiresReview(card))
|
|
1425
|
+
if (card.status === "review" && to === "done" && !confirms(card, actor))
|
|
1426
|
+
throw new Error(`Task "${card.code}" is waiting for ${confirmerOf(card)}'s confirmation`);
|
|
1427
|
+
if (to === "done" && card.status !== "review" && requiresReview(card) && !confirms(card, actor))
|
|
1367
1428
|
to = "review";
|
|
1368
1429
|
if (held && to !== card.status)
|
|
1369
1430
|
this.checkManualMove(card, actor, to, "");
|
|
@@ -1430,7 +1491,13 @@ export class TaskBoard {
|
|
|
1430
1491
|
this.checkOneAtATime(card, actor);
|
|
1431
1492
|
}
|
|
1432
1493
|
else if (from === "review") {
|
|
1433
|
-
if (ai) {
|
|
1494
|
+
if (ai && !own && confirms(card, actor)) {
|
|
1495
|
+
// #2434: an agent's card sent back by the instance that confirms it, as the person sends theirs back.
|
|
1496
|
+
if (!reason)
|
|
1497
|
+
throw new TaskBoardError("invalid", "sending work back needs a reason", "sendback_reason");
|
|
1498
|
+
this.entry(card, "reject", actor, reason);
|
|
1499
|
+
}
|
|
1500
|
+
else if (ai) {
|
|
1434
1501
|
if (!own)
|
|
1435
1502
|
throw notOwner();
|
|
1436
1503
|
if (startsWork)
|
|
@@ -1474,14 +1541,24 @@ export class TaskBoard {
|
|
|
1474
1541
|
}
|
|
1475
1542
|
case "done": {
|
|
1476
1543
|
if (ai) {
|
|
1477
|
-
if (from === "review")
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1544
|
+
if (from === "review") {
|
|
1545
|
+
if (!confirms(card, actor)) {
|
|
1546
|
+
throw new TaskBoardError("forbidden", personConfirms(card) ? `${card.code} is waiting for the person's confirmation: only they finish it`
|
|
1547
|
+
: `${card.code} is waiting for ${confirmerOf(card)}'s confirmation: only they finish it`);
|
|
1548
|
+
}
|
|
1549
|
+
if (reason)
|
|
1550
|
+
this.entry(card, "approve", actor, reason);
|
|
1551
|
+
}
|
|
1552
|
+
else {
|
|
1553
|
+
if (from !== "claimed")
|
|
1554
|
+
throw new TaskBoardError("invalid", `only a card in progress can be done (${card.code} is ${from})`);
|
|
1555
|
+
if (!own)
|
|
1556
|
+
throw notOwner();
|
|
1557
|
+
if (requiresReview(card) && !confirms(card, actor)) {
|
|
1558
|
+
throw new TaskBoardError("needs_review", personConfirms(card) ? `${card.code} needs the person's confirmation; move it to review`
|
|
1559
|
+
: `${card.code} needs ${confirmerOf(card)}'s confirmation; move it to review`);
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1485
1562
|
}
|
|
1486
1563
|
else if (from === "review" && reason) {
|
|
1487
1564
|
this.entry(card, "approve", actor, reason);
|
|
@@ -1687,8 +1764,8 @@ export class TaskBoard {
|
|
|
1687
1764
|
}
|
|
1688
1765
|
/**
|
|
1689
1766
|
* A main task with sub tasks follows them: open until something starts, in progress while they run, and when they
|
|
1690
|
-
* are all done, review (or done, for one that
|
|
1691
|
-
* to done. A blocked or cancelled main task is left alone, and so is one without sub tasks (it is moved by hand).
|
|
1767
|
+
* are all done, review (or done, for one that needs no confirmation). Only whoever confirms it (#2434) moves it
|
|
1768
|
+
* from review to done. A blocked or cancelled main task is left alone, and so is one without sub tasks (it is moved by hand).
|
|
1692
1769
|
*/
|
|
1693
1770
|
/** What a main task's sub tasks make its status (its own, when it is blocked, cancelled or has none). */
|
|
1694
1771
|
derivedStatus(main) {
|
|
@@ -1721,7 +1798,7 @@ export class TaskBoard {
|
|
|
1721
1798
|
this.save(main);
|
|
1722
1799
|
this.event(actor, main, "moved", { from, to: next, auto: true });
|
|
1723
1800
|
if (next === "review")
|
|
1724
|
-
this.say("review_waiting", [main.code, main.title], `${main.code} "${main.title}": every sub task is done; it is waiting for
|
|
1801
|
+
this.say("review_waiting", [main.code, main.title], `${main.code} "${main.title}": every sub task is done; it is waiting for ${confirmerOf(main)}'s confirmation`);
|
|
1725
1802
|
else if (from === "done" || from === "review")
|
|
1726
1803
|
this.say("back_to", [main.code, next], `${main.code} has unfinished sub tasks again; it is back to ${next}`);
|
|
1727
1804
|
if (next === "done")
|
|
@@ -1840,7 +1917,8 @@ export class TaskBoard {
|
|
|
1840
1917
|
add(card, card.assignee, "cancelled", e.actor, why);
|
|
1841
1918
|
continue;
|
|
1842
1919
|
}
|
|
1843
|
-
//
|
|
1920
|
+
// An agent's card waits for its instance dispatcher to confirm it (#2434: its own to confirm, nobody to ask). A
|
|
1921
|
+
// person's card has no instance dispatcher, so no notice: the person has it in Needs you.
|
|
1844
1922
|
if (d.to === "review" && !isPerson(e.actor) && requiresReview(card))
|
|
1845
1923
|
add(card, dispatcherOf(), "to_confirm", e.actor);
|
|
1846
1924
|
if (d.auto) {
|
|
@@ -1852,9 +1930,9 @@ export class TaskBoard {
|
|
|
1852
1930
|
add(card, card.assignee, "start", e.actor);
|
|
1853
1931
|
else if (d.from === "blocked" && d.to === "claimed")
|
|
1854
1932
|
add(card, card.assignee, "answered", e.actor, comments.get(card.uuid));
|
|
1855
|
-
else if (d.from === "review" && (d.to === "claimed" || d.to === "open")
|
|
1933
|
+
else if (d.from === "review" && (d.to === "claimed" || d.to === "open"))
|
|
1856
1934
|
add(card, card.assignee, "sent_back", e.actor, d.reason);
|
|
1857
|
-
else if (d.from === "review" && d.to === "done"
|
|
1935
|
+
else if (d.from === "review" && d.to === "done") {
|
|
1858
1936
|
add(card, card.assignee, "approved", e.actor, d.reason);
|
|
1859
1937
|
add(card, dispatcherOf(), "approved", e.actor, d.reason);
|
|
1860
1938
|
}
|
|
@@ -2087,8 +2165,8 @@ export class TaskBoard {
|
|
|
2087
2165
|
}
|
|
2088
2166
|
insert(card) {
|
|
2089
2167
|
this.db.prepare(`INSERT INTO tasks (id, code, kind, project_id, parent_id, title, description, status, priority, assignee, dispatcher, dispatcher_kind, created_by, depends_on, result,
|
|
2090
|
-
scope, acceptance, context, state, blocked_reason, size, needs_review, version, sort, created_at, updated_at, started_at, submitted_at, done_at, seen_entry_id)
|
|
2091
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(card.uuid, card.code, card.kind, card.projectId, card.parent, card.title, card.goal === "" ? null : card.goal, card.status, card.priority, card.assignee, card.dispatcher?.name ?? null, card.dispatcher?.kind ?? null, card.createdBy, card.deps.length ? JSON.stringify(card.deps) : null, card.result === "" ? null : card.result, card.scope, JSON.stringify(card.acceptance), card.context, card.state, card.blockedReason, card.size, card.needsReview ? 1 : 0, card.version, card.sort, card.createdAt, card.updatedAt, card.startedAt, card.submittedAt, card.doneAt, card.seenEntryId);
|
|
2168
|
+
scope, acceptance, context, state, blocked_reason, size, needs_review, version, sort, created_at, updated_at, started_at, submitted_at, done_at, seen_entry_id, on_board)
|
|
2169
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(card.uuid, card.code, card.kind, card.projectId, card.parent, card.title, card.goal === "" ? null : card.goal, card.status, card.priority, card.assignee, card.dispatcher?.name ?? null, card.dispatcher?.kind ?? null, card.createdBy, card.deps.length ? JSON.stringify(card.deps) : null, card.result === "" ? null : card.result, card.scope, JSON.stringify(card.acceptance), card.context, card.state, card.blockedReason, card.size, card.needsReview ? 1 : 0, card.version, card.sort, card.createdAt, card.updatedAt, card.startedAt, card.submittedAt, card.doneAt, card.seenEntryId, card.onBoard ? 1 : 0);
|
|
2092
2170
|
}
|
|
2093
2171
|
/** Empty text is stored as NULL in the columns the `task` tool has always had (description, result, depends_on). */
|
|
2094
2172
|
save(card) {
|