@songsid/agend 2.1.12 → 2.2.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/README.zh-TW.md +4 -2
- package/dist/agent-cli.js +6 -1
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.js +68 -12
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/agent-token-header.d.ts +13 -0
- package/dist/agent-token-header.js +16 -0
- package/dist/agent-token-header.js.map +1 -0
- package/dist/auth/one-time-code.d.ts +19 -0
- package/dist/auth/one-time-code.js +49 -0
- package/dist/auth/one-time-code.js.map +1 -0
- package/dist/auth-api.d.ts +52 -0
- package/dist/auth-api.js +346 -0
- package/dist/auth-api.js.map +1 -0
- package/dist/backend/antigravity.js +4 -3
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/claude-code.d.ts +4 -0
- package/dist/backend/claude-code.js +97 -0
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex.js +59 -30
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/grok.js +1 -1
- package/dist/backend/grok.js.map +1 -1
- package/dist/backend/kiro-agent.d.ts +66 -0
- package/dist/backend/kiro-agent.js +302 -0
- package/dist/backend/kiro-agent.js.map +1 -0
- package/dist/backend/kiro-identity.d.ts +80 -0
- package/dist/backend/kiro-identity.js +537 -0
- package/dist/backend/kiro-identity.js.map +1 -0
- package/dist/backend/kiro-v2-store-worker.d.ts +1 -0
- package/dist/backend/kiro-v2-store-worker.js +87 -0
- package/dist/backend/kiro-v2-store-worker.js.map +1 -0
- package/dist/backend/kiro-v2-store.d.ts +54 -0
- package/dist/backend/kiro-v2-store.js +131 -0
- package/dist/backend/kiro-v2-store.js.map +1 -0
- package/dist/backend/kiro-v3-identity.d.ts +5 -0
- package/dist/backend/kiro-v3-identity.js +22 -0
- package/dist/backend/kiro-v3-identity.js.map +1 -1
- package/dist/backend/kiro.d.ts +90 -7
- package/dist/backend/kiro.js +500 -124
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/muse.js +1 -1
- package/dist/backend/muse.js.map +1 -1
- package/dist/backend/types.d.ts +51 -3
- package/dist/backend/types.js.map +1 -1
- package/dist/cache-analysis.d.ts +92 -0
- package/dist/cache-analysis.js +147 -0
- package/dist/cache-analysis.js.map +1 -0
- package/dist/cache-ledger.d.ts +108 -0
- package/dist/cache-ledger.js +230 -0
- package/dist/cache-ledger.js.map +1 -0
- package/dist/cache-prices.d.ts +32 -0
- package/dist/cache-prices.js +73 -0
- package/dist/cache-prices.js.map +1 -0
- package/dist/cache-scan.d.ts +39 -0
- package/dist/cache-scan.js +115 -0
- package/dist/cache-scan.js.map +1 -0
- package/dist/cache-service.d.ts +115 -0
- package/dist/cache-service.js +417 -0
- package/dist/cache-service.js.map +1 -0
- package/dist/channel/adapters/discord.d.ts +1 -0
- package/dist/channel/adapters/discord.js +29 -10
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +1 -0
- package/dist/channel/adapters/telegram.js +13 -1
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/types.d.ts +9 -1
- package/dist/classic-channel-manager.d.ts +18 -10
- package/dist/classic-channel-manager.js +45 -18
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli-entry.d.ts +19 -0
- package/dist/cli-entry.js +36 -0
- package/dist/cli-entry.js.map +1 -0
- package/dist/cli.js +471 -146
- package/dist/cli.js.map +1 -1
- package/dist/command-table.d.ts +5 -3
- package/dist/command-table.js +29 -27
- package/dist/command-table.js.map +1 -1
- package/dist/config-validator.js +46 -0
- package/dist/config-validator.js.map +1 -1
- package/dist/config.js +12 -0
- package/dist/config.js.map +1 -1
- package/dist/connection-secrets.d.ts +6 -0
- package/dist/connection-secrets.js +4 -0
- package/dist/connection-secrets.js.map +1 -1
- package/dist/daemon.d.ts +95 -4
- package/dist/daemon.js +748 -111
- package/dist/daemon.js.map +1 -1
- package/dist/darwin-memory.d.ts +6 -1
- package/dist/darwin-memory.js +17 -6
- package/dist/darwin-memory.js.map +1 -1
- package/dist/delivery-consumed-watch.d.ts +85 -0
- package/dist/delivery-consumed-watch.js +244 -0
- package/dist/delivery-consumed-watch.js.map +1 -0
- package/dist/delivery-outbox.d.ts +61 -0
- package/dist/delivery-outbox.js +120 -2
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/delivery-reconciliation.d.ts +14 -5
- package/dist/delivery-reconciliation.js +27 -4
- package/dist/delivery-reconciliation.js.map +1 -1
- package/dist/delivery-reconciliation.test.js +35 -1
- package/dist/delivery-reconciliation.test.js.map +1 -1
- package/dist/event-log.d.ts +4 -1
- package/dist/event-log.js +6 -3
- package/dist/event-log.js.map +1 -1
- package/dist/event-loop-watch.d.ts +28 -0
- package/dist/event-loop-watch.js +75 -3
- package/dist/event-loop-watch.js.map +1 -1
- package/dist/fleet-context.d.ts +22 -2
- package/dist/fleet-control-audit.d.ts +5 -0
- package/dist/fleet-control-audit.js +7 -0
- package/dist/fleet-control-audit.js.map +1 -1
- package/dist/fleet-level-config.d.ts +2 -2
- package/dist/fleet-level-config.js +28 -1
- package/dist/fleet-level-config.js.map +1 -1
- package/dist/fleet-manager.d.ts +339 -12
- package/dist/fleet-manager.js +2623 -461
- package/dist/fleet-manager.js.map +1 -1
- package/dist/full-restart.js +2 -3
- package/dist/full-restart.js.map +1 -1
- package/dist/general-knowledge/skills/persona-emoji/SKILL.md +3 -1
- package/dist/host-memory.d.ts +4 -0
- package/dist/host-memory.js.map +1 -1
- package/dist/install-lock.d.ts +49 -0
- package/dist/install-lock.js +200 -0
- package/dist/install-lock.js.map +1 -0
- package/dist/instance-config-impact.js +8 -2
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +10 -5
- package/dist/instance-lifecycle.js +162 -53
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/locale.js +164 -16
- package/dist/locale.js.map +1 -1
- package/dist/login-controller.d.ts +2 -0
- package/dist/login-controller.js +17 -5
- package/dist/login-controller.js.map +1 -1
- package/dist/memory-pressure.d.ts +7 -8
- package/dist/memory-pressure.js +76 -15
- package/dist/memory-pressure.js.map +1 -1
- package/dist/monotonic-budget.d.ts +2 -0
- package/dist/monotonic-budget.js +28 -0
- package/dist/monotonic-budget.js.map +1 -0
- package/dist/needs-you-hub.d.ts +114 -0
- package/dist/needs-you-hub.js +370 -0
- package/dist/needs-you-hub.js.map +1 -0
- package/dist/needs-you-live.d.ts +116 -0
- package/dist/needs-you-live.js +228 -0
- package/dist/needs-you-live.js.map +1 -0
- package/dist/needs-you.d.ts +132 -0
- package/dist/needs-you.js +164 -0
- package/dist/needs-you.js.map +1 -0
- package/dist/node-version-guard.d.ts +30 -0
- package/dist/node-version-guard.js +50 -0
- package/dist/node-version-guard.js.map +1 -0
- package/dist/operator-control-paths.d.ts +4 -0
- package/dist/operator-control-paths.js +24 -0
- package/dist/operator-control-paths.js.map +1 -0
- package/dist/outbound-handlers.d.ts +2 -0
- package/dist/outbound-handlers.js +9 -2
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +5 -5
- package/dist/outbound-schemas.js +1 -1
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/package-preimage.d.ts +26 -0
- package/dist/package-preimage.js +96 -0
- package/dist/package-preimage.js.map +1 -0
- package/dist/profile-control.js +4 -20
- package/dist/profile-control.js.map +1 -1
- package/dist/public-web-gateway.d.ts +18 -0
- package/dist/public-web-gateway.js +141 -0
- package/dist/public-web-gateway.js.map +1 -0
- package/dist/public-web-link.d.ts +53 -0
- package/dist/public-web-link.js +175 -0
- package/dist/public-web-link.js.map +1 -0
- package/dist/quickstart-api.d.ts +8 -1
- package/dist/quickstart-api.js +86 -48
- package/dist/quickstart-api.js.map +1 -1
- package/dist/quickstart.d.ts +1 -0
- package/dist/quickstart.js +16 -6
- package/dist/quickstart.js.map +1 -1
- package/dist/restart-guard.d.ts +52 -0
- package/dist/restart-guard.js +109 -0
- package/dist/restart-guard.js.map +1 -0
- package/dist/scheduler/db.d.ts +7 -1
- package/dist/scheduler/db.js +44 -2
- package/dist/scheduler/db.js.map +1 -1
- package/dist/scheduler/index.d.ts +1 -1
- package/dist/scheduler/retry-label.d.ts +11 -0
- package/dist/scheduler/retry-label.js +24 -0
- package/dist/scheduler/retry-label.js.map +1 -0
- package/dist/scheduler/scheduler.d.ts +55 -2
- package/dist/scheduler/scheduler.js +220 -8
- package/dist/scheduler/scheduler.js.map +1 -1
- package/dist/scheduler/types.d.ts +22 -0
- package/dist/scheduler/types.js.map +1 -1
- package/dist/secret-store.d.ts +5 -0
- package/dist/secret-store.js +20 -0
- package/dist/secret-store.js.map +1 -1
- package/dist/service-activation.d.ts +152 -0
- package/dist/service-activation.js +407 -0
- package/dist/service-activation.js.map +1 -0
- package/dist/service-installer.d.ts +63 -1
- package/dist/service-installer.js +141 -16
- package/dist/service-installer.js.map +1 -1
- package/dist/service-plan.d.ts +65 -0
- package/dist/service-plan.js +108 -0
- package/dist/service-plan.js.map +1 -0
- package/dist/service-restart-selection.d.ts +6 -5
- package/dist/service-restart-selection.js +6 -5
- package/dist/service-restart-selection.js.map +1 -1
- package/dist/settings-api.d.ts +10 -2
- package/dist/settings-api.js +216 -72
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-baseline.d.ts +20 -0
- package/dist/settings-baseline.js +104 -0
- package/dist/settings-baseline.js.map +1 -0
- package/dist/settings-change.d.ts +21 -0
- package/dist/settings-change.js +161 -0
- package/dist/settings-change.js.map +1 -0
- package/dist/settings-confirmation.d.ts +105 -0
- package/dist/settings-confirmation.js +232 -0
- package/dist/settings-confirmation.js.map +1 -0
- package/dist/settings-control.d.ts +41 -0
- package/dist/settings-control.js +294 -0
- package/dist/settings-control.js.map +1 -0
- package/dist/settings-effect.d.ts +24 -0
- package/dist/settings-effect.js +169 -0
- package/dist/settings-effect.js.map +1 -0
- package/dist/settings-http-confirmation.d.ts +29 -0
- package/dist/settings-http-confirmation.js +123 -0
- package/dist/settings-http-confirmation.js.map +1 -0
- package/dist/settings-instance-patch.d.ts +4 -0
- package/dist/settings-instance-patch.js +26 -0
- package/dist/settings-instance-patch.js.map +1 -0
- package/dist/settings-request-capability.d.ts +16 -0
- package/dist/settings-request-capability.js +32 -0
- package/dist/settings-request-capability.js.map +1 -0
- package/dist/settings-transaction.d.ts +65 -0
- package/dist/settings-transaction.js +223 -0
- package/dist/settings-transaction.js.map +1 -0
- package/dist/setup-auth.d.ts +10 -18
- package/dist/setup-auth.js +14 -38
- package/dist/setup-auth.js.map +1 -1
- package/dist/setup-form.d.ts +1 -1
- package/dist/setup-form.js +75 -18
- package/dist/setup-form.js.map +1 -1
- package/dist/setup-guide.d.ts +13 -0
- package/dist/setup-guide.js +25 -0
- package/dist/setup-guide.js.map +1 -0
- package/dist/setup-host.d.ts +16 -0
- package/dist/setup-host.js +199 -35
- package/dist/setup-host.js.map +1 -1
- package/dist/setup-wizard.js +5 -1
- package/dist/setup-wizard.js.map +1 -1
- package/dist/slash-authz.d.ts +17 -3
- package/dist/slash-authz.js +5 -0
- package/dist/slash-authz.js.map +1 -1
- package/dist/spawn-gate.js +3 -3
- package/dist/spawn-gate.js.map +1 -1
- package/dist/sqlite-open-errors.d.ts +12 -0
- package/dist/sqlite-open-errors.js +13 -0
- package/dist/sqlite-open-errors.js.map +1 -0
- package/dist/statusline-watcher.d.ts +5 -0
- package/dist/statusline-watcher.js +2 -0
- package/dist/statusline-watcher.js.map +1 -1
- package/dist/steer-capability.d.ts +6 -0
- package/dist/steer-capability.js +8 -0
- package/dist/steer-capability.js.map +1 -1
- package/dist/sync-work-attribution.d.ts +14 -0
- package/dist/sync-work-attribution.js +43 -8
- package/dist/sync-work-attribution.js.map +1 -1
- package/dist/tips.js +10 -5
- package/dist/tips.js.map +1 -1
- package/dist/tmux-control.d.ts +57 -5
- package/dist/tmux-control.js +379 -61
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-manager.d.ts +20 -6
- package/dist/tmux-manager.js +90 -47
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tmux-read.d.ts +59 -0
- package/dist/tmux-read.js +213 -0
- package/dist/tmux-read.js.map +1 -0
- package/dist/topic-commands.d.ts +21 -10
- package/dist/topic-commands.js +205 -63
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-delta-reader.js +2 -1
- package/dist/transcript-delta-reader.js.map +1 -1
- package/dist/tunnel/cloudflared-install.d.ts +2 -0
- package/dist/tunnel/cloudflared-install.js +1 -1
- package/dist/tunnel/cloudflared-install.js.map +1 -1
- package/dist/tunnel/purpose-lane.d.ts +14 -0
- package/dist/tunnel/purpose-lane.js +43 -0
- package/dist/tunnel/purpose-lane.js.map +1 -0
- package/dist/turn-reply-guard.d.ts +2 -0
- package/dist/turn-reply-guard.js +10 -1
- package/dist/turn-reply-guard.js.map +1 -1
- package/dist/types.d.ts +33 -0
- package/dist/ui/app.html +18 -0
- package/dist/ui/chat-commands.js +43 -0
- package/dist/ui/chat-render.js +478 -0
- package/dist/ui/chat-store.js +318 -0
- package/dist/ui/chat-strings.js +89 -0
- package/dist/ui/chat-thread.js +246 -0
- package/dist/ui/chat-tour.js +116 -0
- package/dist/ui/fleet-cache.js +168 -0
- package/dist/ui/fleet-org.js +142 -0
- package/dist/ui/panel-chat.js +504 -0
- package/dist/ui/panel-fleet.js +427 -0
- package/dist/ui/panel-needs.js +202 -0
- package/dist/ui/panel-settings.js +754 -0
- package/dist/ui/preview-panel.js +202 -0
- package/dist/ui/preview.js +270 -0
- package/dist/ui/settings-apply.js +239 -0
- package/dist/ui/settings-confirm.js +186 -0
- package/dist/ui/settings-dialogs.js +546 -0
- package/dist/ui/settings-model.js +277 -0
- package/dist/ui/settings-strings.js +654 -0
- package/dist/ui/settings-wizard.js +140 -0
- package/dist/ui/shared/agend-auth.js +93 -0
- package/dist/ui/shared/app-ctx.js +80 -0
- package/dist/ui/shared/app-html.js +9 -0
- package/dist/ui/shared/app-i18n.js +95 -0
- package/dist/ui/shared/app-nav.js +73 -0
- package/dist/ui/shared/app-needs.js +114 -0
- package/dist/ui/shared/app-route.js +73 -0
- package/dist/ui/shared/app-session.js +66 -0
- package/dist/ui/shared/app-shell.js +346 -0
- package/dist/ui/shared/app-store.js +51 -0
- package/dist/ui/shared/app-stream.js +201 -0
- package/dist/ui/shared/app.css +820 -0
- package/dist/ui/shared/app.js +88 -0
- package/dist/ui/shared/fonts/OFL.txt +92 -0
- package/dist/ui/shared/fonts/README.md +21 -0
- package/dist/ui/shared/fonts/inter.woff2 +0 -0
- package/dist/ui/shared/htm.module.js +1 -0
- package/dist/ui/shared/panel-view.js +655 -0
- package/dist/ui/shared/preact-hooks.module.js +2 -0
- package/dist/ui/shared/preact.module.js +2 -0
- package/dist/ui/shared/signin.js +142 -0
- package/dist/ui/shared/theme.js +29 -0
- package/dist/ui/shared/tokens.css +153 -0
- package/dist/ui/shared/ui-confirm.js +43 -0
- package/dist/ui/shared/ui-dialog.js +45 -0
- package/dist/ui/shared/ui-icons.js +63 -0
- package/dist/ui/shared/ui-menu.js +39 -0
- package/dist/ui/shared/ui-states.js +20 -0
- package/dist/ui/shared/ui-toast.js +18 -0
- package/dist/ui/shared/vendor/htm.LICENSE +202 -0
- package/dist/ui/shared/vendor/preact.LICENSE +21 -0
- package/dist/ui/shared/vendor/vendor.json +39 -0
- package/dist/ui/shared/view-strings.js +309 -0
- package/dist/ui/signin.html +52 -0
- package/dist/update-check.d.ts +6 -2
- package/dist/update-check.js +12 -3
- package/dist/update-check.js.map +1 -1
- package/dist/update-dispatch.d.ts +28 -0
- package/dist/update-dispatch.js +73 -0
- package/dist/update-dispatch.js.map +1 -0
- package/dist/update-install.d.ts +129 -0
- package/dist/update-install.js +262 -0
- package/dist/update-install.js.map +1 -0
- package/dist/upgrade-notices.d.ts +17 -0
- package/dist/upgrade-notices.js +93 -0
- package/dist/upgrade-notices.js.map +1 -0
- package/dist/usage/statusline-usage.d.ts +2 -0
- package/dist/usage/statusline-usage.js +14 -10
- package/dist/usage/statusline-usage.js.map +1 -1
- package/dist/view-api.d.ts +6 -1
- package/dist/view-api.js +62 -51
- package/dist/view-api.js.map +1 -1
- package/dist/web-api.d.ts +85 -14
- package/dist/web-api.js +557 -77
- package/dist/web-api.js.map +1 -1
- package/dist/web-auth.d.ts +71 -27
- package/dist/web-auth.js +169 -69
- package/dist/web-auth.js.map +1 -1
- package/dist/web-body.d.ts +3 -0
- package/dist/web-body.js +55 -0
- package/dist/web-body.js.map +1 -0
- package/dist/web-channel-echo.d.ts +9 -0
- package/dist/web-channel-echo.js +55 -0
- package/dist/web-channel-echo.js.map +1 -0
- package/dist/web-chat-history.d.ts +125 -0
- package/dist/web-chat-history.js +184 -0
- package/dist/web-chat-history.js.map +1 -0
- package/dist/web-commands.d.ts +77 -0
- package/dist/web-commands.js +81 -0
- package/dist/web-commands.js.map +1 -0
- package/dist/web-continuation.d.ts +7 -0
- package/dist/web-continuation.js +22 -0
- package/dist/web-continuation.js.map +1 -0
- package/dist/web-host-guard.d.ts +34 -0
- package/dist/web-host-guard.js +57 -1
- package/dist/web-host-guard.js.map +1 -1
- package/dist/web-login.d.ts +72 -0
- package/dist/web-login.js +132 -0
- package/dist/web-login.js.map +1 -0
- package/dist/web-org.d.ts +55 -0
- package/dist/web-org.js +67 -0
- package/dist/web-org.js.map +1 -0
- package/dist/web-preview.d.ts +77 -0
- package/dist/web-preview.js +240 -0
- package/dist/web-preview.js.map +1 -0
- package/dist/web-request-context.d.ts +10 -0
- package/dist/web-request-context.js +13 -0
- package/dist/web-request-context.js.map +1 -0
- package/dist/web-session.d.ts +167 -0
- package/dist/web-session.js +389 -0
- package/dist/web-session.js.map +1 -0
- package/dist/web-shell-routes.d.ts +59 -0
- package/dist/web-shell-routes.js +96 -0
- package/dist/web-shell-routes.js.map +1 -0
- package/dist/web-upload.d.ts +183 -0
- package/dist/web-upload.js +468 -0
- package/dist/web-upload.js.map +1 -0
- package/dist/website-tips-renderer.d.ts +2 -2
- package/dist/website-tips-renderer.js +3 -3
- package/dist/website-tips-renderer.js.map +1 -1
- package/launcher/agend +110 -0
- package/launcher/agend-agent +110 -0
- package/launcher/agend-agent.cjs +4 -0
- package/launcher/agend.cjs +4 -0
- package/launcher/install-admission.cjs +105 -0
- package/launcher/launch.cjs +64 -0
- package/launcher/postinstall.cjs +114 -0
- package/launcher/run-in-process.cjs +13 -0
- package/launcher/runtime-platform.cjs +86 -0
- package/launcher/runtime-select.cjs +217 -0
- package/package.json +18 -7
- package/scripts/preinstall-guard.cjs +55 -0
- package/templates/launchd.plist.ejs +2 -2
- package/templates/systemd.service.ejs +1 -1
- package/dist/ui/dashboard.html +0 -774
- package/dist/ui/settings.html +0 -2165
- package/dist/ui/view.html +0 -1139
package/dist/darwin-memory.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import type { HostMemory } from "./host-memory.js";
|
|
|
2
2
|
export declare const DARWIN_MEMORY_DEADLINE_MS = 2000;
|
|
3
3
|
export declare const DARWIN_MEMORY_CACHE_MS = 30000;
|
|
4
4
|
export declare function unknownDarwinMemory(totalBytes: number): HostMemory;
|
|
5
|
+
/** XNU exposes NOTE_MEMORYSTATUS_PRESSURE_* (1/2/4), not its internal 0/1/2/3 enum. */
|
|
6
|
+
export declare function parseDarwinPressureLevel(text: string): HostMemory["darwinPressureLevel"];
|
|
5
7
|
/** vm_stat's printed free count excludes speculative pages. Purgeable can overlap inactive. */
|
|
6
8
|
export declare function parseDarwinAvailable(text: string, totalBytes: number): number | null;
|
|
7
9
|
/** sysctl prints binary MiB to two decimals, including the valid unallocated 0/0 pool. */
|
|
@@ -18,12 +20,15 @@ interface Options {
|
|
|
18
20
|
run?: MemoryCommandRunner;
|
|
19
21
|
totalmem?: () => number;
|
|
20
22
|
now?: () => number;
|
|
23
|
+
/** Only the periodic fleet sampler requests the kernel alarm. Diagnostics do not fork for it. */
|
|
24
|
+
includePressure?: boolean;
|
|
21
25
|
}
|
|
22
|
-
/** One bounded logical read and at most one physical
|
|
26
|
+
/** One bounded logical read and at most one physical batch, even across stop/restart. */
|
|
23
27
|
export declare class DarwinMemoryProbe {
|
|
24
28
|
private readonly run;
|
|
25
29
|
private readonly total;
|
|
26
30
|
private readonly now;
|
|
31
|
+
private readonly includePressure;
|
|
27
32
|
private flight;
|
|
28
33
|
private cache;
|
|
29
34
|
private epoch;
|
package/dist/darwin-memory.js
CHANGED
|
@@ -4,7 +4,12 @@ export const DARWIN_MEMORY_DEADLINE_MS = 2_000;
|
|
|
4
4
|
export const DARWIN_MEMORY_CACHE_MS = 30_000;
|
|
5
5
|
const MAX_OUTPUT = 32 * 1024;
|
|
6
6
|
export function unknownDarwinMemory(totalBytes) {
|
|
7
|
-
return { totalBytes, availableBytes: null, availableKind: "unknown", swapTotalBytes: null, swapFreeBytes: null };
|
|
7
|
+
return { totalBytes, availableBytes: null, availableKind: "unknown", swapTotalBytes: null, swapFreeBytes: null, darwinPressureLevel: null, darwinPressureRaw: null };
|
|
8
|
+
}
|
|
9
|
+
/** XNU exposes NOTE_MEMORYSTATUS_PRESSURE_* (1/2/4), not its internal 0/1/2/3 enum. */
|
|
10
|
+
export function parseDarwinPressureLevel(text) {
|
|
11
|
+
const match = /^kern\.memorystatus_vm_pressure_level:[ \t]+([124])[ \t]*\r?\n?$/.exec(text);
|
|
12
|
+
return match && match[0].length === text.length ? Number(match[1]) : null;
|
|
8
13
|
}
|
|
9
14
|
/** vm_stat's printed free count excludes speculative pages. Purgeable can overlap inactive. */
|
|
10
15
|
export function parseDarwinAvailable(text, totalBytes) {
|
|
@@ -66,11 +71,12 @@ export const runMemoryCommand = (file, args) => {
|
|
|
66
71
|
return { result, stopped, kill: () => { } };
|
|
67
72
|
}
|
|
68
73
|
};
|
|
69
|
-
/** One bounded logical read and at most one physical
|
|
74
|
+
/** One bounded logical read and at most one physical batch, even across stop/restart. */
|
|
70
75
|
export class DarwinMemoryProbe {
|
|
71
76
|
run;
|
|
72
77
|
total;
|
|
73
78
|
now;
|
|
79
|
+
includePressure;
|
|
74
80
|
flight = null;
|
|
75
81
|
cache = null;
|
|
76
82
|
epoch = 0;
|
|
@@ -78,11 +84,12 @@ export class DarwinMemoryProbe {
|
|
|
78
84
|
this.run = options.run ?? runMemoryCommand;
|
|
79
85
|
this.total = options.totalmem ?? totalmem;
|
|
80
86
|
this.now = options.now ?? (() => performance.now());
|
|
87
|
+
this.includePressure = options.includePressure ?? false;
|
|
81
88
|
}
|
|
82
89
|
read() {
|
|
83
90
|
if (this.cache && this.now() - this.cache.at < DARWIN_MEMORY_CACHE_MS)
|
|
84
91
|
return Promise.resolve({ ...this.cache.memory });
|
|
85
|
-
// A timed-out or cancelled
|
|
92
|
+
// A timed-out or cancelled batch still owns its physical reservation.
|
|
86
93
|
if (this.flight) {
|
|
87
94
|
const flight = this.flight;
|
|
88
95
|
if (flight.completed)
|
|
@@ -121,7 +128,10 @@ export class DarwinMemoryProbe {
|
|
|
121
128
|
// Start the deadline before either constructor; a slow constructor cannot earn extra time.
|
|
122
129
|
timer = setTimeout(cancel, DARWIN_MEMORY_DEADLINE_MS);
|
|
123
130
|
timer.unref?.();
|
|
124
|
-
|
|
131
|
+
const requests = [["/usr/bin/vm_stat", []], ["/usr/sbin/sysctl", ["vm.swapusage"]]];
|
|
132
|
+
if (this.includePressure)
|
|
133
|
+
requests.push(["/usr/sbin/sysctl", ["kern.memorystatus_vm_pressure_level"]]);
|
|
134
|
+
for (const [file, args] of requests) {
|
|
125
135
|
if (this.now() >= deadlineAt) {
|
|
126
136
|
cancel();
|
|
127
137
|
break;
|
|
@@ -141,8 +151,9 @@ export class DarwinMemoryProbe {
|
|
|
141
151
|
return;
|
|
142
152
|
}
|
|
143
153
|
const available = outputs[0] === null || outputs[0] === undefined ? null : parseDarwinAvailable(outputs[0], totalBytes);
|
|
144
|
-
finish(available === null ? unknown : { totalBytes, availableBytes: available, availableKind: "available",
|
|
145
|
-
|
|
154
|
+
finish({ ...(available === null ? unknown : { totalBytes, availableBytes: available, availableKind: "available",
|
|
155
|
+
...parseDarwinSwap(outputs[1] ?? "") }), darwinPressureLevel: parseDarwinPressureLevel(outputs[2] ?? ""),
|
|
156
|
+
darwinPressureRaw: outputs[2]?.slice(0, 1024) ?? null });
|
|
146
157
|
});
|
|
147
158
|
// Never release on kill request/result alone. Rejected cleanup remains reserved.
|
|
148
159
|
void Promise.all(commands.map(command => command.stopped.catch(() => new Promise(() => { })))).then(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"darwin-memory.js","sourceRoot":"","sources":["../src/darwin-memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGnC,MAAM,CAAC,MAAM,yBAAyB,GAAG,KAAK,CAAC;AAC/C,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAC7C,MAAM,UAAU,GAAG,EAAE,GAAG,IAAI,CAAC;AAE7B,MAAM,UAAU,mBAAmB,CAAC,UAAkB;IACpD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"darwin-memory.js","sourceRoot":"","sources":["../src/darwin-memory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { ConsumedVia } from "./delivery-outbox.js";
|
|
2
|
+
export declare const CONSUMED_WATCH: {
|
|
3
|
+
/** Watches alive at once across the fleet. */
|
|
4
|
+
maxWatchers: number;
|
|
5
|
+
/** Bytes one look reads past its offset. */
|
|
6
|
+
chunkBytes: number;
|
|
7
|
+
/** A line longer than this (without its newline) is never decoded: skipped. */
|
|
8
|
+
maxLineBytes: number;
|
|
9
|
+
/** First interval between looks. */
|
|
10
|
+
tickMs: number;
|
|
11
|
+
/** Interval while a backlog is being read (the file is ahead of the offset). */
|
|
12
|
+
catchUpMs: number;
|
|
13
|
+
/** Consecutive looks with no growth before the interval doubles… */
|
|
14
|
+
idleLooksBeforeBackoff: number;
|
|
15
|
+
/** …up to this. */
|
|
16
|
+
maxTickMs: number;
|
|
17
|
+
/** A watch ends after this long (monotonic) whatever it saw. */
|
|
18
|
+
lifetimeMs: number;
|
|
19
|
+
};
|
|
20
|
+
export interface ConsumedWatchTarget {
|
|
21
|
+
deliveryId: string;
|
|
22
|
+
attemptNo: number;
|
|
23
|
+
backend: string;
|
|
24
|
+
path: string;
|
|
25
|
+
offset: number;
|
|
26
|
+
/** False once the attempt's CLI is no longer the one we wrote to (stop, pause, respawn): the watch ends quietly. */
|
|
27
|
+
current(): boolean;
|
|
28
|
+
/** The hit: record it (the outbox decides what it changes). */
|
|
29
|
+
consumed(via: ConsumedVia, evidence: string): void;
|
|
30
|
+
logger?: {
|
|
31
|
+
info(obj: unknown, msg?: string): void;
|
|
32
|
+
warn(obj: unknown, msg?: string): void;
|
|
33
|
+
debug?(obj: unknown, msg?: string): void;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
type Ended = "consumed" | "fenced" | "unavailable" | "expired" | "stopped";
|
|
37
|
+
/** One attempt's watch. Exported for its tests; the fleet starts watches through ConsumedWatchRegistry. */
|
|
38
|
+
export declare class ConsumedWatch {
|
|
39
|
+
private readonly target;
|
|
40
|
+
private readonly onEnd;
|
|
41
|
+
private offset;
|
|
42
|
+
private carry;
|
|
43
|
+
/** The current line overran maxLineBytes: discard bytes until the next newline. */
|
|
44
|
+
private skippingLine;
|
|
45
|
+
private idleLooks;
|
|
46
|
+
private interval;
|
|
47
|
+
private timer;
|
|
48
|
+
private readonly startedAt;
|
|
49
|
+
private ended;
|
|
50
|
+
constructor(target: ConsumedWatchTarget, onEnd: (why: Ended) => void);
|
|
51
|
+
start(): void;
|
|
52
|
+
/** Where the next look reads from (tests). */
|
|
53
|
+
get position(): number;
|
|
54
|
+
/** The interval between looks the watch is at now (tests). */
|
|
55
|
+
get currentInterval(): number;
|
|
56
|
+
/** Bytes of an unfinished line held between looks — never more than CONSUMED_WATCH.maxLineBytes (tests). */
|
|
57
|
+
get carriedBytes(): number;
|
|
58
|
+
stop(): void;
|
|
59
|
+
private schedule;
|
|
60
|
+
private end;
|
|
61
|
+
/**
|
|
62
|
+
* Whether this watch may still act, asked before the first await and again after each one: stopped, its CLI gone
|
|
63
|
+
* (stop, pause, respawn) or its lifetime over ends it — a read that returns after any of those proves nothing.
|
|
64
|
+
*/
|
|
65
|
+
private stillLive;
|
|
66
|
+
/** One bounded look. Never throws; every outcome either schedules the next look or ends the watch. */
|
|
67
|
+
look(): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Complete lines of this chunk (plus the carried start of a line), judged once each. Every line is held to
|
|
70
|
+
* maxLineBytes BEFORE it is decoded — one that completes past the cap is skipped like one that never completes —
|
|
71
|
+
* and only the lines within it are parsed (#1201 review).
|
|
72
|
+
*/
|
|
73
|
+
private scan;
|
|
74
|
+
}
|
|
75
|
+
/** The fleet's watches (one process): started per attempt, capped, ended by their own look or by stopAll. */
|
|
76
|
+
export declare class ConsumedWatchRegistry {
|
|
77
|
+
private readonly active;
|
|
78
|
+
get size(): number;
|
|
79
|
+
/** Starts a watch for this attempt; false when one runs already or the fleet is at the cap (logged). */
|
|
80
|
+
start(target: ConsumedWatchTarget): boolean;
|
|
81
|
+
/** For tests and shutdown: end every watch without a verdict. */
|
|
82
|
+
stopAll(): void;
|
|
83
|
+
}
|
|
84
|
+
export declare const consumedWatches: ConsumedWatchRegistry;
|
|
85
|
+
export {};
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #1201: a late, quiet "consumed" signal for a delivery the CLI took into its own queue — a steer, or a hand-off into
|
|
3
|
+
* a busy CLI's native queue. Such a delivery settles `delivered` (accepted into the CLI's input) or `uncertain` long
|
|
4
|
+
* before the model reads it: Claude Code takes a queued message at the next tool boundary or when the turn ends, which
|
|
5
|
+
* can be minutes later, and records it in its transcript then. The watcher reads the transcript from the attempt's
|
|
6
|
+
* checkpoint and, on the delivery's exact marker in a consumed shape (transcriptDeltaDeliveryMarker: a user entry, or
|
|
7
|
+
* Claude's absorbed-mid-turn queued command), records it through the outbox (DeliveryOutbox.markConsumed).
|
|
8
|
+
*
|
|
9
|
+
* Positive evidence only: a hit upgrades; a miss, an unreadable file, a fence or the end of the watch change nothing.
|
|
10
|
+
*
|
|
11
|
+
* It runs on the fleet's event loop, so it is built not to be felt there (#1235):
|
|
12
|
+
* - every read is async and bounded: one look reads at most CONSUMED_WATCH.chunkBytes from where the previous one
|
|
13
|
+
* stopped, and a larger backlog continues on the following looks;
|
|
14
|
+
* - only complete lines are parsed, each held to CONSUMED_WATCH.maxLineBytes before it is decoded; a longer one (TUI logs
|
|
15
|
+
* can run megabytes without a newline) is skipped whole — complete or not — and proves nothing; the lines after it
|
|
16
|
+
* are still judged;
|
|
17
|
+
* - the number of watches in the process (the fleet) is capped; one over the cap is logged and not started;
|
|
18
|
+
* - a transcript that does not grow is looked at less and less often, and every watch ends after a fixed lifetime,
|
|
19
|
+
* measured on the monotonic clock and checked again after every await (a read that returns late proves nothing).
|
|
20
|
+
*/
|
|
21
|
+
import { open, stat } from "node:fs/promises";
|
|
22
|
+
import { performance } from "node:perf_hooks";
|
|
23
|
+
import { transcriptDeltaDeliveryMarker } from "./delivery-reconciliation.js";
|
|
24
|
+
import { measureSyncWork } from "./sync-work-attribution.js";
|
|
25
|
+
export const CONSUMED_WATCH = {
|
|
26
|
+
/** Watches alive at once across the fleet. */
|
|
27
|
+
maxWatchers: 32,
|
|
28
|
+
/** Bytes one look reads past its offset. */
|
|
29
|
+
chunkBytes: 256 * 1024,
|
|
30
|
+
/** A line longer than this (without its newline) is never decoded: skipped. */
|
|
31
|
+
maxLineBytes: 256 * 1024,
|
|
32
|
+
/** First interval between looks. */
|
|
33
|
+
tickMs: 5_000,
|
|
34
|
+
/** Interval while a backlog is being read (the file is ahead of the offset). */
|
|
35
|
+
catchUpMs: 50,
|
|
36
|
+
/** Consecutive looks with no growth before the interval doubles… */
|
|
37
|
+
idleLooksBeforeBackoff: 6,
|
|
38
|
+
/** …up to this. */
|
|
39
|
+
maxTickMs: 60_000,
|
|
40
|
+
/** A watch ends after this long (monotonic) whatever it saw. */
|
|
41
|
+
lifetimeMs: 30 * 60_000,
|
|
42
|
+
};
|
|
43
|
+
/** One attempt's watch. Exported for its tests; the fleet starts watches through ConsumedWatchRegistry. */
|
|
44
|
+
export class ConsumedWatch {
|
|
45
|
+
target;
|
|
46
|
+
onEnd;
|
|
47
|
+
offset;
|
|
48
|
+
carry = Buffer.alloc(0);
|
|
49
|
+
/** The current line overran maxLineBytes: discard bytes until the next newline. */
|
|
50
|
+
skippingLine = false;
|
|
51
|
+
idleLooks = 0;
|
|
52
|
+
interval = CONSUMED_WATCH.tickMs;
|
|
53
|
+
timer = null;
|
|
54
|
+
startedAt = performance.now();
|
|
55
|
+
ended = false;
|
|
56
|
+
constructor(target, onEnd) {
|
|
57
|
+
this.target = target;
|
|
58
|
+
this.onEnd = onEnd;
|
|
59
|
+
this.offset = target.offset;
|
|
60
|
+
}
|
|
61
|
+
start() { this.schedule(CONSUMED_WATCH.tickMs); }
|
|
62
|
+
/** Where the next look reads from (tests). */
|
|
63
|
+
get position() { return this.offset; }
|
|
64
|
+
/** The interval between looks the watch is at now (tests). */
|
|
65
|
+
get currentInterval() { return this.interval; }
|
|
66
|
+
/** Bytes of an unfinished line held between looks — never more than CONSUMED_WATCH.maxLineBytes (tests). */
|
|
67
|
+
get carriedBytes() { return this.carry.length; }
|
|
68
|
+
stop() { this.end("stopped"); }
|
|
69
|
+
schedule(ms) {
|
|
70
|
+
if (this.ended)
|
|
71
|
+
return;
|
|
72
|
+
this.timer = setTimeout(() => { void this.look(); }, ms);
|
|
73
|
+
this.timer.unref?.();
|
|
74
|
+
}
|
|
75
|
+
end(why) {
|
|
76
|
+
if (this.ended)
|
|
77
|
+
return;
|
|
78
|
+
this.ended = true;
|
|
79
|
+
if (this.timer)
|
|
80
|
+
clearTimeout(this.timer);
|
|
81
|
+
this.timer = null;
|
|
82
|
+
this.onEnd(why);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Whether this watch may still act, asked before the first await and again after each one: stopped, its CLI gone
|
|
86
|
+
* (stop, pause, respawn) or its lifetime over ends it — a read that returns after any of those proves nothing.
|
|
87
|
+
*/
|
|
88
|
+
stillLive() {
|
|
89
|
+
if (this.ended)
|
|
90
|
+
return false;
|
|
91
|
+
if (!this.target.current()) {
|
|
92
|
+
this.end("fenced");
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
if (performance.now() - this.startedAt >= CONSUMED_WATCH.lifetimeMs) {
|
|
96
|
+
this.end("expired");
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
/** One bounded look. Never throws; every outcome either schedules the next look or ends the watch. */
|
|
102
|
+
async look() {
|
|
103
|
+
if (this.ended)
|
|
104
|
+
return;
|
|
105
|
+
try {
|
|
106
|
+
if (!this.stillLive())
|
|
107
|
+
return;
|
|
108
|
+
let size;
|
|
109
|
+
try {
|
|
110
|
+
size = (await stat(this.target.path)).size;
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return this.end("unavailable");
|
|
114
|
+
}
|
|
115
|
+
if (!this.stillLive())
|
|
116
|
+
return;
|
|
117
|
+
if (size < this.offset)
|
|
118
|
+
return this.end("unavailable"); // rotated or truncated below our offset
|
|
119
|
+
if (size === this.offset) {
|
|
120
|
+
if (++this.idleLooks >= CONSUMED_WATCH.idleLooksBeforeBackoff) {
|
|
121
|
+
this.idleLooks = 0;
|
|
122
|
+
this.interval = Math.min(this.interval * 2, CONSUMED_WATCH.maxTickMs);
|
|
123
|
+
}
|
|
124
|
+
return this.schedule(this.interval);
|
|
125
|
+
}
|
|
126
|
+
this.idleLooks = 0;
|
|
127
|
+
const length = Math.min(CONSUMED_WATCH.chunkBytes, size - this.offset);
|
|
128
|
+
const chunk = await readAt(this.target.path, this.offset, length);
|
|
129
|
+
if (!this.stillLive())
|
|
130
|
+
return;
|
|
131
|
+
if (!chunk)
|
|
132
|
+
return this.end("unavailable");
|
|
133
|
+
this.offset += chunk.length;
|
|
134
|
+
const found = measureSyncWork("consumedWatch.scan", () => this.scan(chunk));
|
|
135
|
+
if (found) {
|
|
136
|
+
this.target.consumed(found.via, found.evidence);
|
|
137
|
+
return this.end("consumed");
|
|
138
|
+
}
|
|
139
|
+
this.schedule(this.offset < size ? CONSUMED_WATCH.catchUpMs : this.interval);
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
this.target.logger?.warn({ err, deliveryId: this.target.deliveryId }, "Consumed-signal watch failed; it proves nothing either way");
|
|
143
|
+
this.end("unavailable");
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Complete lines of this chunk (plus the carried start of a line), judged once each. Every line is held to
|
|
148
|
+
* maxLineBytes BEFORE it is decoded — one that completes past the cap is skipped like one that never completes —
|
|
149
|
+
* and only the lines within it are parsed (#1201 review).
|
|
150
|
+
*/
|
|
151
|
+
scan(chunk) {
|
|
152
|
+
let data = chunk;
|
|
153
|
+
if (this.skippingLine) {
|
|
154
|
+
const nl = data.indexOf(0x0a);
|
|
155
|
+
if (nl < 0)
|
|
156
|
+
return null; // still inside the oversized line
|
|
157
|
+
data = data.subarray(nl + 1);
|
|
158
|
+
this.skippingLine = false;
|
|
159
|
+
}
|
|
160
|
+
const buffer = this.carry.length ? Buffer.concat([this.carry, data]) : data;
|
|
161
|
+
const lastNl = buffer.lastIndexOf(0x0a);
|
|
162
|
+
let found = null;
|
|
163
|
+
if (lastNl < 0) {
|
|
164
|
+
this.carry = buffer;
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
this.carry = buffer.subarray(lastNl + 1);
|
|
168
|
+
const kept = [];
|
|
169
|
+
for (let start = 0; start <= lastNl;) {
|
|
170
|
+
const nl = buffer.indexOf(0x0a, start);
|
|
171
|
+
if (nl - start <= CONSUMED_WATCH.maxLineBytes)
|
|
172
|
+
kept.push(buffer.subarray(start, nl + 1));
|
|
173
|
+
start = nl + 1;
|
|
174
|
+
}
|
|
175
|
+
if (kept.length) {
|
|
176
|
+
const kind = transcriptDeltaDeliveryMarker(Buffer.concat(kept).toString("utf8"), this.target.backend, this.target.deliveryId);
|
|
177
|
+
if (kind === "user")
|
|
178
|
+
found = { via: "turn", evidence: "transcript-consumed:user-entry" };
|
|
179
|
+
else if (kind === "absorbed")
|
|
180
|
+
found = { via: "mid_turn", evidence: "transcript-consumed:absorbed-mid-turn" };
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (this.carry.length > CONSUMED_WATCH.maxLineBytes) {
|
|
184
|
+
this.carry = Buffer.alloc(0);
|
|
185
|
+
this.skippingLine = true;
|
|
186
|
+
}
|
|
187
|
+
return found;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async function readAt(path, offset, length) {
|
|
191
|
+
let fh;
|
|
192
|
+
try {
|
|
193
|
+
fh = await open(path, "r");
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
try {
|
|
199
|
+
const buffer = Buffer.alloc(length);
|
|
200
|
+
let read = 0;
|
|
201
|
+
while (read < length) {
|
|
202
|
+
const { bytesRead } = await fh.read(buffer, read, length - read, offset + read);
|
|
203
|
+
if (bytesRead === 0)
|
|
204
|
+
break;
|
|
205
|
+
read += bytesRead;
|
|
206
|
+
}
|
|
207
|
+
return buffer.subarray(0, read);
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
finally {
|
|
213
|
+
await fh.close().catch(() => { });
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/** The fleet's watches (one process): started per attempt, capped, ended by their own look or by stopAll. */
|
|
217
|
+
export class ConsumedWatchRegistry {
|
|
218
|
+
active = new Map();
|
|
219
|
+
get size() { return this.active.size; }
|
|
220
|
+
/** Starts a watch for this attempt; false when one runs already or the fleet is at the cap (logged). */
|
|
221
|
+
start(target) {
|
|
222
|
+
const key = `${target.deliveryId}#${target.attemptNo}`;
|
|
223
|
+
if (this.active.has(key))
|
|
224
|
+
return false;
|
|
225
|
+
if (this.active.size >= CONSUMED_WATCH.maxWatchers) {
|
|
226
|
+
target.logger?.warn({ deliveryId: target.deliveryId, active: this.active.size, cap: CONSUMED_WATCH.maxWatchers }, "Consumed-signal watch not started: the fleet is at its watch cap (the delivery keeps its current state)");
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
const watch = new ConsumedWatch(target, why => {
|
|
230
|
+
this.active.delete(key);
|
|
231
|
+
target.logger?.debug?.({ deliveryId: target.deliveryId, why }, "Consumed-signal watch ended");
|
|
232
|
+
});
|
|
233
|
+
this.active.set(key, watch);
|
|
234
|
+
watch.start();
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
/** For tests and shutdown: end every watch without a verdict. */
|
|
238
|
+
stopAll() {
|
|
239
|
+
for (const watch of [...this.active.values()])
|
|
240
|
+
watch.stop();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
export const consumedWatches = new ConsumedWatchRegistry();
|
|
244
|
+
//# sourceMappingURL=delivery-consumed-watch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery-consumed-watch.js","sourceRoot":"","sources":["../src/delivery-consumed-watch.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,7 +17,17 @@ export interface DaemonDeliveryPort {
|
|
|
17
17
|
get?(deliveryId: string): {
|
|
18
18
|
state: OutboxState;
|
|
19
19
|
} | undefined;
|
|
20
|
+
/** #1201: the CLI's transcript shows this attempt's delivery consumed (see DeliveryOutbox.markConsumed). */
|
|
21
|
+
markConsumed?(deliveryId: string, targetBootId: string, attemptNo: number, via: ConsumedVia, evidence: string): MarkConsumedResult;
|
|
20
22
|
}
|
|
23
|
+
/** #1201: how the CLI took the delivery — as its own turn, or absorbed into the running turn at a tool boundary. */
|
|
24
|
+
export type ConsumedVia = "turn" | "mid_turn";
|
|
25
|
+
/**
|
|
26
|
+
* `marked`: a delivered row now carries consumed_at; `upgraded`: an uncertain row is delivered (its unsent failure
|
|
27
|
+
* notice cancelled); `already`: it was marked before; `ignored`: a state a transcript hit does not change (failed, a
|
|
28
|
+
* newer attempt, another boot's attempt).
|
|
29
|
+
*/
|
|
30
|
+
export type MarkConsumedResult = "marked" | "upgraded" | "already" | "ignored";
|
|
21
31
|
export type OutboxState = "queued" | "delivering" | "submission_started" | "reconciliation_pending" | "retry_wait" | "delivered" | "failed" | "uncertain" | "cancelled";
|
|
22
32
|
export interface NewOutboxDelivery {
|
|
23
33
|
operationId: string;
|
|
@@ -135,6 +145,17 @@ export interface DeliveryStatusItem {
|
|
|
135
145
|
* other query, and operator reads, stay redacted as before (#982).
|
|
136
146
|
*/
|
|
137
147
|
content?: string | null;
|
|
148
|
+
/**
|
|
149
|
+
* How the message was routed, in send_to_instance's own words: `steer` (into the live turn) or `idle_queue` (as the
|
|
150
|
+
* next message). The fleet decided this at admission; it is the row's kind.
|
|
151
|
+
*/
|
|
152
|
+
delivery_mode: "steer" | "idle_queue";
|
|
153
|
+
/** How the latest attempt was written to the pane (`native_queue_handoff`: into the CLI's own queue); null before any. */
|
|
154
|
+
submission_mode: DurableSubmissionMode | null;
|
|
155
|
+
/** #1201: when the CLI's transcript showed it consumed — accepted is not read; null until then (or never seen). */
|
|
156
|
+
consumed_at: string | null;
|
|
157
|
+
/** #1201: `turn` (taken as its own turn) or `mid_turn` (absorbed into a running turn at a tool boundary). */
|
|
158
|
+
consumed_via: ConsumedVia | null;
|
|
138
159
|
/** #926: the reply this request is owed, when it asked for one. */
|
|
139
160
|
reply_obligation?: {
|
|
140
161
|
state: "open" | "answered";
|
|
@@ -198,6 +219,17 @@ export interface DeliveryReconciliationCandidate extends OutboxDelivery {
|
|
|
198
219
|
enterStartedAt: string | null;
|
|
199
220
|
};
|
|
200
221
|
}
|
|
222
|
+
/** The exact statement `needsAttention` runs; exported so the plan test checks this text and no copy of it. */
|
|
223
|
+
export declare const NEEDS_ATTENTION_SQL = "\n SELECT delivery_id, state, source_instance, target_instance, kind, finished_at, last_error\n FROM deliveries INDEXED BY idx_delivery_attention\n WHERE state IN ('uncertain','failed') AND acknowledged_at IS NULL AND finished_at >= ?\n ORDER BY finished_at DESC LIMIT ?";
|
|
224
|
+
export interface NeedsAttentionDelivery {
|
|
225
|
+
deliveryId: string;
|
|
226
|
+
state: "uncertain" | "failed";
|
|
227
|
+
sourceInstance: string;
|
|
228
|
+
targetInstance: string;
|
|
229
|
+
kind: string;
|
|
230
|
+
finishedAt: string;
|
|
231
|
+
lastError: string | null;
|
|
232
|
+
}
|
|
201
233
|
export interface ClaimedOutboxDelivery extends OutboxDelivery {
|
|
202
234
|
targetDaemonBootId: string;
|
|
203
235
|
}
|
|
@@ -270,6 +302,20 @@ export declare class DeliveryOutbox extends EventEmitter {
|
|
|
270
302
|
listPending(): OutboxDelivery[];
|
|
271
303
|
private listPendingSync;
|
|
272
304
|
/** Rows addressed to `target` in any of `states` (indexed: target_instance, state). */
|
|
305
|
+
/**
|
|
306
|
+
* #1386: the deliveries an operator should look at — `uncertain` or `failed`, not acknowledged, finished at or
|
|
307
|
+
* after `sinceIso` — newest first, at most `limit`. Acknowledged rows are excluded before the cap, and the scan
|
|
308
|
+
* is held to that time range by requiring the partial index: without `INDEXED BY`, SQLite picks
|
|
309
|
+
* idx_delivery_state_seq and sorts every uncertain/failed row however old (uncertain rows are never pruned).
|
|
310
|
+
* A database the migration never reached fails here, loudly, instead of scanning.
|
|
311
|
+
*/
|
|
312
|
+
needsAttention(sinceIso: string, limit?: number): NeedsAttentionDelivery[];
|
|
313
|
+
/**
|
|
314
|
+
* #1386: record that `by` looked at this delivery. One statement, so it is atomic: true only when this call
|
|
315
|
+
* acknowledged it — false when it was already acknowledged, is no longer uncertain/failed (delivered by later
|
|
316
|
+
* proof), or does not exist. A write error throws; nothing is remembered as acknowledged elsewhere.
|
|
317
|
+
*/
|
|
318
|
+
acknowledge(deliveryId: string, by: string, atIso?: string): boolean;
|
|
273
319
|
countForTarget(target: string, states: readonly OutboxState[]): number;
|
|
274
320
|
nextRetryAt(): string | null;
|
|
275
321
|
/** Claim the earliest eligible target row; one caller owns each target lane. */
|
|
@@ -282,6 +328,21 @@ export declare class DeliveryOutbox extends EventEmitter {
|
|
|
282
328
|
/** Safe only when the caller can prove no pane write occurred for this attempt. */
|
|
283
329
|
abort(deliveryId: string, targetBootId: string, attemptNo: number, reason: string): boolean;
|
|
284
330
|
complete(deliveryId: string, targetBootId: string, attemptNo: number, outcome: "delivered" | "failed" | "uncertain", evidence?: string): boolean;
|
|
331
|
+
/**
|
|
332
|
+
* #1201: the CLI's own transcript shows this attempt's delivery consumed — its exact `[agend-delivery-id:<id>]`
|
|
333
|
+
* marker in a user entry or a queued-command prompt, read by the late watcher. Positive evidence only: nothing calls
|
|
334
|
+
* this on a miss, so it can never downgrade a row.
|
|
335
|
+
*
|
|
336
|
+
* - `delivered` → stays delivered, gains consumed_at/consumed_via (no state event: nothing about it changed).
|
|
337
|
+
* - `uncertain` → `delivered`: last_error cleared, the attempt marked delivered, the reply obligation it never opened
|
|
338
|
+
* opened, and its failure notice cancelled — but only while that notice is still unsent (queued / retry_wait). One
|
|
339
|
+
* the pump already took is left alone: the protocol tells the sender to check delivery_status after an uncertain
|
|
340
|
+
* outcome, which now says delivered.
|
|
341
|
+
* - anything else (failed, an attempt that is not this one) → `ignored`.
|
|
342
|
+
*
|
|
343
|
+
* Fenced like complete(): the row must still be on this boot's attempt.
|
|
344
|
+
*/
|
|
345
|
+
markConsumed(deliveryId: string, targetBootId: string, attemptNo: number, via: ConsumedVia, evidence: string): MarkConsumedResult;
|
|
285
346
|
/** Transient pre-submit failure: state is retryable and the same row keeps its FIFO position. */
|
|
286
347
|
retryBeforeBegin(deliveryId: string, targetBootId: string, attemptNo: number, reason: string, delayMs?: number): boolean;
|
|
287
348
|
failBeforeBegin(deliveryId: string, reason: string): boolean;
|