@phnx-labs/agents-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +316 -0
- package/LICENSE +21 -0
- package/README.md +537 -0
- package/dist/commands/__tests__/sessions.test.d.ts +2 -0
- package/dist/commands/__tests__/sessions.test.d.ts.map +1 -0
- package/dist/commands/__tests__/sessions.test.js +636 -0
- package/dist/commands/__tests__/sessions.test.js.map +1 -0
- package/dist/commands/cloud.d.ts +3 -0
- package/dist/commands/cloud.d.ts.map +1 -0
- package/dist/commands/cloud.js +322 -0
- package/dist/commands/cloud.js.map +1 -0
- package/dist/commands/commands.d.ts +3 -0
- package/dist/commands/commands.d.ts.map +1 -0
- package/dist/commands/commands.js +628 -0
- package/dist/commands/commands.js.map +1 -0
- package/dist/commands/daemon.d.ts +3 -0
- package/dist/commands/daemon.d.ts.map +1 -0
- package/dist/commands/daemon.js +110 -0
- package/dist/commands/daemon.js.map +1 -0
- package/dist/commands/drive.d.ts +3 -0
- package/dist/commands/drive.d.ts.map +1 -0
- package/dist/commands/drive.js +166 -0
- package/dist/commands/drive.js.map +1 -0
- package/dist/commands/exec.d.ts +3 -0
- package/dist/commands/exec.d.ts.map +1 -0
- package/dist/commands/exec.js +241 -0
- package/dist/commands/exec.js.map +1 -0
- package/dist/commands/fork.d.ts +3 -0
- package/dist/commands/fork.d.ts.map +1 -0
- package/dist/commands/fork.js +139 -0
- package/dist/commands/fork.js.map +1 -0
- package/dist/commands/hooks.d.ts +3 -0
- package/dist/commands/hooks.d.ts.map +1 -0
- package/dist/commands/hooks.js +689 -0
- package/dist/commands/hooks.js.map +1 -0
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +127 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/mcp.d.ts +3 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +581 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/models.d.ts +3 -0
- package/dist/commands/models.d.ts.map +1 -0
- package/dist/commands/models.js +158 -0
- package/dist/commands/models.js.map +1 -0
- package/dist/commands/packages.d.ts +3 -0
- package/dist/commands/packages.d.ts.map +1 -0
- package/dist/commands/packages.js +541 -0
- package/dist/commands/packages.js.map +1 -0
- package/dist/commands/permissions.d.ts +3 -0
- package/dist/commands/permissions.d.ts.map +1 -0
- package/dist/commands/permissions.js +723 -0
- package/dist/commands/permissions.js.map +1 -0
- package/dist/commands/plugins.d.ts +3 -0
- package/dist/commands/plugins.d.ts.map +1 -0
- package/dist/commands/plugins.js +382 -0
- package/dist/commands/plugins.js.map +1 -0
- package/dist/commands/profiles.d.ts +3 -0
- package/dist/commands/profiles.d.ts.map +1 -0
- package/dist/commands/profiles.js +242 -0
- package/dist/commands/profiles.js.map +1 -0
- package/dist/commands/pty.d.ts +20 -0
- package/dist/commands/pty.d.ts.map +1 -0
- package/dist/commands/pty.js +389 -0
- package/dist/commands/pty.js.map +1 -0
- package/dist/commands/pull.d.ts +3 -0
- package/dist/commands/pull.d.ts.map +1 -0
- package/dist/commands/pull.js +448 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/push.d.ts +3 -0
- package/dist/commands/push.d.ts.map +1 -0
- package/dist/commands/push.js +180 -0
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/refresh-memory.d.ts +9 -0
- package/dist/commands/refresh-memory.d.ts.map +1 -0
- package/dist/commands/refresh-memory.js +45 -0
- package/dist/commands/refresh-memory.js.map +1 -0
- package/dist/commands/resource-view.d.ts +31 -0
- package/dist/commands/resource-view.d.ts.map +1 -0
- package/dist/commands/resource-view.js +183 -0
- package/dist/commands/resource-view.js.map +1 -0
- package/dist/commands/routines.d.ts +3 -0
- package/dist/commands/routines.d.ts.map +1 -0
- package/dist/commands/routines.js +579 -0
- package/dist/commands/routines.js.map +1 -0
- package/dist/commands/rules.d.ts +3 -0
- package/dist/commands/rules.d.ts.map +1 -0
- package/dist/commands/rules.js +488 -0
- package/dist/commands/rules.js.map +1 -0
- package/dist/commands/secrets.d.ts +3 -0
- package/dist/commands/secrets.d.ts.map +1 -0
- package/dist/commands/secrets.js +339 -0
- package/dist/commands/secrets.js.map +1 -0
- package/dist/commands/sessions-picker.d.ts +16 -0
- package/dist/commands/sessions-picker.d.ts.map +1 -0
- package/dist/commands/sessions-picker.js +256 -0
- package/dist/commands/sessions-picker.js.map +1 -0
- package/dist/commands/sessions.d.ts +16 -0
- package/dist/commands/sessions.d.ts.map +1 -0
- package/dist/commands/sessions.js +1077 -0
- package/dist/commands/sessions.js.map +1 -0
- package/dist/commands/skills.d.ts +3 -0
- package/dist/commands/skills.d.ts.map +1 -0
- package/dist/commands/skills.js +716 -0
- package/dist/commands/skills.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +19 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/subagents.d.ts +3 -0
- package/dist/commands/subagents.d.ts.map +1 -0
- package/dist/commands/subagents.js +350 -0
- package/dist/commands/subagents.js.map +1 -0
- package/dist/commands/sync.d.ts +3 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +62 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/teams-picker.d.ts +14 -0
- package/dist/commands/teams-picker.d.ts.map +1 -0
- package/dist/commands/teams-picker.js +278 -0
- package/dist/commands/teams-picker.js.map +1 -0
- package/dist/commands/teams.d.ts +3 -0
- package/dist/commands/teams.d.ts.map +1 -0
- package/dist/commands/teams.js +917 -0
- package/dist/commands/teams.js.map +1 -0
- package/dist/commands/utils.d.ts +39 -0
- package/dist/commands/utils.d.ts.map +1 -0
- package/dist/commands/utils.js +100 -0
- package/dist/commands/utils.js.map +1 -0
- package/dist/commands/versions.d.ts +3 -0
- package/dist/commands/versions.d.ts.map +1 -0
- package/dist/commands/versions.js +700 -0
- package/dist/commands/versions.js.map +1 -0
- package/dist/commands/view.d.ts +8 -0
- package/dist/commands/view.d.ts.map +1 -0
- package/dist/commands/view.js +626 -0
- package/dist/commands/view.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +484 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/__tests__/bugfixes.test.d.ts +2 -0
- package/dist/lib/__tests__/bugfixes.test.d.ts.map +1 -0
- package/dist/lib/__tests__/bugfixes.test.js +192 -0
- package/dist/lib/__tests__/bugfixes.test.js.map +1 -0
- package/dist/lib/__tests__/exec.test.d.ts +2 -0
- package/dist/lib/__tests__/exec.test.d.ts.map +1 -0
- package/dist/lib/__tests__/exec.test.js +446 -0
- package/dist/lib/__tests__/exec.test.js.map +1 -0
- package/dist/lib/__tests__/git-sync.test.d.ts +2 -0
- package/dist/lib/__tests__/git-sync.test.d.ts.map +1 -0
- package/dist/lib/__tests__/git-sync.test.js +138 -0
- package/dist/lib/__tests__/git-sync.test.js.map +1 -0
- package/dist/lib/__tests__/hooks.test.d.ts +2 -0
- package/dist/lib/__tests__/hooks.test.d.ts.map +1 -0
- package/dist/lib/__tests__/hooks.test.js +203 -0
- package/dist/lib/__tests__/hooks.test.js.map +1 -0
- package/dist/lib/__tests__/memory-compile.test.d.ts +2 -0
- package/dist/lib/__tests__/memory-compile.test.d.ts.map +1 -0
- package/dist/lib/__tests__/memory-compile.test.js +95 -0
- package/dist/lib/__tests__/memory-compile.test.js.map +1 -0
- package/dist/lib/__tests__/models.test.d.ts +2 -0
- package/dist/lib/__tests__/models.test.d.ts.map +1 -0
- package/dist/lib/__tests__/models.test.js +239 -0
- package/dist/lib/__tests__/models.test.js.map +1 -0
- package/dist/lib/__tests__/rotate.test.d.ts +2 -0
- package/dist/lib/__tests__/rotate.test.d.ts.map +1 -0
- package/dist/lib/__tests__/rotate.test.js +80 -0
- package/dist/lib/__tests__/rotate.test.js.map +1 -0
- package/dist/lib/__tests__/secrets-bundles.test.d.ts +2 -0
- package/dist/lib/__tests__/secrets-bundles.test.d.ts.map +1 -0
- package/dist/lib/__tests__/secrets-bundles.test.js +104 -0
- package/dist/lib/__tests__/secrets-bundles.test.js.map +1 -0
- package/dist/lib/__tests__/secrets.test.d.ts +2 -0
- package/dist/lib/__tests__/secrets.test.d.ts.map +1 -0
- package/dist/lib/__tests__/secrets.test.js +90 -0
- package/dist/lib/__tests__/secrets.test.js.map +1 -0
- package/dist/lib/__tests__/shims.test.d.ts +2 -0
- package/dist/lib/__tests__/shims.test.d.ts.map +1 -0
- package/dist/lib/__tests__/shims.test.js +39 -0
- package/dist/lib/__tests__/shims.test.js.map +1 -0
- package/dist/lib/__tests__/usage.test.d.ts +2 -0
- package/dist/lib/__tests__/usage.test.d.ts.map +1 -0
- package/dist/lib/__tests__/usage.test.js +220 -0
- package/dist/lib/__tests__/usage.test.js.map +1 -0
- package/dist/lib/__tests__/versions.test.d.ts +2 -0
- package/dist/lib/__tests__/versions.test.d.ts.map +1 -0
- package/dist/lib/__tests__/versions.test.js +63 -0
- package/dist/lib/__tests__/versions.test.js.map +1 -0
- package/dist/lib/agents.d.ts +107 -0
- package/dist/lib/agents.d.ts.map +1 -0
- package/dist/lib/agents.js +1096 -0
- package/dist/lib/agents.js.map +1 -0
- package/dist/lib/artifact-actions.d.ts +22 -0
- package/dist/lib/artifact-actions.d.ts.map +1 -0
- package/dist/lib/artifact-actions.js +55 -0
- package/dist/lib/artifact-actions.js.map +1 -0
- package/dist/lib/cloud/codex.d.ts +19 -0
- package/dist/lib/cloud/codex.d.ts.map +1 -0
- package/dist/lib/cloud/codex.js +210 -0
- package/dist/lib/cloud/codex.js.map +1 -0
- package/dist/lib/cloud/factory.d.ts +26 -0
- package/dist/lib/cloud/factory.d.ts.map +1 -0
- package/dist/lib/cloud/factory.js +37 -0
- package/dist/lib/cloud/factory.js.map +1 -0
- package/dist/lib/cloud/registry.d.ts +6 -0
- package/dist/lib/cloud/registry.d.ts.map +1 -0
- package/dist/lib/cloud/registry.js +56 -0
- package/dist/lib/cloud/registry.js.map +1 -0
- package/dist/lib/cloud/rush.d.ts +15 -0
- package/dist/lib/cloud/rush.d.ts.map +1 -0
- package/dist/lib/cloud/rush.js +185 -0
- package/dist/lib/cloud/rush.js.map +1 -0
- package/dist/lib/cloud/store.d.ts +10 -0
- package/dist/lib/cloud/store.d.ts.map +1 -0
- package/dist/lib/cloud/store.js +96 -0
- package/dist/lib/cloud/store.js.map +1 -0
- package/dist/lib/cloud/stream.d.ts +18 -0
- package/dist/lib/cloud/stream.d.ts.map +1 -0
- package/dist/lib/cloud/stream.js +138 -0
- package/dist/lib/cloud/stream.js.map +1 -0
- package/dist/lib/cloud/types.d.ts +60 -0
- package/dist/lib/cloud/types.d.ts.map +1 -0
- package/dist/lib/cloud/types.js +2 -0
- package/dist/lib/cloud/types.js.map +1 -0
- package/dist/lib/commands.d.ts +121 -0
- package/dist/lib/commands.d.ts.map +1 -0
- package/dist/lib/commands.js +499 -0
- package/dist/lib/commands.js.map +1 -0
- package/dist/lib/convert.d.ts +11 -0
- package/dist/lib/convert.d.ts.map +1 -0
- package/dist/lib/convert.js +45 -0
- package/dist/lib/convert.js.map +1 -0
- package/dist/lib/daemon.d.ts +22 -0
- package/dist/lib/daemon.d.ts.map +1 -0
- package/dist/lib/daemon.js +311 -0
- package/dist/lib/daemon.js.map +1 -0
- package/dist/lib/drive-sync.d.ts +28 -0
- package/dist/lib/drive-sync.d.ts.map +1 -0
- package/dist/lib/drive-sync.js +193 -0
- package/dist/lib/drive-sync.js.map +1 -0
- package/dist/lib/exec.d.ts +85 -0
- package/dist/lib/exec.d.ts.map +1 -0
- package/dist/lib/exec.js +423 -0
- package/dist/lib/exec.js.map +1 -0
- package/dist/lib/factory.d.ts +57 -0
- package/dist/lib/factory.d.ts.map +1 -0
- package/dist/lib/factory.js +110 -0
- package/dist/lib/factory.js.map +1 -0
- package/dist/lib/git.d.ts +146 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +635 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/help.d.ts +3 -0
- package/dist/lib/help.d.ts.map +1 -0
- package/dist/lib/help.js +63 -0
- package/dist/lib/help.js.map +1 -0
- package/dist/lib/hooks.d.ts +116 -0
- package/dist/lib/hooks.d.ts.map +1 -0
- package/dist/lib/hooks.js +837 -0
- package/dist/lib/hooks.js.map +1 -0
- package/dist/lib/manifest.d.ts +8 -0
- package/dist/lib/manifest.d.ts.map +1 -0
- package/dist/lib/manifest.js +36 -0
- package/dist/lib/manifest.js.map +1 -0
- package/dist/lib/markdown.d.ts +5 -0
- package/dist/lib/markdown.d.ts.map +1 -0
- package/dist/lib/markdown.js +11 -0
- package/dist/lib/markdown.js.map +1 -0
- package/dist/lib/mcp.d.ts +64 -0
- package/dist/lib/mcp.d.ts.map +1 -0
- package/dist/lib/mcp.js +327 -0
- package/dist/lib/mcp.js.map +1 -0
- package/dist/lib/memory-compile.d.ts +56 -0
- package/dist/lib/memory-compile.d.ts.map +1 -0
- package/dist/lib/memory-compile.js +167 -0
- package/dist/lib/memory-compile.js.map +1 -0
- package/dist/lib/memory.d.ts +56 -0
- package/dist/lib/memory.d.ts.map +1 -0
- package/dist/lib/memory.js +267 -0
- package/dist/lib/memory.js.map +1 -0
- package/dist/lib/models.d.ts +91 -0
- package/dist/lib/models.d.ts.map +1 -0
- package/dist/lib/models.js +706 -0
- package/dist/lib/models.js.map +1 -0
- package/dist/lib/permissions.d.ts +204 -0
- package/dist/lib/permissions.d.ts.map +1 -0
- package/dist/lib/permissions.js +1022 -0
- package/dist/lib/permissions.js.map +1 -0
- package/dist/lib/picker.d.ts +17 -0
- package/dist/lib/picker.d.ts.map +1 -0
- package/dist/lib/picker.js +95 -0
- package/dist/lib/picker.js.map +1 -0
- package/dist/lib/plugins.d.ts +73 -0
- package/dist/lib/plugins.d.ts.map +1 -0
- package/dist/lib/plugins.js +549 -0
- package/dist/lib/plugins.js.map +1 -0
- package/dist/lib/profiles-keychain.d.ts +3 -0
- package/dist/lib/profiles-keychain.d.ts.map +1 -0
- package/dist/lib/profiles-keychain.js +10 -0
- package/dist/lib/profiles-keychain.js.map +1 -0
- package/dist/lib/profiles-presets.d.ts +15 -0
- package/dist/lib/profiles-presets.d.ts.map +1 -0
- package/dist/lib/profiles-presets.js +95 -0
- package/dist/lib/profiles-presets.js.map +1 -0
- package/dist/lib/profiles.d.ts +35 -0
- package/dist/lib/profiles.d.ts.map +1 -0
- package/dist/lib/profiles.js +123 -0
- package/dist/lib/profiles.js.map +1 -0
- package/dist/lib/pty-client.d.ts +22 -0
- package/dist/lib/pty-client.d.ts.map +1 -0
- package/dist/lib/pty-client.js +181 -0
- package/dist/lib/pty-client.js.map +1 -0
- package/dist/lib/pty-server.d.ts +16 -0
- package/dist/lib/pty-server.d.ts.map +1 -0
- package/dist/lib/pty-server.js +422 -0
- package/dist/lib/pty-server.js.map +1 -0
- package/dist/lib/registry.d.ts +28 -0
- package/dist/lib/registry.d.ts.map +1 -0
- package/dist/lib/registry.js +203 -0
- package/dist/lib/registry.js.map +1 -0
- package/dist/lib/resources.d.ts +50 -0
- package/dist/lib/resources.d.ts.map +1 -0
- package/dist/lib/resources.js +103 -0
- package/dist/lib/resources.js.map +1 -0
- package/dist/lib/rotate.d.ts +52 -0
- package/dist/lib/rotate.d.ts.map +1 -0
- package/dist/lib/rotate.js +87 -0
- package/dist/lib/rotate.js.map +1 -0
- package/dist/lib/routines.d.ts +70 -0
- package/dist/lib/routines.d.ts.map +1 -0
- package/dist/lib/routines.js +325 -0
- package/dist/lib/routines.js.map +1 -0
- package/dist/lib/runner.d.ts +12 -0
- package/dist/lib/runner.d.ts.map +1 -0
- package/dist/lib/runner.js +311 -0
- package/dist/lib/runner.js.map +1 -0
- package/dist/lib/sandbox.d.ts +10 -0
- package/dist/lib/sandbox.d.ts.map +1 -0
- package/dist/lib/sandbox.js +201 -0
- package/dist/lib/sandbox.js.map +1 -0
- package/dist/lib/scheduler.d.ts +18 -0
- package/dist/lib/scheduler.d.ts.map +1 -0
- package/dist/lib/scheduler.js +69 -0
- package/dist/lib/scheduler.js.map +1 -0
- package/dist/lib/secrets-bundles.d.ts +29 -0
- package/dist/lib/secrets-bundles.d.ts.map +1 -0
- package/dist/lib/secrets-bundles.js +168 -0
- package/dist/lib/secrets-bundles.js.map +1 -0
- package/dist/lib/secrets.d.ts +27 -0
- package/dist/lib/secrets.d.ts.map +1 -0
- package/dist/lib/secrets.js +127 -0
- package/dist/lib/secrets.js.map +1 -0
- package/dist/lib/session/__tests__/db.test.d.ts +2 -0
- package/dist/lib/session/__tests__/db.test.d.ts.map +1 -0
- package/dist/lib/session/__tests__/db.test.js +54 -0
- package/dist/lib/session/__tests__/db.test.js.map +1 -0
- package/dist/lib/session/__tests__/discover.test.d.ts +2 -0
- package/dist/lib/session/__tests__/discover.test.d.ts.map +1 -0
- package/dist/lib/session/__tests__/discover.test.js +63 -0
- package/dist/lib/session/__tests__/discover.test.js.map +1 -0
- package/dist/lib/session/__tests__/prompt.test.d.ts +2 -0
- package/dist/lib/session/__tests__/prompt.test.d.ts.map +1 -0
- package/dist/lib/session/__tests__/prompt.test.js +44 -0
- package/dist/lib/session/__tests__/prompt.test.js.map +1 -0
- package/dist/lib/session/__tests__/render.test.d.ts +2 -0
- package/dist/lib/session/__tests__/render.test.d.ts.map +1 -0
- package/dist/lib/session/__tests__/render.test.js +602 -0
- package/dist/lib/session/__tests__/render.test.js.map +1 -0
- package/dist/lib/session/artifacts.d.ts +5 -0
- package/dist/lib/session/artifacts.d.ts.map +1 -0
- package/dist/lib/session/artifacts.js +75 -0
- package/dist/lib/session/artifacts.js.map +1 -0
- package/dist/lib/session/db.d.ts +118 -0
- package/dist/lib/session/db.d.ts.map +1 -0
- package/dist/lib/session/db.js +576 -0
- package/dist/lib/session/db.js.map +1 -0
- package/dist/lib/session/discover.d.ts +60 -0
- package/dist/lib/session/discover.d.ts.map +1 -0
- package/dist/lib/session/discover.js +1272 -0
- package/dist/lib/session/discover.js.map +1 -0
- package/dist/lib/session/parse.d.ts +23 -0
- package/dist/lib/session/parse.d.ts.map +1 -0
- package/dist/lib/session/parse.js +650 -0
- package/dist/lib/session/parse.js.map +1 -0
- package/dist/lib/session/prompt.d.ts +4 -0
- package/dist/lib/session/prompt.d.ts.map +1 -0
- package/dist/lib/session/prompt.js +64 -0
- package/dist/lib/session/prompt.js.map +1 -0
- package/dist/lib/session/prompt.test.d.ts +2 -0
- package/dist/lib/session/prompt.test.d.ts.map +1 -0
- package/dist/lib/session/prompt.test.js +57 -0
- package/dist/lib/session/prompt.test.js.map +1 -0
- package/dist/lib/session/render.d.ts +90 -0
- package/dist/lib/session/render.d.ts.map +1 -0
- package/dist/lib/session/render.js +778 -0
- package/dist/lib/session/render.js.map +1 -0
- package/dist/lib/session/team-filter.d.ts +26 -0
- package/dist/lib/session/team-filter.d.ts.map +1 -0
- package/dist/lib/session/team-filter.js +66 -0
- package/dist/lib/session/team-filter.js.map +1 -0
- package/dist/lib/session/team-filter.test.d.ts +2 -0
- package/dist/lib/session/team-filter.test.d.ts.map +1 -0
- package/dist/lib/session/team-filter.test.js +157 -0
- package/dist/lib/session/team-filter.test.js.map +1 -0
- package/dist/lib/session/types.d.ts +69 -0
- package/dist/lib/session/types.d.ts.map +1 -0
- package/dist/lib/session/types.js +2 -0
- package/dist/lib/session/types.js.map +1 -0
- package/dist/lib/shims.d.ts +228 -0
- package/dist/lib/shims.d.ts.map +1 -0
- package/dist/lib/shims.js +1170 -0
- package/dist/lib/shims.js.map +1 -0
- package/dist/lib/skills.d.ts +134 -0
- package/dist/lib/skills.d.ts.map +1 -0
- package/dist/lib/skills.js +783 -0
- package/dist/lib/skills.js.map +1 -0
- package/dist/lib/state.d.ts +53 -0
- package/dist/lib/state.d.ts.map +1 -0
- package/dist/lib/state.js +299 -0
- package/dist/lib/state.js.map +1 -0
- package/dist/lib/subagents.d.ts +75 -0
- package/dist/lib/subagents.d.ts.map +1 -0
- package/dist/lib/subagents.js +402 -0
- package/dist/lib/subagents.js.map +1 -0
- package/dist/lib/teams/agents.d.ts +146 -0
- package/dist/lib/teams/agents.d.ts.map +1 -0
- package/dist/lib/teams/agents.js +1072 -0
- package/dist/lib/teams/agents.js.map +1 -0
- package/dist/lib/teams/api.d.ts +77 -0
- package/dist/lib/teams/api.d.ts.map +1 -0
- package/dist/lib/teams/api.js +229 -0
- package/dist/lib/teams/api.js.map +1 -0
- package/dist/lib/teams/cloud.d.ts +11 -0
- package/dist/lib/teams/cloud.d.ts.map +1 -0
- package/dist/lib/teams/cloud.js +169 -0
- package/dist/lib/teams/cloud.js.map +1 -0
- package/dist/lib/teams/debug.d.ts +2 -0
- package/dist/lib/teams/debug.d.ts.map +1 -0
- package/dist/lib/teams/debug.js +6 -0
- package/dist/lib/teams/debug.js.map +1 -0
- package/dist/lib/teams/file_ops.d.ts +6 -0
- package/dist/lib/teams/file_ops.d.ts.map +1 -0
- package/dist/lib/teams/file_ops.js +59 -0
- package/dist/lib/teams/file_ops.js.map +1 -0
- package/dist/lib/teams/parsers.d.ts +5 -0
- package/dist/lib/teams/parsers.d.ts.map +1 -0
- package/dist/lib/teams/parsers.js +826 -0
- package/dist/lib/teams/parsers.js.map +1 -0
- package/dist/lib/teams/persistence.d.ts +28 -0
- package/dist/lib/teams/persistence.d.ts.map +1 -0
- package/dist/lib/teams/persistence.js +289 -0
- package/dist/lib/teams/persistence.js.map +1 -0
- package/dist/lib/teams/ralph.d.ts +8 -0
- package/dist/lib/teams/ralph.d.ts.map +1 -0
- package/dist/lib/teams/ralph.js +59 -0
- package/dist/lib/teams/ralph.js.map +1 -0
- package/dist/lib/teams/registry.d.ts +11 -0
- package/dist/lib/teams/registry.d.ts.map +1 -0
- package/dist/lib/teams/registry.js +56 -0
- package/dist/lib/teams/registry.js.map +1 -0
- package/dist/lib/teams/summarizer.d.ts +58 -0
- package/dist/lib/teams/summarizer.d.ts.map +1 -0
- package/dist/lib/teams/summarizer.js +766 -0
- package/dist/lib/teams/summarizer.js.map +1 -0
- package/dist/lib/template.d.ts +24 -0
- package/dist/lib/template.d.ts.map +1 -0
- package/dist/lib/template.js +57 -0
- package/dist/lib/template.js.map +1 -0
- package/dist/lib/types.d.ts +282 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +18 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/usage.d.ts +73 -0
- package/dist/lib/usage.d.ts.map +1 -0
- package/dist/lib/usage.js +623 -0
- package/dist/lib/usage.js.map +1 -0
- package/dist/lib/versions.d.ts +248 -0
- package/dist/lib/versions.d.ts.map +1 -0
- package/dist/lib/versions.js +1737 -0
- package/dist/lib/versions.js.map +1 -0
- package/package.json +82 -0
- package/scripts/postinstall.js +72 -0
- package/scripts/rebuild-sqlite.sh +46 -0
|
@@ -0,0 +1,1096 @@
|
|
|
1
|
+
import { exec } from 'child_process';
|
|
2
|
+
import { promisify } from 'util';
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import * as os from 'os';
|
|
6
|
+
import * as TOML from 'smol-toml';
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import { walkForFiles } from './session/discover.js';
|
|
9
|
+
import { getVersionsDir, getShimsDir } from './state.js';
|
|
10
|
+
import { resolveVersion, getVersionHomePath, getBinaryPath } from './versions.js';
|
|
11
|
+
import { loadClaudeOauth } from './usage.js';
|
|
12
|
+
const execAsync = promisify(exec);
|
|
13
|
+
const HOME = os.homedir();
|
|
14
|
+
export const CODEX_HOOKS_MIN_VERSION = '0.116.0';
|
|
15
|
+
const CLI_VERSION_CACHE_PATH = path.join(HOME, '.agents', '.cli-version-cache.json');
|
|
16
|
+
let cliVersionCache = null;
|
|
17
|
+
function loadCliVersionCache() {
|
|
18
|
+
if (cliVersionCache)
|
|
19
|
+
return cliVersionCache;
|
|
20
|
+
try {
|
|
21
|
+
cliVersionCache = JSON.parse(fs.readFileSync(CLI_VERSION_CACHE_PATH, 'utf-8'));
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
/* missing or corrupt cache, rebuild */
|
|
25
|
+
cliVersionCache = {};
|
|
26
|
+
}
|
|
27
|
+
return cliVersionCache;
|
|
28
|
+
}
|
|
29
|
+
function saveCliVersionCache() {
|
|
30
|
+
if (!cliVersionCache)
|
|
31
|
+
return;
|
|
32
|
+
try {
|
|
33
|
+
const dir = path.dirname(CLI_VERSION_CACHE_PATH);
|
|
34
|
+
if (!fs.existsSync(dir))
|
|
35
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
36
|
+
fs.writeFileSync(CLI_VERSION_CACHE_PATH, JSON.stringify(cliVersionCache));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
/* best-effort cache persist */
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** Synchronous PATH search — no subprocess. Returns first matching binary path. */
|
|
43
|
+
function findInPath(command) {
|
|
44
|
+
const pathEnv = process.env.PATH || '';
|
|
45
|
+
const pathExt = process.platform === 'win32' ? (process.env.PATHEXT || '').split(';') : [''];
|
|
46
|
+
for (const dir of pathEnv.split(path.delimiter)) {
|
|
47
|
+
if (!dir)
|
|
48
|
+
continue;
|
|
49
|
+
for (const ext of pathExt) {
|
|
50
|
+
const full = path.join(dir, command + ext);
|
|
51
|
+
try {
|
|
52
|
+
const stat = fs.statSync(full);
|
|
53
|
+
if (stat.isFile())
|
|
54
|
+
return full;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
/* not in this dir */
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
export const AGENTS = {
|
|
64
|
+
claude: {
|
|
65
|
+
id: 'claude',
|
|
66
|
+
name: 'Claude',
|
|
67
|
+
color: 'magenta',
|
|
68
|
+
cliCommand: 'claude',
|
|
69
|
+
npmPackage: '@anthropic-ai/claude-code',
|
|
70
|
+
configDir: path.join(HOME, '.claude'),
|
|
71
|
+
homeFiles: ['.claude.json'],
|
|
72
|
+
commandsDir: path.join(HOME, '.claude', 'commands'),
|
|
73
|
+
commandsSubdir: 'commands',
|
|
74
|
+
skillsDir: path.join(HOME, '.claude', 'skills'),
|
|
75
|
+
hooksDir: 'hooks',
|
|
76
|
+
instructionsFile: 'CLAUDE.md',
|
|
77
|
+
format: 'markdown',
|
|
78
|
+
variableSyntax: '$ARGUMENTS',
|
|
79
|
+
supportsHooks: true,
|
|
80
|
+
capabilities: { hooks: true, mcp: true, allowlist: true, skills: true, commands: true, plugins: true, memoryImports: true },
|
|
81
|
+
},
|
|
82
|
+
codex: {
|
|
83
|
+
id: 'codex',
|
|
84
|
+
name: 'Codex',
|
|
85
|
+
color: 'green',
|
|
86
|
+
cliCommand: 'codex',
|
|
87
|
+
npmPackage: '@openai/codex',
|
|
88
|
+
configDir: path.join(HOME, '.codex'),
|
|
89
|
+
commandsDir: path.join(HOME, '.codex', 'prompts'),
|
|
90
|
+
commandsSubdir: 'prompts',
|
|
91
|
+
skillsDir: path.join(HOME, '.codex', 'skills'),
|
|
92
|
+
hooksDir: 'hooks',
|
|
93
|
+
instructionsFile: 'AGENTS.md',
|
|
94
|
+
format: 'markdown',
|
|
95
|
+
variableSyntax: '$ARGUMENTS',
|
|
96
|
+
supportsHooks: true,
|
|
97
|
+
capabilities: { hooks: true, mcp: true, allowlist: false, skills: true, commands: true, plugins: false },
|
|
98
|
+
},
|
|
99
|
+
gemini: {
|
|
100
|
+
id: 'gemini',
|
|
101
|
+
name: 'Gemini',
|
|
102
|
+
color: 'blue',
|
|
103
|
+
cliCommand: 'gemini',
|
|
104
|
+
npmPackage: '@google/gemini-cli',
|
|
105
|
+
configDir: path.join(HOME, '.gemini'),
|
|
106
|
+
commandsDir: path.join(HOME, '.gemini', 'commands'),
|
|
107
|
+
commandsSubdir: 'commands',
|
|
108
|
+
skillsDir: path.join(HOME, '.gemini', 'skills'),
|
|
109
|
+
hooksDir: 'hooks',
|
|
110
|
+
instructionsFile: 'GEMINI.md',
|
|
111
|
+
format: 'toml',
|
|
112
|
+
variableSyntax: '{{args}}',
|
|
113
|
+
supportsHooks: true,
|
|
114
|
+
nativeAgentsSkillsDir: true,
|
|
115
|
+
capabilities: { hooks: true, mcp: true, allowlist: false, skills: true, commands: true, plugins: false, memoryImports: true },
|
|
116
|
+
},
|
|
117
|
+
cursor: {
|
|
118
|
+
id: 'cursor',
|
|
119
|
+
name: 'Cursor',
|
|
120
|
+
color: 'cyan',
|
|
121
|
+
cliCommand: 'cursor-agent',
|
|
122
|
+
npmPackage: '',
|
|
123
|
+
installScript: 'curl https://cursor.com/install -fsS | bash && mv ~/.local/bin/agent ~/.local/bin/cursor-agent && grep -q "/.local/bin" ~/.zshrc || echo \'export PATH="$HOME/.local/bin:$PATH"\' >> ~/.zshrc',
|
|
124
|
+
configDir: path.join(HOME, '.cursor'),
|
|
125
|
+
commandsDir: path.join(HOME, '.cursor', 'commands'),
|
|
126
|
+
commandsSubdir: 'commands',
|
|
127
|
+
skillsDir: path.join(HOME, '.cursor', 'skills'),
|
|
128
|
+
hooksDir: 'hooks',
|
|
129
|
+
instructionsFile: '.cursorrules',
|
|
130
|
+
format: 'markdown',
|
|
131
|
+
variableSyntax: '$ARGUMENTS',
|
|
132
|
+
supportsHooks: false,
|
|
133
|
+
capabilities: { hooks: false, mcp: true, allowlist: false, skills: true, commands: true, plugins: false },
|
|
134
|
+
},
|
|
135
|
+
opencode: {
|
|
136
|
+
id: 'opencode',
|
|
137
|
+
name: 'OpenCode',
|
|
138
|
+
color: 'yellowBright',
|
|
139
|
+
cliCommand: 'opencode',
|
|
140
|
+
npmPackage: 'opencode-ai',
|
|
141
|
+
configDir: path.join(HOME, '.opencode'),
|
|
142
|
+
commandsDir: path.join(HOME, '.opencode', 'commands'),
|
|
143
|
+
commandsSubdir: 'commands',
|
|
144
|
+
skillsDir: path.join(HOME, '.opencode', 'skills'),
|
|
145
|
+
hooksDir: 'hooks',
|
|
146
|
+
instructionsFile: 'AGENTS.md',
|
|
147
|
+
format: 'markdown',
|
|
148
|
+
variableSyntax: '$ARGUMENTS',
|
|
149
|
+
supportsHooks: false,
|
|
150
|
+
capabilities: { hooks: false, mcp: true, allowlist: false, skills: true, commands: true, plugins: false },
|
|
151
|
+
},
|
|
152
|
+
openclaw: {
|
|
153
|
+
id: 'openclaw',
|
|
154
|
+
name: 'OpenClaw',
|
|
155
|
+
color: 'redBright',
|
|
156
|
+
cliCommand: 'openclaw',
|
|
157
|
+
npmPackage: 'openclaw',
|
|
158
|
+
configDir: path.join(HOME, '.openclaw'),
|
|
159
|
+
commandsDir: '', // OpenClaw uses Gateway-based slash commands, not file-based
|
|
160
|
+
commandsSubdir: '',
|
|
161
|
+
skillsDir: path.join(HOME, '.openclaw', 'skills'),
|
|
162
|
+
hooksDir: 'hooks',
|
|
163
|
+
instructionsFile: 'workspace/AGENTS.md', // Primary memory file (also has SOUL.md, IDENTITY.md, etc.)
|
|
164
|
+
format: 'markdown',
|
|
165
|
+
variableSyntax: '{{ARGUMENTS}}',
|
|
166
|
+
supportsHooks: true,
|
|
167
|
+
capabilities: { hooks: true, mcp: true, allowlist: false, skills: true, commands: false, plugins: true },
|
|
168
|
+
},
|
|
169
|
+
copilot: {
|
|
170
|
+
id: 'copilot',
|
|
171
|
+
name: 'Copilot',
|
|
172
|
+
color: 'whiteBright',
|
|
173
|
+
cliCommand: 'copilot',
|
|
174
|
+
npmPackage: '@github/copilot',
|
|
175
|
+
configDir: path.join(HOME, '.copilot'),
|
|
176
|
+
commandsDir: path.join(HOME, '.copilot', 'commands'),
|
|
177
|
+
commandsSubdir: 'commands',
|
|
178
|
+
skillsDir: path.join(HOME, '.copilot', 'skills'),
|
|
179
|
+
hooksDir: 'hooks',
|
|
180
|
+
instructionsFile: 'AGENTS.md',
|
|
181
|
+
format: 'markdown',
|
|
182
|
+
variableSyntax: '$ARGUMENTS',
|
|
183
|
+
supportsHooks: false,
|
|
184
|
+
capabilities: { hooks: false, mcp: true, allowlist: false, skills: true, commands: true, plugins: false },
|
|
185
|
+
},
|
|
186
|
+
amp: {
|
|
187
|
+
id: 'amp',
|
|
188
|
+
name: 'Amp',
|
|
189
|
+
color: 'blueBright',
|
|
190
|
+
cliCommand: 'amp',
|
|
191
|
+
npmPackage: '@sourcegraph/amp',
|
|
192
|
+
configDir: path.join(HOME, '.config', 'amp'),
|
|
193
|
+
commandsDir: path.join(HOME, '.config', 'amp', 'commands'),
|
|
194
|
+
commandsSubdir: 'commands',
|
|
195
|
+
skillsDir: path.join(HOME, '.config', 'amp', 'skills'),
|
|
196
|
+
hooksDir: 'hooks',
|
|
197
|
+
instructionsFile: 'AGENTS.md',
|
|
198
|
+
format: 'markdown',
|
|
199
|
+
variableSyntax: '$ARGUMENTS',
|
|
200
|
+
supportsHooks: false,
|
|
201
|
+
capabilities: { hooks: false, mcp: true, allowlist: false, skills: true, commands: true, plugins: false },
|
|
202
|
+
},
|
|
203
|
+
kiro: {
|
|
204
|
+
id: 'kiro',
|
|
205
|
+
name: 'Kiro',
|
|
206
|
+
color: 'greenBright',
|
|
207
|
+
cliCommand: 'kiro-cli',
|
|
208
|
+
npmPackage: '',
|
|
209
|
+
installScript: 'brew install --cask kiro-cli',
|
|
210
|
+
configDir: path.join(HOME, '.kiro'),
|
|
211
|
+
commandsDir: path.join(HOME, '.kiro', 'commands'),
|
|
212
|
+
commandsSubdir: 'commands',
|
|
213
|
+
skillsDir: path.join(HOME, '.kiro', 'skills'),
|
|
214
|
+
hooksDir: 'hooks',
|
|
215
|
+
instructionsFile: 'AGENTS.md',
|
|
216
|
+
format: 'markdown',
|
|
217
|
+
variableSyntax: '$ARGUMENTS',
|
|
218
|
+
supportsHooks: false,
|
|
219
|
+
capabilities: { hooks: false, mcp: true, allowlist: false, skills: true, commands: true, plugins: false },
|
|
220
|
+
},
|
|
221
|
+
goose: {
|
|
222
|
+
id: 'goose',
|
|
223
|
+
name: 'Goose',
|
|
224
|
+
color: 'magentaBright',
|
|
225
|
+
cliCommand: 'goose',
|
|
226
|
+
npmPackage: '',
|
|
227
|
+
installScript: 'brew install block-goose-cli',
|
|
228
|
+
configDir: path.join(HOME, '.config', 'goose'),
|
|
229
|
+
commandsDir: path.join(HOME, '.config', 'goose', 'commands'),
|
|
230
|
+
commandsSubdir: 'commands',
|
|
231
|
+
skillsDir: path.join(HOME, '.config', 'goose', 'skills'),
|
|
232
|
+
hooksDir: 'hooks',
|
|
233
|
+
instructionsFile: 'AGENTS.md',
|
|
234
|
+
format: 'markdown',
|
|
235
|
+
variableSyntax: '$ARGUMENTS',
|
|
236
|
+
supportsHooks: false,
|
|
237
|
+
capabilities: { hooks: false, mcp: true, allowlist: false, skills: false, commands: false, plugins: false },
|
|
238
|
+
},
|
|
239
|
+
roo: {
|
|
240
|
+
id: 'roo',
|
|
241
|
+
name: 'Roo Code',
|
|
242
|
+
color: 'cyanBright',
|
|
243
|
+
cliCommand: 'roo',
|
|
244
|
+
npmPackage: '',
|
|
245
|
+
installScript: 'curl -fsSL https://raw.githubusercontent.com/RooCodeInc/Roo-Code/main/apps/cli/install.sh | sh',
|
|
246
|
+
configDir: path.join(HOME, '.roo'),
|
|
247
|
+
commandsDir: path.join(HOME, '.roo', 'commands'),
|
|
248
|
+
commandsSubdir: 'commands',
|
|
249
|
+
skillsDir: path.join(HOME, '.roo', 'skills'),
|
|
250
|
+
hooksDir: 'hooks',
|
|
251
|
+
instructionsFile: 'AGENTS.md',
|
|
252
|
+
format: 'markdown',
|
|
253
|
+
variableSyntax: '$ARGUMENTS',
|
|
254
|
+
supportsHooks: false,
|
|
255
|
+
capabilities: { hooks: false, mcp: true, allowlist: false, skills: true, commands: true, plugins: false },
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
export const ALL_AGENT_IDS = Object.keys(AGENTS);
|
|
259
|
+
export const MCP_CAPABLE_AGENTS = ALL_AGENT_IDS.filter((id) => AGENTS[id].capabilities.mcp);
|
|
260
|
+
export const SKILLS_CAPABLE_AGENTS = ALL_AGENT_IDS.filter((id) => AGENTS[id].capabilities.skills);
|
|
261
|
+
export const COMMANDS_CAPABLE_AGENTS = ALL_AGENT_IDS.filter((id) => AGENTS[id].capabilities.commands);
|
|
262
|
+
export const HOOKS_CAPABLE_AGENTS = ['claude', 'codex', 'gemini', 'openclaw'];
|
|
263
|
+
export const PLUGINS_CAPABLE_AGENTS = ALL_AGENT_IDS.filter((id) => AGENTS[id].capabilities.plugins);
|
|
264
|
+
/** Get the chalk color function for an agent. Works for any AgentId or SessionAgentId. */
|
|
265
|
+
export function colorAgent(agentId) {
|
|
266
|
+
const agent = AGENTS[agentId];
|
|
267
|
+
if (!agent)
|
|
268
|
+
return chalk.white;
|
|
269
|
+
return chalk[agent.color];
|
|
270
|
+
}
|
|
271
|
+
/** Return the agent's display name, colored. */
|
|
272
|
+
export function agentLabel(agentId) {
|
|
273
|
+
const agent = AGENTS[agentId];
|
|
274
|
+
if (!agent)
|
|
275
|
+
return agentId;
|
|
276
|
+
return chalk[agent.color](agent.name);
|
|
277
|
+
}
|
|
278
|
+
export async function isCliInstalled(agentId) {
|
|
279
|
+
const agent = AGENTS[agentId];
|
|
280
|
+
return findInPath(agent.cliCommand) !== null;
|
|
281
|
+
}
|
|
282
|
+
export async function getCliVersion(agentId) {
|
|
283
|
+
const agent = AGENTS[agentId];
|
|
284
|
+
const binaryPath = findInPath(agent.cliCommand);
|
|
285
|
+
if (!binaryPath)
|
|
286
|
+
return null;
|
|
287
|
+
return getCachedVersionForBinary(agentId, binaryPath);
|
|
288
|
+
}
|
|
289
|
+
export async function getCliPath(agentId) {
|
|
290
|
+
return findInPath(AGENTS[agentId].cliCommand);
|
|
291
|
+
}
|
|
292
|
+
/** Look up version from cache by (binary, mtime). On miss or stale, spawn `--version` and cache. */
|
|
293
|
+
async function getCachedVersionForBinary(agentId, binaryPath) {
|
|
294
|
+
let mtime = 0;
|
|
295
|
+
try {
|
|
296
|
+
mtime = fs.statSync(binaryPath).mtimeMs;
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
/* binary vanished between findInPath and statSync */
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
const cache = loadCliVersionCache();
|
|
303
|
+
const cached = cache[agentId];
|
|
304
|
+
if (cached && cached.binaryPath === binaryPath && cached.mtime === mtime) {
|
|
305
|
+
return cached.version;
|
|
306
|
+
}
|
|
307
|
+
const agent = AGENTS[agentId];
|
|
308
|
+
let version = null;
|
|
309
|
+
try {
|
|
310
|
+
const { stdout } = await execAsync(`${agent.cliCommand} --version`, { timeout: 3000 });
|
|
311
|
+
if (agentId === 'openclaw') {
|
|
312
|
+
const match = stdout.match(/openclaw\/(\d+\.\d+\.\d+)/);
|
|
313
|
+
version = match ? match[1] : stdout.trim();
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
const match = stdout.match(/(\d+\.\d+\.\d+)/);
|
|
317
|
+
version = match ? match[1] : stdout.trim();
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
catch {
|
|
321
|
+
/* version command failed */
|
|
322
|
+
version = null;
|
|
323
|
+
}
|
|
324
|
+
cache[agentId] = { binaryPath, mtime, version };
|
|
325
|
+
saveCliVersionCache();
|
|
326
|
+
return version;
|
|
327
|
+
}
|
|
328
|
+
export async function getCliState(agentId) {
|
|
329
|
+
// Fast path: if version-managed, derive state from filesystem (no subprocesses)
|
|
330
|
+
const agent = AGENTS[agentId];
|
|
331
|
+
const agentVersionsDir = path.join(getVersionsDir(), agentId);
|
|
332
|
+
if (fs.existsSync(agentVersionsDir)) {
|
|
333
|
+
// Use resolved version (project manifest -> global default)
|
|
334
|
+
const resolvedVer = resolveVersion(agentId, process.cwd());
|
|
335
|
+
if (resolvedVer) {
|
|
336
|
+
const binaryPath = path.join(agentVersionsDir, resolvedVer, 'node_modules', '.bin', agent.cliCommand);
|
|
337
|
+
if (fs.existsSync(binaryPath)) {
|
|
338
|
+
const shimPath = path.join(getShimsDir(), agent.cliCommand);
|
|
339
|
+
return {
|
|
340
|
+
installed: true,
|
|
341
|
+
version: resolvedVer,
|
|
342
|
+
path: fs.existsSync(shimPath) ? shimPath : binaryPath,
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
// Fallback: if no default set or resolved version not installed, return first available
|
|
347
|
+
const entries = fs.readdirSync(agentVersionsDir, { withFileTypes: true });
|
|
348
|
+
for (const entry of entries) {
|
|
349
|
+
if (entry.isDirectory()) {
|
|
350
|
+
const binaryPath = path.join(agentVersionsDir, entry.name, 'node_modules', '.bin', agent.cliCommand);
|
|
351
|
+
if (fs.existsSync(binaryPath)) {
|
|
352
|
+
const shimPath = path.join(getShimsDir(), agent.cliCommand);
|
|
353
|
+
return {
|
|
354
|
+
installed: true,
|
|
355
|
+
version: entry.name,
|
|
356
|
+
path: fs.existsSync(shimPath) ? shimPath : binaryPath,
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
// Non-version-managed: single PATH lookup + cached version read
|
|
363
|
+
const binaryPath = findInPath(agent.cliCommand);
|
|
364
|
+
if (!binaryPath) {
|
|
365
|
+
return { installed: false, version: null, path: null };
|
|
366
|
+
}
|
|
367
|
+
return {
|
|
368
|
+
installed: true,
|
|
369
|
+
version: await getCachedVersionForBinary(agentId, binaryPath),
|
|
370
|
+
path: binaryPath,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
export async function getAllCliStates() {
|
|
374
|
+
const states = {};
|
|
375
|
+
const results = await Promise.all(ALL_AGENT_IDS.map(async (agentId) => ({
|
|
376
|
+
agentId,
|
|
377
|
+
state: await getCliState(agentId),
|
|
378
|
+
})));
|
|
379
|
+
for (const { agentId, state } of results) {
|
|
380
|
+
states[agentId] = state;
|
|
381
|
+
}
|
|
382
|
+
return states;
|
|
383
|
+
}
|
|
384
|
+
export function isConfigured(agentId) {
|
|
385
|
+
const agent = AGENTS[agentId];
|
|
386
|
+
return fs.existsSync(agent.configDir);
|
|
387
|
+
}
|
|
388
|
+
export function ensureCommandsDir(agentId) {
|
|
389
|
+
const agent = AGENTS[agentId];
|
|
390
|
+
if (!fs.existsSync(agent.commandsDir)) {
|
|
391
|
+
fs.mkdirSync(agent.commandsDir, { recursive: true });
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
export function ensureSkillsDir(agentId) {
|
|
395
|
+
const agent = AGENTS[agentId];
|
|
396
|
+
if (!fs.existsSync(agent.skillsDir)) {
|
|
397
|
+
fs.mkdirSync(agent.skillsDir, { recursive: true });
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
export async function getAccountEmail(agentId, home) {
|
|
401
|
+
const info = await getAccountInfo(agentId, home);
|
|
402
|
+
return info.email;
|
|
403
|
+
}
|
|
404
|
+
export async function getAccountInfo(agentId, home) {
|
|
405
|
+
const base = home || os.homedir();
|
|
406
|
+
const empty = {
|
|
407
|
+
accountKey: null,
|
|
408
|
+
usageKey: null,
|
|
409
|
+
accountId: null,
|
|
410
|
+
organizationId: null,
|
|
411
|
+
userId: null,
|
|
412
|
+
email: null,
|
|
413
|
+
plan: null,
|
|
414
|
+
usageStatus: null,
|
|
415
|
+
overageCredits: null,
|
|
416
|
+
lastActive: null,
|
|
417
|
+
};
|
|
418
|
+
const configFiles = {
|
|
419
|
+
claude: path.join(base, '.claude.json'),
|
|
420
|
+
codex: path.join(base, '.codex', 'auth.json'),
|
|
421
|
+
gemini: path.join(base, '.gemini', 'google_accounts.json'),
|
|
422
|
+
};
|
|
423
|
+
const lastActive = resolveLastActive(agentId, base, configFiles[agentId]);
|
|
424
|
+
try {
|
|
425
|
+
switch (agentId) {
|
|
426
|
+
case 'claude': {
|
|
427
|
+
// Claude reads/writes config at $CLAUDE_CONFIG_DIR/.claude.json when set,
|
|
428
|
+
// falling back to $HOME/.claude.json. Our shim sets CLAUDE_CONFIG_DIR to
|
|
429
|
+
// the per-version .claude dir, so prefer that file; fall back to home-level
|
|
430
|
+
// for versions ever launched without the shim (IDE extension, direct binary).
|
|
431
|
+
const configDirFile = path.join(base, '.claude', '.claude.json');
|
|
432
|
+
const homeLevelFile = path.join(base, '.claude.json');
|
|
433
|
+
const activeFile = fs.existsSync(configDirFile) ? configDirFile : homeLevelFile;
|
|
434
|
+
const data = JSON.parse(await fs.promises.readFile(activeFile, 'utf-8'));
|
|
435
|
+
const oa = data.oauthAccount;
|
|
436
|
+
const accountId = normalizeIdentityPart(oa?.accountUuid);
|
|
437
|
+
const organizationId = normalizeIdentityPart(oa?.organizationUuid);
|
|
438
|
+
const email = oa?.emailAddress || null;
|
|
439
|
+
const accountKey = buildIdentityKey(agentId, [
|
|
440
|
+
['account', accountId],
|
|
441
|
+
['org', organizationId],
|
|
442
|
+
]);
|
|
443
|
+
const usageKey = buildIdentityKey(agentId, [['org', organizationId]]);
|
|
444
|
+
let plan = null;
|
|
445
|
+
const keychainOauth = await loadClaudeOauth(home);
|
|
446
|
+
if (keychainOauth?.subscriptionType) {
|
|
447
|
+
plan = keychainOauth.subscriptionType.charAt(0).toUpperCase()
|
|
448
|
+
+ keychainOauth.subscriptionType.slice(1);
|
|
449
|
+
}
|
|
450
|
+
else if (oa?.billingType === 'stripe_subscription') {
|
|
451
|
+
plan = 'Pro';
|
|
452
|
+
}
|
|
453
|
+
else if (oa?.billingType) {
|
|
454
|
+
plan = oa.billingType;
|
|
455
|
+
}
|
|
456
|
+
let usageStatus = null;
|
|
457
|
+
const reason = data.cachedExtraUsageDisabledReason;
|
|
458
|
+
if (reason === 'out_of_credits')
|
|
459
|
+
usageStatus = 'out_of_credits';
|
|
460
|
+
else if (reason)
|
|
461
|
+
usageStatus = 'rate_limited';
|
|
462
|
+
else
|
|
463
|
+
usageStatus = 'available';
|
|
464
|
+
let overageCredits = null;
|
|
465
|
+
const orgId = oa?.organizationUuid;
|
|
466
|
+
const creditCache = orgId && data.overageCreditGrantCache?.[orgId];
|
|
467
|
+
if (creditCache?.info?.available && creditCache.info.amount_minor_units) {
|
|
468
|
+
overageCredits = {
|
|
469
|
+
amount: creditCache.info.amount_minor_units / 100,
|
|
470
|
+
currency: creditCache.info.currency || 'USD',
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
return {
|
|
474
|
+
accountKey,
|
|
475
|
+
usageKey,
|
|
476
|
+
accountId,
|
|
477
|
+
organizationId,
|
|
478
|
+
userId: null,
|
|
479
|
+
email,
|
|
480
|
+
plan,
|
|
481
|
+
usageStatus,
|
|
482
|
+
overageCredits,
|
|
483
|
+
lastActive,
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
case 'codex': {
|
|
487
|
+
const data = JSON.parse(await fs.promises.readFile(path.join(base, '.codex', 'auth.json'), 'utf-8'));
|
|
488
|
+
const token = data.tokens?.id_token || data.tokens?.access_token;
|
|
489
|
+
if (!token)
|
|
490
|
+
return { ...empty, lastActive };
|
|
491
|
+
const decoded = decodeJwtPayload(token);
|
|
492
|
+
if (!decoded)
|
|
493
|
+
return { ...empty, lastActive };
|
|
494
|
+
const email = decoded.email || null;
|
|
495
|
+
// Plan and subscription from OpenAI auth claim
|
|
496
|
+
const authClaim = decoded['https://api.openai.com/auth'] || {};
|
|
497
|
+
const accountId = normalizeIdentityPart(authClaim.chatgpt_account_id);
|
|
498
|
+
const userId = normalizeIdentityPart(authClaim.chatgpt_user_id || authClaim.user_id);
|
|
499
|
+
const organizationId = normalizeIdentityPart(getCodexDefaultOrgId(authClaim));
|
|
500
|
+
const accountKey = buildIdentityKey(agentId, [
|
|
501
|
+
['account', accountId],
|
|
502
|
+
['user', userId],
|
|
503
|
+
['org', organizationId],
|
|
504
|
+
]);
|
|
505
|
+
const rawPlan = authClaim.chatgpt_plan_type;
|
|
506
|
+
const plan = rawPlan ? rawPlan.charAt(0).toUpperCase() + rawPlan.slice(1) : null;
|
|
507
|
+
// Subscription status: expired = out_of_credits
|
|
508
|
+
let usageStatus = null;
|
|
509
|
+
const activeUntil = authClaim.chatgpt_subscription_active_until;
|
|
510
|
+
if (activeUntil) {
|
|
511
|
+
const expired = new Date(activeUntil).getTime() < Date.now();
|
|
512
|
+
usageStatus = expired ? 'out_of_credits' : 'available';
|
|
513
|
+
}
|
|
514
|
+
return {
|
|
515
|
+
accountKey,
|
|
516
|
+
usageKey: accountKey,
|
|
517
|
+
accountId,
|
|
518
|
+
organizationId,
|
|
519
|
+
userId,
|
|
520
|
+
email,
|
|
521
|
+
plan,
|
|
522
|
+
usageStatus,
|
|
523
|
+
overageCredits: null,
|
|
524
|
+
lastActive,
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
case 'gemini': {
|
|
528
|
+
const data = JSON.parse(await fs.promises.readFile(path.join(base, '.gemini', 'google_accounts.json'), 'utf-8'));
|
|
529
|
+
return { ...empty, email: data.active || null, lastActive };
|
|
530
|
+
}
|
|
531
|
+
default:
|
|
532
|
+
return { ...empty, lastActive };
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
catch {
|
|
536
|
+
/* auth/config file missing or unreadable */
|
|
537
|
+
return { ...empty, lastActive };
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
function resolveLastActive(agentId, base, configPath) {
|
|
541
|
+
const sessionDir = getSessionDir(agentId, base);
|
|
542
|
+
const sessionExt = getSessionExtension(agentId);
|
|
543
|
+
if (sessionDir && sessionExt) {
|
|
544
|
+
const latestSession = getLatestFileMtime(sessionDir, sessionExt);
|
|
545
|
+
if (latestSession) {
|
|
546
|
+
return latestSession;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
if (!configPath)
|
|
550
|
+
return null;
|
|
551
|
+
try {
|
|
552
|
+
return fs.statSync(configPath).mtime;
|
|
553
|
+
}
|
|
554
|
+
catch {
|
|
555
|
+
return null;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
function getSessionDir(agentId, base) {
|
|
559
|
+
switch (agentId) {
|
|
560
|
+
case 'claude':
|
|
561
|
+
return path.join(base, '.claude', 'projects');
|
|
562
|
+
case 'codex':
|
|
563
|
+
return path.join(base, '.codex', 'sessions');
|
|
564
|
+
case 'gemini':
|
|
565
|
+
return path.join(base, '.gemini', 'tmp');
|
|
566
|
+
default:
|
|
567
|
+
return null;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
function getSessionExtension(agentId) {
|
|
571
|
+
switch (agentId) {
|
|
572
|
+
case 'claude':
|
|
573
|
+
case 'codex':
|
|
574
|
+
return '.jsonl';
|
|
575
|
+
case 'gemini':
|
|
576
|
+
return '.json';
|
|
577
|
+
default:
|
|
578
|
+
return null;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
function getLatestFileMtime(dir, ext) {
|
|
582
|
+
if (!fs.existsSync(dir))
|
|
583
|
+
return null;
|
|
584
|
+
const [latest] = walkForFiles(dir, ext, 1);
|
|
585
|
+
if (!latest)
|
|
586
|
+
return null;
|
|
587
|
+
try {
|
|
588
|
+
return fs.statSync(latest).mtime;
|
|
589
|
+
}
|
|
590
|
+
catch {
|
|
591
|
+
return null;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
function decodeJwtPayload(token) {
|
|
595
|
+
const payload = token.split('.')[1];
|
|
596
|
+
if (!payload)
|
|
597
|
+
return null;
|
|
598
|
+
try {
|
|
599
|
+
return JSON.parse(Buffer.from(payload, 'base64url').toString());
|
|
600
|
+
}
|
|
601
|
+
catch {
|
|
602
|
+
return null;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
function getCodexDefaultOrgId(authClaim) {
|
|
606
|
+
const organizations = authClaim?.organizations;
|
|
607
|
+
if (!Array.isArray(organizations))
|
|
608
|
+
return null;
|
|
609
|
+
const first = organizations[0];
|
|
610
|
+
return typeof first?.id === 'string' ? first.id : null;
|
|
611
|
+
}
|
|
612
|
+
function normalizeIdentityPart(value) {
|
|
613
|
+
if (typeof value !== 'string')
|
|
614
|
+
return null;
|
|
615
|
+
const trimmed = value.trim();
|
|
616
|
+
return trimmed || null;
|
|
617
|
+
}
|
|
618
|
+
function buildIdentityKey(agentId, parts) {
|
|
619
|
+
const encoded = parts
|
|
620
|
+
.filter(([, value]) => value)
|
|
621
|
+
.map(([label, value]) => `${label}=${value}`);
|
|
622
|
+
if (encoded.length === 0)
|
|
623
|
+
return null;
|
|
624
|
+
return `${agentId}:${encoded.join(':')}`;
|
|
625
|
+
}
|
|
626
|
+
export async function isMcpRegistered(agentId, mcpName) {
|
|
627
|
+
const agent = AGENTS[agentId];
|
|
628
|
+
if (!agent.capabilities.mcp || !(await isCliInstalled(agentId))) {
|
|
629
|
+
return false;
|
|
630
|
+
}
|
|
631
|
+
try {
|
|
632
|
+
const { stdout } = await execAsync(`${agent.cliCommand} mcp list`);
|
|
633
|
+
return stdout.toLowerCase().includes(mcpName.toLowerCase());
|
|
634
|
+
}
|
|
635
|
+
catch {
|
|
636
|
+
/* mcp list command failed */
|
|
637
|
+
return false;
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
export async function registerMcp(agentId, name, command, scope = 'user', transport = 'stdio', options) {
|
|
641
|
+
const agent = AGENTS[agentId];
|
|
642
|
+
if (!agent.capabilities.mcp) {
|
|
643
|
+
return { success: false, error: 'Agent does not support MCP' };
|
|
644
|
+
}
|
|
645
|
+
if (!options?.binary && !(await isCliInstalled(agentId))) {
|
|
646
|
+
return { success: false, error: 'CLI not installed' };
|
|
647
|
+
}
|
|
648
|
+
try {
|
|
649
|
+
// Use explicit binary path when provided (bypasses shim for version-managed agents)
|
|
650
|
+
const bin = options?.binary || agent.cliCommand;
|
|
651
|
+
let cmd;
|
|
652
|
+
if (agentId === 'claude') {
|
|
653
|
+
cmd = `${bin} mcp add --transport ${transport} --scope ${scope} "${name}" -- ${command}`;
|
|
654
|
+
}
|
|
655
|
+
else {
|
|
656
|
+
cmd = `${bin} mcp add "${name}" -- ${command}`;
|
|
657
|
+
}
|
|
658
|
+
// When home is specified, override HOME so MCP config writes to the version's config dir
|
|
659
|
+
const env = options?.home ? { ...process.env, HOME: options.home } : undefined;
|
|
660
|
+
await execAsync(cmd, env ? { env } : undefined);
|
|
661
|
+
return { success: true };
|
|
662
|
+
}
|
|
663
|
+
catch (err) {
|
|
664
|
+
return { success: false, error: err.message };
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
export async function unregisterMcp(agentId, name, options) {
|
|
668
|
+
const agent = AGENTS[agentId];
|
|
669
|
+
if (!agent.capabilities.mcp) {
|
|
670
|
+
return { success: false, error: 'Agent does not support MCP' };
|
|
671
|
+
}
|
|
672
|
+
if (!options?.binary && !(await isCliInstalled(agentId))) {
|
|
673
|
+
return { success: false, error: 'CLI not installed' };
|
|
674
|
+
}
|
|
675
|
+
try {
|
|
676
|
+
const bin = options?.binary || agent.cliCommand;
|
|
677
|
+
const env = options?.home ? { ...process.env, HOME: options.home } : undefined;
|
|
678
|
+
await execAsync(`${bin} mcp remove "${name}"`, env ? { env } : undefined);
|
|
679
|
+
return { success: true };
|
|
680
|
+
}
|
|
681
|
+
catch (err) {
|
|
682
|
+
return { success: false, error: err.message };
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
export async function registerMcpToTargets(targets, name, command, scope = 'user', transport = 'stdio') {
|
|
686
|
+
const results = [];
|
|
687
|
+
for (const agentId of targets.directAgents) {
|
|
688
|
+
const result = await registerMcp(agentId, name, command, scope, transport);
|
|
689
|
+
results.push({ agentId, success: result.success, error: result.error });
|
|
690
|
+
}
|
|
691
|
+
for (const [agentId, versions] of targets.versionSelections) {
|
|
692
|
+
for (const version of versions) {
|
|
693
|
+
const result = await registerMcp(agentId, name, command, scope, transport, {
|
|
694
|
+
home: getVersionHomePath(agentId, version),
|
|
695
|
+
binary: getBinaryPath(agentId, version),
|
|
696
|
+
});
|
|
697
|
+
results.push({ agentId, version, success: result.success, error: result.error });
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
return results;
|
|
701
|
+
}
|
|
702
|
+
export async function unregisterMcpFromTargets(targets, name) {
|
|
703
|
+
const results = [];
|
|
704
|
+
for (const agentId of targets.directAgents) {
|
|
705
|
+
const result = await unregisterMcp(agentId, name);
|
|
706
|
+
results.push({ agentId, success: result.success, error: result.error });
|
|
707
|
+
}
|
|
708
|
+
for (const [agentId, versions] of targets.versionSelections) {
|
|
709
|
+
for (const version of versions) {
|
|
710
|
+
const result = await unregisterMcp(agentId, name, {
|
|
711
|
+
home: getVersionHomePath(agentId, version),
|
|
712
|
+
binary: getBinaryPath(agentId, version),
|
|
713
|
+
});
|
|
714
|
+
results.push({ agentId, version, success: result.success, error: result.error });
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
return results;
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* Extract version from npm package specification.
|
|
721
|
+
* Examples: @swarmify/agents-mcp@latest -> latest
|
|
722
|
+
* @swarmify/agents-mcp@1.2.3 -> 1.2.3
|
|
723
|
+
* some-package -> undefined
|
|
724
|
+
*/
|
|
725
|
+
function extractNpmVersion(args) {
|
|
726
|
+
// Find npm package argument (looks like @scope/package@version or package@version)
|
|
727
|
+
for (const arg of args) {
|
|
728
|
+
// Match @scope/package@version or package@version
|
|
729
|
+
const match = arg.match(/@([^@]+)$|^([^@]+)@(.+)$/);
|
|
730
|
+
if (match) {
|
|
731
|
+
// @scope/package@version pattern
|
|
732
|
+
const versionMatch = arg.match(/@([^@/]+)$/);
|
|
733
|
+
if (versionMatch) {
|
|
734
|
+
return versionMatch[1];
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
return undefined;
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Strip JSON comments for JSONC parsing.
|
|
742
|
+
* Only removes comments outside of strings.
|
|
743
|
+
*/
|
|
744
|
+
function stripJsonComments(content) {
|
|
745
|
+
let result = '';
|
|
746
|
+
let inString = false;
|
|
747
|
+
let escape = false;
|
|
748
|
+
let i = 0;
|
|
749
|
+
while (i < content.length) {
|
|
750
|
+
const char = content[i];
|
|
751
|
+
const next = content[i + 1];
|
|
752
|
+
if (escape) {
|
|
753
|
+
result += char;
|
|
754
|
+
escape = false;
|
|
755
|
+
i++;
|
|
756
|
+
continue;
|
|
757
|
+
}
|
|
758
|
+
if (char === '\\' && inString) {
|
|
759
|
+
result += char;
|
|
760
|
+
escape = true;
|
|
761
|
+
i++;
|
|
762
|
+
continue;
|
|
763
|
+
}
|
|
764
|
+
if (char === '"') {
|
|
765
|
+
inString = !inString;
|
|
766
|
+
result += char;
|
|
767
|
+
i++;
|
|
768
|
+
continue;
|
|
769
|
+
}
|
|
770
|
+
if (!inString) {
|
|
771
|
+
// Check for single-line comment
|
|
772
|
+
if (char === '/' && next === '/') {
|
|
773
|
+
// Skip until end of line
|
|
774
|
+
while (i < content.length && content[i] !== '\n') {
|
|
775
|
+
i++;
|
|
776
|
+
}
|
|
777
|
+
continue;
|
|
778
|
+
}
|
|
779
|
+
// Check for multi-line comment
|
|
780
|
+
if (char === '/' && next === '*') {
|
|
781
|
+
i += 2;
|
|
782
|
+
while (i < content.length && !(content[i] === '*' && content[i + 1] === '/')) {
|
|
783
|
+
i++;
|
|
784
|
+
}
|
|
785
|
+
i += 2; // Skip */
|
|
786
|
+
continue;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
result += char;
|
|
790
|
+
i++;
|
|
791
|
+
}
|
|
792
|
+
return result;
|
|
793
|
+
}
|
|
794
|
+
/**
|
|
795
|
+
* Parse MCP servers from a JSON/JSONC config file.
|
|
796
|
+
*/
|
|
797
|
+
function parseMcpFromJsonConfig(configPath) {
|
|
798
|
+
if (!fs.existsSync(configPath)) {
|
|
799
|
+
return {};
|
|
800
|
+
}
|
|
801
|
+
try {
|
|
802
|
+
let content = fs.readFileSync(configPath, 'utf-8');
|
|
803
|
+
// Handle JSONC (JSON with comments)
|
|
804
|
+
if (configPath.endsWith('.jsonc')) {
|
|
805
|
+
content = stripJsonComments(content);
|
|
806
|
+
}
|
|
807
|
+
const config = JSON.parse(content);
|
|
808
|
+
// Claude uses mcpServers, others may use mcp_servers or mcp
|
|
809
|
+
return config.mcpServers || config.mcp_servers || config.mcp || {};
|
|
810
|
+
}
|
|
811
|
+
catch {
|
|
812
|
+
/* JSON config corrupt or unreadable */
|
|
813
|
+
return {};
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* Parse MCP servers from a TOML config file (Codex).
|
|
818
|
+
* Codex stores MCPs as [mcp_servers.ServerName] sections.
|
|
819
|
+
*/
|
|
820
|
+
function parseMcpFromTomlConfig(configPath) {
|
|
821
|
+
if (!fs.existsSync(configPath)) {
|
|
822
|
+
return {};
|
|
823
|
+
}
|
|
824
|
+
try {
|
|
825
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
826
|
+
const config = TOML.parse(content);
|
|
827
|
+
// Codex uses mcp_servers as a table with server names as keys
|
|
828
|
+
const mcpServers = config.mcp_servers;
|
|
829
|
+
return mcpServers || {};
|
|
830
|
+
}
|
|
831
|
+
catch {
|
|
832
|
+
/* TOML config corrupt or unreadable */
|
|
833
|
+
return {};
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
/**
|
|
837
|
+
* Parse MCP servers from OpenCode's JSONC config.
|
|
838
|
+
* OpenCode stores MCPs in the "mcp" object with different structure.
|
|
839
|
+
*/
|
|
840
|
+
function parseMcpFromOpenCodeConfig(configPath) {
|
|
841
|
+
if (!fs.existsSync(configPath)) {
|
|
842
|
+
return {};
|
|
843
|
+
}
|
|
844
|
+
try {
|
|
845
|
+
const content = stripJsonComments(fs.readFileSync(configPath, 'utf-8'));
|
|
846
|
+
const config = JSON.parse(content);
|
|
847
|
+
const mcpConfig = config.mcp;
|
|
848
|
+
if (!mcpConfig)
|
|
849
|
+
return {};
|
|
850
|
+
// Convert OpenCode format to our McpConfigEntry format
|
|
851
|
+
const result = {};
|
|
852
|
+
for (const [name, entry] of Object.entries(mcpConfig)) {
|
|
853
|
+
if (entry.type === 'local' && entry.command) {
|
|
854
|
+
// Local MCP: command is an array like ["npx", "-y", "@pkg@version"]
|
|
855
|
+
result[name] = {
|
|
856
|
+
command: entry.command[0],
|
|
857
|
+
args: entry.command.slice(1),
|
|
858
|
+
};
|
|
859
|
+
}
|
|
860
|
+
else if (entry.type === 'remote' && entry.url) {
|
|
861
|
+
// Remote MCP: HTTP URL
|
|
862
|
+
result[name] = {
|
|
863
|
+
url: entry.url,
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
return result;
|
|
868
|
+
}
|
|
869
|
+
catch {
|
|
870
|
+
/* OpenCode JSONC config corrupt or unreadable */
|
|
871
|
+
return {};
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
* Get user-scoped MCP config path for an agent.
|
|
876
|
+
*/
|
|
877
|
+
function getUserMcpConfigPath(agentId) {
|
|
878
|
+
const agent = AGENTS[agentId];
|
|
879
|
+
switch (agentId) {
|
|
880
|
+
case 'claude':
|
|
881
|
+
// Claude user-scoped MCPs are in ~/.claude.json (global user config)
|
|
882
|
+
return path.join(HOME, '.claude.json');
|
|
883
|
+
case 'codex':
|
|
884
|
+
// Codex uses TOML config
|
|
885
|
+
return path.join(agent.configDir, 'config.toml');
|
|
886
|
+
case 'opencode':
|
|
887
|
+
// OpenCode uses JSONC config
|
|
888
|
+
return path.join(agent.configDir, 'opencode.jsonc');
|
|
889
|
+
case 'cursor':
|
|
890
|
+
// Cursor uses mcp.json
|
|
891
|
+
return path.join(agent.configDir, 'mcp.json');
|
|
892
|
+
case 'openclaw':
|
|
893
|
+
// OpenClaw uses openclaw.json
|
|
894
|
+
return path.join(agent.configDir, 'openclaw.json');
|
|
895
|
+
default:
|
|
896
|
+
// Gemini and others use settings.json
|
|
897
|
+
return path.join(agent.configDir, 'settings.json');
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
/**
|
|
901
|
+
* Get MCP config path for a specific HOME directory (used for version-managed agents).
|
|
902
|
+
*/
|
|
903
|
+
export function getMcpConfigPathForHome(agentId, home) {
|
|
904
|
+
switch (agentId) {
|
|
905
|
+
case 'claude':
|
|
906
|
+
return path.join(home, '.claude.json');
|
|
907
|
+
case 'codex':
|
|
908
|
+
return path.join(home, '.codex', 'config.toml');
|
|
909
|
+
case 'opencode':
|
|
910
|
+
return path.join(home, '.opencode', 'opencode.jsonc');
|
|
911
|
+
case 'cursor':
|
|
912
|
+
return path.join(home, '.cursor', 'mcp.json');
|
|
913
|
+
case 'openclaw':
|
|
914
|
+
return path.join(home, '.openclaw', 'openclaw.json');
|
|
915
|
+
case 'copilot':
|
|
916
|
+
return path.join(home, '.copilot', 'mcp-config.json');
|
|
917
|
+
case 'amp':
|
|
918
|
+
return path.join(home, '.config', 'amp', 'settings.json');
|
|
919
|
+
case 'kiro':
|
|
920
|
+
return path.join(home, '.kiro', 'settings', 'mcp.json');
|
|
921
|
+
case 'goose':
|
|
922
|
+
return path.join(home, '.config', 'goose', 'config.yaml');
|
|
923
|
+
case 'roo':
|
|
924
|
+
return path.join(home, '.roo', 'mcp.json');
|
|
925
|
+
default:
|
|
926
|
+
return path.join(home, `.${agentId}`, 'settings.json');
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
/**
|
|
930
|
+
* Get project-scoped MCP config path for an agent.
|
|
931
|
+
*/
|
|
932
|
+
function getProjectMcpConfigPath(agentId, cwd = process.cwd()) {
|
|
933
|
+
switch (agentId) {
|
|
934
|
+
case 'claude':
|
|
935
|
+
// Claude uses .mcp.json at project root for project-scoped MCPs
|
|
936
|
+
return path.join(cwd, '.mcp.json');
|
|
937
|
+
case 'codex':
|
|
938
|
+
return path.join(cwd, `.${agentId}`, 'config.toml');
|
|
939
|
+
case 'opencode':
|
|
940
|
+
return path.join(cwd, `.${agentId}`, 'opencode.jsonc');
|
|
941
|
+
case 'cursor':
|
|
942
|
+
return path.join(cwd, `.${agentId}`, 'mcp.json');
|
|
943
|
+
case 'openclaw':
|
|
944
|
+
return path.join(cwd, `.${agentId}`, 'openclaw.json');
|
|
945
|
+
case 'gemini':
|
|
946
|
+
return path.join(cwd, `.${agentId}`, 'settings.json');
|
|
947
|
+
case 'copilot':
|
|
948
|
+
return path.join(cwd, '.copilot', 'mcp-config.json');
|
|
949
|
+
case 'amp':
|
|
950
|
+
return path.join(cwd, '.amp', 'settings.json');
|
|
951
|
+
case 'kiro':
|
|
952
|
+
return path.join(cwd, '.kiro', 'settings', 'mcp.json');
|
|
953
|
+
case 'goose':
|
|
954
|
+
return path.join(cwd, '.goose', 'config.yaml');
|
|
955
|
+
case 'roo':
|
|
956
|
+
return path.join(cwd, '.roo', 'mcp.json');
|
|
957
|
+
default:
|
|
958
|
+
return path.join(cwd, `.${agentId}`, 'settings.json');
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
/**
|
|
962
|
+
* Parse MCP servers from OpenClaw's JSON config.
|
|
963
|
+
* OpenClaw stores MCPs under mcp.servers with a similar structure to other agents.
|
|
964
|
+
*/
|
|
965
|
+
function parseMcpFromOpenClawConfig(configPath) {
|
|
966
|
+
if (!fs.existsSync(configPath)) {
|
|
967
|
+
return {};
|
|
968
|
+
}
|
|
969
|
+
try {
|
|
970
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
971
|
+
const config = JSON.parse(content);
|
|
972
|
+
// OpenClaw uses mcp.servers for MCP configuration
|
|
973
|
+
const mcpServers = config.mcp?.servers;
|
|
974
|
+
if (!mcpServers)
|
|
975
|
+
return {};
|
|
976
|
+
const result = {};
|
|
977
|
+
for (const [name, entry] of Object.entries(mcpServers)) {
|
|
978
|
+
if (entry.command) {
|
|
979
|
+
result[name] = {
|
|
980
|
+
command: entry.command,
|
|
981
|
+
args: entry.args,
|
|
982
|
+
env: entry.env,
|
|
983
|
+
};
|
|
984
|
+
}
|
|
985
|
+
else if (entry.url) {
|
|
986
|
+
result[name] = {
|
|
987
|
+
url: entry.url,
|
|
988
|
+
type: entry.transport || 'sse',
|
|
989
|
+
};
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
return result;
|
|
993
|
+
}
|
|
994
|
+
catch {
|
|
995
|
+
/* OpenClaw JSON config corrupt or unreadable */
|
|
996
|
+
return {};
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
/**
|
|
1000
|
+
* Parse MCP config based on agent type.
|
|
1001
|
+
*/
|
|
1002
|
+
export function parseMcpConfig(agentId, configPath) {
|
|
1003
|
+
switch (agentId) {
|
|
1004
|
+
case 'codex':
|
|
1005
|
+
return parseMcpFromTomlConfig(configPath);
|
|
1006
|
+
case 'opencode':
|
|
1007
|
+
return parseMcpFromOpenCodeConfig(configPath);
|
|
1008
|
+
case 'openclaw':
|
|
1009
|
+
return parseMcpFromOpenClawConfig(configPath);
|
|
1010
|
+
default:
|
|
1011
|
+
return parseMcpFromJsonConfig(configPath);
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
/**
|
|
1015
|
+
* List installed MCP servers with scope information.
|
|
1016
|
+
* Pass options.home to read from a version-managed agent's home directory.
|
|
1017
|
+
*/
|
|
1018
|
+
export function listInstalledMcpsWithScope(agentId, cwd = process.cwd(), options) {
|
|
1019
|
+
const results = [];
|
|
1020
|
+
// Helper to build full command string
|
|
1021
|
+
const buildCommand = (config) => {
|
|
1022
|
+
if (config.command && config.args?.length) {
|
|
1023
|
+
return `${config.command} ${config.args.join(' ')}`;
|
|
1024
|
+
}
|
|
1025
|
+
return config.command || (config.args ? config.args.join(' ') : undefined);
|
|
1026
|
+
};
|
|
1027
|
+
// User-scoped MCPs (version-aware when home is provided)
|
|
1028
|
+
const userConfigPath = options?.home
|
|
1029
|
+
? getMcpConfigPathForHome(agentId, options.home)
|
|
1030
|
+
: getUserMcpConfigPath(agentId);
|
|
1031
|
+
const userMcps = parseMcpConfig(agentId, userConfigPath);
|
|
1032
|
+
for (const [name, config] of Object.entries(userMcps)) {
|
|
1033
|
+
results.push({
|
|
1034
|
+
name,
|
|
1035
|
+
scope: 'user',
|
|
1036
|
+
command: buildCommand(config),
|
|
1037
|
+
version: config.args ? extractNpmVersion(config.args) : undefined,
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
// Project-scoped MCPs
|
|
1041
|
+
const projectConfigPath = getProjectMcpConfigPath(agentId, cwd);
|
|
1042
|
+
const projectMcps = parseMcpConfig(agentId, projectConfigPath);
|
|
1043
|
+
for (const [name, config] of Object.entries(projectMcps)) {
|
|
1044
|
+
// Skip if already in user scope (project can override, but we show both)
|
|
1045
|
+
results.push({
|
|
1046
|
+
name,
|
|
1047
|
+
scope: 'project',
|
|
1048
|
+
command: buildCommand(config),
|
|
1049
|
+
version: config.args ? extractNpmVersion(config.args) : undefined,
|
|
1050
|
+
});
|
|
1051
|
+
}
|
|
1052
|
+
return results;
|
|
1053
|
+
}
|
|
1054
|
+
// Agent name aliases for flexible input
|
|
1055
|
+
export const AGENT_NAME_ALIASES = {
|
|
1056
|
+
claude: 'claude',
|
|
1057
|
+
'claude-code': 'claude',
|
|
1058
|
+
cc: 'claude',
|
|
1059
|
+
codex: 'codex',
|
|
1060
|
+
'openai-codex': 'codex',
|
|
1061
|
+
cx: 'codex',
|
|
1062
|
+
gemini: 'gemini',
|
|
1063
|
+
'gemini-cli': 'gemini',
|
|
1064
|
+
gx: 'gemini',
|
|
1065
|
+
cursor: 'cursor',
|
|
1066
|
+
'cursor-agent': 'cursor',
|
|
1067
|
+
cr: 'cursor',
|
|
1068
|
+
opencode: 'opencode',
|
|
1069
|
+
oc: 'opencode',
|
|
1070
|
+
openclaw: 'openclaw',
|
|
1071
|
+
claw: 'openclaw',
|
|
1072
|
+
ocl: 'openclaw',
|
|
1073
|
+
copilot: 'copilot',
|
|
1074
|
+
'copilot-cli': 'copilot',
|
|
1075
|
+
'github-copilot': 'copilot',
|
|
1076
|
+
gh: 'copilot',
|
|
1077
|
+
amp: 'amp',
|
|
1078
|
+
sourcegraph: 'amp',
|
|
1079
|
+
kiro: 'kiro',
|
|
1080
|
+
'kiro-cli': 'kiro',
|
|
1081
|
+
goose: 'goose',
|
|
1082
|
+
'block-goose': 'goose',
|
|
1083
|
+
roo: 'roo',
|
|
1084
|
+
'roo-code': 'roo',
|
|
1085
|
+
roocode: 'roo',
|
|
1086
|
+
};
|
|
1087
|
+
export function resolveAgentName(input) {
|
|
1088
|
+
return AGENT_NAME_ALIASES[input.toLowerCase()] || null;
|
|
1089
|
+
}
|
|
1090
|
+
export function isAgentName(input) {
|
|
1091
|
+
return resolveAgentName(input) !== null;
|
|
1092
|
+
}
|
|
1093
|
+
export function formatAgentError(agentName, validAgents = ALL_AGENT_IDS) {
|
|
1094
|
+
return `Unknown agent '${agentName}'. Valid agents: ${validAgents.join(', ')}`;
|
|
1095
|
+
}
|
|
1096
|
+
//# sourceMappingURL=agents.js.map
|