@namzu/cli 29.0.1 → 29.1.0
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/CHANGELOG.md +115 -0
- package/README.md +20 -0
- package/dist/browser/commands.d.ts +29 -0
- package/dist/browser/commands.d.ts.map +1 -0
- package/dist/browser/commands.js +361 -0
- package/dist/browser/commands.js.map +1 -0
- package/dist/browser/control.d.ts +79 -0
- package/dist/browser/control.d.ts.map +1 -0
- package/dist/browser/control.js +140 -0
- package/dist/browser/control.js.map +1 -0
- package/dist/browser/describe.d.ts +12 -0
- package/dist/browser/describe.d.ts.map +1 -0
- package/dist/browser/describe.js +27 -0
- package/dist/browser/describe.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +29 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/acp.d.ts.map +1 -1
- package/dist/commands/acp.js +1 -0
- package/dist/commands/acp.js.map +1 -1
- package/dist/commands/browser.d.ts +7 -0
- package/dist/commands/browser.d.ts.map +1 -0
- package/dist/commands/browser.js +16 -0
- package/dist/commands/browser.js.map +1 -0
- package/dist/commands/drain.d.ts +2 -1
- package/dist/commands/drain.d.ts.map +1 -1
- package/dist/commands/drain.js +6 -3
- package/dist/commands/drain.js.map +1 -1
- package/dist/commands/exec-flags.d.ts +2 -1
- package/dist/commands/exec-flags.d.ts.map +1 -1
- package/dist/commands/exec-flags.js +6 -3
- package/dist/commands/exec-flags.js.map +1 -1
- package/dist/commands/exec-json.d.ts.map +1 -1
- package/dist/commands/exec-json.js +2 -1
- package/dist/commands/exec-json.js.map +1 -1
- package/dist/commands/exec.d.ts.map +1 -1
- package/dist/commands/exec.js +2 -1
- package/dist/commands/exec.js.map +1 -1
- package/dist/commands/host-queries.d.ts.map +1 -1
- package/dist/commands/host-queries.js +10 -3
- package/dist/commands/host-queries.js.map +1 -1
- package/dist/commands/schedule.d.ts +9 -0
- package/dist/commands/schedule.d.ts.map +1 -0
- package/dist/commands/schedule.js +126 -0
- package/dist/commands/schedule.js.map +1 -0
- package/dist/commands/serve.d.ts +3 -1
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +5 -3
- package/dist/commands/serve.js.map +1 -1
- package/dist/commands/skills.d.ts +10 -0
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +23 -7
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/upgrade.d.ts +5 -0
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +11 -0
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/config/load.d.ts +39 -0
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/load.js +232 -1
- package/dist/config/load.js.map +1 -1
- package/dist/config/schema.d.ts +78 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/config/user-config.d.ts +23 -0
- package/dist/config/user-config.d.ts.map +1 -0
- package/dist/config/user-config.js +48 -0
- package/dist/config/user-config.js.map +1 -0
- package/dist/context/capabilities.d.ts +1 -1
- package/dist/context/capabilities.d.ts.map +1 -1
- package/dist/context/capabilities.js +1 -0
- package/dist/context/capabilities.js.map +1 -1
- package/dist/doctor/checks/browser.d.ts +15 -0
- package/dist/doctor/checks/browser.d.ts.map +1 -0
- package/dist/doctor/checks/browser.js +63 -0
- package/dist/doctor/checks/browser.js.map +1 -0
- package/dist/doctor/checks/index.d.ts +4 -1
- package/dist/doctor/checks/index.d.ts.map +1 -1
- package/dist/doctor/checks/index.js +8 -1
- package/dist/doctor/checks/index.js.map +1 -1
- package/dist/doctor/checks/scheduler.d.ts +10 -0
- package/dist/doctor/checks/scheduler.d.ts.map +1 -0
- package/dist/doctor/checks/scheduler.js +74 -0
- package/dist/doctor/checks/scheduler.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations/notifications/desktop/freedesktop.d.ts +10 -0
- package/dist/integrations/notifications/desktop/freedesktop.d.ts.map +1 -0
- package/dist/integrations/notifications/desktop/freedesktop.js +33 -0
- package/dist/integrations/notifications/desktop/freedesktop.js.map +1 -0
- package/dist/integrations/notifications/desktop/macos.d.ts +6 -0
- package/dist/integrations/notifications/desktop/macos.d.ts.map +1 -0
- package/dist/integrations/notifications/desktop/macos.js +17 -0
- package/dist/integrations/notifications/desktop/macos.js.map +1 -0
- package/dist/integrations/notifications/desktop/sanitize.d.ts +16 -0
- package/dist/integrations/notifications/desktop/sanitize.d.ts.map +1 -0
- package/dist/integrations/notifications/desktop/sanitize.js +49 -0
- package/dist/integrations/notifications/desktop/sanitize.js.map +1 -0
- package/dist/integrations/notifications/desktop/throttle.d.ts +10 -0
- package/dist/integrations/notifications/desktop/throttle.d.ts.map +1 -0
- package/dist/integrations/notifications/desktop/throttle.js +39 -0
- package/dist/integrations/notifications/desktop/throttle.js.map +1 -0
- package/dist/integrations/notifications/desktop/windows-toast.d.ts +23 -0
- package/dist/integrations/notifications/desktop/windows-toast.d.ts.map +1 -0
- package/dist/integrations/notifications/desktop/windows-toast.js +56 -0
- package/dist/integrations/notifications/desktop/windows-toast.js.map +1 -0
- package/dist/integrations/notifications/desktop.d.ts +82 -0
- package/dist/integrations/notifications/desktop.d.ts.map +1 -0
- package/dist/integrations/notifications/desktop.js +198 -0
- package/dist/integrations/notifications/desktop.js.map +1 -0
- package/dist/integrations/resident/session-step.d.ts.map +1 -1
- package/dist/integrations/resident/session-step.js +1 -0
- package/dist/integrations/resident/session-step.js.map +1 -1
- package/dist/integrations/subagents/runtime.d.ts +6 -0
- package/dist/integrations/subagents/runtime.d.ts.map +1 -1
- package/dist/integrations/subagents/runtime.js +14 -5
- package/dist/integrations/subagents/runtime.js.map +1 -1
- package/dist/permissions/browser-sites.d.ts +95 -0
- package/dist/permissions/browser-sites.d.ts.map +1 -0
- package/dist/permissions/browser-sites.js +270 -0
- package/dist/permissions/browser-sites.js.map +1 -0
- package/dist/schedule/build.d.ts +79 -0
- package/dist/schedule/build.d.ts.map +1 -0
- package/dist/schedule/build.js +246 -0
- package/dist/schedule/build.js.map +1 -0
- package/dist/schedule/changes.d.ts +22 -0
- package/dist/schedule/changes.d.ts.map +1 -0
- package/dist/schedule/changes.js +55 -0
- package/dist/schedule/changes.js.map +1 -0
- package/dist/schedule/commands/add.d.ts +24 -0
- package/dist/schedule/commands/add.d.ts.map +1 -0
- package/dist/schedule/commands/add.js +459 -0
- package/dist/schedule/commands/add.js.map +1 -0
- package/dist/schedule/commands/args.d.ts +22 -0
- package/dist/schedule/commands/args.d.ts.map +1 -0
- package/dist/schedule/commands/args.js +80 -0
- package/dist/schedule/commands/args.js.map +1 -0
- package/dist/schedule/commands/confirm-prompt.d.ts +6 -0
- package/dist/schedule/commands/confirm-prompt.d.ts.map +1 -0
- package/dist/schedule/commands/confirm-prompt.js +21 -0
- package/dist/schedule/commands/confirm-prompt.js.map +1 -0
- package/dist/schedule/commands/lifecycle.d.ts +39 -0
- package/dist/schedule/commands/lifecycle.d.ts.map +1 -0
- package/dist/schedule/commands/lifecycle.js +585 -0
- package/dist/schedule/commands/lifecycle.js.map +1 -0
- package/dist/schedule/commands/list.d.ts +33 -0
- package/dist/schedule/commands/list.d.ts.map +1 -0
- package/dist/schedule/commands/list.js +202 -0
- package/dist/schedule/commands/list.js.map +1 -0
- package/dist/schedule/commands/logs.d.ts +7 -0
- package/dist/schedule/commands/logs.d.ts.map +1 -0
- package/dist/schedule/commands/logs.js +106 -0
- package/dist/schedule/commands/logs.js.map +1 -0
- package/dist/schedule/commands/service.d.ts +16 -0
- package/dist/schedule/commands/service.d.ts.map +1 -0
- package/dist/schedule/commands/service.js +458 -0
- package/dist/schedule/commands/service.js.map +1 -0
- package/dist/schedule/daemon/daemon.d.ts +156 -0
- package/dist/schedule/daemon/daemon.d.ts.map +1 -0
- package/dist/schedule/daemon/daemon.js +1248 -0
- package/dist/schedule/daemon/daemon.js.map +1 -0
- package/dist/schedule/daemon/endpoint.d.ts +38 -0
- package/dist/schedule/daemon/endpoint.d.ts.map +1 -0
- package/dist/schedule/daemon/endpoint.js +158 -0
- package/dist/schedule/daemon/endpoint.js.map +1 -0
- package/dist/schedule/daemon/exit.d.ts +8 -0
- package/dist/schedule/daemon/exit.d.ts.map +1 -0
- package/dist/schedule/daemon/exit.js +8 -0
- package/dist/schedule/daemon/exit.js.map +1 -0
- package/dist/schedule/daemon/log.d.ts +12 -0
- package/dist/schedule/daemon/log.d.ts.map +1 -0
- package/dist/schedule/daemon/log.js +53 -0
- package/dist/schedule/daemon/log.js.map +1 -0
- package/dist/schedule/daemon/notify.d.ts +31 -0
- package/dist/schedule/daemon/notify.d.ts.map +1 -0
- package/dist/schedule/daemon/notify.js +89 -0
- package/dist/schedule/daemon/notify.js.map +1 -0
- package/dist/schedule/daemon/retention.d.ts +16 -0
- package/dist/schedule/daemon/retention.d.ts.map +1 -0
- package/dist/schedule/daemon/retention.js +46 -0
- package/dist/schedule/daemon/retention.js.map +1 -0
- package/dist/schedule/daemon/sessions.d.ts +23 -0
- package/dist/schedule/daemon/sessions.d.ts.map +1 -0
- package/dist/schedule/daemon/sessions.js +52 -0
- package/dist/schedule/daemon/sessions.js.map +1 -0
- package/dist/schedule/env.d.ts +28 -0
- package/dist/schedule/env.d.ts.map +1 -0
- package/dist/schedule/env.js +99 -0
- package/dist/schedule/env.js.map +1 -0
- package/dist/schedule/fire/browser-preflight.d.ts +41 -0
- package/dist/schedule/fire/browser-preflight.d.ts.map +1 -0
- package/dist/schedule/fire/browser-preflight.js +73 -0
- package/dist/schedule/fire/browser-preflight.js.map +1 -0
- package/dist/schedule/fire/fire.d.ts +78 -0
- package/dist/schedule/fire/fire.d.ts.map +1 -0
- package/dist/schedule/fire/fire.js +482 -0
- package/dist/schedule/fire/fire.js.map +1 -0
- package/dist/schedule/fire/result.d.ts +13 -0
- package/dist/schedule/fire/result.d.ts.map +1 -0
- package/dist/schedule/fire/result.js +18 -0
- package/dist/schedule/fire/result.js.map +1 -0
- package/dist/schedule/fire/unattended-note.d.ts +22 -0
- package/dist/schedule/fire/unattended-note.d.ts.map +1 -0
- package/dist/schedule/fire/unattended-note.js +46 -0
- package/dist/schedule/fire/unattended-note.js.map +1 -0
- package/dist/schedule/floor.d.ts +116 -0
- package/dist/schedule/floor.d.ts.map +1 -0
- package/dist/schedule/floor.js +1051 -0
- package/dist/schedule/floor.js.map +1 -0
- package/dist/schedule/folder.d.ts +34 -0
- package/dist/schedule/folder.d.ts.map +1 -0
- package/dist/schedule/folder.js +84 -0
- package/dist/schedule/folder.js.map +1 -0
- package/dist/schedule/paths.d.ts +49 -0
- package/dist/schedule/paths.d.ts.map +1 -0
- package/dist/schedule/paths.js +53 -0
- package/dist/schedule/paths.js.map +1 -0
- package/dist/schedule/policy.d.ts +141 -0
- package/dist/schedule/policy.d.ts.map +1 -0
- package/dist/schedule/policy.js +378 -0
- package/dist/schedule/policy.js.map +1 -0
- package/dist/schedule/resume-command.d.ts +36 -0
- package/dist/schedule/resume-command.d.ts.map +1 -0
- package/dist/schedule/resume-command.js +72 -0
- package/dist/schedule/resume-command.js.map +1 -0
- package/dist/schedule/service/detect.d.ts +22 -0
- package/dist/schedule/service/detect.d.ts.map +1 -0
- package/dist/schedule/service/detect.js +29 -0
- package/dist/schedule/service/detect.js.map +1 -0
- package/dist/schedule/service/index.d.ts +48 -0
- package/dist/schedule/service/index.d.ts.map +1 -0
- package/dist/schedule/service/index.js +352 -0
- package/dist/schedule/service/index.js.map +1 -0
- package/dist/schedule/service/launchd.d.ts +24 -0
- package/dist/schedule/service/launchd.d.ts.map +1 -0
- package/dist/schedule/service/launchd.js +84 -0
- package/dist/schedule/service/launchd.js.map +1 -0
- package/dist/schedule/service/manifest.d.ts +44 -0
- package/dist/schedule/service/manifest.d.ts.map +1 -0
- package/dist/schedule/service/manifest.js +16 -0
- package/dist/schedule/service/manifest.js.map +1 -0
- package/dist/schedule/service/names.d.ts +9 -0
- package/dist/schedule/service/names.d.ts.map +1 -0
- package/dist/schedule/service/names.js +22 -0
- package/dist/schedule/service/names.js.map +1 -0
- package/dist/schedule/service/quote.d.ts +24 -0
- package/dist/schedule/service/quote.d.ts.map +1 -0
- package/dist/schedule/service/quote.js +64 -0
- package/dist/schedule/service/quote.js.map +1 -0
- package/dist/schedule/service/runner.d.ts +17 -0
- package/dist/schedule/service/runner.d.ts.map +1 -0
- package/dist/schedule/service/runner.js +31 -0
- package/dist/schedule/service/runner.js.map +1 -0
- package/dist/schedule/service/systemd.d.ts +37 -0
- package/dist/schedule/service/systemd.d.ts.map +1 -0
- package/dist/schedule/service/systemd.js +96 -0
- package/dist/schedule/service/systemd.js.map +1 -0
- package/dist/schedule/service/windows-task.d.ts +51 -0
- package/dist/schedule/service/windows-task.d.ts.map +1 -0
- package/dist/schedule/service/windows-task.js +134 -0
- package/dist/schedule/service/windows-task.js.map +1 -0
- package/dist/schedule/service/wsl.d.ts +57 -0
- package/dist/schedule/service/wsl.d.ts.map +1 -0
- package/dist/schedule/service/wsl.js +111 -0
- package/dist/schedule/service/wsl.js.map +1 -0
- package/dist/schedule/store/atomic.d.ts +43 -0
- package/dist/schedule/store/atomic.d.ts.map +1 -0
- package/dist/schedule/store/atomic.js +135 -0
- package/dist/schedule/store/atomic.js.map +1 -0
- package/dist/schedule/store/claims.d.ts +26 -0
- package/dist/schedule/store/claims.d.ts.map +1 -0
- package/dist/schedule/store/claims.js +57 -0
- package/dist/schedule/store/claims.js.map +1 -0
- package/dist/schedule/store/digest.d.ts +18 -0
- package/dist/schedule/store/digest.d.ts.map +1 -0
- package/dist/schedule/store/digest.js +139 -0
- package/dist/schedule/store/digest.js.map +1 -0
- package/dist/schedule/store/history.d.ts +21 -0
- package/dist/schedule/store/history.d.ts.map +1 -0
- package/dist/schedule/store/history.js +114 -0
- package/dist/schedule/store/history.js.map +1 -0
- package/dist/schedule/store/jobs.d.ts +61 -0
- package/dist/schedule/store/jobs.d.ts.map +1 -0
- package/dist/schedule/store/jobs.js +210 -0
- package/dist/schedule/store/jobs.js.map +1 -0
- package/dist/schedule/store/state.d.ts +19 -0
- package/dist/schedule/store/state.d.ts.map +1 -0
- package/dist/schedule/store/state.js +38 -0
- package/dist/schedule/store/state.js.map +1 -0
- package/dist/schedule/types.d.ts +256 -0
- package/dist/schedule/types.d.ts.map +1 -0
- package/dist/schedule/types.js +9 -0
- package/dist/schedule/types.js.map +1 -0
- package/dist/skills/catalog.d.ts +96 -0
- package/dist/skills/catalog.d.ts.map +1 -0
- package/dist/skills/catalog.js +226 -0
- package/dist/skills/catalog.js.map +1 -0
- package/dist/skills/save.d.ts +148 -0
- package/dist/skills/save.d.ts.map +1 -0
- package/dist/skills/save.js +344 -0
- package/dist/skills/save.js.map +1 -0
- package/dist/skills/store.d.ts +103 -16
- package/dist/skills/store.d.ts.map +1 -1
- package/dist/skills/store.js +227 -30
- package/dist/skills/store.js.map +1 -1
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +591 -72
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/LiveActivity.d.ts +8 -1
- package/dist/tui/LiveActivity.d.ts.map +1 -1
- package/dist/tui/LiveActivity.js +20 -4
- package/dist/tui/LiveActivity.js.map +1 -1
- package/dist/tui/PermissionOverlay.d.ts +24 -4
- package/dist/tui/PermissionOverlay.d.ts.map +1 -1
- package/dist/tui/PermissionOverlay.js +113 -15
- package/dist/tui/PermissionOverlay.js.map +1 -1
- package/dist/tui/SaveSkillOverlay.d.ts +33 -0
- package/dist/tui/SaveSkillOverlay.d.ts.map +1 -0
- package/dist/tui/SaveSkillOverlay.js +118 -0
- package/dist/tui/SaveSkillOverlay.js.map +1 -0
- package/dist/tui/agent.d.ts +185 -5
- package/dist/tui/agent.d.ts.map +1 -1
- package/dist/tui/agent.js +325 -54
- package/dist/tui/agent.js.map +1 -1
- package/dist/tui/browser-notices.d.ts +33 -0
- package/dist/tui/browser-notices.d.ts.map +1 -0
- package/dist/tui/browser-notices.js +102 -0
- package/dist/tui/browser-notices.js.map +1 -0
- package/dist/tui/permission-review.d.ts.map +1 -1
- package/dist/tui/permission-review.js +53 -4
- package/dist/tui/permission-review.js.map +1 -1
- package/dist/tui/schedule/host-commands.d.ts +34 -0
- package/dist/tui/schedule/host-commands.d.ts.map +1 -0
- package/dist/tui/schedule/host-commands.js +309 -0
- package/dist/tui/schedule/host-commands.js.map +1 -0
- package/dist/tui/schedule/integration.d.ts +62 -0
- package/dist/tui/schedule/integration.d.ts.map +1 -0
- package/dist/tui/schedule/integration.js +145 -0
- package/dist/tui/schedule/integration.js.map +1 -0
- package/dist/tui/schedule/loop-host.d.ts +42 -0
- package/dist/tui/schedule/loop-host.d.ts.map +1 -0
- package/dist/tui/schedule/loop-host.js +153 -0
- package/dist/tui/schedule/loop-host.js.map +1 -0
- package/dist/tui/schedule/resume.d.ts +122 -0
- package/dist/tui/schedule/resume.d.ts.map +1 -0
- package/dist/tui/schedule/resume.js +324 -0
- package/dist/tui/schedule/resume.js.map +1 -0
- package/dist/tui/schedule/startup.d.ts +11 -0
- package/dist/tui/schedule/startup.d.ts.map +1 -0
- package/dist/tui/schedule/startup.js +121 -0
- package/dist/tui/schedule/startup.js.map +1 -0
- package/dist/tui/schedule/tool-host.d.ts +44 -0
- package/dist/tui/schedule/tool-host.d.ts.map +1 -0
- package/dist/tui/schedule/tool-host.js +294 -0
- package/dist/tui/schedule/tool-host.js.map +1 -0
- package/dist/tui/skills/learning.d.ts +74 -0
- package/dist/tui/skills/learning.d.ts.map +1 -0
- package/dist/tui/skills/learning.js +131 -0
- package/dist/tui/skills/learning.js.map +1 -0
- package/dist/tui/skills/suggest-setting.d.ts +22 -0
- package/dist/tui/skills/suggest-setting.d.ts.map +1 -0
- package/dist/tui/skills/suggest-setting.js +55 -0
- package/dist/tui/skills/suggest-setting.js.map +1 -0
- package/dist/tui/skills/suggestion-ledger.d.ts +35 -0
- package/dist/tui/skills/suggestion-ledger.d.ts.map +1 -0
- package/dist/tui/skills/suggestion-ledger.js +52 -0
- package/dist/tui/skills/suggestion-ledger.js.map +1 -0
- package/dist/tui/slashCommands.d.ts +20 -0
- package/dist/tui/slashCommands.d.ts.map +1 -1
- package/dist/tui/slashCommands.js +76 -2
- package/dist/tui/slashCommands.js.map +1 -1
- package/dist/tui/turn-interruption.d.ts +20 -1
- package/dist/tui/turn-interruption.d.ts.map +1 -1
- package/dist/tui/turn-interruption.js +43 -0
- package/dist/tui/turn-interruption.js.map +1 -1
- package/dist/tui/types.d.ts +9 -1
- package/dist/tui/types.d.ts.map +1 -1
- package/package.json +6 -4
- package/skills/README.md +15 -0
- package/skills/browser-automation/SKILL.md +84 -0
- package/skills/schedule-task/SKILL.md +140 -0
- package/skills/skill-creator/SKILL.md +101 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/loop` and the `session_loop` tool: a prompt the open session re-sends to
|
|
3
|
+
* itself on an interval.
|
|
4
|
+
*
|
|
5
|
+
* It fires only between turns. A loop that comes due while a turn runs fires
|
|
6
|
+
* once when the session is idle again — never once per missed interval: the
|
|
7
|
+
* session is the operator's, and a pile of queued prompts would take it over.
|
|
8
|
+
* At most 20 loops, at least a minute apart, each expiring seven days after it
|
|
9
|
+
* was made. They live in `<session-id>/loops.json` beside the session log and
|
|
10
|
+
* come back with `/resume` (expired ones do not). A loop the model made says
|
|
11
|
+
* so wherever it is shown.
|
|
12
|
+
*/
|
|
13
|
+
import { randomBytes } from 'node:crypto';
|
|
14
|
+
import { readFileSync } from 'node:fs';
|
|
15
|
+
import { describeSchedule, hostTimeZone, nextFireTime, parseScheduleSpec, } from '@namzu/sdk';
|
|
16
|
+
import { writeJsonAtomic } from '../../schedule/store/atomic.js';
|
|
17
|
+
export const MAX_LOOPS = 20;
|
|
18
|
+
export const LOOP_LIFETIME_MS = 7 * 24 * 60 * 60 * 1000;
|
|
19
|
+
/** `5m`, `every 1h`, or five-field cron, as a spec. */
|
|
20
|
+
export function loopSpec(interval, now) {
|
|
21
|
+
const text = interval.trim();
|
|
22
|
+
if (/^\d+\s*[a-z]+$/i.test(text))
|
|
23
|
+
return parseScheduleSpec(`every ${text}`, { now, tz: hostTimeZone() });
|
|
24
|
+
return parseScheduleSpec(text, { now, tz: hostTimeZone() });
|
|
25
|
+
}
|
|
26
|
+
export class SessionLoopScheduler {
|
|
27
|
+
#deps;
|
|
28
|
+
#file;
|
|
29
|
+
#loops = [];
|
|
30
|
+
constructor(deps) {
|
|
31
|
+
this.#deps = deps;
|
|
32
|
+
}
|
|
33
|
+
#now() {
|
|
34
|
+
return (this.#deps.now ?? Date.now)();
|
|
35
|
+
}
|
|
36
|
+
/** Follow the conversation on screen: load its loops when it changes. */
|
|
37
|
+
#sync() {
|
|
38
|
+
const file = this.#deps.file();
|
|
39
|
+
if (file === this.#file)
|
|
40
|
+
return;
|
|
41
|
+
// Loops made before the conversation had a log belong to it once it does.
|
|
42
|
+
const carried = this.#file === undefined ? this.#loops : [];
|
|
43
|
+
this.#file = file;
|
|
44
|
+
this.#loops = [];
|
|
45
|
+
if (!file)
|
|
46
|
+
return;
|
|
47
|
+
try {
|
|
48
|
+
const parsed = JSON.parse(readFileSync(file, 'utf8'));
|
|
49
|
+
if (parsed.kind === 'session-loops' && Array.isArray(parsed.loops)) {
|
|
50
|
+
const now = this.#now();
|
|
51
|
+
this.#loops = parsed.loops.filter((l) => (!l.expiresAt || Date.parse(l.expiresAt) > now) &&
|
|
52
|
+
// A one-shot whose time passed is not restored.
|
|
53
|
+
!(l.spec.kind === 'at' && Date.parse(l.spec.at) <= now));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch { }
|
|
57
|
+
if (carried.length > 0) {
|
|
58
|
+
this.#loops = [...this.#loops, ...carried].slice(0, MAX_LOOPS);
|
|
59
|
+
this.#save();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
#save() {
|
|
63
|
+
if (!this.#file)
|
|
64
|
+
return;
|
|
65
|
+
try {
|
|
66
|
+
writeJsonAtomic(this.#file, {
|
|
67
|
+
v: 1,
|
|
68
|
+
kind: 'session-loops',
|
|
69
|
+
loops: this.#loops,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
catch { }
|
|
73
|
+
}
|
|
74
|
+
async create(request) {
|
|
75
|
+
// Before the conversation has a log the loop is held here, and saved
|
|
76
|
+
// beside the log once the first turn creates it.
|
|
77
|
+
this.#sync();
|
|
78
|
+
if (this.#loops.length >= MAX_LOOPS)
|
|
79
|
+
throw new Error(`A session holds at most ${MAX_LOOPS} loops.`);
|
|
80
|
+
const now = new Date(this.#now());
|
|
81
|
+
const spec = loopSpec(request.interval, now);
|
|
82
|
+
const loop = {
|
|
83
|
+
id: randomBytes(3).toString('hex'),
|
|
84
|
+
schedule: describeSchedule(spec, { tz: hostTimeZone() }),
|
|
85
|
+
prompt: request.prompt,
|
|
86
|
+
createdAt: now.toISOString(),
|
|
87
|
+
expiresAt: new Date(now.getTime() + LOOP_LIFETIME_MS).toISOString(),
|
|
88
|
+
createdBy: request.createdBy,
|
|
89
|
+
spec,
|
|
90
|
+
};
|
|
91
|
+
this.#loops.push(loop);
|
|
92
|
+
this.#save();
|
|
93
|
+
return loop;
|
|
94
|
+
}
|
|
95
|
+
list() {
|
|
96
|
+
this.#sync();
|
|
97
|
+
return this.#loops;
|
|
98
|
+
}
|
|
99
|
+
async delete(id) {
|
|
100
|
+
this.#sync();
|
|
101
|
+
const before = this.#loops.length;
|
|
102
|
+
this.#loops = id === 'all' ? [] : this.#loops.filter((l) => l.id !== id);
|
|
103
|
+
this.#save();
|
|
104
|
+
return before - this.#loops.length;
|
|
105
|
+
}
|
|
106
|
+
/** Fire what is due, when idle. Called on a timer and when a turn ends. */
|
|
107
|
+
tick() {
|
|
108
|
+
this.#sync();
|
|
109
|
+
const now = this.#now();
|
|
110
|
+
let changed = false;
|
|
111
|
+
const kept = [];
|
|
112
|
+
let fired = false;
|
|
113
|
+
for (const loop of this.#loops) {
|
|
114
|
+
if (loop.expiresAt && Date.parse(loop.expiresAt) <= now) {
|
|
115
|
+
changed = true;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
const last = Date.parse(loop.lastFiredAt ?? loop.createdAt);
|
|
119
|
+
const due = nextFireTime(loop.spec, new Date(last));
|
|
120
|
+
const isDue = loop.pending || (due !== null && due.getTime() <= now);
|
|
121
|
+
if (!isDue) {
|
|
122
|
+
kept.push(loop);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (fired || !this.#deps.isIdle()) {
|
|
126
|
+
// Once, when the session is idle again — not once per missed interval.
|
|
127
|
+
if (!loop.pending)
|
|
128
|
+
changed = true;
|
|
129
|
+
kept.push({ ...loop, pending: true });
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
fired = true;
|
|
133
|
+
changed = true;
|
|
134
|
+
const done = loop.spec.kind === 'at';
|
|
135
|
+
const { pending: _pending, ...rest } = loop;
|
|
136
|
+
if (!done)
|
|
137
|
+
kept.push({ ...rest, lastFiredAt: new Date(now).toISOString() });
|
|
138
|
+
this.#deps.fire(loop);
|
|
139
|
+
}
|
|
140
|
+
this.#loops = kept;
|
|
141
|
+
if (changed)
|
|
142
|
+
this.#save();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/** One line per loop, for `/loop list`. */
|
|
146
|
+
export function describeLoops(loops) {
|
|
147
|
+
if (loops.length === 0)
|
|
148
|
+
return 'No loops in this conversation. /loop 5m <prompt> adds one.';
|
|
149
|
+
return loops
|
|
150
|
+
.map((l) => `↻ ${l.id} ${l.schedule}${l.createdBy === 'model' ? ' (created by the model)' : ''}${l.lastFiredAt ? ` last ${new Date(l.lastFiredAt).toLocaleTimeString()}` : ''}\n ${l.prompt.replace(/\s+/g, ' ').slice(0, 100)}`)
|
|
151
|
+
.join('\n');
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=loop-host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop-host.js","sourceRoot":"","sources":["../../../src/tui/schedule/loop-host.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/resume` of a scheduled run parked on a decision, or on a tool's request
|
|
3
|
+
* for a person.
|
|
4
|
+
*
|
|
5
|
+
* The parked batch is put to the operator with the ordinary permission
|
|
6
|
+
* screen. Their answer is applied to exactly that batch (`pendingDecision`,
|
|
7
|
+
* the model is not asked again); calls later in the turn are asked of them
|
|
8
|
+
* live; and the resumed turn is gated by the JOB's rules, recompiled now
|
|
9
|
+
* from the job, not by the folder config the TUI session was built with. The
|
|
10
|
+
* operator's own mode can only make it stricter.
|
|
11
|
+
*
|
|
12
|
+
* The resumed turn runs on the job's provider and model, not the session's.
|
|
13
|
+
*
|
|
14
|
+
* What the rules cannot carry, the TUI session must already match: the
|
|
15
|
+
* resumed turn runs in THIS session's sandbox (or none), working directory
|
|
16
|
+
* and extra roots, so a session whose execution or roots differ from the
|
|
17
|
+
* job's is refused with the command that opens a matching one. And the
|
|
18
|
+
* screen offers no "allow all": a scheduled run has no session-wide approval.
|
|
19
|
+
*
|
|
20
|
+
* A run a tool paused for a person (`ToolResult.handoff`) has no batch to
|
|
21
|
+
* approve. The operator is shown what the tool asked for and chooses to
|
|
22
|
+
* continue it — the next step is a model call, under the job's rules — or to
|
|
23
|
+
* abandon it.
|
|
24
|
+
*/
|
|
25
|
+
import { findPendingCheckpoint } from '@namzu/sdk';
|
|
26
|
+
import type { PermissionMode } from '../../permissions/mode.js';
|
|
27
|
+
import type { ScheduleJob } from '../../schedule/types.js';
|
|
28
|
+
import type { QuestionFn, ResumePausedParams, ScreenPermissionFn } from '../agent.js';
|
|
29
|
+
export interface ScheduledPark {
|
|
30
|
+
readonly job: ScheduleJob;
|
|
31
|
+
readonly runId: string;
|
|
32
|
+
readonly turnId: string;
|
|
33
|
+
/**
|
|
34
|
+
* The provider and model the job's run uses: the job's pin, with the
|
|
35
|
+
* model its turn recorded when the job names only a provider.
|
|
36
|
+
*/
|
|
37
|
+
readonly model: {
|
|
38
|
+
readonly provider: string;
|
|
39
|
+
readonly model?: string;
|
|
40
|
+
readonly effort?: string;
|
|
41
|
+
};
|
|
42
|
+
/** The parked batch; empty for a handoff park, which has none. */
|
|
43
|
+
readonly toolCalls: Extract<NonNullable<Awaited<ReturnType<typeof findPendingCheckpoint>>>['pending']['request'], {
|
|
44
|
+
type: 'tool_review';
|
|
45
|
+
}>['toolCalls'];
|
|
46
|
+
/** Present when a tool asked for a person instead of a batch waiting for approval. */
|
|
47
|
+
readonly handoff?: ScheduledHandoff;
|
|
48
|
+
}
|
|
49
|
+
export interface ScheduledHandoff {
|
|
50
|
+
readonly reason: string;
|
|
51
|
+
readonly detail?: Readonly<Record<string, string>>;
|
|
52
|
+
}
|
|
53
|
+
/** The job whose run is parked in this session, and the batch it waits on. */
|
|
54
|
+
export declare function findScheduledPark(home: string, sessionId: string): Promise<ScheduledPark | undefined>;
|
|
55
|
+
/** What the TUI session a scheduled turn would resume in actually runs with. */
|
|
56
|
+
export interface ResumeEnvironment {
|
|
57
|
+
readonly cwd: string;
|
|
58
|
+
/** The session's extra roots (`--add-dir`, `/add-dir`). */
|
|
59
|
+
readonly roots: readonly string[];
|
|
60
|
+
/** Whether the session's commands run in a sandbox. */
|
|
61
|
+
readonly sandboxed: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* The providers this session has a credential for, by id; the resumed
|
|
64
|
+
* turn runs on the job's. Absent: not checked here (the turn still fails
|
|
65
|
+
* without one, after the question).
|
|
66
|
+
*/
|
|
67
|
+
readonly providers?: readonly string[];
|
|
68
|
+
/**
|
|
69
|
+
* Whether this session has the browser tools. Absent: not checked. A job
|
|
70
|
+
* with a browser grant cannot continue in a session without them.
|
|
71
|
+
*/
|
|
72
|
+
readonly browser?: boolean;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* How `environment` differs from what the job's runs get, one phrase each;
|
|
76
|
+
* empty when a resumed turn would run exactly as the job's own run did.
|
|
77
|
+
*/
|
|
78
|
+
export declare function scheduledResumeMismatch(job: ScheduleJob, environment: ResumeEnvironment): string[];
|
|
79
|
+
/** What `resumePaused` needs to continue a parked scheduled turn. */
|
|
80
|
+
export type ScheduledResumeParams = Pick<ResumePausedParams, 'pendingDecision' | 'onPermission' | 'rules' | 'permissionMode' | 'model' | 'systemNote'> & {
|
|
81
|
+
/**
|
|
82
|
+
* For a job with a browser grant: the profile and sites the session's
|
|
83
|
+
* browser must run under while the turn continues (`BrowserControl.runAs`),
|
|
84
|
+
* so the host holds it to the job's sites as the gate does.
|
|
85
|
+
*/
|
|
86
|
+
readonly browser?: {
|
|
87
|
+
readonly profile: string;
|
|
88
|
+
readonly sites: Readonly<Record<string, 'deny' | 'read' | 'ask' | 'act'>>;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* The operator's answer to a parked scheduled run: continue it with these
|
|
93
|
+
* parameters, abandon its turn (with the reason to record), or leave it
|
|
94
|
+
* waiting.
|
|
95
|
+
*/
|
|
96
|
+
export type ScheduledResume = ScheduledResumeParams | {
|
|
97
|
+
readonly abandon: string;
|
|
98
|
+
} | {
|
|
99
|
+
readonly leave: true;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* A run a tool paused for a person: say what the tool asked for, then put
|
|
103
|
+
* Continue / Abandon on the choice screen. Esc, or no choice screen, leaves
|
|
104
|
+
* the run waiting.
|
|
105
|
+
*/
|
|
106
|
+
export declare function chooseHandoffContinuation(park: Pick<ScheduledPark, 'job' | 'runId' | 'model' | 'handoff'>, choose: QuestionFn | undefined, say: (text: string) => void): Promise<'continue' | 'abandon' | 'leave'>;
|
|
107
|
+
/**
|
|
108
|
+
* Ask the operator about the parked batch — or, for a handoff park, whether
|
|
109
|
+
* to continue — and return what `resumePaused` needs, or `undefined` when
|
|
110
|
+
* this session is not a parked scheduled run.
|
|
111
|
+
*/
|
|
112
|
+
export declare function prepareScheduledResume(input: {
|
|
113
|
+
readonly home: string;
|
|
114
|
+
readonly sessionId: string;
|
|
115
|
+
readonly operatorMode: PermissionMode;
|
|
116
|
+
readonly environment: ResumeEnvironment;
|
|
117
|
+
readonly ask: ScreenPermissionFn;
|
|
118
|
+
/** The choice screen, for a handoff park's Continue / Abandon. */
|
|
119
|
+
readonly choose?: QuestionFn;
|
|
120
|
+
readonly say: (text: string) => void;
|
|
121
|
+
}): Promise<ScheduledResume | undefined>;
|
|
122
|
+
//# sourceMappingURL=resume.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resume.d.ts","sourceRoot":"","sources":["../../../src/tui/schedule/resume.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/resume` of a scheduled run parked on a decision, or on a tool's request
|
|
3
|
+
* for a person.
|
|
4
|
+
*
|
|
5
|
+
* The parked batch is put to the operator with the ordinary permission
|
|
6
|
+
* screen. Their answer is applied to exactly that batch (`pendingDecision`,
|
|
7
|
+
* the model is not asked again); calls later in the turn are asked of them
|
|
8
|
+
* live; and the resumed turn is gated by the JOB's rules, recompiled now
|
|
9
|
+
* from the job, not by the folder config the TUI session was built with. The
|
|
10
|
+
* operator's own mode can only make it stricter.
|
|
11
|
+
*
|
|
12
|
+
* The resumed turn runs on the job's provider and model, not the session's.
|
|
13
|
+
*
|
|
14
|
+
* What the rules cannot carry, the TUI session must already match: the
|
|
15
|
+
* resumed turn runs in THIS session's sandbox (or none), working directory
|
|
16
|
+
* and extra roots, so a session whose execution or roots differ from the
|
|
17
|
+
* job's is refused with the command that opens a matching one. And the
|
|
18
|
+
* screen offers no "allow all": a scheduled run has no session-wide approval.
|
|
19
|
+
*
|
|
20
|
+
* A run a tool paused for a person (`ToolResult.handoff`) has no batch to
|
|
21
|
+
* approve. The operator is shown what the tool asked for and chooses to
|
|
22
|
+
* continue it — the next step is a model call, under the job's rules — or to
|
|
23
|
+
* abandon it.
|
|
24
|
+
*/
|
|
25
|
+
import { realpathSync } from 'node:fs';
|
|
26
|
+
import { resolve } from 'node:path';
|
|
27
|
+
import { DECLINED_TOOL_CALL_FEEDBACK, DiskSessionLog, SessionPaths, asSessionId, findPendingCheckpoint, hostTimeZone, } from '@namzu/sdk';
|
|
28
|
+
import { readPermissionLayers } from '../../config/load.js';
|
|
29
|
+
import { currentTimeLine } from '../../schedule/fire/unattended-note.js';
|
|
30
|
+
import { schedulePaths } from '../../schedule/paths.js';
|
|
31
|
+
import { allowsCommands, compileJobPolicy } from '../../schedule/policy.js';
|
|
32
|
+
import { resumeCommand } from '../../schedule/resume-command.js';
|
|
33
|
+
import { listJobs } from '../../schedule/store/jobs.js';
|
|
34
|
+
import { readState } from '../../schedule/store/state.js';
|
|
35
|
+
import { terminalDisplayText } from '../terminal-display.js';
|
|
36
|
+
import { handoffContinuationNote } from '../turn-interruption.js';
|
|
37
|
+
/** The job whose run is parked in this session, and the batch it waits on. */
|
|
38
|
+
export async function findScheduledPark(home, sessionId) {
|
|
39
|
+
const paths = schedulePaths(home);
|
|
40
|
+
for (const job of listJobs(paths).jobs) {
|
|
41
|
+
const run = readState(paths, job.id).activeRun;
|
|
42
|
+
if (run?.status !== 'awaiting-approval' || run.sessionId !== sessionId || !run.projectSlug)
|
|
43
|
+
continue;
|
|
44
|
+
const log = DiskSessionLog.at(new SessionPaths({ home, slug: run.projectSlug }), {
|
|
45
|
+
sessionId: asSessionId(sessionId),
|
|
46
|
+
});
|
|
47
|
+
const park = await findPendingCheckpoint(log);
|
|
48
|
+
const handoff = park ? undefined : await pausedForHandoff(log, run.turnId);
|
|
49
|
+
if (park && park.pending.request.type !== 'tool_review')
|
|
50
|
+
return undefined;
|
|
51
|
+
const turnId = park?.pending.request.turnId ?? handoff?.turnId;
|
|
52
|
+
if (!turnId)
|
|
53
|
+
return undefined;
|
|
54
|
+
const recorded = await recordedTurnModel(log, turnId);
|
|
55
|
+
const model = job.model.model ?? recorded.model;
|
|
56
|
+
const effort = job.model.effort ?? recorded.effort;
|
|
57
|
+
return {
|
|
58
|
+
job,
|
|
59
|
+
runId: run.runId,
|
|
60
|
+
turnId,
|
|
61
|
+
model: {
|
|
62
|
+
provider: job.model.provider,
|
|
63
|
+
...(model ? { model } : {}),
|
|
64
|
+
...(effort ? { effort } : {}),
|
|
65
|
+
},
|
|
66
|
+
toolCalls: park?.pending.request.type === 'tool_review' ? park.pending.request.toolCalls : [],
|
|
67
|
+
...(handoff ? { handoff: handoff.handoff } : {}),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The turn's handoff, when its latest segment ended with `turn_paused`
|
|
74
|
+
* carrying one: a tool asked for a person and nothing has resumed the turn
|
|
75
|
+
* since. `turnId` narrows it to the run's turn when the run recorded one.
|
|
76
|
+
*/
|
|
77
|
+
async function pausedForHandoff(log, turnId) {
|
|
78
|
+
let latest;
|
|
79
|
+
try {
|
|
80
|
+
for await (const { record } of log.read({ mode: 'strict' })) {
|
|
81
|
+
if (!('turnId' in record) || typeof record.turnId !== 'string')
|
|
82
|
+
continue;
|
|
83
|
+
if (turnId !== undefined && record.turnId !== turnId)
|
|
84
|
+
continue;
|
|
85
|
+
if (record.type === 'turn_paused') {
|
|
86
|
+
latest = record.handoff
|
|
87
|
+
? {
|
|
88
|
+
turnId: record.turnId,
|
|
89
|
+
handoff: {
|
|
90
|
+
reason: record.handoff.reason,
|
|
91
|
+
...(record.handoff.detail ? { detail: record.handoff.detail } : {}),
|
|
92
|
+
},
|
|
93
|
+
}
|
|
94
|
+
: undefined;
|
|
95
|
+
}
|
|
96
|
+
else if (record.type === 'turn_resuming' ||
|
|
97
|
+
record.type === 'turn_completed' ||
|
|
98
|
+
record.type === 'turn_failed') {
|
|
99
|
+
latest = undefined;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
return latest;
|
|
107
|
+
}
|
|
108
|
+
/** The model and effort a turn's `turn_started` recorded, when it recorded them. */
|
|
109
|
+
async function recordedTurnModel(log, turnId) {
|
|
110
|
+
try {
|
|
111
|
+
for await (const { record } of log.read({ mode: 'strict' })) {
|
|
112
|
+
if (record.type !== 'turn_started' || record.turnId !== turnId)
|
|
113
|
+
continue;
|
|
114
|
+
const config = { ...record.config };
|
|
115
|
+
return {
|
|
116
|
+
...(typeof config.model === 'string' ? { model: config.model } : {}),
|
|
117
|
+
...(typeof config.effort === 'string' ? { effort: config.effort } : {}),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// An unreadable log leaves the job's own pin; the provider default fills the rest.
|
|
123
|
+
}
|
|
124
|
+
return {};
|
|
125
|
+
}
|
|
126
|
+
const STRICTER = ['plan', 'strict'];
|
|
127
|
+
function canonical(path) {
|
|
128
|
+
try {
|
|
129
|
+
return realpathSync(path);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return resolve(path);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* How `environment` differs from what the job's runs get, one phrase each;
|
|
137
|
+
* empty when a resumed turn would run exactly as the job's own run did.
|
|
138
|
+
*/
|
|
139
|
+
export function scheduledResumeMismatch(job, environment) {
|
|
140
|
+
const reasons = [];
|
|
141
|
+
const wantsSandbox = job.permissions.execution === 'sandbox';
|
|
142
|
+
// Where commands run matters only to a job that can run one: a browser
|
|
143
|
+
// job with bash denied continues the same in either session.
|
|
144
|
+
if (allowsCommands(job.permissions) && environment.sandboxed !== wantsSandbox) {
|
|
145
|
+
reasons.push(wantsSandbox
|
|
146
|
+
? 'the job runs commands in a sandbox and this session runs them on the host'
|
|
147
|
+
: 'the job runs commands on the host and this session runs them in a sandbox');
|
|
148
|
+
}
|
|
149
|
+
if (canonical(environment.cwd) !== job.folder.canonical) {
|
|
150
|
+
reasons.push(`this session's folder is not the job's (${job.folder.canonical})`);
|
|
151
|
+
}
|
|
152
|
+
const jobRoots = new Set((job.permissions.additionalDirectories ?? []).map(canonical));
|
|
153
|
+
const sessionRoots = new Set(environment.roots.map(canonical));
|
|
154
|
+
const extra = [...sessionRoots].filter((root) => !jobRoots.has(root));
|
|
155
|
+
const missing = [...jobRoots].filter((root) => !sessionRoots.has(root));
|
|
156
|
+
if (extra.length > 0)
|
|
157
|
+
reasons.push(`this session also reaches ${extra.join(', ')}`);
|
|
158
|
+
if (missing.length > 0)
|
|
159
|
+
reasons.push(`this session does not reach ${missing.join(', ')}`);
|
|
160
|
+
if (job.permissions.browser && environment.browser === false) {
|
|
161
|
+
reasons.push('the job drives the browser and this session has none (check `browser.enabled` and `namzu doctor`)');
|
|
162
|
+
}
|
|
163
|
+
if (environment.providers && !environment.providers.includes(job.model.provider)) {
|
|
164
|
+
reasons.push(`the job runs on ${job.model.provider}${job.model.model ? `/${job.model.model}` : ''} and this session has no credential for ${job.model.provider} (sign in with \`namzu login\`, or set its API key)`);
|
|
165
|
+
}
|
|
166
|
+
return reasons;
|
|
167
|
+
}
|
|
168
|
+
function describeModel(model) {
|
|
169
|
+
return model.model ? `${model.provider}/${model.model}` : model.provider;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* The operator's permission screen for a scheduled turn: one prompt at a
|
|
173
|
+
* time, each for its own batch only.
|
|
174
|
+
*
|
|
175
|
+
* Batch-only because a scheduled run has no session-wide approval, so the
|
|
176
|
+
* screen offers no "allow all" (and an "approve-all" that reached here
|
|
177
|
+
* anyway is answered as "yes" for the batch on screen). One at a time
|
|
178
|
+
* because the screen answers every prompt it has queued with an "allow all"
|
|
179
|
+
* given to another; a scheduled turn's later batches would be approved
|
|
180
|
+
* without ever being shown.
|
|
181
|
+
*/
|
|
182
|
+
function scheduledPermission(ask) {
|
|
183
|
+
let queue = Promise.resolve();
|
|
184
|
+
return (request) => {
|
|
185
|
+
const answer = queue.then(() => ask({ ...request, batchOnly: true }));
|
|
186
|
+
queue = answer.catch(() => undefined);
|
|
187
|
+
return answer.then((decision) => decision.kind === 'approve-all' ? { kind: 'approve' } : decision);
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
const CONTINUE = 'continue';
|
|
191
|
+
const ABANDON = 'abandon';
|
|
192
|
+
/**
|
|
193
|
+
* A run a tool paused for a person: say what the tool asked for, then put
|
|
194
|
+
* Continue / Abandon on the choice screen. Esc, or no choice screen, leaves
|
|
195
|
+
* the run waiting.
|
|
196
|
+
*/
|
|
197
|
+
export async function chooseHandoffContinuation(park, choose, say) {
|
|
198
|
+
const handoff = park.handoff;
|
|
199
|
+
if (!handoff)
|
|
200
|
+
return 'leave';
|
|
201
|
+
// Read back from the log, so shown as data: one line each.
|
|
202
|
+
const safe = (text) => terminalDisplayText(text).replace(/\s+/g, ' ').trim();
|
|
203
|
+
// The browser's details in words; anything else a tool sent, as it sent it.
|
|
204
|
+
const facts = handoff.detail ?? {};
|
|
205
|
+
const known = new Set(['tool', 'cause', 'origin', 'profile', 'loginCommand']);
|
|
206
|
+
const where = [
|
|
207
|
+
facts.origin ? `site ${safe(facts.origin)}` : '',
|
|
208
|
+
facts.profile ? `browser profile ${safe(facts.profile)}` : '',
|
|
209
|
+
].filter(Boolean);
|
|
210
|
+
const detail = [
|
|
211
|
+
...(where.length > 0 ? [`\n ${where.join(' · ')}`] : []),
|
|
212
|
+
...(facts.loginCommand
|
|
213
|
+
? [`\n If you have not signed in again yet: ${safe(facts.loginCommand)}`]
|
|
214
|
+
: []),
|
|
215
|
+
...Object.entries(facts)
|
|
216
|
+
.filter(([key]) => !known.has(key))
|
|
217
|
+
.map(([key, value]) => `\n ${safe(key)}: ${safe(value)}`),
|
|
218
|
+
].join('');
|
|
219
|
+
say(`⏲ The scheduled job ${park.job.name} stopped because it needs you: ${safe(handoff.reason)}${detail}\nContinue once that is done: the turn goes on under the job’s rules and on its model (${describeModel(park.model)}).`);
|
|
220
|
+
if (!choose)
|
|
221
|
+
return 'leave';
|
|
222
|
+
const choice = await choose({
|
|
223
|
+
questionId: `schedule-handoff:${park.runId}`,
|
|
224
|
+
header: park.job.name,
|
|
225
|
+
question: 'Continue the scheduled run?',
|
|
226
|
+
options: [
|
|
227
|
+
{
|
|
228
|
+
id: CONTINUE,
|
|
229
|
+
label: 'Continue',
|
|
230
|
+
description: 'It is done; carry on from here',
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
id: ABANDON,
|
|
234
|
+
label: 'Abandon',
|
|
235
|
+
description: 'Stop this run; the job stays scheduled',
|
|
236
|
+
},
|
|
237
|
+
],
|
|
238
|
+
multiSelect: false,
|
|
239
|
+
allowFreeText: false,
|
|
240
|
+
});
|
|
241
|
+
if (choice.kind !== 'answer')
|
|
242
|
+
return 'leave';
|
|
243
|
+
if (choice.selectedOptionIds.includes(CONTINUE))
|
|
244
|
+
return 'continue';
|
|
245
|
+
if (choice.selectedOptionIds.includes(ABANDON))
|
|
246
|
+
return 'abandon';
|
|
247
|
+
return 'leave';
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Ask the operator about the parked batch — or, for a handoff park, whether
|
|
251
|
+
* to continue — and return what `resumePaused` needs, or `undefined` when
|
|
252
|
+
* this session is not a parked scheduled run.
|
|
253
|
+
*/
|
|
254
|
+
export async function prepareScheduledResume(input) {
|
|
255
|
+
const park = await findScheduledPark(input.home, input.sessionId);
|
|
256
|
+
if (!park)
|
|
257
|
+
return undefined;
|
|
258
|
+
const mismatch = scheduledResumeMismatch(park.job, input.environment);
|
|
259
|
+
if (mismatch.length > 0) {
|
|
260
|
+
const execution = park.job.permissions.execution === 'sandbox'
|
|
261
|
+
? ' with `sandbox.enabled: true` in your config'
|
|
262
|
+
: ' with the sandbox off (`sandbox.enabled: false`)';
|
|
263
|
+
throw new Error(`the scheduled job ${park.job.name} ${park.handoff ? 'is waiting for you' : 'is waiting for approval'}, but its turn must continue as the job runs: ${mismatch.join('; ')}. ${park.handoff ? 'Continue' : 'Answer'} it from a session that matches: ${resumeCommand(park.job, input.sessionId)}${mismatch.some((reason) => reason.includes('sandbox')) ? execution : ''}.`);
|
|
264
|
+
}
|
|
265
|
+
const ask = scheduledPermission(input.ask);
|
|
266
|
+
const layers = readPermissionLayers({ cwd: park.job.folder.canonical });
|
|
267
|
+
const policy = compileJobPolicy(park.job.permissions, {
|
|
268
|
+
layers,
|
|
269
|
+
namzuHome: input.home,
|
|
270
|
+
folder: park.job.folder,
|
|
271
|
+
});
|
|
272
|
+
const grant = park.job.permissions.browser;
|
|
273
|
+
const zone = park.job.schedule.kind === 'cron' ? park.job.schedule.tz : hostTimeZone();
|
|
274
|
+
const resumeWith = (pendingDecision) => ({
|
|
275
|
+
...(pendingDecision ? { pendingDecision } : {}),
|
|
276
|
+
// The run may have waited days for its answer: the time its note gave is old.
|
|
277
|
+
systemNote: currentTimeLine(new Date(), zone),
|
|
278
|
+
onPermission: ask,
|
|
279
|
+
rules: policy.rules,
|
|
280
|
+
permissionMode: STRICTER.includes(input.operatorMode) ? input.operatorMode : policy.mode,
|
|
281
|
+
model: park.model,
|
|
282
|
+
...(grant
|
|
283
|
+
? {
|
|
284
|
+
browser: {
|
|
285
|
+
profile: grant.profile,
|
|
286
|
+
sites: {
|
|
287
|
+
...grant.sites,
|
|
288
|
+
...Object.fromEntries(layers
|
|
289
|
+
.flatMap((layer) => layer.browserDenies ?? [])
|
|
290
|
+
.map((site) => [site, 'deny'])),
|
|
291
|
+
'*': 'deny',
|
|
292
|
+
},
|
|
293
|
+
},
|
|
294
|
+
}
|
|
295
|
+
: {}),
|
|
296
|
+
});
|
|
297
|
+
if (park.handoff) {
|
|
298
|
+
const choice = await chooseHandoffContinuation(park, input.choose, input.say);
|
|
299
|
+
if (choice === 'continue') {
|
|
300
|
+
return {
|
|
301
|
+
...resumeWith(),
|
|
302
|
+
systemNote: handoffContinuationNote(park.handoff.reason, new Date(), zone),
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
if (choice === 'abandon')
|
|
306
|
+
return {
|
|
307
|
+
abandon: 'Scheduled run: the operator abandoned it at a handoff',
|
|
308
|
+
};
|
|
309
|
+
return { leave: true };
|
|
310
|
+
}
|
|
311
|
+
input.say(`⏲ The scheduled job ${park.job.name} is waiting for your approval. Approve runs exactly this batch; the rest of the turn stays under the job’s rules and on its model (${describeModel(park.model)}), and asks you again, one batch at a time.`);
|
|
312
|
+
const answer = await ask({
|
|
313
|
+
sessionId: input.sessionId,
|
|
314
|
+
turnId: park.turnId,
|
|
315
|
+
toolCalls: park.toolCalls,
|
|
316
|
+
});
|
|
317
|
+
return resumeWith(answer.kind === 'reject'
|
|
318
|
+
? {
|
|
319
|
+
action: 'reject_tools',
|
|
320
|
+
feedback: answer.feedback ?? DECLINED_TOOL_CALL_FEEDBACK,
|
|
321
|
+
}
|
|
322
|
+
: { action: 'approve_tools' });
|
|
323
|
+
}
|
|
324
|
+
//# sourceMappingURL=resume.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resume.js","sourceRoot":"","sources":["../../../src/tui/schedule/resume.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EACN,2BAA2B,EAC3B,cAAc,EAEd,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,YAAY,GACZ,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAE3D,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AACvD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAA;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAA;AAGzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AA6BjE,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACtC,IAAY,EACZ,SAAiB;IAEjB,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;IACjC,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,SAAS,CAAA;QAC9C,IAAI,GAAG,EAAE,MAAM,KAAK,mBAAmB,IAAI,GAAG,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,WAAW;YACzF,SAAQ;QACT,MAAM,GAAG,GAAG,cAAc,CAAC,EAAE,CAAC,IAAI,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE;YAChF,SAAS,EAAE,WAAW,CAAC,SAAS,CAAC;SACjC,CAAC,CAAA;QACF,MAAM,IAAI,GAAG,MAAM,qBAAqB,CAAC,GAAG,CAAC,CAAA;QAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;QAC1E,IAAI,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,KAAK,aAAa;YAAE,OAAO,SAAS,CAAA;QACzE,MAAM,MAAM,GAAG,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,EAAE,MAAM,CAAA;QAC9D,IAAI,CAAC,MAAM;YAAE,OAAO,SAAS,CAAA;QAC7B,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QACrD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAA;QAC/C,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAA;QAClD,OAAO;YACN,GAAG;YACH,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,MAAM;YACN,KAAK,EAAE;gBACN,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,QAAQ;gBAC5B,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC3B,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC7B;YACD,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;YAC7F,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChD,CAAA;IACF,CAAC;IACD,OAAO,SAAS,CAAA;AACjB,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,gBAAgB,CAC9B,GAAiC,EACjC,MAA0B;IAE1B,IAAI,MAAiE,CAAA;IACrE,IAAI,CAAC;QACJ,IAAI,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;YAC7D,IAAI,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ;gBAAE,SAAQ;YACxE,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM;gBAAE,SAAQ;YAC9D,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;gBACnC,MAAM,GAAG,MAAM,CAAC,OAAO;oBACtB,CAAC,CAAC;wBACA,MAAM,EAAE,MAAM,CAAC,MAAM;wBACrB,OAAO,EAAE;4BACR,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM;4BAC7B,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;yBACnE;qBACD;oBACF,CAAC,CAAC,SAAS,CAAA;YACb,CAAC;iBAAM,IACN,MAAM,CAAC,IAAI,KAAK,eAAe;gBAC/B,MAAM,CAAC,IAAI,KAAK,gBAAgB;gBAChC,MAAM,CAAC,IAAI,KAAK,aAAa,EAC5B,CAAC;gBACF,MAAM,GAAG,SAAS,CAAA;YACnB,CAAC;QACF,CAAC;IACF,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAA;IACjB,CAAC;IACD,OAAO,MAAM,CAAA;AACd,CAAC;AAED,oFAAoF;AACpF,KAAK,UAAU,iBAAiB,CAC/B,GAAiC,EACjC,MAAc;IAEd,IAAI,CAAC;QACJ,IAAI,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;YAC7D,IAAI,MAAM,CAAC,IAAI,KAAK,cAAc,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM;gBAAE,SAAQ;YACxE,MAAM,MAAM,GAA4B,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,CAAA;YAC5D,OAAO;gBACN,GAAG,CAAC,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACpE,GAAG,CAAC,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACvE,CAAA;QACF,CAAC;IACF,CAAC;IAAC,MAAM,CAAC;QACR,mFAAmF;IACpF,CAAC;IACD,OAAO,EAAE,CAAA;AACV,CAAC;AAED,MAAM,QAAQ,GAA8B,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;AAsB9D,SAAS,SAAS,CAAC,IAAY;IAC9B,IAAI,CAAC;QACJ,OAAO,YAAY,CAAC,IAAI,CAAC,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,OAAO,CAAC,IAAI,CAAC,CAAA;IACrB,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACtC,GAAgB,EAChB,WAA8B;IAE9B,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,MAAM,YAAY,GAAG,GAAG,CAAC,WAAW,CAAC,SAAS,KAAK,SAAS,CAAA;IAC5D,uEAAuE;IACvE,6DAA6D;IAC7D,IAAI,cAAc,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,SAAS,KAAK,YAAY,EAAE,CAAC;QAC/E,OAAO,CAAC,IAAI,CACX,YAAY;YACX,CAAC,CAAC,2EAA2E;YAC7E,CAAC,CAAC,2EAA2E,CAC9E,CAAA;IACF,CAAC;IACD,IAAI,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACzD,OAAO,CAAC,IAAI,CAAC,2CAA2C,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,CAAA;IACjF,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,qBAAqB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAA;IACtF,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAA;IAC9D,MAAM,KAAK,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAA;IACrE,MAAM,OAAO,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAA;IACvE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,6BAA6B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACnF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,+BAA+B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACzF,IAAI,GAAG,CAAC,WAAW,CAAC,OAAO,IAAI,WAAW,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;QAC9D,OAAO,CAAC,IAAI,CACX,mGAAmG,CACnG,CAAA;IACF,CAAC;IACD,IAAI,WAAW,CAAC,SAAS,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClF,OAAO,CAAC,IAAI,CACX,mBAAmB,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,2CAA2C,GAAG,CAAC,KAAK,CAAC,QAAQ,qDAAqD,CACtM,CAAA;IACF,CAAC;IACD,OAAO,OAAO,CAAA;AACf,CAAC;AAED,SAAS,aAAa,CAAC,KAA6B;IACnD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAA;AACzE,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,mBAAmB,CAAC,GAAuB;IACnD,IAAI,KAAK,GAAqB,OAAO,CAAC,OAAO,EAAE,CAAA;IAC/C,OAAO,CAAC,OAAO,EAAE,EAAE;QAClB,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QACrE,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;QACrC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC/B,QAAQ,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAkB,EAAE,CAAC,CAAC,CAAC,QAAQ,CACzE,CAAA;IACF,CAAC,CAAA;AACF,CAAC;AA4BD,MAAM,QAAQ,GAAG,UAAU,CAAA;AAC3B,MAAM,OAAO,GAAG,SAAS,CAAA;AAEzB;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC9C,IAAgE,EAChE,MAA8B,EAC9B,GAA2B;IAE3B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;IAC5B,IAAI,CAAC,OAAO;QAAE,OAAO,OAAO,CAAA;IAC5B,2DAA2D;IAC3D,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;IACpF,4EAA4E;IAC5E,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,CAAA;IAClC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC,CAAA;IAC7E,MAAM,KAAK,GAAG;QACb,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;QAChD,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,mBAAmB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;KAC7D,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACjB,MAAM,MAAM,GAAG;QACd,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,CAAC,KAAK,CAAC,YAAY;YACrB,CAAC,CAAC,CAAC,4CAA4C,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;YAC1E,CAAC,CAAC,EAAE,CAAC;QACN,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;aACtB,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;aAClC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;KAC3D,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACV,GAAG,CACF,uBAAuB,IAAI,CAAC,GAAG,CAAC,IAAI,kCAAkC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,0FAA0F,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAC1N,CAAA;IACD,IAAI,CAAC,MAAM;QAAE,OAAO,OAAO,CAAA;IAC3B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC;QAC3B,UAAU,EAAE,oBAAoB,IAAI,CAAC,KAAK,EAAE;QAC5C,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI;QACrB,QAAQ,EAAE,6BAA6B;QACvC,OAAO,EAAE;YACR;gBACC,EAAE,EAAE,QAAQ;gBACZ,KAAK,EAAE,UAAU;gBACjB,WAAW,EAAE,gCAAgC;aAC7C;YACD;gBACC,EAAE,EAAE,OAAO;gBACX,KAAK,EAAE,SAAS;gBAChB,WAAW,EAAE,wCAAwC;aACrD;SACD;QACD,WAAW,EAAE,KAAK;QAClB,aAAa,EAAE,KAAK;KACpB,CAAC,CAAA;IACF,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAA;IAC5C,IAAI,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,UAAU,CAAA;IAClE,IAAI,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAA;IAChE,OAAO,OAAO,CAAA;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,KAS5C;IACA,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;IACjE,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAA;IAC3B,MAAM,QAAQ,GAAG,uBAAuB,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,WAAW,CAAC,CAAA;IACrE,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,SAAS,GACd,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,SAAS,KAAK,SAAS;YAC3C,CAAC,CAAC,8CAA8C;YAChD,CAAC,CAAC,kDAAkD,CAAA;QACtD,MAAM,IAAI,KAAK,CACd,qBAAqB,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,yBAAyB,iDAAiD,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,oCAAoC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,CAC1W,CAAA;IACF,CAAC;IACD,MAAM,GAAG,GAAG,mBAAmB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC1C,MAAM,MAAM,GAAG,oBAAoB,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAA;IACvE,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE;QACrD,MAAM;QACN,SAAS,EAAE,KAAK,CAAC,IAAI;QACrB,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM;KACvB,CAAC,CAAA;IACF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAA;IAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,EAAE,CAAA;IACtF,MAAM,UAAU,GAAG,CAAC,eAAoC,EAAyB,EAAE,CAAC,CAAC;QACpF,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,8EAA8E;QAC9E,UAAU,EAAE,eAAe,CAAC,IAAI,IAAI,EAAE,EAAE,IAAI,CAAC;QAC7C,YAAY,EAAE,GAAG;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,cAAc,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI;QACxF,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,GAAG,CAAC,KAAK;YACR,CAAC,CAAC;gBACA,OAAO,EAAE;oBACR,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,KAAK,EAAE;wBACN,GAAG,KAAK,CAAC,KAAK;wBACd,GAAG,MAAM,CAAC,WAAW,CACpB,MAAM;6BACJ,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa,IAAI,EAAE,CAAC;6BAC7C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,MAAe,CAAC,CAAC,CACxC;wBACD,GAAG,EAAE,MAAe;qBACpB;iBACD;aACD;YACF,CAAC,CAAC,EAAE,CAAC;KACN,CAAC,CAAA;IACF,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;QAC7E,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;YAC3B,OAAO;gBACN,GAAG,UAAU,EAAE;gBACf,UAAU,EAAE,uBAAuB,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,EAAE,IAAI,CAAC;aAC1E,CAAA;QACF,CAAC;QACD,IAAI,MAAM,KAAK,SAAS;YACvB,OAAO;gBACN,OAAO,EAAE,uDAAuD;aAChE,CAAA;QACF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IACvB,CAAC;IACD,KAAK,CAAC,GAAG,CACR,uBAAuB,IAAI,CAAC,GAAG,CAAC,IAAI,sIAAsI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,6CAA6C,CAChP,CAAA;IACD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC;QACxB,SAAS,EAAE,KAAK,CAAC,SAAkB;QACnC,MAAM,EAAE,IAAI,CAAC,MAAe;QAC5B,SAAS,EAAE,IAAI,CAAC,SAAS;KACzB,CAAC,CAAA;IACF,OAAO,UAAU,CAChB,MAAM,CAAC,IAAI,KAAK,QAAQ;QACvB,CAAC,CAAC;YACA,MAAM,EAAE,cAAc;YACtB,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,2BAA2B;SACxD;QACF,CAAC,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAC9B,CAAA;AACF,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one line the TUI prints on open about scheduled work since it last
|
|
3
|
+
* looked: runs that finished or failed, runs waiting for approval, jobs on
|
|
4
|
+
* hold or paused by failures, a scheduler that is not installed or not
|
|
5
|
+
* running, a run working in this folder right now. Nothing when there is
|
|
6
|
+
* nothing to say. Reads are bounded (each job's history tail), and the caller
|
|
7
|
+
* gives it a time budget so a slow disk never delays the first paint.
|
|
8
|
+
*/
|
|
9
|
+
/** Compute the line and record that it was shown. `undefined` when there is nothing to say. */
|
|
10
|
+
export declare function scheduleStartupLine(home: string, cwd: string, now?: number): string | undefined;
|
|
11
|
+
//# sourceMappingURL=startup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"startup.d.ts","sourceRoot":"","sources":["../../../src/tui/schedule/startup.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAmBH,+FAA+F;AAC/F,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,GAAG,SAAa,GACd,MAAM,GAAG,SAAS,CAoFpB"}
|