@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/runner.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Job execution engine for routines.
|
|
3
|
+
*
|
|
4
|
+
* Builds agent-specific CLI commands from job configs, spawns them with
|
|
5
|
+
* sandboxed or unsandboxed environments, captures stdout to log files,
|
|
6
|
+
* enforces timeouts, and extracts the final assistant report from the
|
|
7
|
+
* agent's stream-JSON output.
|
|
8
|
+
*/
|
|
1
9
|
import { spawn } from 'child_process';
|
|
2
10
|
import * as fs from 'fs';
|
|
3
11
|
import * as path from 'path';
|
|
@@ -6,11 +14,13 @@ import { resolveJobPrompt, parseTimeout, writeRunMeta, getRunDir, } from './rout
|
|
|
6
14
|
import { getRunsDir } from './state.js';
|
|
7
15
|
import { prepareJobHome, buildSpawnEnv } from './sandbox.js';
|
|
8
16
|
import { resolveModel, buildReasoningFlags } from './models.js';
|
|
17
|
+
/** CLI command templates per agent, with {prompt} as a placeholder. */
|
|
9
18
|
const AGENT_COMMANDS = {
|
|
10
19
|
claude: ['claude', '-p', '--verbose', '{prompt}', '--output-format', 'stream-json', '--permission-mode', 'plan'],
|
|
11
20
|
codex: ['codex', 'exec', '--sandbox', 'workspace-write', '{prompt}', '--json'],
|
|
12
21
|
gemini: ['gemini', '{prompt}', '--output-format', 'stream-json'],
|
|
13
22
|
};
|
|
23
|
+
/** Build the full CLI argv for executing a job, applying mode, model, and permission flags. */
|
|
14
24
|
export function buildJobCommand(config, resolvedPrompt) {
|
|
15
25
|
const template = AGENT_COMMANDS[config.agent];
|
|
16
26
|
if (!template) {
|
|
@@ -31,6 +41,12 @@ export function buildJobCommand(config, resolvedPrompt) {
|
|
|
31
41
|
}
|
|
32
42
|
if (config.allow?.dirs) {
|
|
33
43
|
for (const dir of config.allow.dirs) {
|
|
44
|
+
// Reject leading '-' so a routine YAML can't smuggle an argv flag like
|
|
45
|
+
// `--dangerously-skip-permissions` past the sandbox by hiding it as an
|
|
46
|
+
// allow.dirs entry.
|
|
47
|
+
if (dir.startsWith('-')) {
|
|
48
|
+
throw new Error(`allow.dirs entries must not start with '-': ${JSON.stringify(dir)}`);
|
|
49
|
+
}
|
|
34
50
|
const resolved = dir.replace(/^~/, os.homedir());
|
|
35
51
|
cmd.push('--add-dir', resolved);
|
|
36
52
|
}
|
|
@@ -89,6 +105,7 @@ function appendModelAndReasoning(cmd, config) {
|
|
|
89
105
|
function generateRunId() {
|
|
90
106
|
return new Date().toISOString().replace(/[:.]/g, '-');
|
|
91
107
|
}
|
|
108
|
+
/** Execute a job synchronously (waits for completion or timeout before resolving). */
|
|
92
109
|
export async function executeJob(config) {
|
|
93
110
|
const resolvedPrompt = resolveJobPrompt(config);
|
|
94
111
|
const cmd = buildJobCommand(config, resolvedPrompt);
|
|
@@ -98,7 +115,7 @@ export async function executeJob(config) {
|
|
|
98
115
|
const runDir = getRunDir(config.name, runId);
|
|
99
116
|
fs.mkdirSync(runDir, { recursive: true });
|
|
100
117
|
const stdoutPath = path.join(runDir, 'stdout.log');
|
|
101
|
-
const stdoutFd = fs.openSync(stdoutPath, 'w');
|
|
118
|
+
const stdoutFd = fs.openSync(stdoutPath, 'w', 0o600);
|
|
102
119
|
let spawnEnv = useSandbox ? buildSpawnEnv(overlayHome) : { ...process.env };
|
|
103
120
|
if (config.timezone) {
|
|
104
121
|
spawnEnv.TZ = config.timezone;
|
|
@@ -179,6 +196,7 @@ export async function executeJob(config) {
|
|
|
179
196
|
child.unref();
|
|
180
197
|
});
|
|
181
198
|
}
|
|
199
|
+
/** Spawn a job as a detached process and return immediately with run metadata. */
|
|
182
200
|
export async function executeJobDetached(config) {
|
|
183
201
|
const resolvedPrompt = resolveJobPrompt(config);
|
|
184
202
|
const cmd = buildJobCommand(config, resolvedPrompt);
|
|
@@ -188,7 +206,7 @@ export async function executeJobDetached(config) {
|
|
|
188
206
|
const runDir = getRunDir(config.name, runId);
|
|
189
207
|
fs.mkdirSync(runDir, { recursive: true });
|
|
190
208
|
const stdoutPath = path.join(runDir, 'stdout.log');
|
|
191
|
-
const stdoutFd = fs.openSync(stdoutPath, 'w');
|
|
209
|
+
const stdoutFd = fs.openSync(stdoutPath, 'w', 0o600);
|
|
192
210
|
let spawnEnv = useSandbox ? buildSpawnEnv(overlayHome) : { ...process.env };
|
|
193
211
|
if (config.timezone) {
|
|
194
212
|
spawnEnv.TZ = config.timezone;
|
|
@@ -233,6 +251,7 @@ function extractAndSaveReport(stdoutPath, agentType, runDir) {
|
|
|
233
251
|
}
|
|
234
252
|
return null;
|
|
235
253
|
}
|
|
254
|
+
/** Extract the final assistant message from a stream-JSON log file as a markdown report. */
|
|
236
255
|
export function extractReport(stdoutPath, agentType) {
|
|
237
256
|
if (!fs.existsSync(stdoutPath))
|
|
238
257
|
return null;
|
|
@@ -273,6 +292,7 @@ export function extractReport(stdoutPath, agentType) {
|
|
|
273
292
|
return null;
|
|
274
293
|
}
|
|
275
294
|
}
|
|
295
|
+
/** Scan all runs marked "running" and finalize any whose process has exited. */
|
|
276
296
|
export function monitorRunningJobs() {
|
|
277
297
|
const runsDir = getRunsDir();
|
|
278
298
|
if (!fs.existsSync(runsDir))
|
|
@@ -308,4 +328,3 @@ export function monitorRunningJobs() {
|
|
|
308
328
|
}
|
|
309
329
|
}
|
|
310
330
|
}
|
|
311
|
-
//# sourceMappingURL=runner.js.map
|
package/dist/lib/sandbox.d.ts
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandbox environment for routine job execution.
|
|
3
|
+
*
|
|
4
|
+
* Creates an overlay HOME directory per job with symlinked allowed
|
|
5
|
+
* directories and agent-specific config files (permissions, settings).
|
|
6
|
+
* The spawned agent process sees only the overlay, limiting filesystem
|
|
7
|
+
* access to explicitly allowed paths.
|
|
8
|
+
*/
|
|
1
9
|
import type { JobConfig } from './routines.js';
|
|
10
|
+
/** Build a restricted environment for a sandboxed process, setting HOME to the overlay. */
|
|
2
11
|
export declare function buildSpawnEnv(overlayHome: string, extraEnv?: Record<string, string>): Record<string, string>;
|
|
12
|
+
/** Get the overlay HOME directory path for a named job. */
|
|
3
13
|
export declare function getJobHomePath(name: string): string;
|
|
14
|
+
/** Create a fresh overlay HOME for a job, including agent config and allowed-dir symlinks. */
|
|
4
15
|
export declare function prepareJobHome(config: JobConfig): string;
|
|
16
|
+
/** Remove a job's overlay HOME directory entirely. */
|
|
5
17
|
export declare function cleanJobHome(name: string): void;
|
|
18
|
+
/** Symlink allowed directories into the overlay HOME, skipping paths outside the real HOME. */
|
|
6
19
|
export declare function symlinkAllowedDirs(overlayHome: string, dirs: string[]): void;
|
|
20
|
+
/** Generate a Claude settings.json in the overlay with scoped permissions from the job config. */
|
|
7
21
|
export declare function generateClaudeConfig(overlayHome: string, config: JobConfig): void;
|
|
22
|
+
/** Generate a Codex config.toml in the overlay with model and approval-mode settings. */
|
|
8
23
|
export declare function generateCodexConfig(overlayHome: string, config: JobConfig): void;
|
|
24
|
+
/** Generate a Gemini settings.json in the overlay from the job's config block. */
|
|
9
25
|
export declare function generateGeminiConfig(overlayHome: string, config: JobConfig): void;
|
|
10
|
-
//# sourceMappingURL=sandbox.d.ts.map
|
package/dist/lib/sandbox.js
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandbox environment for routine job execution.
|
|
3
|
+
*
|
|
4
|
+
* Creates an overlay HOME directory per job with symlinked allowed
|
|
5
|
+
* directories and agent-specific config files (permissions, settings).
|
|
6
|
+
* The spawned agent process sees only the overlay, limiting filesystem
|
|
7
|
+
* access to explicitly allowed paths.
|
|
8
|
+
*/
|
|
1
9
|
import * as fs from 'fs';
|
|
2
10
|
import * as path from 'path';
|
|
3
11
|
import * as os from 'os';
|
|
12
|
+
import { setGeminiAutoUpdateDisabled, updateGeminiSettings } from './gemini-settings.js';
|
|
4
13
|
import { getRoutinesDir } from './state.js';
|
|
5
14
|
const REAL_HOME = os.homedir();
|
|
15
|
+
/** Environment variables forwarded from the parent process into the sandbox. */
|
|
6
16
|
const ENV_ALLOWLIST = [
|
|
7
17
|
'PATH',
|
|
8
18
|
'SHELL',
|
|
@@ -25,13 +35,20 @@ const ENV_ALLOWLIST = [
|
|
|
25
35
|
'NO_COLOR',
|
|
26
36
|
'FORCE_COLOR',
|
|
27
37
|
];
|
|
28
|
-
|
|
38
|
+
/** Tools safe to grant as wildcards (no filesystem access). */
|
|
29
39
|
const SAFE_TOOLS = {
|
|
30
40
|
web_search: 'WebSearch(*)',
|
|
31
41
|
web_fetch: 'WebFetch(*)',
|
|
32
42
|
};
|
|
33
|
-
|
|
43
|
+
/** Bare tool names that get scoped to allow.dirs, never wildcarded. */
|
|
34
44
|
const DIR_SCOPED_TOOLS = new Set(['read', 'write', 'edit', 'glob', 'grep', 'notebook_edit']);
|
|
45
|
+
function tomlString(value) {
|
|
46
|
+
if (/[\r\n]/.test(value)) {
|
|
47
|
+
throw new Error(`TOML value contains newline: ${JSON.stringify(value)}`);
|
|
48
|
+
}
|
|
49
|
+
return `"${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
|
|
50
|
+
}
|
|
51
|
+
/** Build a restricted environment for a sandboxed process, setting HOME to the overlay. */
|
|
35
52
|
export function buildSpawnEnv(overlayHome, extraEnv) {
|
|
36
53
|
const env = { HOME: overlayHome };
|
|
37
54
|
for (const key of ENV_ALLOWLIST) {
|
|
@@ -44,9 +61,11 @@ export function buildSpawnEnv(overlayHome, extraEnv) {
|
|
|
44
61
|
}
|
|
45
62
|
return env;
|
|
46
63
|
}
|
|
64
|
+
/** Get the overlay HOME directory path for a named job. */
|
|
47
65
|
export function getJobHomePath(name) {
|
|
48
66
|
return path.join(getRoutinesDir(), name, 'home');
|
|
49
67
|
}
|
|
68
|
+
/** Create a fresh overlay HOME for a job, including agent config and allowed-dir symlinks. */
|
|
50
69
|
export function prepareJobHome(config) {
|
|
51
70
|
const overlayHome = getJobHomePath(config.name);
|
|
52
71
|
cleanJobHome(config.name);
|
|
@@ -65,12 +84,14 @@ export function prepareJobHome(config) {
|
|
|
65
84
|
}
|
|
66
85
|
return overlayHome;
|
|
67
86
|
}
|
|
87
|
+
/** Remove a job's overlay HOME directory entirely. */
|
|
68
88
|
export function cleanJobHome(name) {
|
|
69
89
|
const overlayHome = getJobHomePath(name);
|
|
70
90
|
if (fs.existsSync(overlayHome)) {
|
|
71
91
|
fs.rmSync(overlayHome, { recursive: true, force: true });
|
|
72
92
|
}
|
|
73
93
|
}
|
|
94
|
+
/** Symlink allowed directories into the overlay HOME, skipping paths outside the real HOME. */
|
|
74
95
|
export function symlinkAllowedDirs(overlayHome, dirs) {
|
|
75
96
|
for (const dir of dirs) {
|
|
76
97
|
const expanded = dir.replace(/^~/, REAL_HOME);
|
|
@@ -99,6 +120,7 @@ export function symlinkAllowedDirs(overlayHome, dirs) {
|
|
|
99
120
|
}
|
|
100
121
|
}
|
|
101
122
|
}
|
|
123
|
+
/** Generate a Claude settings.json in the overlay with scoped permissions from the job config. */
|
|
102
124
|
export function generateClaudeConfig(overlayHome, config) {
|
|
103
125
|
const claudeDir = path.join(overlayHome, '.claude');
|
|
104
126
|
fs.mkdirSync(claudeDir, { recursive: true });
|
|
@@ -156,13 +178,14 @@ export function generateClaudeConfig(overlayHome, config) {
|
|
|
156
178
|
};
|
|
157
179
|
fs.writeFileSync(path.join(claudeDir, 'settings.json'), JSON.stringify(settings, null, 2), 'utf-8');
|
|
158
180
|
}
|
|
181
|
+
/** Generate a Codex config.toml in the overlay with model and approval-mode settings. */
|
|
159
182
|
export function generateCodexConfig(overlayHome, config) {
|
|
160
183
|
const codexDir = path.join(overlayHome, '.codex');
|
|
161
184
|
fs.mkdirSync(codexDir, { recursive: true });
|
|
162
185
|
const lines = [];
|
|
163
186
|
const model = config.config?.model;
|
|
164
187
|
if (model) {
|
|
165
|
-
lines.push(`model =
|
|
188
|
+
lines.push(`model = ${tomlString(model)}`);
|
|
166
189
|
}
|
|
167
190
|
if (config.mode === 'edit') {
|
|
168
191
|
lines.push('approval_mode = "full-auto"');
|
|
@@ -175,7 +198,7 @@ export function generateCodexConfig(overlayHome, config) {
|
|
|
175
198
|
if (key === 'model')
|
|
176
199
|
continue;
|
|
177
200
|
if (typeof value === 'string') {
|
|
178
|
-
lines.push(`${key} =
|
|
201
|
+
lines.push(`${key} = ${tomlString(value)}`);
|
|
179
202
|
}
|
|
180
203
|
else if (typeof value === 'boolean' || typeof value === 'number') {
|
|
181
204
|
lines.push(`${key} = ${value}`);
|
|
@@ -184,18 +207,18 @@ export function generateCodexConfig(overlayHome, config) {
|
|
|
184
207
|
}
|
|
185
208
|
fs.writeFileSync(path.join(codexDir, 'config.toml'), lines.join('\n') + '\n', 'utf-8');
|
|
186
209
|
}
|
|
210
|
+
/** Generate a Gemini settings.json in the overlay from the job's config block. */
|
|
187
211
|
export function generateGeminiConfig(overlayHome, config) {
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
settings.model = config.config.model;
|
|
193
|
-
}
|
|
194
|
-
if (config.config) {
|
|
195
|
-
for (const [key, value] of Object.entries(config.config)) {
|
|
196
|
-
settings[key] = value;
|
|
212
|
+
const settingsPath = path.join(overlayHome, '.gemini', 'settings.json');
|
|
213
|
+
updateGeminiSettings(settingsPath, (settings) => {
|
|
214
|
+
if (config.config?.model) {
|
|
215
|
+
settings.model = config.config.model;
|
|
197
216
|
}
|
|
198
|
-
|
|
199
|
-
|
|
217
|
+
if (config.config) {
|
|
218
|
+
for (const [key, value] of Object.entries(config.config)) {
|
|
219
|
+
settings[key] = value;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
setGeminiAutoUpdateDisabled(settings);
|
|
223
|
+
});
|
|
200
224
|
}
|
|
201
|
-
//# sourceMappingURL=sandbox.js.map
|
package/dist/lib/scheduler.d.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cron-based job scheduler for routines.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the croner library to manage scheduled jobs in-memory. The daemon
|
|
5
|
+
* process creates a single JobScheduler instance that loads enabled jobs
|
|
6
|
+
* on startup and reloads them on SIGHUP.
|
|
7
|
+
*/
|
|
1
8
|
import type { JobConfig } from './routines.js';
|
|
9
|
+
/** In-memory cron scheduler that triggers a callback when jobs fire. */
|
|
2
10
|
export declare class JobScheduler {
|
|
3
11
|
private jobs;
|
|
4
12
|
private onTrigger;
|
|
@@ -15,4 +23,3 @@ export declare class JobScheduler {
|
|
|
15
23
|
enabled: boolean;
|
|
16
24
|
}>;
|
|
17
25
|
}
|
|
18
|
-
//# sourceMappingURL=scheduler.d.ts.map
|
package/dist/lib/scheduler.js
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cron-based job scheduler for routines.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the croner library to manage scheduled jobs in-memory. The daemon
|
|
5
|
+
* process creates a single JobScheduler instance that loads enabled jobs
|
|
6
|
+
* on startup and reloads them on SIGHUP.
|
|
7
|
+
*/
|
|
1
8
|
import { Cron } from 'croner';
|
|
2
9
|
import { listJobs, deleteJob } from './routines.js';
|
|
10
|
+
/** In-memory cron scheduler that triggers a callback when jobs fire. */
|
|
3
11
|
export class JobScheduler {
|
|
4
12
|
jobs = new Map();
|
|
5
13
|
onTrigger;
|
|
@@ -66,4 +74,3 @@ export class JobScheduler {
|
|
|
66
74
|
return result;
|
|
67
75
|
}
|
|
68
76
|
}
|
|
69
|
-
//# sourceMappingURL=scheduler.js.map
|
|
Binary file
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>CFBundleIdentifier</key>
|
|
6
|
+
<string>com.phnx-labs.agents-keychain</string>
|
|
7
|
+
<key>CFBundleName</key>
|
|
8
|
+
<string>AgentsKeychain</string>
|
|
9
|
+
<key>CFBundleExecutable</key>
|
|
10
|
+
<string>AgentsKeychain</string>
|
|
11
|
+
<key>CFBundlePackageType</key>
|
|
12
|
+
<string>APPL</string>
|
|
13
|
+
<key>CFBundleVersion</key>
|
|
14
|
+
<string>1</string>
|
|
15
|
+
<key>CFBundleShortVersionString</key>
|
|
16
|
+
<string>1.0</string>
|
|
17
|
+
<key>LSMinimumSystemVersion</key>
|
|
18
|
+
<string>12.0</string>
|
|
19
|
+
<key>LSUIElement</key>
|
|
20
|
+
<true/>
|
|
21
|
+
</dict>
|
|
22
|
+
</plist>
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>files</key>
|
|
6
|
+
<dict/>
|
|
7
|
+
<key>files2</key>
|
|
8
|
+
<dict>
|
|
9
|
+
<key>embedded.provisionprofile</key>
|
|
10
|
+
<dict>
|
|
11
|
+
<key>hash2</key>
|
|
12
|
+
<data>
|
|
13
|
+
2vfA/eR3dTYgNc/fXhdADUPkp5tRIepPzE3FCLfDx4w=
|
|
14
|
+
</data>
|
|
15
|
+
</dict>
|
|
16
|
+
</dict>
|
|
17
|
+
<key>rules</key>
|
|
18
|
+
<dict>
|
|
19
|
+
<key>^Resources/</key>
|
|
20
|
+
<true/>
|
|
21
|
+
<key>^Resources/.*\.lproj/</key>
|
|
22
|
+
<dict>
|
|
23
|
+
<key>optional</key>
|
|
24
|
+
<true/>
|
|
25
|
+
<key>weight</key>
|
|
26
|
+
<real>1000</real>
|
|
27
|
+
</dict>
|
|
28
|
+
<key>^Resources/.*\.lproj/locversion.plist$</key>
|
|
29
|
+
<dict>
|
|
30
|
+
<key>omit</key>
|
|
31
|
+
<true/>
|
|
32
|
+
<key>weight</key>
|
|
33
|
+
<real>1100</real>
|
|
34
|
+
</dict>
|
|
35
|
+
<key>^Resources/Base\.lproj/</key>
|
|
36
|
+
<dict>
|
|
37
|
+
<key>weight</key>
|
|
38
|
+
<real>1010</real>
|
|
39
|
+
</dict>
|
|
40
|
+
<key>^version.plist$</key>
|
|
41
|
+
<true/>
|
|
42
|
+
</dict>
|
|
43
|
+
<key>rules2</key>
|
|
44
|
+
<dict>
|
|
45
|
+
<key>.*\.dSYM($|/)</key>
|
|
46
|
+
<dict>
|
|
47
|
+
<key>weight</key>
|
|
48
|
+
<real>11</real>
|
|
49
|
+
</dict>
|
|
50
|
+
<key>^(.*/)?\.DS_Store$</key>
|
|
51
|
+
<dict>
|
|
52
|
+
<key>omit</key>
|
|
53
|
+
<true/>
|
|
54
|
+
<key>weight</key>
|
|
55
|
+
<real>2000</real>
|
|
56
|
+
</dict>
|
|
57
|
+
<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
|
|
58
|
+
<dict>
|
|
59
|
+
<key>nested</key>
|
|
60
|
+
<true/>
|
|
61
|
+
<key>weight</key>
|
|
62
|
+
<real>10</real>
|
|
63
|
+
</dict>
|
|
64
|
+
<key>^.*</key>
|
|
65
|
+
<true/>
|
|
66
|
+
<key>^Info\.plist$</key>
|
|
67
|
+
<dict>
|
|
68
|
+
<key>omit</key>
|
|
69
|
+
<true/>
|
|
70
|
+
<key>weight</key>
|
|
71
|
+
<real>20</real>
|
|
72
|
+
</dict>
|
|
73
|
+
<key>^PkgInfo$</key>
|
|
74
|
+
<dict>
|
|
75
|
+
<key>omit</key>
|
|
76
|
+
<true/>
|
|
77
|
+
<key>weight</key>
|
|
78
|
+
<real>20</real>
|
|
79
|
+
</dict>
|
|
80
|
+
<key>^Resources/</key>
|
|
81
|
+
<dict>
|
|
82
|
+
<key>weight</key>
|
|
83
|
+
<real>20</real>
|
|
84
|
+
</dict>
|
|
85
|
+
<key>^Resources/.*\.lproj/</key>
|
|
86
|
+
<dict>
|
|
87
|
+
<key>optional</key>
|
|
88
|
+
<true/>
|
|
89
|
+
<key>weight</key>
|
|
90
|
+
<real>1000</real>
|
|
91
|
+
</dict>
|
|
92
|
+
<key>^Resources/.*\.lproj/locversion.plist$</key>
|
|
93
|
+
<dict>
|
|
94
|
+
<key>omit</key>
|
|
95
|
+
<true/>
|
|
96
|
+
<key>weight</key>
|
|
97
|
+
<real>1100</real>
|
|
98
|
+
</dict>
|
|
99
|
+
<key>^Resources/Base\.lproj/</key>
|
|
100
|
+
<dict>
|
|
101
|
+
<key>weight</key>
|
|
102
|
+
<real>1010</real>
|
|
103
|
+
</dict>
|
|
104
|
+
<key>^[^/]+$</key>
|
|
105
|
+
<dict>
|
|
106
|
+
<key>nested</key>
|
|
107
|
+
<true/>
|
|
108
|
+
<key>weight</key>
|
|
109
|
+
<real>10</real>
|
|
110
|
+
</dict>
|
|
111
|
+
<key>^embedded\.provisionprofile$</key>
|
|
112
|
+
<dict>
|
|
113
|
+
<key>weight</key>
|
|
114
|
+
<real>20</real>
|
|
115
|
+
</dict>
|
|
116
|
+
<key>^version\.plist$</key>
|
|
117
|
+
<dict>
|
|
118
|
+
<key>weight</key>
|
|
119
|
+
<real>20</real>
|
|
120
|
+
</dict>
|
|
121
|
+
</dict>
|
|
122
|
+
</dict>
|
|
123
|
+
</plist>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret bundles -- named sets of keychain-backed environment variables.
|
|
3
|
+
*
|
|
4
|
+
* Each bundle is a YAML file in ~/.agents/secrets/ declaring key names.
|
|
5
|
+
* Values live in the macOS Keychain and are injected into the agent's
|
|
6
|
+
* environment at spawn time via `agents run --secrets <bundle>`.
|
|
7
|
+
*/
|
|
8
|
+
import { type BundleValue, type SecretRef } from './index.js';
|
|
9
|
+
/** A named set of environment variable definitions backed by various secret providers. */
|
|
10
|
+
export interface SecretsBundle {
|
|
11
|
+
name: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
allow_exec?: boolean;
|
|
14
|
+
/** When true, keychain-backed values are stored in iCloud Keychain so they sync across the user's Macs. */
|
|
15
|
+
icloud_sync?: boolean;
|
|
16
|
+
vars: Record<string, BundleValue>;
|
|
17
|
+
}
|
|
18
|
+
/** Validate a bundle name against the allowed pattern. Throws on invalid input. */
|
|
19
|
+
export declare function validateBundleName(name: string): void;
|
|
20
|
+
export declare function validateEnvKey(key: string): void;
|
|
21
|
+
export declare function bundleExists(name: string): boolean;
|
|
22
|
+
export declare function readBundle(name: string): SecretsBundle;
|
|
23
|
+
export declare function writeBundle(bundle: SecretsBundle): void;
|
|
24
|
+
export declare function deleteBundle(name: string): boolean;
|
|
25
|
+
export declare function listBundles(): SecretsBundle[];
|
|
26
|
+
export interface BundleEntryInfo {
|
|
27
|
+
key: string;
|
|
28
|
+
kind: 'literal' | 'keychain' | 'env' | 'file' | 'exec';
|
|
29
|
+
detail: string;
|
|
30
|
+
}
|
|
31
|
+
export declare function describeBundle(bundle: SecretsBundle): BundleEntryInfo[];
|
|
32
|
+
export declare function resolveBundleEnv(bundle: SecretsBundle): Record<string, string>;
|
|
33
|
+
export declare function keychainRef(key: string): string;
|
|
34
|
+
export declare function keychainItemsForBundle(bundle: SecretsBundle): Array<{
|
|
35
|
+
key: string;
|
|
36
|
+
item: string;
|
|
37
|
+
}>;
|
|
38
|
+
export declare function parseDotenv(content: string): Record<string, string>;
|
|
39
|
+
export type { SecretRef };
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret bundles -- named sets of keychain-backed environment variables.
|
|
3
|
+
*
|
|
4
|
+
* Each bundle is a YAML file in ~/.agents/secrets/ declaring key names.
|
|
5
|
+
* Values live in the macOS Keychain and are injected into the agent's
|
|
6
|
+
* environment at spawn time via `agents run --secrets <bundle>`.
|
|
7
|
+
*/
|
|
8
|
+
import * as fs from 'fs';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
import * as yaml from 'yaml';
|
|
11
|
+
import { getSecretsDir, getUserSecretsDir } from '../state.js';
|
|
12
|
+
import { parseBundleValue, resolveRef, secretsKeychainItem, } from './index.js';
|
|
13
|
+
const BUNDLE_NAME_PATTERN = /^[a-z0-9][a-z0-9-_]{0,48}$/i;
|
|
14
|
+
const ENV_KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
15
|
+
/** Validate a bundle name against the allowed pattern. Throws on invalid input. */
|
|
16
|
+
export function validateBundleName(name) {
|
|
17
|
+
if (!BUNDLE_NAME_PATTERN.test(name)) {
|
|
18
|
+
throw new Error(`Invalid bundle name '${name}'. Use letters, digits, dash, underscore (max 48 chars).`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function validateEnvKey(key) {
|
|
22
|
+
if (!ENV_KEY_PATTERN.test(key)) {
|
|
23
|
+
throw new Error(`Invalid environment variable name '${key}'. Must match [A-Za-z_][A-Za-z0-9_]*.`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function bundlePath(name) {
|
|
27
|
+
// Check user dir first (for reads), write to user dir
|
|
28
|
+
const userPath = path.join(getUserSecretsDir(), `${name}.yml`);
|
|
29
|
+
if (fs.existsSync(userPath))
|
|
30
|
+
return userPath;
|
|
31
|
+
const systemPath = path.join(getSecretsDir(), `${name}.yml`);
|
|
32
|
+
if (fs.existsSync(systemPath))
|
|
33
|
+
return systemPath;
|
|
34
|
+
return userPath; // default write location
|
|
35
|
+
}
|
|
36
|
+
export function bundleExists(name) {
|
|
37
|
+
return fs.existsSync(bundlePath(name));
|
|
38
|
+
}
|
|
39
|
+
export function readBundle(name) {
|
|
40
|
+
validateBundleName(name);
|
|
41
|
+
const file = bundlePath(name);
|
|
42
|
+
if (!fs.existsSync(file)) {
|
|
43
|
+
throw new Error(`Secrets bundle '${name}' not found.`);
|
|
44
|
+
}
|
|
45
|
+
const raw = fs.readFileSync(file, 'utf-8');
|
|
46
|
+
const parsed = yaml.parse(raw);
|
|
47
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
48
|
+
throw new Error(`Bundle '${name}' is malformed.`);
|
|
49
|
+
}
|
|
50
|
+
const bundle = {
|
|
51
|
+
name: parsed.name || name,
|
|
52
|
+
description: parsed.description,
|
|
53
|
+
allow_exec: Boolean(parsed.allow_exec),
|
|
54
|
+
icloud_sync: Boolean(parsed.icloud_sync),
|
|
55
|
+
vars: parsed.vars && typeof parsed.vars === 'object' ? parsed.vars : {},
|
|
56
|
+
};
|
|
57
|
+
for (const key of Object.keys(bundle.vars)) {
|
|
58
|
+
validateEnvKey(key);
|
|
59
|
+
}
|
|
60
|
+
return bundle;
|
|
61
|
+
}
|
|
62
|
+
export function writeBundle(bundle) {
|
|
63
|
+
validateBundleName(bundle.name);
|
|
64
|
+
for (const key of Object.keys(bundle.vars)) {
|
|
65
|
+
validateEnvKey(key);
|
|
66
|
+
}
|
|
67
|
+
const dir = getUserSecretsDir();
|
|
68
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
69
|
+
const body = yaml.stringify({
|
|
70
|
+
name: bundle.name,
|
|
71
|
+
description: bundle.description,
|
|
72
|
+
allow_exec: bundle.allow_exec ? true : undefined,
|
|
73
|
+
icloud_sync: bundle.icloud_sync ? true : undefined,
|
|
74
|
+
vars: bundle.vars,
|
|
75
|
+
});
|
|
76
|
+
const file = bundlePath(bundle.name);
|
|
77
|
+
const tmp = `${file}.tmp-${process.pid}`;
|
|
78
|
+
fs.writeFileSync(tmp, body, 'utf-8');
|
|
79
|
+
fs.renameSync(tmp, file);
|
|
80
|
+
}
|
|
81
|
+
export function deleteBundle(name) {
|
|
82
|
+
validateBundleName(name);
|
|
83
|
+
const file = bundlePath(name);
|
|
84
|
+
if (!fs.existsSync(file))
|
|
85
|
+
return false;
|
|
86
|
+
fs.unlinkSync(file);
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
export function listBundles() {
|
|
90
|
+
const seen = new Set();
|
|
91
|
+
const bundles = [];
|
|
92
|
+
for (const dir of [getUserSecretsDir(), getSecretsDir()]) {
|
|
93
|
+
if (!fs.existsSync(dir))
|
|
94
|
+
continue;
|
|
95
|
+
for (const entry of fs.readdirSync(dir).filter((f) => f.endsWith('.yml') || f.endsWith('.yaml'))) {
|
|
96
|
+
const name = entry.replace(/\.(yml|yaml)$/, '');
|
|
97
|
+
if (seen.has(name))
|
|
98
|
+
continue;
|
|
99
|
+
seen.add(name);
|
|
100
|
+
try {
|
|
101
|
+
bundles.push(readBundle(name));
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// Skip malformed bundles; surfaced via `agents secrets view <name>`.
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return bundles.sort((a, b) => a.name.localeCompare(b.name));
|
|
109
|
+
}
|
|
110
|
+
export function describeBundle(bundle) {
|
|
111
|
+
const out = [];
|
|
112
|
+
for (const [key, raw] of Object.entries(bundle.vars)) {
|
|
113
|
+
const parsed = parseBundleValue(raw);
|
|
114
|
+
if ('literal' in parsed) {
|
|
115
|
+
out.push({ key, kind: 'literal', detail: '' });
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
out.push({ key, kind: parsed.ref.provider, detail: parsed.ref.value });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return out;
|
|
122
|
+
}
|
|
123
|
+
// Walk the bundle and produce a flat env map. Keychain refs are translated via
|
|
124
|
+
// the bundle-scoped naming scheme so two bundles with the same short ID never
|
|
125
|
+
// collide. Throws on the first missing secret so `agents run` fails loudly
|
|
126
|
+
// rather than silently injecting empty strings.
|
|
127
|
+
export function resolveBundleEnv(bundle) {
|
|
128
|
+
const env = {};
|
|
129
|
+
for (const [key, raw] of Object.entries(bundle.vars)) {
|
|
130
|
+
const parsed = parseBundleValue(raw);
|
|
131
|
+
if ('literal' in parsed) {
|
|
132
|
+
env[key] = parsed.literal;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
env[key] = resolveRef(parsed.ref, {
|
|
137
|
+
allowExec: bundle.allow_exec,
|
|
138
|
+
iCloudSync: bundle.icloud_sync,
|
|
139
|
+
keychainItemFor: (shortId) => secretsKeychainItem(bundle.name, shortId),
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
const msg = err.message;
|
|
144
|
+
if (parsed.ref.provider === 'keychain' && /not found/.test(msg)) {
|
|
145
|
+
throw new Error(`${msg} Run: agents secrets add ${bundle.name} ${key}`);
|
|
146
|
+
}
|
|
147
|
+
throw new Error(`Bundle '${bundle.name}' key '${key}': ${msg}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return env;
|
|
151
|
+
}
|
|
152
|
+
// Build a keychain ref expression from a bundle+key pair, for storage in YAML.
|
|
153
|
+
export function keychainRef(key) {
|
|
154
|
+
return `keychain:${key}`;
|
|
155
|
+
}
|
|
156
|
+
// Iterate all keychain-backed keys in a bundle for cleanup on rm/unset.
|
|
157
|
+
export function keychainItemsForBundle(bundle) {
|
|
158
|
+
const items = [];
|
|
159
|
+
for (const [key, raw] of Object.entries(bundle.vars)) {
|
|
160
|
+
const parsed = parseBundleValue(raw);
|
|
161
|
+
if ('ref' in parsed && parsed.ref.provider === 'keychain') {
|
|
162
|
+
items.push({ key, item: secretsKeychainItem(bundle.name, parsed.ref.value) });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return items;
|
|
166
|
+
}
|
|
167
|
+
// Parse a dotenv string into key=value pairs, preserving last-wins on duplicates.
|
|
168
|
+
export function parseDotenv(content) {
|
|
169
|
+
const out = {};
|
|
170
|
+
for (const raw of content.split('\n')) {
|
|
171
|
+
const line = raw.trim();
|
|
172
|
+
if (!line || line.startsWith('#'))
|
|
173
|
+
continue;
|
|
174
|
+
const stripped = line.startsWith('export ') ? line.slice('export '.length) : line;
|
|
175
|
+
const eq = stripped.indexOf('=');
|
|
176
|
+
if (eq <= 0)
|
|
177
|
+
continue;
|
|
178
|
+
const key = stripped.slice(0, eq).trim();
|
|
179
|
+
let value = stripped.slice(eq + 1).trim();
|
|
180
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
181
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
182
|
+
value = value.slice(1, -1);
|
|
183
|
+
}
|
|
184
|
+
if (ENV_KEY_PATTERN.test(key)) {
|
|
185
|
+
out[key] = value;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return out;
|
|
189
|
+
}
|