@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
package/dist/lib/usage.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Usage and rate-limit tracking for Claude and Codex agents.
|
|
3
|
+
*
|
|
4
|
+
* Fetches live usage data from the Anthropic OAuth API (Claude) or parses
|
|
5
|
+
* rate-limit events from Codex session logs. Results are normalized into a
|
|
6
|
+
* common UsageSnapshot shape, cached to disk, and rendered as terminal
|
|
7
|
+
* progress bars for the `agents view` and `agents status` commands.
|
|
8
|
+
*/
|
|
1
9
|
import { execFile } from 'child_process';
|
|
2
10
|
import { createHash } from 'crypto';
|
|
3
11
|
import * as fs from 'fs';
|
|
@@ -6,8 +14,8 @@ import * as path from 'path';
|
|
|
6
14
|
import * as readline from 'readline';
|
|
7
15
|
import { promisify } from 'util';
|
|
8
16
|
import chalk from 'chalk';
|
|
17
|
+
import { walkForFiles } from './fs-walk.js';
|
|
9
18
|
import { getAgentsDir } from './state.js';
|
|
10
|
-
import { walkForFiles } from './session/discover.js';
|
|
11
19
|
const execFileAsync = promisify(execFile);
|
|
12
20
|
const CLAUDE_USAGE_URL = 'https://api.anthropic.com/api/oauth/usage';
|
|
13
21
|
const CLAUDE_TOKEN_URL = 'https://platform.claude.com/v1/oauth/token';
|
|
@@ -22,12 +30,13 @@ const CLAUDE_SCOPES = [
|
|
|
22
30
|
'user:file_upload',
|
|
23
31
|
];
|
|
24
32
|
const CLAUDE_KEYCHAIN_SERVICE = 'Claude Code-credentials';
|
|
25
|
-
const
|
|
33
|
+
const getClaudeUsageCachePath = () => path.join(getAgentsDir(), 'cache', 'claude-usage.json');
|
|
26
34
|
const CACHED_CLAUDE_USAGE_SOURCE_LABEL = 'last seen live account data';
|
|
27
35
|
const COMPACT_BAR_LEN = 5;
|
|
28
36
|
const USAGE_BAR_LEN = 10;
|
|
29
37
|
const FULL = '\u2588';
|
|
30
38
|
const EMPTY = '\u2591';
|
|
39
|
+
/** Fetch usage info for a given agent, dispatching to the agent-specific implementation. */
|
|
31
40
|
export async function getUsageInfo(agentId, options) {
|
|
32
41
|
switch (agentId) {
|
|
33
42
|
case 'claude':
|
|
@@ -38,9 +47,14 @@ export async function getUsageInfo(agentId, options) {
|
|
|
38
47
|
return { snapshot: null, error: null };
|
|
39
48
|
}
|
|
40
49
|
}
|
|
50
|
+
/** Derive a stable lookup key from account info for usage deduplication. */
|
|
41
51
|
export function getUsageLookupKey(info) {
|
|
42
52
|
return info?.usageKey || info?.accountKey || null;
|
|
43
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Deduplicate identity inputs into canonical (most-recently-active) accounts
|
|
56
|
+
* and build the corresponding fetch inputs for each unique usage key.
|
|
57
|
+
*/
|
|
44
58
|
export function buildCanonicalUsageContext(inputs) {
|
|
45
59
|
const canonicalByUsageKey = new Map();
|
|
46
60
|
const usageFetchInputs = new Map();
|
|
@@ -64,6 +78,7 @@ export function buildCanonicalUsageContext(inputs) {
|
|
|
64
78
|
}
|
|
65
79
|
return { canonicalByUsageKey, usageFetchInputs };
|
|
66
80
|
}
|
|
81
|
+
/** Fetch usage info for all unique accounts in parallel, keyed by usage key. */
|
|
67
82
|
export async function getUsageInfoByIdentity(inputs) {
|
|
68
83
|
const { canonicalByUsageKey, usageFetchInputs } = buildCanonicalUsageContext(inputs);
|
|
69
84
|
const usageResults = await Promise.all([...usageFetchInputs.entries()].map(async ([key, input]) => ({
|
|
@@ -81,6 +96,10 @@ export async function getUsageInfoByIdentity(inputs) {
|
|
|
81
96
|
};
|
|
82
97
|
}
|
|
83
98
|
const USAGE_CACHE_FRESH_MS = 2 * 60 * 1000; // 2 minutes
|
|
99
|
+
/**
|
|
100
|
+
* Fetch usage for a single identity, with a 2-minute cache fast path.
|
|
101
|
+
* Falls back to cached data when the live fetch fails.
|
|
102
|
+
*/
|
|
84
103
|
export async function getUsageInfoForIdentity(input) {
|
|
85
104
|
const usageKey = getUsageLookupKey(input.info);
|
|
86
105
|
// Fast path: serve from cache if fresh. Skips the network call entirely.
|
|
@@ -93,7 +112,7 @@ export async function getUsageInfoForIdentity(input) {
|
|
|
93
112
|
}
|
|
94
113
|
}
|
|
95
114
|
}
|
|
96
|
-
// Cache miss or stale
|
|
115
|
+
// Cache miss or stale -- make the network call.
|
|
97
116
|
const usage = await getUsageInfo(input.agentId, {
|
|
98
117
|
home: input.home,
|
|
99
118
|
cliVersion: input.cliVersion,
|
|
@@ -112,6 +131,7 @@ export async function getUsageInfoForIdentity(input) {
|
|
|
112
131
|
}
|
|
113
132
|
return usage;
|
|
114
133
|
}
|
|
134
|
+
/** Format a one-line usage summary with compact bars for inline display. */
|
|
115
135
|
export function formatUsageSummary(plan, snapshot, planWidth = 3) {
|
|
116
136
|
const parts = [];
|
|
117
137
|
if (plan) {
|
|
@@ -127,6 +147,7 @@ export function formatUsageSummary(plan, snapshot, planWidth = 3) {
|
|
|
127
147
|
}
|
|
128
148
|
return parts.join(' ');
|
|
129
149
|
}
|
|
150
|
+
/** Format a multi-line usage section for detailed agent views. */
|
|
130
151
|
export function formatUsageSection(usage) {
|
|
131
152
|
if (!usage.snapshot && !usage.error) {
|
|
132
153
|
return [];
|
|
@@ -151,6 +172,7 @@ export function formatUsageSection(usage) {
|
|
|
151
172
|
lines.push(` ${chalk.dim(`Source: ${usage.snapshot.sourceLabel}`)}`);
|
|
152
173
|
return lines;
|
|
153
174
|
}
|
|
175
|
+
/** Fetch Codex usage by scanning the most recent session files for rate-limit events. */
|
|
154
176
|
async function getCodexUsageInfo(options) {
|
|
155
177
|
try {
|
|
156
178
|
const files = collectCodexSessionFiles(options?.home);
|
|
@@ -177,6 +199,7 @@ async function getCodexUsageInfo(options) {
|
|
|
177
199
|
return { snapshot: null, error: null };
|
|
178
200
|
}
|
|
179
201
|
}
|
|
202
|
+
/** Fetch Claude usage via the Anthropic OAuth usage API. */
|
|
180
203
|
async function getClaudeUsageInfo(options) {
|
|
181
204
|
try {
|
|
182
205
|
const oauth = await loadClaudeOauth(options?.home);
|
|
@@ -224,6 +247,7 @@ async function getClaudeUsageInfo(options) {
|
|
|
224
247
|
return { snapshot: null, error: 'Usage data unavailable right now.' };
|
|
225
248
|
}
|
|
226
249
|
}
|
|
250
|
+
/** Collect Codex JSONL session files sorted newest-first. */
|
|
227
251
|
function collectCodexSessionFiles(home) {
|
|
228
252
|
const base = home || os.homedir();
|
|
229
253
|
const dir = path.join(base, '.codex', 'sessions');
|
|
@@ -244,6 +268,7 @@ function collectCodexSessionFiles(home) {
|
|
|
244
268
|
files.sort((a, b) => b.mtime - a.mtime);
|
|
245
269
|
return files.map((file) => file.path);
|
|
246
270
|
}
|
|
271
|
+
/** Stream a Codex JSONL file and return the last rate_limits payload found. */
|
|
247
272
|
async function readLatestCodexRateLimits(filePath) {
|
|
248
273
|
return new Promise((resolve) => {
|
|
249
274
|
let latest = null;
|
|
@@ -270,6 +295,7 @@ async function readLatestCodexRateLimits(filePath) {
|
|
|
270
295
|
rl.on('error', () => resolve(latest));
|
|
271
296
|
});
|
|
272
297
|
}
|
|
298
|
+
/** Normalize Codex rate-limit windows into the common UsageWindow shape. */
|
|
273
299
|
function normalizeCodexWindows(rateLimits) {
|
|
274
300
|
const windows = [];
|
|
275
301
|
const primary = normalizeCodexWindow(rateLimits.primary, 'session', 'Current session', 'S');
|
|
@@ -280,6 +306,7 @@ function normalizeCodexWindows(rateLimits) {
|
|
|
280
306
|
windows.push(secondary);
|
|
281
307
|
return windows;
|
|
282
308
|
}
|
|
309
|
+
/** Normalize a single Codex rate-limit window. */
|
|
283
310
|
function normalizeCodexWindow(window, key, label, shortLabel) {
|
|
284
311
|
const usedPercent = normalizePercent(window?.used_percent);
|
|
285
312
|
if (usedPercent === null)
|
|
@@ -293,6 +320,7 @@ function normalizeCodexWindow(window, key, label, shortLabel) {
|
|
|
293
320
|
windowMinutes: normalizeWindowMinutes(window?.window_minutes),
|
|
294
321
|
};
|
|
295
322
|
}
|
|
323
|
+
/** Normalize Claude API usage windows into the common UsageWindow shape. */
|
|
296
324
|
function normalizeClaudeWindows(data) {
|
|
297
325
|
const windows = [
|
|
298
326
|
normalizeClaudeWindow(data.five_hour, 'session', 'Current session', 'S'),
|
|
@@ -301,6 +329,7 @@ function normalizeClaudeWindows(data) {
|
|
|
301
329
|
];
|
|
302
330
|
return windows.filter((window) => window !== null);
|
|
303
331
|
}
|
|
332
|
+
/** Normalize a single Claude API usage window. */
|
|
304
333
|
function normalizeClaudeWindow(window, key, label, shortLabel) {
|
|
305
334
|
const usedPercent = normalizePercent(window?.utilization);
|
|
306
335
|
if (usedPercent === null)
|
|
@@ -314,7 +343,8 @@ function normalizeClaudeWindow(window, key, label, shortLabel) {
|
|
|
314
343
|
windowMinutes: inferWindowMinutes(key),
|
|
315
344
|
};
|
|
316
345
|
}
|
|
317
|
-
|
|
346
|
+
/** Load Claude OAuth credentials from the macOS Keychain. */
|
|
347
|
+
export async function loadClaudeOauth(home) {
|
|
318
348
|
if (process.platform !== 'darwin') {
|
|
319
349
|
return null;
|
|
320
350
|
}
|
|
@@ -330,6 +360,8 @@ async function loadClaudeOauth(home) {
|
|
|
330
360
|
'-w',
|
|
331
361
|
]);
|
|
332
362
|
const payload = JSON.parse(stdout.trim());
|
|
363
|
+
if (typeof payload?.claudeAiOauth?.accessToken !== 'string')
|
|
364
|
+
return null;
|
|
333
365
|
if (!payload.claudeAiOauth) {
|
|
334
366
|
return null;
|
|
335
367
|
}
|
|
@@ -342,6 +374,10 @@ async function loadClaudeOauth(home) {
|
|
|
342
374
|
return null;
|
|
343
375
|
}
|
|
344
376
|
}
|
|
377
|
+
/**
|
|
378
|
+
* Derive the Keychain service name for a Claude home directory.
|
|
379
|
+
* Managed (non-default) homes get a hash suffix for isolation.
|
|
380
|
+
*/
|
|
345
381
|
export function getClaudeKeychainService(home) {
|
|
346
382
|
if (!home) {
|
|
347
383
|
return CLAUDE_KEYCHAIN_SERVICE;
|
|
@@ -350,12 +386,17 @@ export function getClaudeKeychainService(home) {
|
|
|
350
386
|
const hash = createHash('sha256').update(configDir).digest('hex').slice(0, 8);
|
|
351
387
|
return `${CLAUDE_KEYCHAIN_SERVICE}-${hash}`;
|
|
352
388
|
}
|
|
389
|
+
/**
|
|
390
|
+
* Check whether a requested org ID matches the live OAuth org ID.
|
|
391
|
+
* Returns true when either is absent (no filtering) or when they match.
|
|
392
|
+
*/
|
|
353
393
|
export function isClaudeUsageOrgMatch(requestedOrgId, liveOrgId) {
|
|
354
394
|
const requested = normalizeString(requestedOrgId);
|
|
355
395
|
const live = normalizeString(liveOrgId);
|
|
356
396
|
return !requested || !live || requested === live;
|
|
357
397
|
}
|
|
358
|
-
|
|
398
|
+
/** Read a cached usage snapshot for a given usage key. Returns null if absent or stale. */
|
|
399
|
+
export function readClaudeUsageCache(usageKey, cachePath = getClaudeUsageCachePath(), now = new Date()) {
|
|
359
400
|
const cache = readClaudeUsageCacheFile(cachePath);
|
|
360
401
|
const cached = cache[usageKey];
|
|
361
402
|
if (!cached) {
|
|
@@ -368,11 +409,13 @@ export function readClaudeUsageCache(usageKey, cachePath = CLAUDE_USAGE_CACHE_PA
|
|
|
368
409
|
}
|
|
369
410
|
return snapshot;
|
|
370
411
|
}
|
|
371
|
-
|
|
412
|
+
/** Write a usage snapshot to the on-disk cache. */
|
|
413
|
+
export function writeClaudeUsageCache(usageKey, snapshot, cachePath = getClaudeUsageCachePath()) {
|
|
372
414
|
const cache = readClaudeUsageCacheFile(cachePath);
|
|
373
415
|
cache[usageKey] = serializeClaudeUsageSnapshot(snapshot);
|
|
374
416
|
writeClaudeUsageCacheFile(cache, cachePath);
|
|
375
417
|
}
|
|
418
|
+
/** Read the entire usage cache file from disk. */
|
|
376
419
|
function readClaudeUsageCacheFile(cachePath) {
|
|
377
420
|
if (!fs.existsSync(cachePath)) {
|
|
378
421
|
return {};
|
|
@@ -385,6 +428,7 @@ function readClaudeUsageCacheFile(cachePath) {
|
|
|
385
428
|
return {};
|
|
386
429
|
}
|
|
387
430
|
}
|
|
431
|
+
/** Write the entire usage cache to disk. Best-effort; failures are silent. */
|
|
388
432
|
function writeClaudeUsageCacheFile(cache, cachePath) {
|
|
389
433
|
try {
|
|
390
434
|
fs.mkdirSync(path.dirname(cachePath), { recursive: true });
|
|
@@ -394,6 +438,7 @@ function writeClaudeUsageCacheFile(cache, cachePath) {
|
|
|
394
438
|
/* best-effort cache write */
|
|
395
439
|
}
|
|
396
440
|
}
|
|
441
|
+
/** Convert a live UsageSnapshot to its JSON-serializable cached form. */
|
|
397
442
|
function serializeClaudeUsageSnapshot(snapshot) {
|
|
398
443
|
return {
|
|
399
444
|
capturedAt: snapshot.capturedAt?.toISOString() || null,
|
|
@@ -407,18 +452,24 @@ function serializeClaudeUsageSnapshot(snapshot) {
|
|
|
407
452
|
})),
|
|
408
453
|
};
|
|
409
454
|
}
|
|
455
|
+
/** Deserialize a cached snapshot, zeroing out windows whose reset time has passed. */
|
|
410
456
|
function deserializeClaudeUsageSnapshot(snapshot, now) {
|
|
411
457
|
const capturedAt = parseDateValue(snapshot.capturedAt);
|
|
412
458
|
const windows = snapshot.windows
|
|
413
|
-
.map((window) =>
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
459
|
+
.map((window) => {
|
|
460
|
+
const w = {
|
|
461
|
+
key: window.key,
|
|
462
|
+
label: window.label,
|
|
463
|
+
shortLabel: window.shortLabel,
|
|
464
|
+
usedPercent: window.usedPercent,
|
|
465
|
+
resetsAt: parseDateValue(window.resetsAt),
|
|
466
|
+
windowMinutes: window.windowMinutes,
|
|
467
|
+
};
|
|
468
|
+
if (!isCachedUsageWindowFresh(w, capturedAt, now)) {
|
|
469
|
+
w.usedPercent = 0;
|
|
470
|
+
}
|
|
471
|
+
return w;
|
|
472
|
+
});
|
|
422
473
|
if (windows.length === 0) {
|
|
423
474
|
return null;
|
|
424
475
|
}
|
|
@@ -429,6 +480,7 @@ function deserializeClaudeUsageSnapshot(snapshot, now) {
|
|
|
429
480
|
windows,
|
|
430
481
|
};
|
|
431
482
|
}
|
|
483
|
+
/** Check whether a cached usage window is still relevant (not expired or reset). */
|
|
432
484
|
function isCachedUsageWindowFresh(window, capturedAt, now) {
|
|
433
485
|
if (window.resetsAt && window.resetsAt.getTime() <= now.getTime()) {
|
|
434
486
|
return false;
|
|
@@ -441,6 +493,7 @@ function isCachedUsageWindowFresh(window, capturedAt, now) {
|
|
|
441
493
|
}
|
|
442
494
|
return true;
|
|
443
495
|
}
|
|
496
|
+
/** Obtain a valid access token, refreshing if expired. */
|
|
444
497
|
async function getClaudeAccessToken(oauth) {
|
|
445
498
|
const accessToken = oauth.accessToken?.trim();
|
|
446
499
|
if (!accessToken) {
|
|
@@ -456,6 +509,7 @@ async function getClaudeAccessToken(oauth) {
|
|
|
456
509
|
const refreshed = await refreshClaudeToken(oauth);
|
|
457
510
|
return refreshed?.accessToken?.trim() || null;
|
|
458
511
|
}
|
|
512
|
+
/** Refresh an expired Claude OAuth access token using the refresh token. */
|
|
459
513
|
async function refreshClaudeToken(oauth) {
|
|
460
514
|
const response = await fetch(CLAUDE_TOKEN_URL, {
|
|
461
515
|
method: 'POST',
|
|
@@ -484,27 +538,44 @@ async function refreshClaudeToken(oauth) {
|
|
|
484
538
|
scopes: data.scope ? data.scope.split(/\s+/).filter(Boolean) : (oauth.scopes || CLAUDE_SCOPES),
|
|
485
539
|
};
|
|
486
540
|
}
|
|
541
|
+
/**
|
|
542
|
+
* Check whether the Claude OAuth credentials for a given home are usable.
|
|
543
|
+
* Attempts a token refresh if the access token is expired.
|
|
544
|
+
* Returns true only when a valid access token can be obtained.
|
|
545
|
+
*/
|
|
546
|
+
export async function isClaudeAuthValid(home) {
|
|
547
|
+
const oauth = await loadClaudeOauth(home);
|
|
548
|
+
if (!oauth)
|
|
549
|
+
return false;
|
|
550
|
+
const token = await getClaudeAccessToken(oauth);
|
|
551
|
+
return token !== null;
|
|
552
|
+
}
|
|
553
|
+
/** Build a User-Agent string for Claude API requests. */
|
|
487
554
|
function getClaudeUserAgent(cliVersion) {
|
|
488
555
|
return cliVersion ? `claude-code/${cliVersion}` : 'claude-code';
|
|
489
556
|
}
|
|
557
|
+
/** Map an HTTP status code to a user-facing error message. */
|
|
490
558
|
function formatClaudeUsageError(status) {
|
|
491
559
|
if (status === 429) {
|
|
492
560
|
return 'Usage data unavailable right now.';
|
|
493
561
|
}
|
|
494
562
|
return 'Could not load usage data right now.';
|
|
495
563
|
}
|
|
564
|
+
/** Clamp a numeric value to 0..100, returning null for non-finite values. */
|
|
496
565
|
function normalizePercent(value) {
|
|
497
566
|
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
498
567
|
return null;
|
|
499
568
|
}
|
|
500
569
|
return Math.max(0, Math.min(100, value));
|
|
501
570
|
}
|
|
571
|
+
/** Validate and return a positive window duration, or null. */
|
|
502
572
|
function normalizeWindowMinutes(value) {
|
|
503
573
|
if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) {
|
|
504
574
|
return null;
|
|
505
575
|
}
|
|
506
576
|
return value;
|
|
507
577
|
}
|
|
578
|
+
/** Infer the window duration in minutes from a well-known window key. */
|
|
508
579
|
function inferWindowMinutes(key) {
|
|
509
580
|
switch (key) {
|
|
510
581
|
case 'session':
|
|
@@ -514,6 +585,7 @@ function inferWindowMinutes(key) {
|
|
|
514
585
|
return 10080;
|
|
515
586
|
}
|
|
516
587
|
}
|
|
588
|
+
/** Parse a date value from a number (epoch seconds or ms) or ISO string. */
|
|
517
589
|
function parseDateValue(value) {
|
|
518
590
|
if (value === null || value === undefined || value === '') {
|
|
519
591
|
return null;
|
|
@@ -531,27 +603,33 @@ function parseDateValue(value) {
|
|
|
531
603
|
}
|
|
532
604
|
return null;
|
|
533
605
|
}
|
|
606
|
+
/** Trim and return a string, or null if empty/non-string. */
|
|
534
607
|
function normalizeString(value) {
|
|
535
608
|
if (typeof value !== 'string')
|
|
536
609
|
return null;
|
|
537
610
|
const trimmed = value.trim();
|
|
538
611
|
return trimmed || null;
|
|
539
612
|
}
|
|
613
|
+
/** Render a full-width usage bar for detailed views. */
|
|
540
614
|
function renderUsageBar(usedPercent) {
|
|
541
615
|
return renderBar(usedPercent, USAGE_BAR_LEN);
|
|
542
616
|
}
|
|
617
|
+
/** Render a compact usage bar for inline summaries. */
|
|
543
618
|
function renderCompactUsageBar(usedPercent) {
|
|
544
619
|
return renderBar(usedPercent, COMPACT_BAR_LEN, usedPercent > 0 ? 1 : 0);
|
|
545
620
|
}
|
|
621
|
+
/** Render a colored block-character progress bar. */
|
|
546
622
|
function renderBar(usedPercent, length, minimumVisible = 0) {
|
|
547
623
|
const rounded = Math.round((usedPercent / 100) * length);
|
|
548
624
|
const filled = Math.max(minimumVisible, Math.max(0, Math.min(length, rounded)));
|
|
549
625
|
const color = getUsageColor(usedPercent);
|
|
550
626
|
return color(FULL.repeat(filled)) + chalk.dim(EMPTY.repeat(length - filled));
|
|
551
627
|
}
|
|
628
|
+
/** Apply the appropriate color to a text string based on usage percentage. */
|
|
552
629
|
function colorUsage(text, usedPercent) {
|
|
553
630
|
return getUsageColor(usedPercent)(text);
|
|
554
631
|
}
|
|
632
|
+
/** Return a chalk color function based on the usage percentage threshold. */
|
|
555
633
|
function getUsageColor(usedPercent) {
|
|
556
634
|
if (usedPercent >= 100)
|
|
557
635
|
return chalk.red;
|
|
@@ -559,10 +637,12 @@ function getUsageColor(usedPercent) {
|
|
|
559
637
|
return chalk.yellow;
|
|
560
638
|
return chalk.cyan;
|
|
561
639
|
}
|
|
640
|
+
/** Format a percentage value with at most one decimal place. */
|
|
562
641
|
function formatPercent(value) {
|
|
563
642
|
const rounded = Math.round(value * 10) / 10;
|
|
564
643
|
return Number.isInteger(rounded) ? String(rounded) : rounded.toFixed(1);
|
|
565
644
|
}
|
|
645
|
+
/** Format a reset timestamp as a human-readable relative or absolute time. */
|
|
566
646
|
function formatResetAt(date) {
|
|
567
647
|
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
568
648
|
const now = new Date();
|
|
@@ -587,6 +667,7 @@ function formatResetAt(date) {
|
|
|
587
667
|
}
|
|
588
668
|
return `${date.toLocaleString('en-US', options)} (${timezone})`;
|
|
589
669
|
}
|
|
670
|
+
/** Safe wrapper around fs.realpathSync that returns null on error. */
|
|
590
671
|
function safeRealpathSync(filePath) {
|
|
591
672
|
try {
|
|
592
673
|
return fs.realpathSync(filePath);
|
|
@@ -595,6 +676,7 @@ function safeRealpathSync(filePath) {
|
|
|
595
676
|
return null;
|
|
596
677
|
}
|
|
597
678
|
}
|
|
679
|
+
/** Safe wrapper around fs.statSync that returns null on error. */
|
|
598
680
|
function safeStatSync(filePath) {
|
|
599
681
|
try {
|
|
600
682
|
return fs.statSync(filePath);
|
|
@@ -603,4 +685,3 @@ function safeStatSync(filePath) {
|
|
|
603
685
|
return null;
|
|
604
686
|
}
|
|
605
687
|
}
|
|
606
|
-
//# sourceMappingURL=usage.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type AccountInfo } from './agents.js';
|
|
2
|
+
import type { AgentId } from './types.js';
|
|
3
|
+
export interface VersionAccountEntry {
|
|
4
|
+
version: string;
|
|
5
|
+
info: AccountInfo;
|
|
6
|
+
}
|
|
7
|
+
export interface NewerDuplicateVersion {
|
|
8
|
+
version: string;
|
|
9
|
+
email: string | null;
|
|
10
|
+
plan: string | null;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Return installed versions newer than selectedVersion that share the same
|
|
14
|
+
* account identity. This is intentionally pure so command output can share one
|
|
15
|
+
* duplicate rule with tests.
|
|
16
|
+
*/
|
|
17
|
+
export declare function findNewerDuplicateVersions(entries: VersionAccountEntry[], selectedVersion: string): NewerDuplicateVersion[];
|
|
18
|
+
/** Collect account info for an agent and find newer duplicates of selectedVersion. */
|
|
19
|
+
export declare function getNewerDuplicateVersions(agentId: AgentId, selectedVersion: string): Promise<NewerDuplicateVersion[]>;
|
|
20
|
+
/** Format the non-interactive guidance shown by view/run when duplicates exist. */
|
|
21
|
+
export declare function formatNewerDuplicateNotice(agentId: AgentId, selectedVersion: string, duplicates: NewerDuplicateVersion[], selectedLabel?: string): string;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { getAccountInfo, agentLabel } from './agents.js';
|
|
3
|
+
import { compareVersions, getVersionHomePath, listInstalledVersions, } from './versions.js';
|
|
4
|
+
import { getUsageInfoByIdentity, getUsageLookupKey, } from './usage.js';
|
|
5
|
+
function duplicateIdentity(info) {
|
|
6
|
+
if (!info)
|
|
7
|
+
return null;
|
|
8
|
+
const usageKey = getUsageLookupKey(info);
|
|
9
|
+
if (usageKey)
|
|
10
|
+
return usageKey;
|
|
11
|
+
return info.email ? `email:${info.email.toLowerCase()}` : null;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Return installed versions newer than selectedVersion that share the same
|
|
15
|
+
* account identity. This is intentionally pure so command output can share one
|
|
16
|
+
* duplicate rule with tests.
|
|
17
|
+
*/
|
|
18
|
+
export function findNewerDuplicateVersions(entries, selectedVersion) {
|
|
19
|
+
const selected = entries.find((entry) => entry.version === selectedVersion);
|
|
20
|
+
const selectedIdentity = duplicateIdentity(selected?.info);
|
|
21
|
+
if (!selectedIdentity)
|
|
22
|
+
return [];
|
|
23
|
+
return entries
|
|
24
|
+
.filter((entry) => entry.version !== selectedVersion &&
|
|
25
|
+
compareVersions(entry.version, selectedVersion) > 0 &&
|
|
26
|
+
duplicateIdentity(entry.info) === selectedIdentity)
|
|
27
|
+
.sort((a, b) => compareVersions(b.version, a.version))
|
|
28
|
+
.map((entry) => ({
|
|
29
|
+
version: entry.version,
|
|
30
|
+
email: entry.info.email,
|
|
31
|
+
plan: entry.info.plan,
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
/** Collect account info for an agent and find newer duplicates of selectedVersion. */
|
|
35
|
+
export async function getNewerDuplicateVersions(agentId, selectedVersion) {
|
|
36
|
+
const rows = await Promise.all(listInstalledVersions(agentId).map(async (version) => {
|
|
37
|
+
const home = getVersionHomePath(agentId, version);
|
|
38
|
+
const info = await getAccountInfo(agentId, home);
|
|
39
|
+
return { version, home, info };
|
|
40
|
+
}));
|
|
41
|
+
const { canonicalByUsageKey } = await getUsageInfoByIdentity(rows.map(({ version, home, info }) => ({
|
|
42
|
+
agentId,
|
|
43
|
+
home,
|
|
44
|
+
cliVersion: version,
|
|
45
|
+
info,
|
|
46
|
+
})));
|
|
47
|
+
const entries = rows.map(({ version, info }) => {
|
|
48
|
+
const key = getUsageLookupKey(info);
|
|
49
|
+
const canon = key ? canonicalByUsageKey.get(key) : undefined;
|
|
50
|
+
return {
|
|
51
|
+
version,
|
|
52
|
+
info: canon
|
|
53
|
+
? {
|
|
54
|
+
...info,
|
|
55
|
+
plan: canon.plan,
|
|
56
|
+
usageStatus: canon.usageStatus,
|
|
57
|
+
overageCredits: canon.overageCredits,
|
|
58
|
+
}
|
|
59
|
+
: info,
|
|
60
|
+
};
|
|
61
|
+
});
|
|
62
|
+
return findNewerDuplicateVersions(entries, selectedVersion);
|
|
63
|
+
}
|
|
64
|
+
/** Format the non-interactive guidance shown by view/run when duplicates exist. */
|
|
65
|
+
export function formatNewerDuplicateNotice(agentId, selectedVersion, duplicates, selectedLabel = '') {
|
|
66
|
+
if (duplicates.length === 0)
|
|
67
|
+
return '';
|
|
68
|
+
const versionLabel = selectedLabel
|
|
69
|
+
? `${selectedLabel} ${agentLabel(agentId)}@${selectedVersion}`
|
|
70
|
+
: `${agentLabel(agentId)}@${selectedVersion}`;
|
|
71
|
+
const plural = duplicates.length === 1 ? 'duplicate' : 'duplicates';
|
|
72
|
+
const maxVersion = Math.max(...duplicates.map((duplicate) => duplicate.version.length));
|
|
73
|
+
const maxEmail = Math.max(0, ...duplicates.map((duplicate) => duplicate.email?.length ?? 0));
|
|
74
|
+
const lines = [
|
|
75
|
+
`Found ${duplicates.length} newer ${plural} for ${versionLabel}:`,
|
|
76
|
+
];
|
|
77
|
+
for (const duplicate of duplicates) {
|
|
78
|
+
const parts = [` ${duplicate.version.padEnd(maxVersion)}`];
|
|
79
|
+
if (maxEmail > 0) {
|
|
80
|
+
parts.push(duplicate.email ? chalk.cyan(duplicate.email.padEnd(maxEmail)) : ''.padEnd(maxEmail));
|
|
81
|
+
}
|
|
82
|
+
if (duplicate.plan) {
|
|
83
|
+
parts.push(duplicate.plan);
|
|
84
|
+
}
|
|
85
|
+
lines.push(parts.join(' '));
|
|
86
|
+
}
|
|
87
|
+
lines.push('');
|
|
88
|
+
lines.push(`Run: agents use ${agentId}@${duplicates[0].version}`);
|
|
89
|
+
return lines.join('\n');
|
|
90
|
+
}
|
package/dist/lib/versions.d.ts
CHANGED
|
@@ -18,6 +18,11 @@ export interface ResourceSelection {
|
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
20
|
* Available resources in ~/.agents/ for syncing.
|
|
21
|
+
*
|
|
22
|
+
* `promptcuts` is a boolean, not a list — there is at most one
|
|
23
|
+
* ~/.agents/promptcuts.yaml file. It is NOT version-scoped: the
|
|
24
|
+
* expand-promptcuts hook reads it directly, so no per-version copy
|
|
25
|
+
* is made and no sync step is needed.
|
|
21
26
|
*/
|
|
22
27
|
export interface AvailableResources {
|
|
23
28
|
commands: string[];
|
|
@@ -28,6 +33,7 @@ export interface AvailableResources {
|
|
|
28
33
|
permissions: string[];
|
|
29
34
|
subagents: string[];
|
|
30
35
|
plugins: string[];
|
|
36
|
+
promptcuts: boolean;
|
|
31
37
|
}
|
|
32
38
|
/**
|
|
33
39
|
* Get all available resources from ~/.agents/.
|
|
@@ -60,6 +66,7 @@ export declare function promptNewResourceSelection(agent: AgentId, newResources:
|
|
|
60
66
|
* Returns the selection, or null if user cancels.
|
|
61
67
|
*/
|
|
62
68
|
export declare function promptResourceSelection(agent: AgentId): Promise<ResourceSelection | null>;
|
|
69
|
+
/** Parsed agent@version specification from CLI input. */
|
|
63
70
|
export interface AgentSpec {
|
|
64
71
|
agent: AgentId;
|
|
65
72
|
version: string;
|
|
@@ -121,11 +128,14 @@ export declare function installVersion(agent: AgentId, version: string, onProgre
|
|
|
121
128
|
error?: string;
|
|
122
129
|
}>;
|
|
123
130
|
/**
|
|
124
|
-
* Remove a specific version of an agent.
|
|
131
|
+
* Remove a specific version of an agent. Preserves `home/` under the version
|
|
132
|
+
* directory so conversation history survives reinstalls.
|
|
125
133
|
*/
|
|
126
134
|
export declare function removeVersion(agent: AgentId, version: string): boolean;
|
|
127
135
|
/**
|
|
128
|
-
* Remove all versions of an agent.
|
|
136
|
+
* Remove all versions of an agent. Preserves each version's `home/` directory
|
|
137
|
+
* so conversation history is never deleted; the per-version folders (now
|
|
138
|
+
* containing only `home/`) remain under the agent dir.
|
|
129
139
|
*/
|
|
130
140
|
export declare function removeAllVersions(agent: AgentId): number;
|
|
131
141
|
/**
|
|
@@ -134,7 +144,28 @@ export declare function removeAllVersions(agent: AgentId): number;
|
|
|
134
144
|
*/
|
|
135
145
|
export declare function resolveVersion(agent: AgentId, projectPath?: string): string | null;
|
|
136
146
|
/**
|
|
137
|
-
*
|
|
147
|
+
* Normalize a user-supplied @version token across CLI subcommands.
|
|
148
|
+
*
|
|
149
|
+
* undefined / "" / "default" -> undefined (caller falls back to project pin or global default)
|
|
150
|
+
* "latest" -> highest installed version (process.exit if none installed)
|
|
151
|
+
* "x.y.z" (installed) -> "x.y.z"
|
|
152
|
+
* "x.y.z" (not installed) -> process.exit with installed-list hint
|
|
153
|
+
*
|
|
154
|
+
* Use this anywhere the user can type `agents <cmd> claude@<token>` to keep the
|
|
155
|
+
* vocabulary consistent. Subcommands with different semantics for `latest`
|
|
156
|
+
* (install/remove/use, where `latest` means npm-latest) keep their existing
|
|
157
|
+
* parsing.
|
|
158
|
+
*/
|
|
159
|
+
export declare function resolveVersionAlias(agent: AgentId, raw: string | undefined | null): string | undefined;
|
|
160
|
+
/**
|
|
161
|
+
* Loose variant of resolveVersionAlias for record-filter contexts (sessions,
|
|
162
|
+
* team history). Same `default`/`latest` semantics, but explicit versions
|
|
163
|
+
* pass through unchanged so historical records of uninstalled versions remain
|
|
164
|
+
* queryable.
|
|
165
|
+
*/
|
|
166
|
+
export declare function resolveVersionAliasLoose(agent: AgentId, raw: string | undefined | null): string | undefined;
|
|
167
|
+
/**
|
|
168
|
+
* Get version specified in a project-root agents.yaml (not the user ~/.agents-system/agents.yaml).
|
|
138
169
|
*/
|
|
139
170
|
export declare function getProjectVersion(agent: AgentId, startPath: string): string | null;
|
|
140
171
|
/**
|
|
@@ -145,6 +176,7 @@ export declare function compareVersions(a: string, b: string): number;
|
|
|
145
176
|
* Get actual version from an installed 'latest' directory.
|
|
146
177
|
*/
|
|
147
178
|
export declare function getInstalledVersion(agent: AgentId, version: string): Promise<string | null>;
|
|
179
|
+
/** Outcome of syncing resources to a version home, keyed by resource type. */
|
|
148
180
|
export interface SyncResult {
|
|
149
181
|
commands: boolean;
|
|
150
182
|
skills: boolean;
|
|
@@ -155,6 +187,7 @@ export interface SyncResult {
|
|
|
155
187
|
subagents: string[];
|
|
156
188
|
plugins: string[];
|
|
157
189
|
}
|
|
190
|
+
/** Diff between central ~/.agents/ resources and what is synced to a version home. */
|
|
158
191
|
export interface ResourceDiff {
|
|
159
192
|
commands: {
|
|
160
193
|
added: string[];
|
|
@@ -193,6 +226,7 @@ export declare function getResourceDiff(agent: AgentId, version: string): Resour
|
|
|
193
226
|
export declare function syncResourcesToVersion(agent: AgentId, version: string, selection?: ResourceSelection, options?: {
|
|
194
227
|
projectDir?: string;
|
|
195
228
|
cwd?: string;
|
|
229
|
+
force?: boolean;
|
|
196
230
|
}): SyncResult;
|
|
197
231
|
/**
|
|
198
232
|
* Get the effective HOME directory for an agent.
|
|
@@ -200,10 +234,12 @@ export declare function syncResourcesToVersion(agent: AgentId, version: string,
|
|
|
200
234
|
* Otherwise returns the real HOME.
|
|
201
235
|
*/
|
|
202
236
|
export declare function getEffectiveHome(agentId: AgentId): string;
|
|
237
|
+
/** Result of resolving agent/version targets from CLI input or interactive selection. */
|
|
203
238
|
export interface VersionSelectionResult {
|
|
204
239
|
selectedAgents: AgentId[];
|
|
205
240
|
versionSelections: Map<AgentId, string[]>;
|
|
206
241
|
}
|
|
242
|
+
/** Extended target result that distinguishes managed versions from direct (unmanaged) agent homes. */
|
|
207
243
|
export interface InstalledAgentTargetResult {
|
|
208
244
|
selectedAgents: AgentId[];
|
|
209
245
|
directAgents: AgentId[];
|
|
@@ -239,4 +275,3 @@ export declare function resolveConfiguredAgentTargets(agents: readonly AgentId[]
|
|
|
239
275
|
export declare function promptAgentVersionSelection(availableAgents: AgentId[], options?: {
|
|
240
276
|
skipPrompts?: boolean;
|
|
241
277
|
}): Promise<VersionSelectionResult>;
|
|
242
|
-
//# sourceMappingURL=versions.d.ts.map
|