@phnx-labs/agents-cli 1.12.0 → 1.14.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/CHANGELOG.md +7 -1
- package/README.md +308 -297
- package/dist/commands/alias.d.ts +11 -0
- package/dist/commands/alias.js +117 -0
- package/dist/commands/beta.d.ts +2 -0
- package/dist/commands/beta.js +53 -0
- package/dist/commands/cloud.d.ts +10 -0
- package/dist/commands/cloud.js +408 -0
- package/dist/commands/commands.d.ts +9 -1
- package/dist/commands/commands.js +24 -172
- package/dist/commands/daemon.d.ts +8 -1
- package/dist/commands/daemon.js +13 -5
- package/dist/commands/doctor.d.ts +15 -0
- package/dist/commands/doctor.js +132 -0
- package/dist/commands/drive.d.ts +8 -1
- package/dist/commands/drive.js +20 -3
- package/dist/commands/exec.d.ts +8 -1
- package/dist/commands/exec.js +207 -20
- package/dist/commands/factory.d.ts +19 -0
- package/dist/commands/factory.js +71 -0
- package/dist/commands/fork.d.ts +8 -1
- package/dist/commands/fork.js +11 -4
- package/dist/commands/hooks.d.ts +9 -1
- package/dist/commands/hooks.js +30 -182
- package/dist/commands/init.d.ts +15 -1
- package/dist/commands/init.js +168 -74
- package/dist/commands/mcp.d.ts +9 -1
- package/dist/commands/mcp.js +11 -7
- package/dist/commands/models.d.ts +8 -1
- package/dist/commands/models.js +45 -6
- package/dist/commands/packages.d.ts +8 -1
- package/dist/commands/packages.js +13 -7
- package/dist/commands/permissions.d.ts +9 -1
- package/dist/commands/permissions.js +3 -3
- package/dist/commands/plugins.d.ts +8 -1
- package/dist/commands/plugins.js +13 -2
- package/dist/commands/profiles.d.ts +11 -0
- package/dist/commands/profiles.js +291 -0
- package/dist/commands/prune.d.ts +22 -0
- package/dist/commands/prune.js +191 -0
- package/dist/commands/pty.d.ts +1 -1
- package/dist/commands/pty.js +2 -1
- package/dist/commands/pull.d.ts +8 -1
- package/dist/commands/pull.js +93 -129
- package/dist/commands/refresh-memory.d.ts +7 -1
- package/dist/commands/refresh-memory.js +7 -1
- package/dist/commands/repo.d.ts +15 -0
- package/dist/commands/repo.js +570 -0
- package/dist/commands/resource-view.d.ts +10 -3
- package/dist/commands/resource-view.js +18 -5
- package/dist/commands/routines.d.ts +8 -1
- package/dist/commands/routines.js +17 -4
- package/dist/commands/rules.d.ts +9 -1
- package/dist/commands/rules.js +16 -11
- package/dist/commands/secrets.d.ts +10 -0
- package/dist/commands/secrets.js +518 -0
- package/dist/commands/sessions-picker.d.ts +2 -1
- package/dist/commands/sessions-picker.js +88 -11
- package/dist/commands/sessions-tail.d.ts +19 -0
- package/dist/commands/sessions-tail.js +235 -0
- package/dist/commands/sessions.d.ts +2 -1
- package/dist/commands/sessions.js +288 -7
- package/dist/commands/skills.d.ts +9 -1
- package/dist/commands/skills.js +28 -178
- package/dist/commands/status.d.ts +7 -1
- package/dist/commands/status.js +7 -1
- package/dist/commands/subagents.d.ts +8 -1
- package/dist/commands/subagents.js +11 -1
- package/dist/commands/sync.d.ts +8 -1
- package/dist/commands/sync.js +8 -1
- package/dist/commands/teams-picker.d.ts +4 -1
- package/dist/commands/teams-picker.js +55 -3
- package/dist/commands/teams.d.ts +15 -1
- package/dist/commands/teams.js +323 -69
- package/dist/commands/usage.d.ts +11 -0
- package/dist/commands/usage.js +60 -0
- package/dist/commands/utils.d.ts +6 -1
- package/dist/commands/utils.js +6 -1
- package/dist/commands/versions.d.ts +8 -1
- package/dist/commands/versions.js +4 -3
- package/dist/commands/view.d.ts +47 -2
- package/dist/commands/view.js +353 -20
- package/dist/index.d.ts +7 -2
- package/dist/index.js +205 -38
- package/dist/lib/acp/client.d.ts +31 -0
- package/dist/lib/acp/client.js +117 -0
- package/dist/lib/acp/harnesses.d.ts +26 -0
- package/dist/lib/acp/harnesses.js +65 -0
- package/dist/lib/acp/run.d.ts +18 -0
- package/dist/lib/acp/run.js +39 -0
- package/dist/lib/agents.d.ts +74 -2
- package/dist/lib/agents.js +207 -23
- package/dist/lib/artifact-actions.d.ts +8 -4
- package/dist/lib/artifact-actions.js +8 -6
- package/dist/lib/auto-pull-worker.d.ts +11 -0
- package/dist/lib/auto-pull-worker.js +121 -0
- package/dist/lib/auto-pull.d.ts +31 -0
- package/dist/lib/auto-pull.js +97 -0
- package/dist/lib/beta.d.ts +23 -0
- package/dist/lib/beta.js +90 -0
- package/dist/lib/capabilities.d.ts +29 -0
- package/dist/lib/capabilities.js +74 -0
- package/dist/lib/cloud/codex.d.ts +25 -0
- package/dist/lib/cloud/codex.js +250 -0
- package/dist/lib/cloud/factory.d.ts +31 -0
- package/dist/lib/cloud/factory.js +53 -0
- package/dist/lib/cloud/registry.d.ts +15 -0
- package/dist/lib/cloud/registry.js +67 -0
- package/dist/lib/cloud/rush.d.ts +75 -0
- package/dist/lib/cloud/rush.js +438 -0
- package/dist/lib/cloud/store.d.ts +22 -0
- package/dist/lib/cloud/store.js +115 -0
- package/dist/lib/cloud/stream.d.ts +23 -0
- package/dist/lib/cloud/stream.js +194 -0
- package/dist/lib/cloud/types.d.ts +205 -0
- package/dist/lib/cloud/types.js +34 -0
- package/dist/lib/command-skills.d.ts +20 -0
- package/dist/lib/command-skills.js +142 -0
- package/dist/lib/commands.d.ts +22 -2
- package/dist/lib/commands.js +51 -11
- package/dist/lib/convert.d.ts +10 -1
- package/dist/lib/convert.js +9 -1
- package/dist/lib/daemon.d.ts +21 -1
- package/dist/lib/daemon.js +97 -4
- package/dist/lib/drive-sync.d.ts +18 -1
- package/dist/lib/drive-sync.js +57 -15
- package/dist/lib/exec.d.ts +25 -5
- package/dist/lib/exec.js +72 -27
- package/dist/lib/fs-walk.d.ts +2 -0
- package/dist/lib/fs-walk.js +40 -0
- package/dist/lib/fuzzy.d.ts +53 -0
- package/dist/lib/fuzzy.js +72 -0
- package/dist/lib/gemini-settings.d.ts +4 -0
- package/dist/lib/gemini-settings.js +33 -0
- package/dist/lib/git.d.ts +12 -2
- package/dist/lib/git.js +17 -6
- package/dist/lib/help.d.ts +20 -1
- package/dist/lib/help.js +45 -6
- package/dist/lib/hooks/match.d.ts +32 -0
- package/dist/lib/hooks/match.js +120 -0
- package/dist/lib/hooks.d.ts +17 -4
- package/dist/lib/hooks.js +191 -21
- package/dist/lib/manifest.d.ts +6 -1
- package/dist/lib/manifest.js +15 -4
- package/dist/lib/markdown.d.ts +0 -1
- package/dist/lib/markdown.js +6 -1
- package/dist/lib/mcp.d.ts +0 -1
- package/dist/lib/mcp.js +29 -33
- package/dist/lib/memory-compile.d.ts +13 -3
- package/dist/lib/memory-compile.js +31 -9
- package/dist/lib/memory.d.ts +14 -7
- package/dist/lib/memory.js +67 -38
- package/dist/lib/migrate.d.ts +8 -0
- package/dist/lib/migrate.js +85 -0
- package/dist/lib/models.d.ts +25 -11
- package/dist/lib/models.js +405 -16
- package/dist/lib/onepassword.d.ts +63 -0
- package/dist/lib/onepassword.js +186 -0
- package/dist/lib/paths.d.ts +8 -0
- package/dist/lib/paths.js +20 -0
- package/dist/lib/permissions.d.ts +24 -2
- package/dist/lib/permissions.js +117 -48
- package/dist/lib/picker.d.ts +10 -1
- package/dist/lib/picker.js +15 -1
- package/dist/lib/plugins.d.ts +7 -1
- package/dist/lib/plugins.js +10 -1
- package/dist/lib/profiles-presets.d.ts +24 -0
- package/dist/lib/profiles-presets.js +103 -0
- package/dist/lib/profiles.d.ts +69 -0
- package/dist/lib/profiles.js +144 -0
- package/dist/lib/pty-client.d.ts +1 -1
- package/dist/lib/pty-client.js +0 -1
- package/dist/lib/pty-server.d.ts +16 -2
- package/dist/lib/pty-server.js +92 -3
- package/dist/lib/registry.d.ts +23 -3
- package/dist/lib/registry.js +153 -8
- package/dist/lib/resources.d.ts +28 -1
- package/dist/lib/resources.js +79 -1
- package/dist/lib/rotate.d.ts +89 -0
- package/dist/lib/rotate.js +327 -0
- package/dist/lib/routines.d.ts +29 -1
- package/dist/lib/routines.js +32 -5
- package/dist/lib/runner.d.ts +14 -1
- package/dist/lib/runner.js +22 -3
- package/dist/lib/sandbox.d.ts +16 -1
- package/dist/lib/sandbox.js +39 -16
- package/dist/lib/scheduler.d.ts +8 -1
- package/dist/lib/scheduler.js +8 -1
- package/dist/lib/secrets/AgentsKeychain.app/Contents/CodeResources +0 -0
- package/dist/lib/secrets/AgentsKeychain.app/Contents/Info.plist +22 -0
- package/dist/lib/secrets/AgentsKeychain.app/Contents/MacOS/AgentsKeychain +0 -0
- package/dist/lib/secrets/AgentsKeychain.app/Contents/_CodeSignature/CodeResources +123 -0
- package/dist/lib/secrets/AgentsKeychain.app/Contents/embedded.provisionprofile +0 -0
- package/dist/lib/secrets/bundles.d.ts +39 -0
- package/dist/lib/secrets/bundles.js +189 -0
- package/dist/lib/secrets/index.d.ts +55 -0
- package/dist/lib/secrets/index.js +211 -0
- package/dist/lib/secrets/profiles.d.ts +10 -0
- package/dist/lib/secrets/profiles.js +13 -0
- package/dist/lib/session/active.d.ts +43 -0
- package/dist/lib/session/active.js +392 -0
- package/dist/lib/session/artifacts.d.ts +16 -0
- package/dist/lib/session/artifacts.js +95 -0
- package/dist/lib/session/cloud.d.ts +30 -0
- package/dist/lib/session/cloud.js +121 -0
- package/dist/lib/session/db.d.ts +23 -2
- package/dist/lib/session/db.js +76 -12
- package/dist/lib/session/discover.d.ts +19 -4
- package/dist/lib/session/discover.js +344 -48
- package/dist/lib/session/parse.d.ts +28 -1
- package/dist/lib/session/parse.js +267 -9
- package/dist/lib/session/prompt.d.ts +9 -1
- package/dist/lib/session/prompt.js +17 -3
- package/dist/lib/session/render.d.ts +13 -1
- package/dist/lib/session/render.js +20 -1
- package/dist/lib/session/team-filter.d.ts +9 -1
- package/dist/lib/session/team-filter.js +11 -2
- package/dist/lib/session/types.d.ts +24 -2
- package/dist/lib/session/types.js +10 -2
- package/dist/lib/shims.d.ts +93 -5
- package/dist/lib/shims.js +380 -67
- package/dist/lib/skills.d.ts +27 -2
- package/dist/lib/skills.js +127 -65
- package/dist/lib/sqlite.d.ts +43 -0
- package/dist/lib/sqlite.js +94 -0
- package/dist/lib/state.d.ts +114 -22
- package/dist/lib/state.js +323 -138
- package/dist/lib/subagents.d.ts +9 -1
- package/dist/lib/subagents.js +70 -63
- package/dist/lib/sync-manifest.d.ts +81 -0
- package/dist/lib/sync-manifest.js +450 -0
- package/dist/lib/teams/agents.d.ts +103 -5
- package/dist/lib/teams/agents.js +414 -91
- package/dist/lib/teams/api.d.ts +26 -3
- package/dist/lib/teams/api.js +63 -3
- package/dist/lib/teams/debug.d.ts +6 -1
- package/dist/lib/teams/debug.js +6 -1
- package/dist/lib/teams/file_ops.d.ts +7 -1
- package/dist/lib/teams/file_ops.js +7 -1
- package/dist/lib/teams/index.d.ts +15 -0
- package/dist/lib/teams/index.js +14 -0
- package/dist/lib/teams/parsers.d.ts +4 -1
- package/dist/lib/teams/parsers.js +11 -1
- package/dist/lib/teams/persistence.d.ts +15 -1
- package/dist/lib/teams/persistence.js +102 -20
- package/dist/lib/teams/registry.d.ts +12 -1
- package/dist/lib/teams/registry.js +116 -33
- package/dist/lib/teams/summarizer.d.ts +15 -1
- package/dist/lib/teams/summarizer.js +14 -1
- package/dist/lib/teams/supervisor.d.ts +48 -0
- package/dist/lib/teams/supervisor.js +73 -0
- package/dist/lib/template.d.ts +8 -6
- package/dist/lib/template.js +8 -6
- package/dist/lib/types.d.ts +147 -8
- package/dist/lib/types.js +26 -3
- package/dist/lib/usage.d.ts +48 -1
- package/dist/lib/usage.js +97 -16
- package/dist/lib/version-duplicates.d.ts +21 -0
- package/dist/lib/version-duplicates.js +90 -0
- package/dist/lib/versions.d.ts +39 -4
- package/dist/lib/versions.js +401 -111
- package/package.json +33 -18
- package/scripts/postinstall.js +126 -30
- package/dist/commands/__tests__/sessions.test.d.ts +0 -2
- package/dist/commands/__tests__/sessions.test.d.ts.map +0 -1
- package/dist/commands/__tests__/sessions.test.js +0 -636
- package/dist/commands/__tests__/sessions.test.js.map +0 -1
- package/dist/commands/commands.d.ts.map +0 -1
- package/dist/commands/commands.js.map +0 -1
- package/dist/commands/daemon.d.ts.map +0 -1
- package/dist/commands/daemon.js.map +0 -1
- package/dist/commands/drive.d.ts.map +0 -1
- package/dist/commands/drive.js.map +0 -1
- package/dist/commands/exec.d.ts.map +0 -1
- package/dist/commands/exec.js.map +0 -1
- package/dist/commands/fork.d.ts.map +0 -1
- package/dist/commands/fork.js.map +0 -1
- package/dist/commands/hooks.d.ts.map +0 -1
- package/dist/commands/hooks.js.map +0 -1
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/mcp.d.ts.map +0 -1
- package/dist/commands/mcp.js.map +0 -1
- package/dist/commands/models.d.ts.map +0 -1
- package/dist/commands/models.js.map +0 -1
- package/dist/commands/packages.d.ts.map +0 -1
- package/dist/commands/packages.js.map +0 -1
- package/dist/commands/permissions.d.ts.map +0 -1
- package/dist/commands/permissions.js.map +0 -1
- package/dist/commands/plugins.d.ts.map +0 -1
- package/dist/commands/plugins.js.map +0 -1
- package/dist/commands/pty.d.ts.map +0 -1
- package/dist/commands/pty.js.map +0 -1
- package/dist/commands/pull.d.ts.map +0 -1
- package/dist/commands/pull.js.map +0 -1
- package/dist/commands/push.d.ts +0 -3
- package/dist/commands/push.d.ts.map +0 -1
- package/dist/commands/push.js +0 -180
- package/dist/commands/push.js.map +0 -1
- package/dist/commands/refresh-memory.d.ts.map +0 -1
- package/dist/commands/refresh-memory.js.map +0 -1
- package/dist/commands/resource-view.d.ts.map +0 -1
- package/dist/commands/resource-view.js.map +0 -1
- package/dist/commands/routines.d.ts.map +0 -1
- package/dist/commands/routines.js.map +0 -1
- package/dist/commands/rules.d.ts.map +0 -1
- package/dist/commands/rules.js.map +0 -1
- package/dist/commands/sessions-picker.d.ts.map +0 -1
- package/dist/commands/sessions-picker.js.map +0 -1
- package/dist/commands/sessions.d.ts.map +0 -1
- package/dist/commands/sessions.js.map +0 -1
- package/dist/commands/skills.d.ts.map +0 -1
- package/dist/commands/skills.js.map +0 -1
- package/dist/commands/status.d.ts.map +0 -1
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/subagents.d.ts.map +0 -1
- package/dist/commands/subagents.js.map +0 -1
- package/dist/commands/sync.d.ts.map +0 -1
- package/dist/commands/sync.js.map +0 -1
- package/dist/commands/teams-picker.d.ts.map +0 -1
- package/dist/commands/teams-picker.js.map +0 -1
- package/dist/commands/teams.d.ts.map +0 -1
- package/dist/commands/teams.js.map +0 -1
- package/dist/commands/utils.d.ts.map +0 -1
- package/dist/commands/utils.js.map +0 -1
- package/dist/commands/versions.d.ts.map +0 -1
- package/dist/commands/versions.js.map +0 -1
- package/dist/commands/view.d.ts.map +0 -1
- package/dist/commands/view.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/__tests__/bugfixes.test.d.ts +0 -2
- package/dist/lib/__tests__/bugfixes.test.d.ts.map +0 -1
- package/dist/lib/__tests__/bugfixes.test.js +0 -192
- package/dist/lib/__tests__/bugfixes.test.js.map +0 -1
- package/dist/lib/__tests__/exec.test.d.ts +0 -2
- package/dist/lib/__tests__/exec.test.d.ts.map +0 -1
- package/dist/lib/__tests__/exec.test.js +0 -446
- package/dist/lib/__tests__/exec.test.js.map +0 -1
- package/dist/lib/__tests__/git-sync.test.d.ts +0 -2
- package/dist/lib/__tests__/git-sync.test.d.ts.map +0 -1
- package/dist/lib/__tests__/git-sync.test.js +0 -138
- package/dist/lib/__tests__/git-sync.test.js.map +0 -1
- package/dist/lib/__tests__/hooks.test.d.ts +0 -2
- package/dist/lib/__tests__/hooks.test.d.ts.map +0 -1
- package/dist/lib/__tests__/hooks.test.js +0 -203
- package/dist/lib/__tests__/hooks.test.js.map +0 -1
- package/dist/lib/__tests__/memory-compile.test.d.ts +0 -2
- package/dist/lib/__tests__/memory-compile.test.d.ts.map +0 -1
- package/dist/lib/__tests__/memory-compile.test.js +0 -95
- package/dist/lib/__tests__/memory-compile.test.js.map +0 -1
- package/dist/lib/__tests__/models.test.d.ts +0 -2
- package/dist/lib/__tests__/models.test.d.ts.map +0 -1
- package/dist/lib/__tests__/models.test.js +0 -184
- package/dist/lib/__tests__/models.test.js.map +0 -1
- package/dist/lib/__tests__/usage.test.d.ts +0 -2
- package/dist/lib/__tests__/usage.test.d.ts.map +0 -1
- package/dist/lib/__tests__/usage.test.js +0 -218
- package/dist/lib/__tests__/usage.test.js.map +0 -1
- package/dist/lib/agents.d.ts.map +0 -1
- package/dist/lib/agents.js.map +0 -1
- package/dist/lib/artifact-actions.d.ts.map +0 -1
- package/dist/lib/artifact-actions.js.map +0 -1
- package/dist/lib/commands.d.ts.map +0 -1
- package/dist/lib/commands.js.map +0 -1
- package/dist/lib/convert.d.ts.map +0 -1
- package/dist/lib/convert.js.map +0 -1
- package/dist/lib/daemon.d.ts.map +0 -1
- package/dist/lib/daemon.js.map +0 -1
- package/dist/lib/drive-sync.d.ts.map +0 -1
- package/dist/lib/drive-sync.js.map +0 -1
- package/dist/lib/exec.d.ts.map +0 -1
- package/dist/lib/exec.js.map +0 -1
- package/dist/lib/factory.d.ts +0 -57
- package/dist/lib/factory.d.ts.map +0 -1
- package/dist/lib/factory.js +0 -110
- package/dist/lib/factory.js.map +0 -1
- package/dist/lib/git.d.ts.map +0 -1
- package/dist/lib/git.js.map +0 -1
- package/dist/lib/help.d.ts.map +0 -1
- package/dist/lib/help.js.map +0 -1
- package/dist/lib/hooks.d.ts.map +0 -1
- package/dist/lib/hooks.js.map +0 -1
- package/dist/lib/manifest.d.ts.map +0 -1
- package/dist/lib/manifest.js.map +0 -1
- package/dist/lib/markdown.d.ts.map +0 -1
- package/dist/lib/markdown.js.map +0 -1
- package/dist/lib/mcp.d.ts.map +0 -1
- package/dist/lib/mcp.js.map +0 -1
- package/dist/lib/memory-compile.d.ts.map +0 -1
- package/dist/lib/memory-compile.js.map +0 -1
- package/dist/lib/memory.d.ts.map +0 -1
- package/dist/lib/memory.js.map +0 -1
- package/dist/lib/models.d.ts.map +0 -1
- package/dist/lib/models.js.map +0 -1
- package/dist/lib/permissions.d.ts.map +0 -1
- package/dist/lib/permissions.js.map +0 -1
- package/dist/lib/picker.d.ts.map +0 -1
- package/dist/lib/picker.js.map +0 -1
- package/dist/lib/plugins.d.ts.map +0 -1
- package/dist/lib/plugins.js.map +0 -1
- package/dist/lib/pty-client.d.ts.map +0 -1
- package/dist/lib/pty-client.js.map +0 -1
- package/dist/lib/pty-server.d.ts.map +0 -1
- package/dist/lib/pty-server.js.map +0 -1
- package/dist/lib/registry.d.ts.map +0 -1
- package/dist/lib/registry.js.map +0 -1
- package/dist/lib/resources.d.ts.map +0 -1
- package/dist/lib/resources.js.map +0 -1
- package/dist/lib/routines.d.ts.map +0 -1
- package/dist/lib/routines.js.map +0 -1
- package/dist/lib/runner.d.ts.map +0 -1
- package/dist/lib/runner.js.map +0 -1
- package/dist/lib/sandbox.d.ts.map +0 -1
- package/dist/lib/sandbox.js.map +0 -1
- package/dist/lib/scheduler.d.ts.map +0 -1
- package/dist/lib/scheduler.js.map +0 -1
- package/dist/lib/session/__tests__/db.test.d.ts +0 -2
- package/dist/lib/session/__tests__/db.test.d.ts.map +0 -1
- package/dist/lib/session/__tests__/db.test.js +0 -54
- package/dist/lib/session/__tests__/db.test.js.map +0 -1
- package/dist/lib/session/__tests__/discover.test.d.ts +0 -2
- package/dist/lib/session/__tests__/discover.test.d.ts.map +0 -1
- package/dist/lib/session/__tests__/discover.test.js +0 -63
- package/dist/lib/session/__tests__/discover.test.js.map +0 -1
- package/dist/lib/session/__tests__/prompt.test.d.ts +0 -2
- package/dist/lib/session/__tests__/prompt.test.d.ts.map +0 -1
- package/dist/lib/session/__tests__/prompt.test.js +0 -44
- package/dist/lib/session/__tests__/prompt.test.js.map +0 -1
- package/dist/lib/session/__tests__/render.test.d.ts +0 -2
- package/dist/lib/session/__tests__/render.test.d.ts.map +0 -1
- package/dist/lib/session/__tests__/render.test.js +0 -602
- package/dist/lib/session/__tests__/render.test.js.map +0 -1
- package/dist/lib/session/db.d.ts.map +0 -1
- package/dist/lib/session/db.js.map +0 -1
- package/dist/lib/session/discover.d.ts.map +0 -1
- package/dist/lib/session/discover.js.map +0 -1
- package/dist/lib/session/parse.d.ts.map +0 -1
- package/dist/lib/session/parse.js.map +0 -1
- package/dist/lib/session/prompt.d.ts.map +0 -1
- package/dist/lib/session/prompt.js.map +0 -1
- package/dist/lib/session/prompt.test.d.ts +0 -2
- package/dist/lib/session/prompt.test.d.ts.map +0 -1
- package/dist/lib/session/prompt.test.js +0 -57
- package/dist/lib/session/prompt.test.js.map +0 -1
- package/dist/lib/session/render.d.ts.map +0 -1
- package/dist/lib/session/render.js.map +0 -1
- package/dist/lib/session/team-filter.d.ts.map +0 -1
- package/dist/lib/session/team-filter.js.map +0 -1
- package/dist/lib/session/team-filter.test.d.ts +0 -2
- package/dist/lib/session/team-filter.test.d.ts.map +0 -1
- package/dist/lib/session/team-filter.test.js +0 -157
- package/dist/lib/session/team-filter.test.js.map +0 -1
- package/dist/lib/session/types.d.ts.map +0 -1
- package/dist/lib/session/types.js.map +0 -1
- package/dist/lib/shims.d.ts.map +0 -1
- package/dist/lib/shims.js.map +0 -1
- package/dist/lib/skills.d.ts.map +0 -1
- package/dist/lib/skills.js.map +0 -1
- package/dist/lib/state.d.ts.map +0 -1
- package/dist/lib/state.js.map +0 -1
- package/dist/lib/subagents.d.ts.map +0 -1
- package/dist/lib/subagents.js.map +0 -1
- package/dist/lib/teams/agents.d.ts.map +0 -1
- package/dist/lib/teams/agents.js.map +0 -1
- package/dist/lib/teams/api.d.ts.map +0 -1
- package/dist/lib/teams/api.js.map +0 -1
- package/dist/lib/teams/cloud.d.ts +0 -11
- package/dist/lib/teams/cloud.d.ts.map +0 -1
- package/dist/lib/teams/cloud.js +0 -169
- package/dist/lib/teams/cloud.js.map +0 -1
- package/dist/lib/teams/debug.d.ts.map +0 -1
- package/dist/lib/teams/debug.js.map +0 -1
- package/dist/lib/teams/file_ops.d.ts.map +0 -1
- package/dist/lib/teams/file_ops.js.map +0 -1
- package/dist/lib/teams/parsers.d.ts.map +0 -1
- package/dist/lib/teams/parsers.js.map +0 -1
- package/dist/lib/teams/persistence.d.ts.map +0 -1
- package/dist/lib/teams/persistence.js.map +0 -1
- package/dist/lib/teams/ralph.d.ts +0 -8
- package/dist/lib/teams/ralph.d.ts.map +0 -1
- package/dist/lib/teams/ralph.js +0 -59
- package/dist/lib/teams/ralph.js.map +0 -1
- package/dist/lib/teams/registry.d.ts.map +0 -1
- package/dist/lib/teams/registry.js.map +0 -1
- package/dist/lib/teams/summarizer.d.ts.map +0 -1
- package/dist/lib/teams/summarizer.js.map +0 -1
- package/dist/lib/template.d.ts.map +0 -1
- package/dist/lib/template.js.map +0 -1
- package/dist/lib/types.d.ts.map +0 -1
- package/dist/lib/types.js.map +0 -1
- package/dist/lib/usage.d.ts.map +0 -1
- package/dist/lib/usage.js.map +0 -1
- package/dist/lib/versions.d.ts.map +0 -1
- package/dist/lib/versions.js.map +0 -1
- package/scripts/rebuild-sqlite.sh +0 -46
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Account rotation across agent versions.
|
|
3
|
+
*
|
|
4
|
+
* Detects which installed versions have expired credentials and rotates
|
|
5
|
+
* authentication tokens so users maintain active sessions across version switches.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import * as yaml from 'yaml';
|
|
10
|
+
import { getAccountInfo } from './agents.js';
|
|
11
|
+
import { readMeta, writeMeta, getAgentsDir } from './state.js';
|
|
12
|
+
import { listInstalledVersions, getVersionHomePath, resolveVersion } from './versions.js';
|
|
13
|
+
import { getUsageInfoByIdentity, getUsageLookupKey, isClaudeAuthValid, } from './usage.js';
|
|
14
|
+
export const RUN_STRATEGIES = ['pinned', 'available', 'balanced'];
|
|
15
|
+
/**
|
|
16
|
+
* Return a run strategy when the input is valid, otherwise null.
|
|
17
|
+
*
|
|
18
|
+
* `'rotate'` is accepted as a deprecated alias for `'balanced'` so old yaml
|
|
19
|
+
* configs and `--strategy rotate` invocations keep working. The legacy alias
|
|
20
|
+
* normalizes to `'balanced'` and uses the weighted-random algorithm.
|
|
21
|
+
*/
|
|
22
|
+
export function normalizeRunStrategy(value) {
|
|
23
|
+
if (typeof value !== 'string')
|
|
24
|
+
return null;
|
|
25
|
+
if (value === 'rotate')
|
|
26
|
+
return 'balanced';
|
|
27
|
+
return RUN_STRATEGIES.includes(value) ? value : null;
|
|
28
|
+
}
|
|
29
|
+
/** Read project-local run strategy from the nearest agents.yaml, if present. */
|
|
30
|
+
export function getProjectRunStrategy(agent, startPath) {
|
|
31
|
+
let dir = path.resolve(startPath);
|
|
32
|
+
const userAgentsYaml = path.join(getAgentsDir(), 'agents.yaml');
|
|
33
|
+
while (dir !== path.dirname(dir)) {
|
|
34
|
+
const manifestPath = path.join(dir, 'agents.yaml');
|
|
35
|
+
if (manifestPath !== userAgentsYaml && fs.existsSync(manifestPath)) {
|
|
36
|
+
try {
|
|
37
|
+
const parsed = yaml.parse(fs.readFileSync(manifestPath, 'utf-8'));
|
|
38
|
+
const strategy = normalizeRunStrategy(parsed?.run?.[agent]?.strategy);
|
|
39
|
+
if (strategy)
|
|
40
|
+
return strategy;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// Ignore malformed project config and keep walking, matching version resolution.
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
dir = path.dirname(dir);
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
/** Resolve the configured strategy: project agents.yaml, then ~/.agents-system/agents.yaml, then pinned. */
|
|
51
|
+
export function getConfiguredRunStrategy(agent, startPath = process.cwd()) {
|
|
52
|
+
return getProjectRunStrategy(agent, startPath)
|
|
53
|
+
?? normalizeRunStrategy(readMeta().run?.[agent]?.strategy)
|
|
54
|
+
?? 'pinned';
|
|
55
|
+
}
|
|
56
|
+
/** Persist the global run strategy used by bare `agents run <agent>`. */
|
|
57
|
+
export function setGlobalRunStrategy(agent, strategy) {
|
|
58
|
+
const meta = readMeta();
|
|
59
|
+
if (!meta.run)
|
|
60
|
+
meta.run = {};
|
|
61
|
+
meta.run[agent] = { ...(meta.run[agent] ?? {}), strategy };
|
|
62
|
+
writeMeta(meta);
|
|
63
|
+
}
|
|
64
|
+
function isRotationEligible(candidate) {
|
|
65
|
+
return !!candidate.email
|
|
66
|
+
&& candidate.authValid
|
|
67
|
+
&& hasUsageAvailable(candidate);
|
|
68
|
+
}
|
|
69
|
+
function isAvailableEligible(candidate) {
|
|
70
|
+
return !!candidate.email
|
|
71
|
+
&& candidate.authValid
|
|
72
|
+
&& hasUsageAvailable(candidate);
|
|
73
|
+
}
|
|
74
|
+
function hasUsageAvailable(candidate) {
|
|
75
|
+
const usedPercent = getRoutingUsedPercent(candidate.usageSnapshot);
|
|
76
|
+
if (usedPercent !== null) {
|
|
77
|
+
return usedPercent < 100;
|
|
78
|
+
}
|
|
79
|
+
if (candidate.usageStatus === 'out_of_credits' || candidate.usageStatus === 'rate_limited') {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
function getRoutingUsedPercent(snapshot) {
|
|
85
|
+
if (!snapshot || snapshot.windows.length === 0)
|
|
86
|
+
return null;
|
|
87
|
+
const routingWindows = snapshot.windows.filter((window) => window.key !== 'session');
|
|
88
|
+
const windows = routingWindows.length > 0 ? routingWindows : snapshot.windows;
|
|
89
|
+
return Math.max(...windows.map((window) => window.usedPercent));
|
|
90
|
+
}
|
|
91
|
+
function compareCandidates(a, b) {
|
|
92
|
+
const au = getRoutingUsedPercent(a.usageSnapshot);
|
|
93
|
+
const bu = getRoutingUsedPercent(b.usageSnapshot);
|
|
94
|
+
if (au !== null || bu !== null) {
|
|
95
|
+
if (au === null)
|
|
96
|
+
return 1;
|
|
97
|
+
if (bu === null)
|
|
98
|
+
return -1;
|
|
99
|
+
if (au !== bu)
|
|
100
|
+
return au - bu;
|
|
101
|
+
}
|
|
102
|
+
const ta = a.lastActive ? a.lastActive.getTime() : 0;
|
|
103
|
+
const tb = b.lastActive ? b.lastActive.getTime() : 0;
|
|
104
|
+
if (ta !== tb)
|
|
105
|
+
return ta - tb;
|
|
106
|
+
return Math.random() - 0.5;
|
|
107
|
+
}
|
|
108
|
+
function dedupeAndSortCandidates(candidates) {
|
|
109
|
+
const byEmail = new Map();
|
|
110
|
+
for (const c of candidates) {
|
|
111
|
+
const email = c.email;
|
|
112
|
+
const existing = byEmail.get(email);
|
|
113
|
+
if (!existing) {
|
|
114
|
+
byEmail.set(email, c);
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (compareCandidates(c, existing) < 0)
|
|
118
|
+
byEmail.set(email, c);
|
|
119
|
+
}
|
|
120
|
+
return [...byEmail.values()].sort(compareCandidates);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Pick a healthy candidate using weighted random by remaining capacity.
|
|
124
|
+
*
|
|
125
|
+
* Each healthy candidate gets weight = max(1, 100 - usedPercent) where
|
|
126
|
+
* usedPercent is the highest-utilized non-session window (week / sonnet_week
|
|
127
|
+
* for Claude). An account at 10% used gets weight 90; one at 90% used gets
|
|
128
|
+
* weight 10 — so the fresher account is 9× more likely to be picked. Over N
|
|
129
|
+
* calls, traffic distributes across healthy accounts proportional to their
|
|
130
|
+
* headroom, with no stampede on the lowest-usage one. Stateless — parallel
|
|
131
|
+
* callers naturally fan out via the random roll.
|
|
132
|
+
*
|
|
133
|
+
* Eligibility: signed in (email present), auth valid, and usage available
|
|
134
|
+
* (any non-session window strictly under 100%, or local flag not exhausted
|
|
135
|
+
* when no live snapshot exists).
|
|
136
|
+
*
|
|
137
|
+
* Dedupe: when multiple versions share an email, collapse to one candidate
|
|
138
|
+
* per email (the least-recently-active version). Prevents two parallel pods
|
|
139
|
+
* from "balancing" to different versions but hitting the same Anthropic
|
|
140
|
+
* account and both 429ing.
|
|
141
|
+
*
|
|
142
|
+
* Returns null if no candidate is eligible — callers fall back to the pinned
|
|
143
|
+
* version so behavior stays predictable.
|
|
144
|
+
*/
|
|
145
|
+
export function pickBalancedCandidate(candidates) {
|
|
146
|
+
const healthy = [];
|
|
147
|
+
const excluded = [];
|
|
148
|
+
for (const c of candidates) {
|
|
149
|
+
if (!isRotationEligible(c)) {
|
|
150
|
+
excluded.push(c);
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
healthy.push(c);
|
|
154
|
+
}
|
|
155
|
+
if (healthy.length === 0)
|
|
156
|
+
return null;
|
|
157
|
+
const sorted = dedupeAndSortCandidates(healthy);
|
|
158
|
+
const deduped = new Set(sorted);
|
|
159
|
+
for (const c of healthy) {
|
|
160
|
+
if (!deduped.has(c))
|
|
161
|
+
excluded.push(c);
|
|
162
|
+
}
|
|
163
|
+
const picked = weightedRandomByCapacity(sorted);
|
|
164
|
+
return { picked, healthy: sorted, excluded };
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Pick one candidate from `sorted` using weights proportional to remaining
|
|
168
|
+
* routing capacity. Floor each weight at 1 so a near-exhausted-but-still-
|
|
169
|
+
* eligible candidate can still be picked occasionally. When usage is unknown
|
|
170
|
+
* (no live snapshot), treat the candidate as full-capacity (weight 100) — we
|
|
171
|
+
* have no signal to deprioritize it.
|
|
172
|
+
*/
|
|
173
|
+
function weightedRandomByCapacity(sorted) {
|
|
174
|
+
const weights = sorted.map((c) => {
|
|
175
|
+
const used = getRoutingUsedPercent(c.usageSnapshot);
|
|
176
|
+
if (used === null)
|
|
177
|
+
return 100;
|
|
178
|
+
return Math.max(1, 100 - used);
|
|
179
|
+
});
|
|
180
|
+
const total = weights.reduce((sum, w) => sum + w, 0);
|
|
181
|
+
if (total <= 0)
|
|
182
|
+
return sorted[0];
|
|
183
|
+
let roll = Math.random() * total;
|
|
184
|
+
for (let i = 0; i < sorted.length; i++) {
|
|
185
|
+
roll -= weights[i];
|
|
186
|
+
if (roll <= 0)
|
|
187
|
+
return sorted[i];
|
|
188
|
+
}
|
|
189
|
+
return sorted[sorted.length - 1];
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Pick an available candidate. Prefers the configured pinned version when that
|
|
193
|
+
* version has usage available; otherwise routes to the candidate with the most
|
|
194
|
+
* usage headroom.
|
|
195
|
+
*/
|
|
196
|
+
export function pickAvailableCandidate(candidates, preferredVersion) {
|
|
197
|
+
const healthy = [];
|
|
198
|
+
const excluded = [];
|
|
199
|
+
for (const c of candidates) {
|
|
200
|
+
if (!isAvailableEligible(c)) {
|
|
201
|
+
excluded.push(c);
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
healthy.push(c);
|
|
205
|
+
}
|
|
206
|
+
if (healthy.length === 0)
|
|
207
|
+
return null;
|
|
208
|
+
const sorted = dedupeAndSortCandidates(healthy);
|
|
209
|
+
const deduped = new Set(sorted);
|
|
210
|
+
for (const c of healthy) {
|
|
211
|
+
if (!deduped.has(c))
|
|
212
|
+
excluded.push(c);
|
|
213
|
+
}
|
|
214
|
+
const preferred = preferredVersion
|
|
215
|
+
? sorted.find((candidate) => candidate.version === preferredVersion)
|
|
216
|
+
: undefined;
|
|
217
|
+
return { picked: preferred ?? sorted[0], healthy: sorted, excluded };
|
|
218
|
+
}
|
|
219
|
+
async function collectRunCandidates(agent) {
|
|
220
|
+
const versions = listInstalledVersions(agent);
|
|
221
|
+
const rows = await Promise.all(versions.map(async (version) => {
|
|
222
|
+
const home = getVersionHomePath(agent, version);
|
|
223
|
+
const info = await getAccountInfo(agent, home);
|
|
224
|
+
const authValid = info.email
|
|
225
|
+
? agent === 'claude' ? await isClaudeAuthValid(home) : true
|
|
226
|
+
: false;
|
|
227
|
+
return {
|
|
228
|
+
agent,
|
|
229
|
+
version,
|
|
230
|
+
home,
|
|
231
|
+
info,
|
|
232
|
+
email: info.email,
|
|
233
|
+
usageStatus: info.usageStatus,
|
|
234
|
+
authValid,
|
|
235
|
+
lastActive: info.lastActive,
|
|
236
|
+
};
|
|
237
|
+
}));
|
|
238
|
+
const { usageByKey } = await getUsageInfoByIdentity(rows.map(({ home, info, version }) => ({
|
|
239
|
+
agentId: agent,
|
|
240
|
+
home,
|
|
241
|
+
cliVersion: version,
|
|
242
|
+
info,
|
|
243
|
+
})));
|
|
244
|
+
return rows.map(({ home: _home, info, ...candidate }) => {
|
|
245
|
+
const usageKey = getUsageLookupKey(info);
|
|
246
|
+
const usageSnapshot = usageKey
|
|
247
|
+
? usageByKey.get(usageKey)?.snapshot ?? null
|
|
248
|
+
: null;
|
|
249
|
+
return { ...candidate, usageSnapshot };
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Pick a healthy version for `agent` using weighted random by remaining
|
|
254
|
+
* capacity. See `pickBalancedCandidate` for algorithm details.
|
|
255
|
+
*
|
|
256
|
+
* No external state — health and capacity are both read off per-version
|
|
257
|
+
* AccountInfo (same data `agents view` surfaces). The weighted random roll
|
|
258
|
+
* keeps parallel callers fanned out without rotation files or locks.
|
|
259
|
+
*
|
|
260
|
+
* Returns null if no installed version is eligible. Callers fall back to the
|
|
261
|
+
* global default so behavior stays predictable — we never refuse to run.
|
|
262
|
+
*/
|
|
263
|
+
export async function selectBalancedVersion(agent) {
|
|
264
|
+
return pickBalancedCandidate(await collectRunCandidates(agent));
|
|
265
|
+
}
|
|
266
|
+
/** Select the configured version if available, otherwise another available version. */
|
|
267
|
+
export async function selectAvailableVersion(agent, preferredVersion) {
|
|
268
|
+
return pickAvailableCandidate(await collectRunCandidates(agent), preferredVersion);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Resolve the version `agents run` should use when the caller did not pin
|
|
272
|
+
* one with `@version`. The caller supplies the effective strategy; if that
|
|
273
|
+
* strategy cannot find a usable candidate, fall back to the pinned
|
|
274
|
+
* workspace/global version.
|
|
275
|
+
*/
|
|
276
|
+
/**
|
|
277
|
+
* Record a rotation pick so parallel callers see it as recently-used.
|
|
278
|
+
* Writes a stamp file per agent — lightweight, no locking needed since
|
|
279
|
+
* a torn write just means the next reader sees a stale timestamp (harmless).
|
|
280
|
+
*/
|
|
281
|
+
function recordRotationPick(agent, version) {
|
|
282
|
+
const stampPath = path.join(getAgentsDir(), `rotate-stamp-${agent}.json`);
|
|
283
|
+
try {
|
|
284
|
+
fs.writeFileSync(stampPath, JSON.stringify({ version, ts: Date.now() }), 'utf-8');
|
|
285
|
+
}
|
|
286
|
+
catch { /* best effort — doesn't block the run */ }
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Read the most recent rotation pick for an agent. Returns null if no stamp
|
|
290
|
+
* or stamp is older than 60 seconds (stale).
|
|
291
|
+
*/
|
|
292
|
+
function readRotationStamp(agent) {
|
|
293
|
+
const stampPath = path.join(getAgentsDir(), `rotate-stamp-${agent}.json`);
|
|
294
|
+
try {
|
|
295
|
+
const raw = JSON.parse(fs.readFileSync(stampPath, 'utf-8'));
|
|
296
|
+
if (Date.now() - raw.ts < 60_000)
|
|
297
|
+
return raw.version;
|
|
298
|
+
}
|
|
299
|
+
catch { /* missing or corrupt — treat as no stamp */ }
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
export async function resolveRunVersion(agent, strategy, cwd = process.cwd()) {
|
|
303
|
+
const fallback = resolveVersion(agent, cwd);
|
|
304
|
+
if (strategy === 'pinned') {
|
|
305
|
+
return { version: fallback, rotation: null };
|
|
306
|
+
}
|
|
307
|
+
const rotation = strategy === 'available'
|
|
308
|
+
? await selectAvailableVersion(agent, fallback)
|
|
309
|
+
: await selectBalancedVersion(agent);
|
|
310
|
+
if (rotation) {
|
|
311
|
+
// `available` is sticky to the pinned default when healthy. Use the 60s
|
|
312
|
+
// anti-collision stamp to nudge parallel callers off the same version.
|
|
313
|
+
// `balanced` doesn't need this — its weighted random roll already
|
|
314
|
+
// distributes naturally across healthy accounts.
|
|
315
|
+
if (strategy === 'available') {
|
|
316
|
+
const recentPick = readRotationStamp(agent);
|
|
317
|
+
if (recentPick === rotation.picked.version && rotation.healthy.length > 1) {
|
|
318
|
+
const alt = rotation.healthy.find(c => c.version !== recentPick);
|
|
319
|
+
if (alt)
|
|
320
|
+
rotation.picked = alt;
|
|
321
|
+
}
|
|
322
|
+
recordRotationPick(agent, rotation.picked.version);
|
|
323
|
+
}
|
|
324
|
+
return { version: rotation.picked.version, rotation };
|
|
325
|
+
}
|
|
326
|
+
return { version: fallback, rotation: null };
|
|
327
|
+
}
|
package/dist/lib/routines.d.ts
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scheduled job (routine) configuration and run history management.
|
|
3
|
+
*
|
|
4
|
+
* Routines are YAML files in ~/.agents/routines/ that define recurring or
|
|
5
|
+
* one-shot agent tasks. This module handles CRUD operations on job configs,
|
|
6
|
+
* run metadata persistence, prompt variable expansion, and one-shot "at" time
|
|
7
|
+
* scheduling.
|
|
8
|
+
*/
|
|
1
9
|
import type { AgentId } from './types.js';
|
|
10
|
+
/** Tool/site/directory allow-list for sandboxed job execution. */
|
|
2
11
|
export interface JobAllowConfig {
|
|
3
12
|
tools?: string[];
|
|
4
13
|
sites?: string[];
|
|
5
14
|
dirs?: string[];
|
|
6
15
|
}
|
|
16
|
+
/** Full configuration for a scheduled routine (persisted as YAML). */
|
|
7
17
|
export interface JobConfig {
|
|
8
18
|
name: string;
|
|
9
19
|
schedule: string;
|
|
@@ -21,6 +31,7 @@ export interface JobConfig {
|
|
|
21
31
|
version?: string;
|
|
22
32
|
runOnce?: boolean;
|
|
23
33
|
}
|
|
34
|
+
/** Metadata for a single job execution, persisted as JSON in the run directory. */
|
|
24
35
|
export interface RunMeta {
|
|
25
36
|
jobName: string;
|
|
26
37
|
runId: string;
|
|
@@ -31,24 +42,40 @@ export interface RunMeta {
|
|
|
31
42
|
completedAt: string | null;
|
|
32
43
|
exitCode: number | null;
|
|
33
44
|
}
|
|
45
|
+
/** List all job configs from ~/.agents/routines/. */
|
|
34
46
|
export declare function listJobs(): JobConfig[];
|
|
47
|
+
/** Read a single job config by name. Returns null if not found. */
|
|
35
48
|
export declare function readJob(name: string): JobConfig | null;
|
|
49
|
+
/** Write a job config to disk, omitting fields that match defaults. */
|
|
36
50
|
export declare function writeJob(config: JobConfig): void;
|
|
51
|
+
/** Delete a job config file by name. Returns true if the file existed. */
|
|
37
52
|
export declare function deleteJob(name: string): boolean;
|
|
53
|
+
/** Enable or disable a job by name. */
|
|
38
54
|
export declare function setJobEnabled(name: string, enabled: boolean): void;
|
|
55
|
+
/** Validate a partial job config, returning a list of human-readable errors. */
|
|
39
56
|
export declare function validateJob(config: Partial<JobConfig>): string[];
|
|
57
|
+
/** Expand built-in and user-defined template variables in a job's prompt string. */
|
|
40
58
|
export declare function resolveJobPrompt(config: JobConfig): string;
|
|
59
|
+
/** Parse a human-readable timeout string (e.g. "30m", "2h", "1h30m") into milliseconds. */
|
|
41
60
|
export declare function parseTimeout(timeout: string): number | null;
|
|
61
|
+
/** List all run metadata entries for a job, sorted chronologically. */
|
|
42
62
|
export declare function listRuns(jobName: string): RunMeta[];
|
|
63
|
+
/** Get the most recent run for a job, or null if never run. */
|
|
43
64
|
export declare function getLatestRun(jobName: string): RunMeta | null;
|
|
65
|
+
/** Persist run metadata to its run directory as meta.json. */
|
|
44
66
|
export declare function writeRunMeta(meta: RunMeta): void;
|
|
67
|
+
/** Read run metadata from disk. Returns null if missing or corrupt. */
|
|
45
68
|
export declare function readRunMeta(jobName: string, runId: string): RunMeta | null;
|
|
69
|
+
/** Get the filesystem path for a specific run's directory. */
|
|
46
70
|
export declare function getRunDir(jobName: string, runId: string): string;
|
|
71
|
+
/** Discover routine YAML files in a repository's routines/ directory. */
|
|
47
72
|
export declare function discoverJobsFromRepo(repoPath: string): Array<{
|
|
48
73
|
name: string;
|
|
49
74
|
path: string;
|
|
50
75
|
}>;
|
|
76
|
+
/** Check whether a job with the given name exists on disk. */
|
|
51
77
|
export declare function jobExists(name: string): boolean;
|
|
78
|
+
/** Get the filesystem path of a job's YAML config file, or null if not found. */
|
|
52
79
|
export declare function getJobPath(name: string): string | null;
|
|
53
80
|
/**
|
|
54
81
|
* Parse an "at" time string into a one-shot cron expression.
|
|
@@ -62,9 +89,10 @@ export declare function parseAtTime(atTime: string): {
|
|
|
62
89
|
schedule: string;
|
|
63
90
|
runOnce: boolean;
|
|
64
91
|
} | null;
|
|
92
|
+
/** Check if an installed job's normalized YAML matches the source file. */
|
|
65
93
|
export declare function jobContentMatches(name: string, sourcePath: string): boolean;
|
|
94
|
+
/** Install a job by reading and validating a YAML source file. */
|
|
66
95
|
export declare function installJobFromSource(sourcePath: string, name: string): {
|
|
67
96
|
success: boolean;
|
|
68
97
|
error?: string;
|
|
69
98
|
};
|
|
70
|
-
//# sourceMappingURL=routines.d.ts.map
|
package/dist/lib/routines.js
CHANGED
|
@@ -1,15 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scheduled job (routine) configuration and run history management.
|
|
3
|
+
*
|
|
4
|
+
* Routines are YAML files in ~/.agents/routines/ that define recurring or
|
|
5
|
+
* one-shot agent tasks. This module handles CRUD operations on job configs,
|
|
6
|
+
* run metadata persistence, prompt variable expansion, and one-shot "at" time
|
|
7
|
+
* scheduling.
|
|
8
|
+
*/
|
|
1
9
|
import * as fs from 'fs';
|
|
2
10
|
import * as path from 'path';
|
|
3
11
|
import * as yaml from 'yaml';
|
|
4
12
|
import { Cron } from 'croner';
|
|
5
13
|
import { getRoutinesDir, getRunsDir, ensureAgentsDir } from './state.js';
|
|
14
|
+
import { safeJoin } from './paths.js';
|
|
6
15
|
import { ALL_AGENT_IDS } from './agents.js';
|
|
16
|
+
/** Default values applied to every job config when fields are omitted. */
|
|
7
17
|
const JOB_DEFAULTS = {
|
|
8
18
|
mode: 'plan',
|
|
9
19
|
effort: 'auto',
|
|
10
20
|
timeout: '30m',
|
|
11
21
|
enabled: true,
|
|
12
22
|
};
|
|
23
|
+
/** List all job configs from ~/.agents/routines/. */
|
|
13
24
|
export function listJobs() {
|
|
14
25
|
ensureAgentsDir();
|
|
15
26
|
const jobsDir = getRoutinesDir();
|
|
@@ -24,11 +35,12 @@ export function listJobs() {
|
|
|
24
35
|
}
|
|
25
36
|
return jobs;
|
|
26
37
|
}
|
|
38
|
+
/** Read a single job config by name. Returns null if not found. */
|
|
27
39
|
export function readJob(name) {
|
|
28
40
|
ensureAgentsDir();
|
|
29
41
|
const jobsDir = getRoutinesDir();
|
|
30
42
|
for (const ext of ['.yml', '.yaml']) {
|
|
31
|
-
const filePath =
|
|
43
|
+
const filePath = safeJoin(jobsDir, name + ext);
|
|
32
44
|
if (fs.existsSync(filePath)) {
|
|
33
45
|
return readJobFile(filePath);
|
|
34
46
|
}
|
|
@@ -51,10 +63,11 @@ function readJobFile(filePath) {
|
|
|
51
63
|
return null;
|
|
52
64
|
}
|
|
53
65
|
}
|
|
66
|
+
/** Write a job config to disk, omitting fields that match defaults. */
|
|
54
67
|
export function writeJob(config) {
|
|
55
68
|
ensureAgentsDir();
|
|
56
69
|
const jobsDir = getRoutinesDir();
|
|
57
|
-
const filePath =
|
|
70
|
+
const filePath = safeJoin(jobsDir, config.name + '.yml');
|
|
58
71
|
const output = { ...config };
|
|
59
72
|
if (output.mode === 'plan')
|
|
60
73
|
delete output.mode;
|
|
@@ -68,10 +81,11 @@ export function writeJob(config) {
|
|
|
68
81
|
delete output.runOnce;
|
|
69
82
|
fs.writeFileSync(filePath, yaml.stringify(output), 'utf-8');
|
|
70
83
|
}
|
|
84
|
+
/** Delete a job config file by name. Returns true if the file existed. */
|
|
71
85
|
export function deleteJob(name) {
|
|
72
86
|
const jobsDir = getRoutinesDir();
|
|
73
87
|
for (const ext of ['.yml', '.yaml']) {
|
|
74
|
-
const filePath =
|
|
88
|
+
const filePath = safeJoin(jobsDir, name + ext);
|
|
75
89
|
if (fs.existsSync(filePath)) {
|
|
76
90
|
fs.unlinkSync(filePath);
|
|
77
91
|
return true;
|
|
@@ -79,6 +93,7 @@ export function deleteJob(name) {
|
|
|
79
93
|
}
|
|
80
94
|
return false;
|
|
81
95
|
}
|
|
96
|
+
/** Enable or disable a job by name. */
|
|
82
97
|
export function setJobEnabled(name, enabled) {
|
|
83
98
|
const job = readJob(name);
|
|
84
99
|
if (!job)
|
|
@@ -86,6 +101,7 @@ export function setJobEnabled(name, enabled) {
|
|
|
86
101
|
job.enabled = enabled;
|
|
87
102
|
writeJob(job);
|
|
88
103
|
}
|
|
104
|
+
/** Validate a partial job config, returning a list of human-readable errors. */
|
|
89
105
|
export function validateJob(config) {
|
|
90
106
|
const errors = [];
|
|
91
107
|
if (!config.name || typeof config.name !== 'string') {
|
|
@@ -123,6 +139,7 @@ export function validateJob(config) {
|
|
|
123
139
|
}
|
|
124
140
|
return errors;
|
|
125
141
|
}
|
|
142
|
+
/** Expand built-in and user-defined template variables in a job's prompt string. */
|
|
126
143
|
export function resolveJobPrompt(config) {
|
|
127
144
|
const now = new Date();
|
|
128
145
|
const tz = config.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
@@ -162,6 +179,7 @@ export function resolveJobPrompt(config) {
|
|
|
162
179
|
}
|
|
163
180
|
return prompt;
|
|
164
181
|
}
|
|
182
|
+
/** Parse a human-readable timeout string (e.g. "30m", "2h", "1h30m") into milliseconds. */
|
|
165
183
|
export function parseTimeout(timeout) {
|
|
166
184
|
const match = timeout.match(/^(?:(\d+)h)?(?:(\d+)m)?$/);
|
|
167
185
|
if (!match)
|
|
@@ -171,6 +189,7 @@ export function parseTimeout(timeout) {
|
|
|
171
189
|
const ms = (hours * 60 + minutes) * 60 * 1000;
|
|
172
190
|
return ms > 0 ? ms : null;
|
|
173
191
|
}
|
|
192
|
+
/** List all run metadata entries for a job, sorted chronologically. */
|
|
174
193
|
export function listRuns(jobName) {
|
|
175
194
|
const runsDir = getRunsDir();
|
|
176
195
|
const jobRunsDir = path.join(runsDir, jobName);
|
|
@@ -188,16 +207,19 @@ export function listRuns(jobName) {
|
|
|
188
207
|
}
|
|
189
208
|
return runs;
|
|
190
209
|
}
|
|
210
|
+
/** Get the most recent run for a job, or null if never run. */
|
|
191
211
|
export function getLatestRun(jobName) {
|
|
192
212
|
const runs = listRuns(jobName);
|
|
193
213
|
return runs.length > 0 ? runs[runs.length - 1] : null;
|
|
194
214
|
}
|
|
215
|
+
/** Persist run metadata to its run directory as meta.json. */
|
|
195
216
|
export function writeRunMeta(meta) {
|
|
196
217
|
ensureAgentsDir();
|
|
197
218
|
const runDir = path.join(getRunsDir(), meta.jobName, meta.runId);
|
|
198
219
|
fs.mkdirSync(runDir, { recursive: true });
|
|
199
220
|
fs.writeFileSync(path.join(runDir, 'meta.json'), JSON.stringify(meta, null, 2), 'utf-8');
|
|
200
221
|
}
|
|
222
|
+
/** Read run metadata from disk. Returns null if missing or corrupt. */
|
|
201
223
|
export function readRunMeta(jobName, runId) {
|
|
202
224
|
const metaPath = path.join(getRunsDir(), jobName, runId, 'meta.json');
|
|
203
225
|
if (!fs.existsSync(metaPath))
|
|
@@ -209,9 +231,11 @@ export function readRunMeta(jobName, runId) {
|
|
|
209
231
|
return null;
|
|
210
232
|
}
|
|
211
233
|
}
|
|
234
|
+
/** Get the filesystem path for a specific run's directory. */
|
|
212
235
|
export function getRunDir(jobName, runId) {
|
|
213
236
|
return path.join(getRunsDir(), jobName, runId);
|
|
214
237
|
}
|
|
238
|
+
/** Discover routine YAML files in a repository's routines/ directory. */
|
|
215
239
|
export function discoverJobsFromRepo(repoPath) {
|
|
216
240
|
const jobsPath = path.join(repoPath, 'routines');
|
|
217
241
|
if (!fs.existsSync(jobsPath))
|
|
@@ -223,13 +247,15 @@ export function discoverJobsFromRepo(repoPath) {
|
|
|
223
247
|
path: path.join(jobsPath, f),
|
|
224
248
|
}));
|
|
225
249
|
}
|
|
250
|
+
/** Check whether a job with the given name exists on disk. */
|
|
226
251
|
export function jobExists(name) {
|
|
227
252
|
return readJob(name) !== null;
|
|
228
253
|
}
|
|
254
|
+
/** Get the filesystem path of a job's YAML config file, or null if not found. */
|
|
229
255
|
export function getJobPath(name) {
|
|
230
256
|
const jobsDir = getRoutinesDir();
|
|
231
257
|
for (const ext of ['.yml', '.yaml']) {
|
|
232
|
-
const filePath =
|
|
258
|
+
const filePath = safeJoin(jobsDir, name + ext);
|
|
233
259
|
if (fs.existsSync(filePath)) {
|
|
234
260
|
return filePath;
|
|
235
261
|
}
|
|
@@ -282,6 +308,7 @@ export function parseAtTime(atTime) {
|
|
|
282
308
|
}
|
|
283
309
|
return null;
|
|
284
310
|
}
|
|
311
|
+
/** Check if an installed job's normalized YAML matches the source file. */
|
|
285
312
|
export function jobContentMatches(name, sourcePath) {
|
|
286
313
|
const existing = readJob(name);
|
|
287
314
|
if (!existing)
|
|
@@ -300,6 +327,7 @@ export function jobContentMatches(name, sourcePath) {
|
|
|
300
327
|
return false;
|
|
301
328
|
}
|
|
302
329
|
}
|
|
330
|
+
/** Install a job by reading and validating a YAML source file. */
|
|
303
331
|
export function installJobFromSource(sourcePath, name) {
|
|
304
332
|
try {
|
|
305
333
|
const content = fs.readFileSync(sourcePath, 'utf-8');
|
|
@@ -322,4 +350,3 @@ export function installJobFromSource(sourcePath, name) {
|
|
|
322
350
|
return { success: false, error: err.message };
|
|
323
351
|
}
|
|
324
352
|
}
|
|
325
|
-
//# sourceMappingURL=routines.js.map
|
package/dist/lib/runner.d.ts
CHANGED
|
@@ -1,12 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Job execution engine for routines.
|
|
3
|
+
*
|
|
4
|
+
* Builds agent-specific CLI commands from job configs, spawns them with
|
|
5
|
+
* sandboxed or unsandboxed environments, captures stdout to log files,
|
|
6
|
+
* enforces timeouts, and extracts the final assistant report from the
|
|
7
|
+
* agent's stream-JSON output.
|
|
8
|
+
*/
|
|
1
9
|
import type { JobConfig, RunMeta } from './routines.js';
|
|
2
10
|
import type { AgentId } from './types.js';
|
|
11
|
+
/** Result of a completed job execution, including metadata and optional report. */
|
|
3
12
|
export interface RunResult {
|
|
4
13
|
meta: RunMeta;
|
|
5
14
|
reportPath: string | null;
|
|
6
15
|
}
|
|
16
|
+
/** Build the full CLI argv for executing a job, applying mode, model, and permission flags. */
|
|
7
17
|
export declare function buildJobCommand(config: JobConfig, resolvedPrompt: string): string[];
|
|
18
|
+
/** Execute a job synchronously (waits for completion or timeout before resolving). */
|
|
8
19
|
export declare function executeJob(config: JobConfig): Promise<RunResult>;
|
|
20
|
+
/** Spawn a job as a detached process and return immediately with run metadata. */
|
|
9
21
|
export declare function executeJobDetached(config: JobConfig): Promise<RunMeta>;
|
|
22
|
+
/** Extract the final assistant message from a stream-JSON log file as a markdown report. */
|
|
10
23
|
export declare function extractReport(stdoutPath: string, agentType: AgentId): string | null;
|
|
24
|
+
/** Scan all runs marked "running" and finalize any whose process has exited. */
|
|
11
25
|
export declare function monitorRunningJobs(): void;
|
|
12
|
-
//# sourceMappingURL=runner.d.ts.map
|