@swarmify/agents-cli 1.12.0 → 1.13.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 +33 -0
- package/LICENSE +21 -0
- package/README.md +209 -233
- package/dist/commands/__tests__/sessions.test.js +90 -20
- package/dist/commands/__tests__/sessions.test.js.map +1 -1
- package/dist/commands/cloud.d.ts +11 -0
- package/dist/commands/cloud.d.ts.map +1 -0
- package/dist/commands/cloud.js +363 -0
- package/dist/commands/cloud.js.map +1 -0
- package/dist/commands/commands.d.ts +9 -0
- package/dist/commands/commands.d.ts.map +1 -1
- package/dist/commands/commands.js +330 -139
- package/dist/commands/commands.js.map +1 -1
- package/dist/commands/daemon.d.ts +8 -0
- package/dist/commands/daemon.d.ts.map +1 -1
- package/dist/commands/daemon.js +38 -222
- package/dist/commands/daemon.js.map +1 -1
- package/dist/commands/drive.d.ts +8 -0
- package/dist/commands/drive.d.ts.map +1 -1
- package/dist/commands/drive.js +70 -7
- package/dist/commands/drive.js.map +1 -1
- package/dist/commands/exec.d.ts +9 -1
- package/dist/commands/exec.d.ts.map +1 -1
- package/dist/commands/exec.js +198 -24
- package/dist/commands/exec.js.map +1 -1
- package/dist/commands/factory.d.ts +11 -0
- package/dist/commands/factory.d.ts.map +1 -0
- package/dist/commands/factory.js +445 -0
- package/dist/commands/factory.js.map +1 -0
- package/dist/commands/fork.d.ts +8 -0
- package/dist/commands/fork.d.ts.map +1 -1
- package/dist/commands/fork.js +38 -4
- package/dist/commands/fork.js.map +1 -1
- package/dist/commands/hooks.d.ts +9 -0
- package/dist/commands/hooks.d.ts.map +1 -1
- package/dist/commands/hooks.js +252 -18
- package/dist/commands/hooks.js.map +1 -1
- package/dist/commands/init.d.ts +15 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +137 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/mcp.d.ts +9 -0
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +250 -169
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/models.d.ts +11 -0
- package/dist/commands/models.d.ts.map +1 -0
- package/dist/commands/models.js +170 -0
- package/dist/commands/models.js.map +1 -0
- package/dist/commands/packages.d.ts +8 -0
- package/dist/commands/packages.d.ts.map +1 -1
- package/dist/commands/packages.js +155 -14
- package/dist/commands/packages.js.map +1 -1
- package/dist/commands/permissions.d.ts +9 -0
- package/dist/commands/permissions.d.ts.map +1 -1
- package/dist/commands/permissions.js +72 -13
- package/dist/commands/permissions.js.map +1 -1
- package/dist/commands/plugins.d.ts +8 -0
- package/dist/commands/plugins.d.ts.map +1 -1
- package/dist/commands/plugins.js +265 -44
- package/dist/commands/plugins.js.map +1 -1
- package/dist/commands/profiles.d.ts +12 -0
- package/dist/commands/profiles.d.ts.map +1 -0
- package/dist/commands/profiles.js +255 -0
- package/dist/commands/profiles.js.map +1 -0
- package/dist/commands/pty.d.ts +1 -0
- package/dist/commands/pty.d.ts.map +1 -1
- package/dist/commands/pty.js +133 -22
- package/dist/commands/pty.js.map +1 -1
- package/dist/commands/pull.d.ts +8 -0
- package/dist/commands/pull.d.ts.map +1 -1
- package/dist/commands/pull.js +103 -14
- package/dist/commands/pull.js.map +1 -1
- package/dist/commands/push.d.ts +8 -0
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +37 -3
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/refresh-memory.d.ts +16 -0
- package/dist/commands/refresh-memory.d.ts.map +1 -0
- package/dist/commands/refresh-memory.js +52 -0
- package/dist/commands/refresh-memory.js.map +1 -0
- package/dist/commands/resource-view.d.ts +39 -0
- package/dist/commands/resource-view.d.ts.map +1 -0
- package/dist/commands/resource-view.js +197 -0
- package/dist/commands/resource-view.js.map +1 -0
- package/dist/commands/routines.d.ts +8 -0
- package/dist/commands/routines.d.ts.map +1 -1
- package/dist/commands/routines.js +163 -34
- package/dist/commands/routines.js.map +1 -1
- package/dist/commands/rules.d.ts +9 -0
- package/dist/commands/rules.d.ts.map +1 -1
- package/dist/commands/rules.js +83 -12
- package/dist/commands/rules.js.map +1 -1
- package/dist/commands/secrets.d.ts +11 -0
- package/dist/commands/secrets.d.ts.map +1 -0
- package/dist/commands/secrets.js +352 -0
- package/dist/commands/secrets.js.map +1 -0
- package/dist/commands/sessions-picker.d.ts +18 -0
- package/dist/commands/sessions-picker.d.ts.map +1 -0
- package/dist/commands/sessions-picker.js +265 -0
- package/dist/commands/sessions-picker.js.map +1 -0
- package/dist/commands/sessions.d.ts +15 -0
- package/dist/commands/sessions.d.ts.map +1 -1
- package/dist/commands/sessions.js +700 -263
- package/dist/commands/sessions.js.map +1 -1
- package/dist/commands/skills.d.ts +9 -0
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +355 -233
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/status.d.ts +7 -0
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +7 -0
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/subagents.d.ts +8 -0
- package/dist/commands/subagents.d.ts.map +1 -1
- package/dist/commands/subagents.js +214 -74
- package/dist/commands/subagents.js.map +1 -1
- package/dist/commands/sync.d.ts +8 -0
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +15 -7
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/teams-picker.d.ts +18 -0
- package/dist/commands/teams-picker.d.ts.map +1 -0
- package/dist/commands/teams-picker.js +290 -0
- package/dist/commands/teams-picker.js.map +1 -0
- package/dist/commands/teams.d.ts +18 -0
- package/dist/commands/teams.d.ts.map +1 -0
- package/dist/commands/teams.js +1098 -0
- package/dist/commands/teams.js.map +1 -0
- package/dist/commands/utils.d.ts +20 -0
- package/dist/commands/utils.d.ts.map +1 -1
- package/dist/commands/utils.js +34 -0
- package/dist/commands/utils.js.map +1 -1
- package/dist/commands/versions.d.ts +8 -0
- package/dist/commands/versions.d.ts.map +1 -1
- package/dist/commands/versions.js +71 -8
- package/dist/commands/versions.js.map +1 -1
- package/dist/commands/view.d.ts +34 -1
- package/dist/commands/view.d.ts.map +1 -1
- package/dist/commands/view.js +207 -13
- package/dist/commands/view.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +136 -51
- package/dist/index.js.map +1 -1
- package/dist/lib/__tests__/bugfixes.test.js +3 -3
- package/dist/lib/__tests__/bugfixes.test.js.map +1 -1
- package/dist/lib/__tests__/exec.test.js +125 -19
- package/dist/lib/__tests__/exec.test.js.map +1 -1
- 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.js +4 -2
- package/dist/lib/__tests__/usage.test.js.map +1 -1
- 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 +53 -1
- package/dist/lib/agents.d.ts.map +1 -1
- package/dist/lib/agents.js +178 -37
- package/dist/lib/agents.js.map +1 -1
- package/dist/lib/artifact-actions.d.ts +8 -3
- package/dist/lib/artifact-actions.d.ts.map +1 -1
- package/dist/lib/artifact-actions.js +8 -5
- package/dist/lib/artifact-actions.js.map +1 -1
- package/dist/lib/cloud/codex.d.ts +26 -0
- package/dist/lib/cloud/codex.d.ts.map +1 -0
- package/dist/lib/cloud/codex.js +237 -0
- package/dist/lib/cloud/codex.js.map +1 -0
- package/dist/lib/cloud/factory.d.ts +32 -0
- package/dist/lib/cloud/factory.d.ts.map +1 -0
- package/dist/lib/cloud/factory.js +43 -0
- package/dist/lib/cloud/factory.js.map +1 -0
- package/dist/lib/cloud/registry.d.ts +16 -0
- package/dist/lib/cloud/registry.d.ts.map +1 -0
- package/dist/lib/cloud/registry.js +68 -0
- package/dist/lib/cloud/registry.js.map +1 -0
- package/dist/lib/cloud/rush.d.ts +37 -0
- package/dist/lib/cloud/rush.d.ts.map +1 -0
- package/dist/lib/cloud/rush.js +230 -0
- package/dist/lib/cloud/rush.js.map +1 -0
- package/dist/lib/cloud/rush.test.d.ts +2 -0
- package/dist/lib/cloud/rush.test.d.ts.map +1 -0
- package/dist/lib/cloud/rush.test.js +63 -0
- package/dist/lib/cloud/rush.test.js.map +1 -0
- package/dist/lib/cloud/store.d.ts +23 -0
- package/dist/lib/cloud/store.d.ts.map +1 -0
- package/dist/lib/cloud/store.js +116 -0
- package/dist/lib/cloud/store.js.map +1 -0
- package/dist/lib/cloud/stream.d.ts +24 -0
- package/dist/lib/cloud/stream.d.ts.map +1 -0
- package/dist/lib/cloud/stream.js +145 -0
- package/dist/lib/cloud/stream.js.map +1 -0
- package/dist/lib/cloud/types.d.ts +109 -0
- package/dist/lib/cloud/types.d.ts.map +1 -0
- package/dist/lib/cloud/types.js +33 -0
- package/dist/lib/cloud/types.js.map +1 -0
- package/dist/lib/cloud/types.test.d.ts +2 -0
- package/dist/lib/cloud/types.test.d.ts.map +1 -0
- package/dist/lib/cloud/types.test.js +41 -0
- package/dist/lib/cloud/types.test.js.map +1 -0
- package/dist/lib/commands.d.ts +67 -0
- package/dist/lib/commands.d.ts.map +1 -1
- package/dist/lib/commands.js +161 -2
- package/dist/lib/commands.js.map +1 -1
- package/dist/lib/convert.d.ts +10 -0
- package/dist/lib/convert.d.ts.map +1 -1
- package/dist/lib/convert.js +9 -0
- package/dist/lib/convert.js.map +1 -1
- package/dist/lib/daemon.d.ts +21 -0
- package/dist/lib/daemon.d.ts.map +1 -1
- package/dist/lib/daemon.js +21 -0
- package/dist/lib/daemon.js.map +1 -1
- package/dist/lib/drive-sync.d.ts +18 -0
- package/dist/lib/drive-sync.d.ts.map +1 -1
- package/dist/lib/drive-sync.js +16 -0
- package/dist/lib/drive-sync.js.map +1 -1
- package/dist/lib/exec.d.ts +64 -3
- package/dist/lib/exec.d.ts.map +1 -1
- package/dist/lib/exec.js +218 -80
- package/dist/lib/exec.js.map +1 -1
- package/dist/lib/factory/__tests__/config.test.d.ts +2 -0
- package/dist/lib/factory/__tests__/config.test.d.ts.map +1 -0
- package/dist/lib/factory/__tests__/config.test.js +128 -0
- package/dist/lib/factory/__tests__/config.test.js.map +1 -0
- package/dist/lib/factory/config.d.ts +49 -0
- package/dist/lib/factory/config.d.ts.map +1 -0
- package/dist/lib/factory/config.js +127 -0
- package/dist/lib/factory/config.js.map +1 -0
- package/dist/lib/factory.js +1 -1
- package/dist/lib/factory.js.map +1 -1
- package/dist/lib/git.d.ts +16 -1
- package/dist/lib/git.d.ts.map +1 -1
- package/dist/lib/git.js +33 -4
- package/dist/lib/git.js.map +1 -1
- package/dist/lib/help.d.ts +7 -0
- package/dist/lib/help.d.ts.map +1 -1
- package/dist/lib/help.js +3 -0
- package/dist/lib/help.js.map +1 -1
- package/dist/lib/hooks.d.ts +59 -3
- package/dist/lib/hooks.d.ts.map +1 -1
- package/dist/lib/hooks.js +413 -33
- package/dist/lib/hooks.js.map +1 -1
- package/dist/lib/ledger/__tests__/local.test.d.ts +2 -0
- package/dist/lib/ledger/__tests__/local.test.d.ts.map +1 -0
- package/dist/lib/ledger/__tests__/local.test.js +177 -0
- package/dist/lib/ledger/__tests__/local.test.js.map +1 -0
- package/dist/lib/ledger/__tests__/sync.test.d.ts +2 -0
- package/dist/lib/ledger/__tests__/sync.test.d.ts.map +1 -0
- package/dist/lib/ledger/__tests__/sync.test.js +117 -0
- package/dist/lib/ledger/__tests__/sync.test.js.map +1 -0
- package/dist/lib/ledger/index.d.ts +18 -0
- package/dist/lib/ledger/index.d.ts.map +1 -0
- package/dist/lib/ledger/index.js +32 -0
- package/dist/lib/ledger/index.js.map +1 -0
- package/dist/lib/ledger/local.d.ts +22 -0
- package/dist/lib/ledger/local.d.ts.map +1 -0
- package/dist/lib/ledger/local.js +333 -0
- package/dist/lib/ledger/local.js.map +1 -0
- package/dist/lib/ledger/r2.d.ts +41 -0
- package/dist/lib/ledger/r2.d.ts.map +1 -0
- package/dist/lib/ledger/r2.js +335 -0
- package/dist/lib/ledger/r2.js.map +1 -0
- package/dist/lib/ledger/sync.d.ts +33 -0
- package/dist/lib/ledger/sync.d.ts.map +1 -0
- package/dist/lib/ledger/sync.js +106 -0
- package/dist/lib/ledger/sync.js.map +1 -0
- package/dist/lib/ledger/types.d.ts +100 -0
- package/dist/lib/ledger/types.d.ts.map +1 -0
- package/dist/lib/ledger/types.js +21 -0
- package/dist/lib/ledger/types.js.map +1 -0
- package/dist/lib/manifest.d.ts +6 -0
- package/dist/lib/manifest.d.ts.map +1 -1
- package/dist/lib/manifest.js +12 -0
- package/dist/lib/manifest.js.map +1 -1
- package/dist/lib/markdown.d.ts.map +1 -1
- package/dist/lib/markdown.js +6 -0
- package/dist/lib/markdown.js.map +1 -1
- package/dist/lib/mcp.d.ts +0 -9
- package/dist/lib/mcp.d.ts.map +1 -1
- package/dist/lib/mcp.js +0 -20
- package/dist/lib/mcp.js.map +1 -1
- package/dist/lib/memory-compile.d.ts +65 -0
- package/dist/lib/memory-compile.d.ts.map +1 -0
- package/dist/lib/memory-compile.js +174 -0
- package/dist/lib/memory-compile.js.map +1 -0
- package/dist/lib/memory.d.ts +8 -0
- package/dist/lib/memory.d.ts.map +1 -1
- package/dist/lib/memory.js +8 -0
- package/dist/lib/memory.js.map +1 -1
- package/dist/lib/models.d.ts +98 -0
- package/dist/lib/models.d.ts.map +1 -0
- package/dist/lib/models.js +722 -0
- package/dist/lib/models.js.map +1 -0
- package/dist/lib/permissions.d.ts +3 -1
- package/dist/lib/permissions.d.ts.map +1 -1
- package/dist/lib/permissions.js +13 -3
- package/dist/lib/permissions.js.map +1 -1
- package/dist/lib/picker.d.ts +27 -0
- package/dist/lib/picker.d.ts.map +1 -0
- package/dist/lib/picker.js +110 -0
- package/dist/lib/picker.js.map +1 -0
- package/dist/lib/plugins.d.ts +22 -0
- package/dist/lib/plugins.d.ts.map +1 -1
- package/dist/lib/plugins.js +114 -0
- package/dist/lib/plugins.js.map +1 -1
- package/dist/lib/profiles-keychain.d.ts +11 -0
- package/dist/lib/profiles-keychain.d.ts.map +1 -0
- package/dist/lib/profiles-keychain.js +14 -0
- package/dist/lib/profiles-keychain.js.map +1 -0
- package/dist/lib/profiles-presets.d.ts +25 -0
- package/dist/lib/profiles-presets.d.ts.map +1 -0
- package/dist/lib/profiles-presets.js +104 -0
- package/dist/lib/profiles-presets.js.map +1 -0
- package/dist/lib/profiles.d.ts +70 -0
- package/dist/lib/profiles.d.ts.map +1 -0
- package/dist/lib/profiles.js +145 -0
- package/dist/lib/profiles.js.map +1 -0
- package/dist/lib/pty-client.d.ts +1 -0
- package/dist/lib/pty-client.d.ts.map +1 -1
- package/dist/lib/pty-client.js.map +1 -1
- package/dist/lib/pty-server.d.ts +5 -0
- package/dist/lib/pty-server.d.ts.map +1 -1
- package/dist/lib/pty-server.js +5 -0
- package/dist/lib/pty-server.js.map +1 -1
- package/dist/lib/registry.d.ts +17 -0
- package/dist/lib/registry.d.ts.map +1 -1
- package/dist/lib/registry.js +17 -0
- package/dist/lib/registry.js.map +1 -1
- package/dist/lib/resources.d.ts +5 -0
- package/dist/lib/resources.d.ts.map +1 -1
- package/dist/lib/resources.js.map +1 -1
- package/dist/lib/rotate.d.ts +58 -0
- package/dist/lib/rotate.d.ts.map +1 -0
- package/dist/lib/rotate.js +93 -0
- package/dist/lib/rotate.js.map +1 -0
- package/dist/lib/routines.d.ts +30 -1
- package/dist/lib/routines.d.ts.map +1 -1
- package/dist/lib/routines.js +31 -4
- package/dist/lib/routines.js.map +1 -1
- package/dist/lib/runner.d.ts +14 -0
- package/dist/lib/runner.d.ts.map +1 -1
- package/dist/lib/runner.js +45 -11
- package/dist/lib/runner.js.map +1 -1
- package/dist/lib/sandbox.d.ts +16 -0
- package/dist/lib/sandbox.d.ts.map +1 -1
- package/dist/lib/sandbox.js +19 -2
- package/dist/lib/sandbox.js.map +1 -1
- package/dist/lib/scheduler.d.ts +8 -0
- package/dist/lib/scheduler.d.ts.map +1 -1
- package/dist/lib/scheduler.js +8 -0
- package/dist/lib/scheduler.js.map +1 -1
- package/dist/lib/secrets-bundles.d.ts +38 -0
- package/dist/lib/secrets-bundles.d.ts.map +1 -0
- package/dist/lib/secrets-bundles.js +176 -0
- package/dist/lib/secrets-bundles.js.map +1 -0
- package/dist/lib/secrets.d.ts +53 -0
- package/dist/lib/secrets.d.ts.map +1 -0
- package/dist/lib/secrets.js +140 -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.js +54 -91
- package/dist/lib/session/__tests__/discover.test.js.map +1 -1
- 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 +15 -0
- package/dist/lib/session/artifacts.d.ts.map +1 -0
- package/dist/lib/session/artifacts.js +86 -0
- package/dist/lib/session/artifacts.js.map +1 -0
- package/dist/lib/session/db.d.ts +140 -0
- package/dist/lib/session/db.d.ts.map +1 -0
- package/dist/lib/session/db.js +599 -0
- package/dist/lib/session/db.js.map +1 -0
- package/dist/lib/session/discover.d.ts +44 -32
- package/dist/lib/session/discover.d.ts.map +1 -1
- package/dist/lib/session/discover.js +418 -464
- package/dist/lib/session/discover.js.map +1 -1
- package/dist/lib/session/parse.d.ts +11 -0
- package/dist/lib/session/parse.d.ts.map +1 -1
- package/dist/lib/session/parse.js +50 -0
- package/dist/lib/session/parse.js.map +1 -1
- package/dist/lib/session/prompt.d.ts +10 -0
- package/dist/lib/session/prompt.d.ts.map +1 -1
- package/dist/lib/session/prompt.js +38 -2
- package/dist/lib/session/prompt.js.map +1 -1
- 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 +91 -10
- package/dist/lib/session/render.d.ts.map +1 -1
- package/dist/lib/session/render.js +708 -180
- package/dist/lib/session/render.js.map +1 -1
- package/dist/lib/session/team-filter.d.ts +35 -0
- package/dist/lib/session/team-filter.d.ts.map +1 -0
- package/dist/lib/session/team-filter.js +75 -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 +48 -6
- package/dist/lib/session/types.d.ts.map +1 -1
- package/dist/lib/session/types.js +9 -0
- package/dist/lib/session/types.js.map +1 -1
- package/dist/lib/shims.d.ts +73 -2
- package/dist/lib/shims.d.ts.map +1 -1
- package/dist/lib/shims.js +171 -25
- package/dist/lib/shims.js.map +1 -1
- package/dist/lib/skills.d.ts +68 -0
- package/dist/lib/skills.d.ts.map +1 -1
- package/dist/lib/skills.js +267 -1
- package/dist/lib/skills.js.map +1 -1
- package/dist/lib/state.d.ts +41 -2
- package/dist/lib/state.d.ts.map +1 -1
- package/dist/lib/state.js +63 -4
- package/dist/lib/state.js.map +1 -1
- package/dist/lib/subagents.d.ts +9 -0
- package/dist/lib/subagents.d.ts.map +1 -1
- package/dist/lib/subagents.js +9 -1
- package/dist/lib/subagents.js.map +1 -1
- package/dist/lib/teams/__tests__/oracle.test.d.ts +2 -0
- package/dist/lib/teams/__tests__/oracle.test.d.ts.map +1 -0
- package/dist/lib/teams/__tests__/oracle.test.js +89 -0
- package/dist/lib/teams/__tests__/oracle.test.js.map +1 -0
- package/dist/lib/teams/__tests__/supervisor.test.d.ts +2 -0
- package/dist/lib/teams/__tests__/supervisor.test.d.ts.map +1 -0
- package/dist/lib/teams/__tests__/supervisor.test.js +179 -0
- package/dist/lib/teams/__tests__/supervisor.test.js.map +1 -0
- package/dist/lib/teams/agents.d.ts +247 -0
- package/dist/lib/teams/agents.d.ts.map +1 -0
- package/dist/lib/teams/agents.js +1244 -0
- package/dist/lib/teams/agents.js.map +1 -0
- package/dist/lib/teams/api.d.ts +91 -0
- package/dist/lib/teams/api.d.ts.map +1 -0
- package/dist/lib/teams/api.js +239 -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 +8 -0
- package/dist/lib/teams/debug.d.ts.map +1 -0
- package/dist/lib/teams/debug.js +12 -0
- package/dist/lib/teams/debug.js.map +1 -0
- package/dist/lib/teams/file_ops.d.ts +13 -0
- package/dist/lib/teams/file_ops.d.ts.map +1 -0
- package/dist/lib/teams/file_ops.js +66 -0
- package/dist/lib/teams/file_ops.js.map +1 -0
- package/dist/lib/teams/index.d.ts +16 -0
- package/dist/lib/teams/index.d.ts.map +1 -0
- package/dist/lib/teams/index.js +15 -0
- package/dist/lib/teams/index.js.map +1 -0
- package/dist/lib/teams/oracle.d.ts +20 -0
- package/dist/lib/teams/oracle.d.ts.map +1 -0
- package/dist/lib/teams/oracle.js +59 -0
- package/dist/lib/teams/oracle.js.map +1 -0
- package/dist/lib/teams/parsers.d.ts +9 -0
- package/dist/lib/teams/parsers.d.ts.map +1 -0
- package/dist/lib/teams/parsers.js +837 -0
- package/dist/lib/teams/parsers.js.map +1 -0
- package/dist/lib/teams/persistence.d.ts +43 -0
- package/dist/lib/teams/persistence.d.ts.map +1 -0
- package/dist/lib/teams/persistence.js +299 -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 +18 -0
- package/dist/lib/teams/registry.d.ts.map +1 -0
- package/dist/lib/teams/registry.js +68 -0
- package/dist/lib/teams/registry.js.map +1 -0
- package/dist/lib/teams/summarizer.d.ts +73 -0
- package/dist/lib/teams/summarizer.d.ts.map +1 -0
- package/dist/lib/teams/summarizer.js +780 -0
- package/dist/lib/teams/summarizer.js.map +1 -0
- package/dist/lib/teams/supervisor.d.ts +49 -0
- package/dist/lib/teams/supervisor.d.ts.map +1 -0
- package/dist/lib/teams/supervisor.js +74 -0
- package/dist/lib/teams/supervisor.js.map +1 -0
- package/dist/lib/template.d.ts +8 -5
- package/dist/lib/template.d.ts.map +1 -1
- package/dist/lib/template.js +8 -5
- package/dist/lib/template.js.map +1 -1
- package/dist/lib/types.d.ts +58 -1
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js +16 -1
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/usage.d.ts +48 -0
- package/dist/lib/usage.d.ts.map +1 -1
- package/dist/lib/usage.js +103 -11
- package/dist/lib/usage.js.map +1 -1
- package/dist/lib/versions.d.ts +12 -1
- package/dist/lib/versions.d.ts.map +1 -1
- package/dist/lib/versions.js +91 -35
- package/dist/lib/versions.js.map +1 -1
- package/package.json +20 -6
- package/scripts/postinstall.js +1 -1
- package/scripts/rebuild-sqlite.sh +46 -0
- package/dist/commands/sessions.test.d.ts +0 -2
- package/dist/commands/sessions.test.d.ts.map +0 -1
- package/dist/commands/sessions.test.js +0 -53
- package/dist/commands/sessions.test.js.map +0 -1
|
@@ -0,0 +1,602 @@
|
|
|
1
|
+
import { describe, expect, it, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
// Mock HOME for normalizeForDedup tests
|
|
3
|
+
const ORIG_HOME = process.env.HOME;
|
|
4
|
+
import { unwrapCommand, normalizeForDedup, bucketKey, relativeToCwd, linkPath, collapseRetries, computeSummaryStats, renderSummaryHeader, renderSummary, filterEvents, parseRoleList, renderConversationMarkdown, } from '../render.js';
|
|
5
|
+
// ── filterEvents ──────────────────────────────────────────────────────────────
|
|
6
|
+
describe('filterEvents', () => {
|
|
7
|
+
const events = [
|
|
8
|
+
{ type: 'message', agent: 'claude', timestamp: '2024-01-01T00:00:00Z', role: 'user', content: 'Hello' },
|
|
9
|
+
{ type: 'message', agent: 'claude', timestamp: '2024-01-01T00:00:01Z', role: 'assistant', content: 'Hi there' },
|
|
10
|
+
{ type: 'thinking', agent: 'claude', timestamp: '2024-01-01T00:00:02Z', content: 'Let me think' },
|
|
11
|
+
{ type: 'tool_use', agent: 'claude', timestamp: '2024-01-01T00:00:03Z', tool: 'Read', args: {} },
|
|
12
|
+
{ type: 'tool_result', agent: 'claude', timestamp: '2024-01-01T00:00:04Z', content: 'file contents' },
|
|
13
|
+
{ type: 'error', agent: 'claude', timestamp: '2024-01-01T00:00:05Z', content: 'fail' },
|
|
14
|
+
];
|
|
15
|
+
it('include: keeps only whitelisted roles', () => {
|
|
16
|
+
const result = filterEvents(events, { include: ['user'] });
|
|
17
|
+
expect(result).toHaveLength(1);
|
|
18
|
+
expect(result[0].role).toBe('user');
|
|
19
|
+
});
|
|
20
|
+
it('include: supports multiple roles', () => {
|
|
21
|
+
const result = filterEvents(events, { include: ['user', 'assistant'] });
|
|
22
|
+
expect(result).toHaveLength(2);
|
|
23
|
+
expect(result.every(e => e.type === 'message')).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
it('include: tools captures both tool_use and tool_result', () => {
|
|
26
|
+
const result = filterEvents(events, { include: ['tools'] });
|
|
27
|
+
expect(result).toHaveLength(2);
|
|
28
|
+
expect(result.every(e => e.type === 'tool_use' || e.type === 'tool_result')).toBe(true);
|
|
29
|
+
});
|
|
30
|
+
it('exclude: drops listed roles, keeps non-role events', () => {
|
|
31
|
+
// error has no role, so it stays.
|
|
32
|
+
const result = filterEvents(events, { exclude: ['thinking', 'tools'] });
|
|
33
|
+
expect(result.some(e => e.type === 'message' && e.role === 'user')).toBe(true);
|
|
34
|
+
expect(result.some(e => e.type === 'message' && e.role === 'assistant')).toBe(true);
|
|
35
|
+
expect(result.some(e => e.type === 'error')).toBe(true);
|
|
36
|
+
expect(result.every(e => e.type !== 'thinking' && e.type !== 'tool_use' && e.type !== 'tool_result')).toBe(true);
|
|
37
|
+
});
|
|
38
|
+
it('throws when include and exclude are both passed', () => {
|
|
39
|
+
expect(() => filterEvents(events, { include: ['user'], exclude: ['tools'] })).toThrow(/mutually exclusive/);
|
|
40
|
+
});
|
|
41
|
+
it('first: keeps events up to the Nth user turn', () => {
|
|
42
|
+
const twoTurns = [
|
|
43
|
+
{ type: 'message', agent: 'claude', timestamp: 't0', role: 'user', content: 'q1' },
|
|
44
|
+
{ type: 'message', agent: 'claude', timestamp: 't1', role: 'assistant', content: 'a1' },
|
|
45
|
+
{ type: 'message', agent: 'claude', timestamp: 't2', role: 'user', content: 'q2' },
|
|
46
|
+
{ type: 'message', agent: 'claude', timestamp: 't3', role: 'assistant', content: 'a2' },
|
|
47
|
+
];
|
|
48
|
+
const result = filterEvents(twoTurns, { first: 1 });
|
|
49
|
+
expect(result).toHaveLength(2);
|
|
50
|
+
expect(result[0].content).toBe('q1');
|
|
51
|
+
expect(result[1].content).toBe('a1');
|
|
52
|
+
});
|
|
53
|
+
it('last: keeps events from the start of the (M-N+1)th user turn', () => {
|
|
54
|
+
const twoTurns = [
|
|
55
|
+
{ type: 'message', agent: 'claude', timestamp: 't0', role: 'user', content: 'q1' },
|
|
56
|
+
{ type: 'message', agent: 'claude', timestamp: 't1', role: 'assistant', content: 'a1' },
|
|
57
|
+
{ type: 'message', agent: 'claude', timestamp: 't2', role: 'user', content: 'q2' },
|
|
58
|
+
{ type: 'message', agent: 'claude', timestamp: 't3', role: 'assistant', content: 'a2' },
|
|
59
|
+
];
|
|
60
|
+
const result = filterEvents(twoTurns, { last: 1 });
|
|
61
|
+
expect(result).toHaveLength(2);
|
|
62
|
+
expect(result[0].content).toBe('q2');
|
|
63
|
+
expect(result[1].content).toBe('a2');
|
|
64
|
+
});
|
|
65
|
+
it('first with N >= total turns returns all events', () => {
|
|
66
|
+
const result = filterEvents(events, { first: 100 });
|
|
67
|
+
expect(result).toHaveLength(events.length);
|
|
68
|
+
});
|
|
69
|
+
it('throws when first and last are both passed', () => {
|
|
70
|
+
expect(() => filterEvents(events, { first: 1, last: 1 })).toThrow(/mutually exclusive/);
|
|
71
|
+
});
|
|
72
|
+
it('turn slice and role filter compose: last 1 turn, user only', () => {
|
|
73
|
+
const twoTurns = [
|
|
74
|
+
{ type: 'message', agent: 'claude', timestamp: 't0', role: 'user', content: 'q1' },
|
|
75
|
+
{ type: 'message', agent: 'claude', timestamp: 't1', role: 'assistant', content: 'a1' },
|
|
76
|
+
{ type: 'message', agent: 'claude', timestamp: 't2', role: 'user', content: 'q2' },
|
|
77
|
+
{ type: 'message', agent: 'claude', timestamp: 't3', role: 'assistant', content: 'a2' },
|
|
78
|
+
];
|
|
79
|
+
const result = filterEvents(twoTurns, { last: 1, include: ['user'] });
|
|
80
|
+
expect(result).toHaveLength(1);
|
|
81
|
+
expect(result[0].content).toBe('q2');
|
|
82
|
+
});
|
|
83
|
+
it('no filters is a passthrough', () => {
|
|
84
|
+
const result = filterEvents(events, {});
|
|
85
|
+
expect(result).toEqual(events);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
// ── parseRoleList ─────────────────────────────────────────────────────────────
|
|
89
|
+
describe('parseRoleList', () => {
|
|
90
|
+
it('parses a comma-separated list', () => {
|
|
91
|
+
expect(parseRoleList('user,assistant', '--include')).toEqual(['user', 'assistant']);
|
|
92
|
+
});
|
|
93
|
+
it('trims whitespace', () => {
|
|
94
|
+
expect(parseRoleList(' user , thinking ', '--exclude')).toEqual(['user', 'thinking']);
|
|
95
|
+
});
|
|
96
|
+
it('rejects unknown roles with the flag name', () => {
|
|
97
|
+
expect(() => parseRoleList('user,foo', '--include')).toThrow(/"foo" for --include/);
|
|
98
|
+
expect(() => parseRoleList('user,foo', '--include')).toThrow(/user, assistant, thinking, tools/);
|
|
99
|
+
});
|
|
100
|
+
it('rejects empty input', () => {
|
|
101
|
+
expect(() => parseRoleList('', '--include')).toThrow(/at least one role/);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
// ── renderConversationMarkdown ────────────────────────────────────────────────
|
|
105
|
+
describe('renderConversationMarkdown', () => {
|
|
106
|
+
it('includes user, assistant, thinking, and tool calls in event order', () => {
|
|
107
|
+
const events = [
|
|
108
|
+
{ type: 'message', agent: 'claude', timestamp: 't0', role: 'user', content: 'Read foo.ts' },
|
|
109
|
+
{ type: 'thinking', agent: 'claude', timestamp: 't1', content: 'I should open the file first.' },
|
|
110
|
+
{ type: 'message', agent: 'claude', timestamp: 't2', role: 'assistant', content: 'Reading now.' },
|
|
111
|
+
{ type: 'tool_use', agent: 'claude', timestamp: 't3', tool: 'Read', args: { file_path: '/x/foo.ts' }, path: '/x/foo.ts' },
|
|
112
|
+
];
|
|
113
|
+
const out = renderConversationMarkdown(events);
|
|
114
|
+
expect(out).toContain('## User');
|
|
115
|
+
expect(out).toContain('Read foo.ts');
|
|
116
|
+
expect(out).toContain('### Thinking');
|
|
117
|
+
expect(out).toContain('I should open the file first.');
|
|
118
|
+
expect(out).toContain('## Assistant');
|
|
119
|
+
expect(out).toContain('Reading now.');
|
|
120
|
+
expect(out).toContain('### Tool: Read');
|
|
121
|
+
expect(out).toContain('/x/foo.ts');
|
|
122
|
+
// Order: user before thinking before assistant before tool
|
|
123
|
+
const userIdx = out.indexOf('## User');
|
|
124
|
+
const thinkIdx = out.indexOf('### Thinking');
|
|
125
|
+
const asstIdx = out.indexOf('## Assistant');
|
|
126
|
+
const toolIdx = out.indexOf('### Tool: Read');
|
|
127
|
+
expect(userIdx).toBeLessThan(thinkIdx);
|
|
128
|
+
expect(thinkIdx).toBeLessThan(asstIdx);
|
|
129
|
+
expect(asstIdx).toBeLessThan(toolIdx);
|
|
130
|
+
});
|
|
131
|
+
it('renders bash commands inside a code fence', () => {
|
|
132
|
+
const events = [
|
|
133
|
+
{ type: 'tool_use', agent: 'claude', timestamp: 't0', tool: 'Bash', args: { command: 'ls -la' }, command: 'ls -la' },
|
|
134
|
+
];
|
|
135
|
+
const out = renderConversationMarkdown(events);
|
|
136
|
+
expect(out).toContain('```bash');
|
|
137
|
+
expect(out).toContain('ls -la');
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
// ── unwrapCommand ─────────────────────────────────────────────────────────────
|
|
141
|
+
describe('unwrapCommand', () => {
|
|
142
|
+
it('returns bare command unchanged', () => {
|
|
143
|
+
expect(unwrapCommand('ls -la')).toBe('ls -la');
|
|
144
|
+
});
|
|
145
|
+
it('unwraps ssh with double-quoted payload', () => {
|
|
146
|
+
expect(unwrapCommand('ssh host "ls -la"')).toBe('ls -la');
|
|
147
|
+
});
|
|
148
|
+
it('unwraps ssh with quoted payload plus pipe (pipe is stripped)', () => {
|
|
149
|
+
// ls is not a wrapper so recursion stops there; pipe after closing quote is stripped
|
|
150
|
+
expect(unwrapCommand('ssh host "ls -la" | cat')).toBe('ls -la');
|
|
151
|
+
});
|
|
152
|
+
it('unwraps sudo prefix', () => {
|
|
153
|
+
expect(unwrapCommand('sudo bun install')).toBe('bun install');
|
|
154
|
+
});
|
|
155
|
+
it('unwraps cd && prefix', () => {
|
|
156
|
+
expect(unwrapCommand('cd /tmp && ls')).toBe('ls');
|
|
157
|
+
});
|
|
158
|
+
it('keeps bun run intact (two-level bucketKey handles it)', () => {
|
|
159
|
+
expect(unwrapCommand('bun run build')).toBe('bun run build');
|
|
160
|
+
});
|
|
161
|
+
it('unwraps npx prefix', () => {
|
|
162
|
+
expect(unwrapCommand('npx tsc --noEmit')).toBe('tsc --noEmit');
|
|
163
|
+
});
|
|
164
|
+
it('unwraps shell env prefix', () => {
|
|
165
|
+
expect(unwrapCommand('BENCH_MODE=full npx tsx bench/x.ts')).toBe('tsx bench/x.ts');
|
|
166
|
+
expect(unwrapCommand('FOO=bar BAR=baz cargo build')).toBe('cargo build');
|
|
167
|
+
});
|
|
168
|
+
it('unwraps ssh with env-prefixed inner command', () => {
|
|
169
|
+
expect(unwrapCommand('ssh host "PATH=/opt/bin:$PATH openclaw browser profiles"')).toBe('openclaw browser profiles');
|
|
170
|
+
});
|
|
171
|
+
it('unwraps nested: ssh + sudo', () => {
|
|
172
|
+
expect(unwrapCommand('ssh host "sudo tsc --noEmit"')).toBe('tsc --noEmit');
|
|
173
|
+
});
|
|
174
|
+
it('unwraps time prefix', () => {
|
|
175
|
+
expect(unwrapCommand('time cargo build')).toBe('cargo build');
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
// ── normalizeForDedup ─────────────────────────────────────────────────────────
|
|
179
|
+
describe('normalizeForDedup', () => {
|
|
180
|
+
beforeEach(() => {
|
|
181
|
+
process.env.HOME = '/home/user';
|
|
182
|
+
});
|
|
183
|
+
afterEach(() => {
|
|
184
|
+
process.env.HOME = ORIG_HOME;
|
|
185
|
+
});
|
|
186
|
+
it('strips short flags', () => {
|
|
187
|
+
expect(normalizeForDedup('ls -lh /tmp')).toBe('ls /tmp');
|
|
188
|
+
});
|
|
189
|
+
it('strips long flags', () => {
|
|
190
|
+
expect(normalizeForDedup('git --no-pager log')).toBe('git log');
|
|
191
|
+
});
|
|
192
|
+
it('strips long flags with value', () => {
|
|
193
|
+
expect(normalizeForDedup('git log --format=oneline')).toBe('git log');
|
|
194
|
+
});
|
|
195
|
+
it('strips trailing pipe to head', () => {
|
|
196
|
+
expect(normalizeForDedup('ls /tmp | head -20')).toBe('ls /tmp');
|
|
197
|
+
});
|
|
198
|
+
it('strips trailing pipe to wc', () => {
|
|
199
|
+
expect(normalizeForDedup('ls /tmp | wc -l')).toBe('ls /tmp');
|
|
200
|
+
});
|
|
201
|
+
it('strips 2>&1', () => {
|
|
202
|
+
expect(normalizeForDedup('ls /tmp 2>&1')).toBe('ls /tmp');
|
|
203
|
+
});
|
|
204
|
+
it('strips ; echo done suffix', () => {
|
|
205
|
+
expect(normalizeForDedup('bun test; echo done')).toBe('bun test');
|
|
206
|
+
});
|
|
207
|
+
it('replaces leading $HOME with ~ when command starts with home path', () => {
|
|
208
|
+
// The ^ anchor replaces only when the string begins with $HOME
|
|
209
|
+
expect(normalizeForDedup('/home/user/.agents/run.sh')).toBe('~/.agents/run.sh');
|
|
210
|
+
});
|
|
211
|
+
it('collapses ls -lh + ls -la + ls 2>&1 to same key', () => {
|
|
212
|
+
const a = normalizeForDedup('ls -lh /home/user/sessions/ | head');
|
|
213
|
+
const b = normalizeForDedup('ls -la /home/user/sessions/');
|
|
214
|
+
const c = normalizeForDedup('ls /home/user/sessions/ 2>&1');
|
|
215
|
+
expect(a).toBe(b);
|
|
216
|
+
expect(b).toBe(c);
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
// ── bucketKey ─────────────────────────────────────────────────────────────────
|
|
220
|
+
describe('bucketKey', () => {
|
|
221
|
+
it('returns two-level key for git', () => {
|
|
222
|
+
expect(bucketKey('git status')).toBe('git status');
|
|
223
|
+
expect(bucketKey('git diff HEAD')).toBe('git diff');
|
|
224
|
+
});
|
|
225
|
+
it('returns two-level key for gh', () => {
|
|
226
|
+
expect(bucketKey('gh pr view 123')).toBe('gh pr');
|
|
227
|
+
});
|
|
228
|
+
it('returns two-level key for bun', () => {
|
|
229
|
+
expect(bucketKey('bun test --watch')).toBe('bun test');
|
|
230
|
+
});
|
|
231
|
+
it('returns two-level key for cargo', () => {
|
|
232
|
+
expect(bucketKey('cargo build --release')).toBe('cargo build');
|
|
233
|
+
});
|
|
234
|
+
it('returns single-token key for ls', () => {
|
|
235
|
+
expect(bucketKey('ls -la')).toBe('ls');
|
|
236
|
+
});
|
|
237
|
+
it('returns single-token key for grep', () => {
|
|
238
|
+
expect(bucketKey('grep -r pattern .')).toBe('grep');
|
|
239
|
+
});
|
|
240
|
+
it('returns ssh→CMD prefix for ssh-wrapped commands', () => {
|
|
241
|
+
expect(bucketKey('ssh host "ls -la"')).toBe('ssh\u2192ls');
|
|
242
|
+
});
|
|
243
|
+
it('returns ssh→two-level for ssh-wrapped openclaw', () => {
|
|
244
|
+
expect(bucketKey('ssh host "openclaw browser profiles"')).toBe('ssh\u2192openclaw browser');
|
|
245
|
+
});
|
|
246
|
+
it('returns ssh→git status for ssh-wrapped git', () => {
|
|
247
|
+
expect(bucketKey('ssh host "git status"')).toBe('ssh\u2192git status');
|
|
248
|
+
});
|
|
249
|
+
it('returns single token for unknown commands', () => {
|
|
250
|
+
expect(bucketKey('python3 bench.py')).toBe('python3');
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
// ── Category routing ──────────────────────────────────────────────────────────
|
|
254
|
+
describe('category routing (via renderSummary commands section)', () => {
|
|
255
|
+
function buildBashEvents(cmds) {
|
|
256
|
+
return cmds.map((cmd, i) => ({
|
|
257
|
+
type: 'tool_use',
|
|
258
|
+
agent: 'claude',
|
|
259
|
+
timestamp: new Date(Date.now() + i * 1000).toISOString(),
|
|
260
|
+
tool: 'Bash',
|
|
261
|
+
args: { command: cmd },
|
|
262
|
+
command: cmd,
|
|
263
|
+
}));
|
|
264
|
+
}
|
|
265
|
+
it('includes Build/test bucket for bun commands', () => {
|
|
266
|
+
const events = buildBashEvents(['bun run build', 'bun test']);
|
|
267
|
+
const out = renderSummary(events);
|
|
268
|
+
expect(out).toContain('Build/test');
|
|
269
|
+
});
|
|
270
|
+
it('includes VCS bucket for git commands', () => {
|
|
271
|
+
const events = buildBashEvents(['git status', 'git diff']);
|
|
272
|
+
const out = renderSummary(events);
|
|
273
|
+
expect(out).toContain('VCS');
|
|
274
|
+
});
|
|
275
|
+
it('includes Remote bucket for ssh commands', () => {
|
|
276
|
+
const events = buildBashEvents(['ssh host "ls"']);
|
|
277
|
+
const out = renderSummary(events);
|
|
278
|
+
expect(out).toContain('Remote');
|
|
279
|
+
});
|
|
280
|
+
it('Probes bucket uses low signal (inline list, not expanded)', () => {
|
|
281
|
+
const events = buildBashEvents(['ls /tmp', 'cat file.txt', 'head -n 5 file.txt']);
|
|
282
|
+
const out = renderSummary(events);
|
|
283
|
+
expect(out).toContain('Probes');
|
|
284
|
+
// Low signal: should show inline dash-separated list, not individual lines
|
|
285
|
+
expect(out).toMatch(/Probes.*—/);
|
|
286
|
+
});
|
|
287
|
+
it('Other bucket catches uncategorized tokens', () => {
|
|
288
|
+
const events = buildBashEvents(['python3 bench.py', 'ruby script.rb']);
|
|
289
|
+
const out = renderSummary(events);
|
|
290
|
+
expect(out).toContain('Other');
|
|
291
|
+
});
|
|
292
|
+
it('Wait bucket for sleep commands', () => {
|
|
293
|
+
const events = buildBashEvents(['sleep 30', 'sleep 10']);
|
|
294
|
+
const out = renderSummary(events);
|
|
295
|
+
expect(out).toContain('Wait');
|
|
296
|
+
// Low signal — inline
|
|
297
|
+
expect(out).toMatch(/Wait.*—/);
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
// ── collapseRetries ───────────────────────────────────────────────────────────
|
|
301
|
+
describe('collapseRetries', () => {
|
|
302
|
+
const base = Date.now();
|
|
303
|
+
it('collapses 3 identical commands within 60s to one entry', () => {
|
|
304
|
+
const cmds = [
|
|
305
|
+
{ cmd: 'bun test', ts: base },
|
|
306
|
+
{ cmd: 'bun test', ts: base + 10_000 },
|
|
307
|
+
{ cmd: 'bun test', ts: base + 20_000 },
|
|
308
|
+
];
|
|
309
|
+
const result = collapseRetries(cmds);
|
|
310
|
+
expect(result).toHaveLength(1);
|
|
311
|
+
expect(result[0].count).toBe(3);
|
|
312
|
+
});
|
|
313
|
+
it('keeps 2 identical commands within 60s as separate entries', () => {
|
|
314
|
+
const cmds = [
|
|
315
|
+
{ cmd: 'bun test', ts: base },
|
|
316
|
+
{ cmd: 'bun test', ts: base + 10_000 },
|
|
317
|
+
];
|
|
318
|
+
const result = collapseRetries(cmds);
|
|
319
|
+
expect(result).toHaveLength(2);
|
|
320
|
+
expect(result[0].count).toBe(1);
|
|
321
|
+
expect(result[1].count).toBe(1);
|
|
322
|
+
});
|
|
323
|
+
it('keeps invocations >60s apart as separate entries', () => {
|
|
324
|
+
const cmds = [
|
|
325
|
+
{ cmd: 'bun test', ts: base },
|
|
326
|
+
{ cmd: 'bun test', ts: base + 10_000 },
|
|
327
|
+
{ cmd: 'bun test', ts: base + 90_000 }, // >60s gap
|
|
328
|
+
];
|
|
329
|
+
const result = collapseRetries(cmds);
|
|
330
|
+
// First two: within 60s but count=2, expanded back to 2
|
|
331
|
+
// Third: new group
|
|
332
|
+
expect(result.some(r => r.count === 1)).toBe(true);
|
|
333
|
+
});
|
|
334
|
+
it('collapses flag-variant commands that normalize to same key', () => {
|
|
335
|
+
const cmds = [
|
|
336
|
+
{ cmd: 'ls -la /tmp', ts: base },
|
|
337
|
+
{ cmd: 'ls -lh /tmp', ts: base + 5_000 },
|
|
338
|
+
{ cmd: 'ls /tmp 2>&1', ts: base + 10_000 },
|
|
339
|
+
];
|
|
340
|
+
const result = collapseRetries(cmds);
|
|
341
|
+
expect(result).toHaveLength(1);
|
|
342
|
+
expect(result[0].count).toBe(3);
|
|
343
|
+
});
|
|
344
|
+
});
|
|
345
|
+
// ── relativeToCwd ─────────────────────────────────────────────────────────────
|
|
346
|
+
describe('relativeToCwd', () => {
|
|
347
|
+
beforeEach(() => { process.env.HOME = '/home/user'; });
|
|
348
|
+
afterEach(() => { process.env.HOME = ORIG_HOME; });
|
|
349
|
+
it('returns cwd-relative path when inside cwd', () => {
|
|
350
|
+
expect(relativeToCwd('/home/user/project/src/index.ts', '/home/user/project')).toBe('src/index.ts');
|
|
351
|
+
});
|
|
352
|
+
it('returns . when path equals cwd', () => {
|
|
353
|
+
expect(relativeToCwd('/home/user/project', '/home/user/project')).toBe('.');
|
|
354
|
+
});
|
|
355
|
+
it('returns home-relative path when outside cwd', () => {
|
|
356
|
+
expect(relativeToCwd('/home/user/.claude/settings.json', '/home/user/project')).toBe('~/.claude/settings.json');
|
|
357
|
+
});
|
|
358
|
+
it('returns absolute path when outside both cwd and home', () => {
|
|
359
|
+
expect(relativeToCwd('/etc/hosts', '/home/user/project')).toBe('/etc/hosts');
|
|
360
|
+
});
|
|
361
|
+
it('works without cwd (falls back to home-relative)', () => {
|
|
362
|
+
expect(relativeToCwd('/home/user/foo.ts')).toBe('~/foo.ts');
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
// ── linkPath ──────────────────────────────────────────────────────────────────
|
|
366
|
+
describe('linkPath', () => {
|
|
367
|
+
it('returns plain label when stdout is not TTY', () => {
|
|
368
|
+
const origIsTTY = process.stdout.isTTY;
|
|
369
|
+
Object.defineProperty(process.stdout, 'isTTY', { value: false, configurable: true });
|
|
370
|
+
const result = linkPath('/some/path', 'label');
|
|
371
|
+
expect(result).toBe('label');
|
|
372
|
+
Object.defineProperty(process.stdout, 'isTTY', { value: origIsTTY, configurable: true });
|
|
373
|
+
});
|
|
374
|
+
it('emits OSC 8 sequence when TTY env is set', () => {
|
|
375
|
+
const origIsTTY = process.stdout.isTTY;
|
|
376
|
+
const origTermProgram = process.env.TERM_PROGRAM;
|
|
377
|
+
Object.defineProperty(process.stdout, 'isTTY', { value: true, configurable: true });
|
|
378
|
+
process.env.TERM_PROGRAM = 'iTerm.app';
|
|
379
|
+
const result = linkPath('/some/path', 'label');
|
|
380
|
+
expect(result).toContain('\x1b]8;;file:///some/path\x1b\\');
|
|
381
|
+
expect(result).toContain('label');
|
|
382
|
+
expect(result).toContain('\x1b]8;;\x1b\\');
|
|
383
|
+
Object.defineProperty(process.stdout, 'isTTY', { value: origIsTTY, configurable: true });
|
|
384
|
+
if (origTermProgram === undefined)
|
|
385
|
+
delete process.env.TERM_PROGRAM;
|
|
386
|
+
else
|
|
387
|
+
process.env.TERM_PROGRAM = origTermProgram;
|
|
388
|
+
});
|
|
389
|
+
});
|
|
390
|
+
// ── computeSummaryStats ───────────────────────────────────────────────────────
|
|
391
|
+
describe('computeSummaryStats', () => {
|
|
392
|
+
it('counts user/assistant turns, tools, errors', () => {
|
|
393
|
+
const events = [
|
|
394
|
+
{ type: 'message', agent: 'claude', timestamp: '2024-01-01T00:00:00Z', role: 'user', content: 'hi' },
|
|
395
|
+
{ type: 'tool_use', agent: 'claude', timestamp: '2024-01-01T00:00:01Z', tool: 'Read', args: {} },
|
|
396
|
+
{ type: 'message', agent: 'claude', timestamp: '2024-01-01T00:00:02Z', role: 'assistant', content: 'done' },
|
|
397
|
+
{ type: 'error', agent: 'claude', timestamp: '2024-01-01T00:00:03Z', content: 'fail' },
|
|
398
|
+
];
|
|
399
|
+
const stats = computeSummaryStats(events);
|
|
400
|
+
expect(stats.userTurns).toBe(1);
|
|
401
|
+
expect(stats.assistantTurns).toBe(1);
|
|
402
|
+
expect(stats.toolCount).toBe(1);
|
|
403
|
+
expect(stats.errorCount).toBe(1);
|
|
404
|
+
});
|
|
405
|
+
it('sums token counts from usage events', () => {
|
|
406
|
+
const events = [
|
|
407
|
+
{
|
|
408
|
+
type: 'usage', agent: 'claude', timestamp: '2024-01-01T00:00:00Z',
|
|
409
|
+
model: 'claude-opus-4-7-20251001',
|
|
410
|
+
outputTokens: 1000, cacheReadTokens: 50000,
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
type: 'usage', agent: 'claude', timestamp: '2024-01-01T00:00:01Z',
|
|
414
|
+
model: 'claude-opus-4-7-20251001',
|
|
415
|
+
outputTokens: 500, cacheReadTokens: 10000,
|
|
416
|
+
},
|
|
417
|
+
];
|
|
418
|
+
const stats = computeSummaryStats(events);
|
|
419
|
+
expect(stats.outputTokens).toBe(1500);
|
|
420
|
+
expect(stats.cacheReadTokens).toBe(60000);
|
|
421
|
+
expect(stats.models).toEqual(['opus-4-7']);
|
|
422
|
+
});
|
|
423
|
+
it('skips local tool_use events in tool count', () => {
|
|
424
|
+
const events = [
|
|
425
|
+
{ type: 'tool_use', agent: 'claude', timestamp: '2024-01-01T00:00:00Z', tool: 'Bash', args: {}, _local: true },
|
|
426
|
+
];
|
|
427
|
+
const stats = computeSummaryStats(events);
|
|
428
|
+
expect(stats.toolCount).toBe(0);
|
|
429
|
+
});
|
|
430
|
+
});
|
|
431
|
+
// ── renderSummaryHeader ───────────────────────────────────────────────────────
|
|
432
|
+
describe('renderSummaryHeader', () => {
|
|
433
|
+
it('formats turn/tool/token/duration stats', () => {
|
|
434
|
+
const stats = {
|
|
435
|
+
models: ['opus-4-7'],
|
|
436
|
+
userTurns: 10,
|
|
437
|
+
assistantTurns: 10,
|
|
438
|
+
toolCount: 50,
|
|
439
|
+
errorCount: 2,
|
|
440
|
+
outputTokens: 361_000,
|
|
441
|
+
cacheReadTokens: 67_500_000,
|
|
442
|
+
firstTs: 0,
|
|
443
|
+
lastTs: 12 * 60_000,
|
|
444
|
+
};
|
|
445
|
+
const out = renderSummaryHeader(stats);
|
|
446
|
+
expect(out).toContain('20 turns');
|
|
447
|
+
expect(out).toContain('50 tools');
|
|
448
|
+
expect(out).toContain('2 errors');
|
|
449
|
+
expect(out).toContain('67.5M cached');
|
|
450
|
+
expect(out).toContain('361K out');
|
|
451
|
+
expect(out).toContain('12 min');
|
|
452
|
+
});
|
|
453
|
+
it('omits token section when no tokens recorded', () => {
|
|
454
|
+
const stats = {
|
|
455
|
+
models: [],
|
|
456
|
+
userTurns: 5,
|
|
457
|
+
assistantTurns: 5,
|
|
458
|
+
toolCount: 0,
|
|
459
|
+
errorCount: 0,
|
|
460
|
+
outputTokens: 0,
|
|
461
|
+
cacheReadTokens: 0,
|
|
462
|
+
firstTs: 0,
|
|
463
|
+
lastTs: 0,
|
|
464
|
+
};
|
|
465
|
+
const out = renderSummaryHeader(stats);
|
|
466
|
+
expect(out).not.toContain('cached');
|
|
467
|
+
expect(out).not.toContain('out');
|
|
468
|
+
});
|
|
469
|
+
});
|
|
470
|
+
// ── renderSummary integration ─────────────────────────────────────────────────
|
|
471
|
+
describe('renderSummary', () => {
|
|
472
|
+
function makeEvent(overrides) {
|
|
473
|
+
return {
|
|
474
|
+
type: 'message',
|
|
475
|
+
agent: 'claude',
|
|
476
|
+
timestamp: '2024-01-01T00:00:00Z',
|
|
477
|
+
...overrides,
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
it('dedupes Read vs Modified: modified file not in read count', () => {
|
|
481
|
+
const events = [
|
|
482
|
+
makeEvent({ type: 'tool_use', tool: 'Read', args: { file_path: '/project/src/a.ts' }, path: '/project/src/a.ts' }),
|
|
483
|
+
makeEvent({ type: 'tool_use', tool: 'Edit', args: { file_path: '/project/src/a.ts' }, path: '/project/src/a.ts' }),
|
|
484
|
+
];
|
|
485
|
+
const out = renderSummary(events, '/project');
|
|
486
|
+
// a.ts should appear in Modified, not in Read
|
|
487
|
+
expect(out).toContain('Modified');
|
|
488
|
+
// The Read section should not appear since the only read file was also modified
|
|
489
|
+
// (and would be deduped out, leaving 0 read-only files)
|
|
490
|
+
const readMatch = out.match(/Read\s+\((\d+)\)/);
|
|
491
|
+
if (readMatch) {
|
|
492
|
+
expect(parseInt(readMatch[1])).toBe(0);
|
|
493
|
+
}
|
|
494
|
+
});
|
|
495
|
+
it('renders final message up to 3000 chars', () => {
|
|
496
|
+
const longMsg = 'x'.repeat(4000);
|
|
497
|
+
const events = [
|
|
498
|
+
makeEvent({ role: 'assistant', content: longMsg }),
|
|
499
|
+
];
|
|
500
|
+
const out = renderSummary(events);
|
|
501
|
+
expect(out).toContain('x'.repeat(100));
|
|
502
|
+
// Should truncate at 3000
|
|
503
|
+
expect(out.indexOf('...')).toBeGreaterThan(0);
|
|
504
|
+
expect(out.indexOf('x'.repeat(3001))).toBe(-1);
|
|
505
|
+
});
|
|
506
|
+
it('renders prompt without 300-char cap', () => {
|
|
507
|
+
const longPrompt = 'Implement a feature that '.repeat(20); // >300 chars
|
|
508
|
+
const events = [
|
|
509
|
+
makeEvent({ role: 'user', content: longPrompt }),
|
|
510
|
+
];
|
|
511
|
+
const out = renderSummary(events);
|
|
512
|
+
// Should not be truncated at 300 chars
|
|
513
|
+
expect(out.length).toBeGreaterThan(300);
|
|
514
|
+
// Should not contain '...' from truncation
|
|
515
|
+
const promptSection = out.split('\n').find(l => l.includes('Prompt:'));
|
|
516
|
+
expect(promptSection).toBeTruthy();
|
|
517
|
+
expect(promptSection?.endsWith('...')).toBe(false);
|
|
518
|
+
});
|
|
519
|
+
it('shows attachment count line for image blocks', () => {
|
|
520
|
+
const events = [
|
|
521
|
+
makeEvent({ type: 'attachment', mediaType: 'image/png', sizeBytes: 1024 }),
|
|
522
|
+
makeEvent({ type: 'attachment', mediaType: 'image/jpeg', sizeBytes: 2048 }),
|
|
523
|
+
];
|
|
524
|
+
const out = renderSummary(events);
|
|
525
|
+
expect(out).toContain('2 screenshot');
|
|
526
|
+
expect(out).toContain('image/png');
|
|
527
|
+
expect(out).toContain('image/jpeg');
|
|
528
|
+
});
|
|
529
|
+
it('shows TodoWrite items in Plan section', () => {
|
|
530
|
+
const events = [
|
|
531
|
+
makeEvent({
|
|
532
|
+
type: 'tool_use',
|
|
533
|
+
tool: 'TodoWrite',
|
|
534
|
+
args: {
|
|
535
|
+
todos: [
|
|
536
|
+
{ content: 'Write tests', status: 'pending' },
|
|
537
|
+
{ content: 'Build project', status: 'pending' },
|
|
538
|
+
],
|
|
539
|
+
},
|
|
540
|
+
}),
|
|
541
|
+
];
|
|
542
|
+
const out = renderSummary(events);
|
|
543
|
+
expect(out).toContain('Plan');
|
|
544
|
+
expect(out).toContain('Write tests');
|
|
545
|
+
expect(out).toContain('Build project');
|
|
546
|
+
});
|
|
547
|
+
it('shows subagent spawns in Subagents section', () => {
|
|
548
|
+
const events = [
|
|
549
|
+
makeEvent({
|
|
550
|
+
type: 'tool_use',
|
|
551
|
+
tool: 'Agent',
|
|
552
|
+
args: {
|
|
553
|
+
description: 'Explore the codebase',
|
|
554
|
+
subagent_type: 'Explore',
|
|
555
|
+
},
|
|
556
|
+
}),
|
|
557
|
+
];
|
|
558
|
+
const out = renderSummary(events);
|
|
559
|
+
expect(out).toContain('Subagents');
|
|
560
|
+
expect(out).toContain('Explore the codebase');
|
|
561
|
+
expect(out).toContain('Explore');
|
|
562
|
+
});
|
|
563
|
+
it('shows error count and first failing tool', () => {
|
|
564
|
+
const events = [
|
|
565
|
+
makeEvent({ type: 'error', tool: 'Bash', args: { command: 'bun test' }, content: 'exit 1' }),
|
|
566
|
+
makeEvent({ type: 'error', tool: 'Bash', args: { command: 'bun build' }, content: 'exit 1' }),
|
|
567
|
+
];
|
|
568
|
+
const out = renderSummary(events);
|
|
569
|
+
expect(out).toContain('2 failure');
|
|
570
|
+
expect(out).toContain('Bash');
|
|
571
|
+
});
|
|
572
|
+
it('separates external edits (outside cwd) from in-project Modified', () => {
|
|
573
|
+
const events = [
|
|
574
|
+
makeEvent({ type: 'tool_use', tool: 'Edit', args: { file_path: '/project/src/a.ts' }, path: '/project/src/a.ts' }),
|
|
575
|
+
makeEvent({ type: 'tool_use', tool: 'Edit', args: { file_path: '/tmp/scratch.md' }, path: '/tmp/scratch.md' }),
|
|
576
|
+
];
|
|
577
|
+
const out = renderSummary(events, '/project');
|
|
578
|
+
expect(out).toContain('Modified');
|
|
579
|
+
expect(out).toContain('src/a.ts');
|
|
580
|
+
expect(out).toContain('External edits');
|
|
581
|
+
expect(out).toContain('/tmp/scratch.md');
|
|
582
|
+
});
|
|
583
|
+
it('surfaces TaskCreate descriptions in Plan section', () => {
|
|
584
|
+
const events = [
|
|
585
|
+
makeEvent({ type: 'tool_use', tool: 'TaskCreate', args: { description: 'Build benchmark harness', prompt: '...' } }),
|
|
586
|
+
makeEvent({ type: 'tool_use', tool: 'TaskCreate', args: { description: 'Migrate to FTS5 index' } }),
|
|
587
|
+
];
|
|
588
|
+
const out = renderSummary(events);
|
|
589
|
+
expect(out).toContain('Plan');
|
|
590
|
+
expect(out).toContain('Build benchmark harness');
|
|
591
|
+
expect(out).toContain('Migrate to FTS5 index');
|
|
592
|
+
});
|
|
593
|
+
it('uses cwd-relative paths in Modified section', () => {
|
|
594
|
+
const events = [
|
|
595
|
+
makeEvent({ type: 'tool_use', tool: 'Edit', args: { file_path: '/project/src/lib/render.ts' }, path: '/project/src/lib/render.ts' }),
|
|
596
|
+
];
|
|
597
|
+
const out = renderSummary(events, '/project');
|
|
598
|
+
expect(out).toContain('src/lib/render.ts');
|
|
599
|
+
expect(out).not.toContain('/project/src/lib/render.ts');
|
|
600
|
+
});
|
|
601
|
+
});
|
|
602
|
+
//# sourceMappingURL=render.test.js.map
|