@swarmify/agents-cli 1.13.4 → 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/README.md +4 -319
- package/bin/agents.js +2 -0
- package/package.json +13 -79
- package/scripts/postinstall.js +4 -71
- package/CHANGELOG.md +0 -316
- package/LICENSE +0 -21
- package/dist/commands/__tests__/sessions-tail.test.d.ts +0 -2
- package/dist/commands/__tests__/sessions-tail.test.d.ts.map +0 -1
- package/dist/commands/__tests__/sessions-tail.test.js +0 -108
- package/dist/commands/__tests__/sessions-tail.test.js.map +0 -1
- 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/cloud.d.ts +0 -11
- package/dist/commands/cloud.d.ts.map +0 -1
- package/dist/commands/cloud.js +0 -363
- package/dist/commands/cloud.js.map +0 -1
- package/dist/commands/commands.d.ts +0 -12
- package/dist/commands/commands.d.ts.map +0 -1
- package/dist/commands/commands.js +0 -629
- package/dist/commands/commands.js.map +0 -1
- package/dist/commands/daemon.d.ts +0 -11
- package/dist/commands/daemon.d.ts.map +0 -1
- package/dist/commands/daemon.js +0 -119
- package/dist/commands/daemon.js.map +0 -1
- package/dist/commands/drive.d.ts +0 -11
- package/dist/commands/drive.d.ts.map +0 -1
- package/dist/commands/drive.js +0 -175
- package/dist/commands/drive.js.map +0 -1
- package/dist/commands/exec.d.ts +0 -11
- package/dist/commands/exec.d.ts.map +0 -1
- package/dist/commands/exec.js +0 -251
- package/dist/commands/exec.js.map +0 -1
- package/dist/commands/factory.d.ts +0 -11
- package/dist/commands/factory.d.ts.map +0 -1
- package/dist/commands/factory.js +0 -445
- package/dist/commands/factory.js.map +0 -1
- package/dist/commands/fork.d.ts +0 -11
- package/dist/commands/fork.d.ts.map +0 -1
- package/dist/commands/fork.js +0 -147
- package/dist/commands/fork.js.map +0 -1
- package/dist/commands/hooks.d.ts +0 -12
- package/dist/commands/hooks.d.ts.map +0 -1
- package/dist/commands/hooks.js +0 -690
- package/dist/commands/hooks.js.map +0 -1
- package/dist/commands/init.d.ts +0 -15
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js +0 -137
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/mcp.d.ts +0 -12
- package/dist/commands/mcp.d.ts.map +0 -1
- package/dist/commands/mcp.js +0 -583
- package/dist/commands/mcp.js.map +0 -1
- package/dist/commands/models.d.ts +0 -11
- package/dist/commands/models.d.ts.map +0 -1
- package/dist/commands/models.js +0 -170
- package/dist/commands/models.js.map +0 -1
- package/dist/commands/packages.d.ts +0 -11
- package/dist/commands/packages.d.ts.map +0 -1
- package/dist/commands/packages.js +0 -551
- package/dist/commands/packages.js.map +0 -1
- package/dist/commands/permissions.d.ts +0 -12
- package/dist/commands/permissions.d.ts.map +0 -1
- package/dist/commands/permissions.js +0 -724
- package/dist/commands/permissions.js.map +0 -1
- package/dist/commands/plugins.d.ts +0 -11
- package/dist/commands/plugins.d.ts.map +0 -1
- package/dist/commands/plugins.js +0 -393
- package/dist/commands/plugins.js.map +0 -1
- package/dist/commands/profiles.d.ts +0 -12
- package/dist/commands/profiles.d.ts.map +0 -1
- package/dist/commands/profiles.js +0 -255
- package/dist/commands/profiles.js.map +0 -1
- package/dist/commands/pty.d.ts +0 -21
- package/dist/commands/pty.d.ts.map +0 -1
- package/dist/commands/pty.js +0 -391
- package/dist/commands/pty.js.map +0 -1
- package/dist/commands/pull.d.ts +0 -11
- package/dist/commands/pull.d.ts.map +0 -1
- package/dist/commands/pull.js +0 -456
- package/dist/commands/pull.js.map +0 -1
- package/dist/commands/push.d.ts +0 -11
- package/dist/commands/push.d.ts.map +0 -1
- package/dist/commands/push.js +0 -188
- package/dist/commands/push.js.map +0 -1
- package/dist/commands/refresh-memory.d.ts +0 -16
- package/dist/commands/refresh-memory.d.ts.map +0 -1
- package/dist/commands/refresh-memory.js +0 -52
- package/dist/commands/refresh-memory.js.map +0 -1
- package/dist/commands/resource-view.d.ts +0 -39
- package/dist/commands/resource-view.d.ts.map +0 -1
- package/dist/commands/resource-view.js +0 -197
- package/dist/commands/resource-view.js.map +0 -1
- package/dist/commands/routines.d.ts +0 -11
- package/dist/commands/routines.d.ts.map +0 -1
- package/dist/commands/routines.js +0 -590
- package/dist/commands/routines.js.map +0 -1
- package/dist/commands/rules.d.ts +0 -12
- package/dist/commands/rules.d.ts.map +0 -1
- package/dist/commands/rules.js +0 -489
- package/dist/commands/rules.js.map +0 -1
- package/dist/commands/secrets.d.ts +0 -11
- package/dist/commands/secrets.d.ts.map +0 -1
- package/dist/commands/secrets.js +0 -352
- package/dist/commands/secrets.js.map +0 -1
- package/dist/commands/sessions-picker.d.ts +0 -18
- package/dist/commands/sessions-picker.d.ts.map +0 -1
- package/dist/commands/sessions-picker.js +0 -265
- package/dist/commands/sessions-picker.js.map +0 -1
- package/dist/commands/sessions-tail.d.ts +0 -20
- package/dist/commands/sessions-tail.d.ts.map +0 -1
- package/dist/commands/sessions-tail.js +0 -236
- package/dist/commands/sessions-tail.js.map +0 -1
- package/dist/commands/sessions.d.ts +0 -18
- package/dist/commands/sessions.d.ts.map +0 -1
- package/dist/commands/sessions.js +0 -1173
- package/dist/commands/sessions.js.map +0 -1
- package/dist/commands/skills.d.ts +0 -12
- package/dist/commands/skills.d.ts.map +0 -1
- package/dist/commands/skills.js +0 -717
- package/dist/commands/skills.js.map +0 -1
- package/dist/commands/status.d.ts +0 -10
- package/dist/commands/status.d.ts.map +0 -1
- package/dist/commands/status.js +0 -26
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/subagents.d.ts +0 -11
- package/dist/commands/subagents.d.ts.map +0 -1
- package/dist/commands/subagents.js +0 -361
- package/dist/commands/subagents.js.map +0 -1
- package/dist/commands/sync.d.ts +0 -11
- package/dist/commands/sync.d.ts.map +0 -1
- package/dist/commands/sync.js +0 -70
- package/dist/commands/sync.js.map +0 -1
- package/dist/commands/teams-picker.d.ts +0 -18
- package/dist/commands/teams-picker.d.ts.map +0 -1
- package/dist/commands/teams-picker.js +0 -290
- package/dist/commands/teams-picker.js.map +0 -1
- package/dist/commands/teams.d.ts +0 -18
- package/dist/commands/teams.d.ts.map +0 -1
- package/dist/commands/teams.js +0 -1144
- package/dist/commands/teams.js.map +0 -1
- package/dist/commands/utils.d.ts +0 -45
- package/dist/commands/utils.d.ts.map +0 -1
- package/dist/commands/utils.js +0 -106
- package/dist/commands/utils.js.map +0 -1
- package/dist/commands/versions.d.ts +0 -11
- package/dist/commands/versions.d.ts.map +0 -1
- package/dist/commands/versions.js +0 -701
- package/dist/commands/versions.js.map +0 -1
- package/dist/commands/view.d.ts +0 -43
- package/dist/commands/view.d.ts.map +0 -1
- package/dist/commands/view.js +0 -894
- package/dist/commands/view.js.map +0 -1
- package/dist/index.d.ts +0 -9
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -496
- 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 -239
- package/dist/lib/__tests__/models.test.js.map +0 -1
- package/dist/lib/__tests__/rotate.test.d.ts +0 -2
- package/dist/lib/__tests__/rotate.test.d.ts.map +0 -1
- package/dist/lib/__tests__/rotate.test.js +0 -80
- package/dist/lib/__tests__/rotate.test.js.map +0 -1
- package/dist/lib/__tests__/secrets-bundles.test.d.ts +0 -2
- package/dist/lib/__tests__/secrets-bundles.test.d.ts.map +0 -1
- package/dist/lib/__tests__/secrets-bundles.test.js +0 -104
- package/dist/lib/__tests__/secrets-bundles.test.js.map +0 -1
- package/dist/lib/__tests__/secrets.test.d.ts +0 -2
- package/dist/lib/__tests__/secrets.test.d.ts.map +0 -1
- package/dist/lib/__tests__/secrets.test.js +0 -90
- package/dist/lib/__tests__/secrets.test.js.map +0 -1
- package/dist/lib/__tests__/shims.test.d.ts +0 -2
- package/dist/lib/__tests__/shims.test.d.ts.map +0 -1
- package/dist/lib/__tests__/shims.test.js +0 -57
- package/dist/lib/__tests__/shims.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 -220
- package/dist/lib/__tests__/usage.test.js.map +0 -1
- package/dist/lib/__tests__/versions.test.d.ts +0 -2
- package/dist/lib/__tests__/versions.test.d.ts.map +0 -1
- package/dist/lib/__tests__/versions.test.js +0 -63
- package/dist/lib/__tests__/versions.test.js.map +0 -1
- package/dist/lib/agents.d.ts +0 -158
- package/dist/lib/agents.d.ts.map +0 -1
- package/dist/lib/agents.js +0 -1159
- package/dist/lib/agents.js.map +0 -1
- package/dist/lib/artifact-actions.d.ts +0 -27
- package/dist/lib/artifact-actions.d.ts.map +0 -1
- package/dist/lib/artifact-actions.js +0 -58
- package/dist/lib/artifact-actions.js.map +0 -1
- package/dist/lib/cloud/codex.d.ts +0 -26
- package/dist/lib/cloud/codex.d.ts.map +0 -1
- package/dist/lib/cloud/codex.js +0 -237
- package/dist/lib/cloud/codex.js.map +0 -1
- package/dist/lib/cloud/factory.d.ts +0 -32
- package/dist/lib/cloud/factory.d.ts.map +0 -1
- package/dist/lib/cloud/factory.js +0 -43
- package/dist/lib/cloud/factory.js.map +0 -1
- package/dist/lib/cloud/registry.d.ts +0 -16
- package/dist/lib/cloud/registry.d.ts.map +0 -1
- package/dist/lib/cloud/registry.js +0 -68
- package/dist/lib/cloud/registry.js.map +0 -1
- package/dist/lib/cloud/rush.d.ts +0 -37
- package/dist/lib/cloud/rush.d.ts.map +0 -1
- package/dist/lib/cloud/rush.js +0 -230
- package/dist/lib/cloud/rush.js.map +0 -1
- package/dist/lib/cloud/rush.test.d.ts +0 -2
- package/dist/lib/cloud/rush.test.d.ts.map +0 -1
- package/dist/lib/cloud/rush.test.js +0 -63
- package/dist/lib/cloud/rush.test.js.map +0 -1
- package/dist/lib/cloud/store.d.ts +0 -23
- package/dist/lib/cloud/store.d.ts.map +0 -1
- package/dist/lib/cloud/store.js +0 -116
- package/dist/lib/cloud/store.js.map +0 -1
- package/dist/lib/cloud/stream.d.ts +0 -24
- package/dist/lib/cloud/stream.d.ts.map +0 -1
- package/dist/lib/cloud/stream.js +0 -145
- package/dist/lib/cloud/stream.js.map +0 -1
- package/dist/lib/cloud/types.d.ts +0 -109
- package/dist/lib/cloud/types.d.ts.map +0 -1
- package/dist/lib/cloud/types.js +0 -33
- package/dist/lib/cloud/types.js.map +0 -1
- package/dist/lib/cloud/types.test.d.ts +0 -2
- package/dist/lib/cloud/types.test.d.ts.map +0 -1
- package/dist/lib/cloud/types.test.js +0 -41
- package/dist/lib/cloud/types.test.js.map +0 -1
- package/dist/lib/commands.d.ts +0 -141
- package/dist/lib/commands.d.ts.map +0 -1
- package/dist/lib/commands.js +0 -514
- package/dist/lib/commands.js.map +0 -1
- package/dist/lib/convert.d.ts +0 -21
- package/dist/lib/convert.d.ts.map +0 -1
- package/dist/lib/convert.js +0 -54
- package/dist/lib/convert.js.map +0 -1
- package/dist/lib/daemon.d.ts +0 -43
- package/dist/lib/daemon.d.ts.map +0 -1
- package/dist/lib/daemon.js +0 -332
- package/dist/lib/daemon.js.map +0 -1
- package/dist/lib/drive-sync.d.ts +0 -46
- package/dist/lib/drive-sync.d.ts.map +0 -1
- package/dist/lib/drive-sync.js +0 -209
- package/dist/lib/drive-sync.js.map +0 -1
- package/dist/lib/exec.d.ts +0 -101
- package/dist/lib/exec.d.ts.map +0 -1
- package/dist/lib/exec.js +0 -450
- package/dist/lib/exec.js.map +0 -1
- package/dist/lib/factory/__tests__/config.test.d.ts +0 -2
- package/dist/lib/factory/__tests__/config.test.d.ts.map +0 -1
- package/dist/lib/factory/__tests__/config.test.js +0 -128
- package/dist/lib/factory/__tests__/config.test.js.map +0 -1
- package/dist/lib/factory/config.d.ts +0 -49
- package/dist/lib/factory/config.d.ts.map +0 -1
- package/dist/lib/factory/config.js +0 -127
- package/dist/lib/factory/config.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 -107
- package/dist/lib/factory.js.map +0 -1
- package/dist/lib/git.d.ts +0 -157
- package/dist/lib/git.d.ts.map +0 -1
- package/dist/lib/git.js +0 -647
- package/dist/lib/git.js.map +0 -1
- package/dist/lib/help.d.ts +0 -10
- package/dist/lib/help.d.ts.map +0 -1
- package/dist/lib/help.js +0 -66
- package/dist/lib/help.js.map +0 -1
- package/dist/lib/hooks.d.ts +0 -125
- package/dist/lib/hooks.d.ts.map +0 -1
- package/dist/lib/hooks.js +0 -846
- package/dist/lib/hooks.js.map +0 -1
- package/dist/lib/ledger/__tests__/local.test.d.ts +0 -2
- package/dist/lib/ledger/__tests__/local.test.d.ts.map +0 -1
- package/dist/lib/ledger/__tests__/local.test.js +0 -177
- package/dist/lib/ledger/__tests__/local.test.js.map +0 -1
- package/dist/lib/ledger/__tests__/sync.test.d.ts +0 -2
- package/dist/lib/ledger/__tests__/sync.test.d.ts.map +0 -1
- package/dist/lib/ledger/__tests__/sync.test.js +0 -117
- package/dist/lib/ledger/__tests__/sync.test.js.map +0 -1
- package/dist/lib/ledger/index.d.ts +0 -18
- package/dist/lib/ledger/index.d.ts.map +0 -1
- package/dist/lib/ledger/index.js +0 -32
- package/dist/lib/ledger/index.js.map +0 -1
- package/dist/lib/ledger/local.d.ts +0 -22
- package/dist/lib/ledger/local.d.ts.map +0 -1
- package/dist/lib/ledger/local.js +0 -333
- package/dist/lib/ledger/local.js.map +0 -1
- package/dist/lib/ledger/r2.d.ts +0 -41
- package/dist/lib/ledger/r2.d.ts.map +0 -1
- package/dist/lib/ledger/r2.js +0 -335
- package/dist/lib/ledger/r2.js.map +0 -1
- package/dist/lib/ledger/sync.d.ts +0 -33
- package/dist/lib/ledger/sync.d.ts.map +0 -1
- package/dist/lib/ledger/sync.js +0 -106
- package/dist/lib/ledger/sync.js.map +0 -1
- package/dist/lib/ledger/types.d.ts +0 -100
- package/dist/lib/ledger/types.d.ts.map +0 -1
- package/dist/lib/ledger/types.js +0 -21
- package/dist/lib/ledger/types.js.map +0 -1
- package/dist/lib/manifest.d.ts +0 -14
- package/dist/lib/manifest.d.ts.map +0 -1
- package/dist/lib/manifest.js +0 -48
- package/dist/lib/manifest.js.map +0 -1
- package/dist/lib/markdown.d.ts +0 -5
- package/dist/lib/markdown.d.ts.map +0 -1
- package/dist/lib/markdown.js +0 -17
- package/dist/lib/markdown.js.map +0 -1
- package/dist/lib/mcp.d.ts +0 -64
- package/dist/lib/mcp.d.ts.map +0 -1
- package/dist/lib/mcp.js +0 -327
- package/dist/lib/mcp.js.map +0 -1
- package/dist/lib/memory-compile.d.ts +0 -65
- package/dist/lib/memory-compile.d.ts.map +0 -1
- package/dist/lib/memory-compile.js +0 -174
- package/dist/lib/memory-compile.js.map +0 -1
- package/dist/lib/memory.d.ts +0 -64
- package/dist/lib/memory.d.ts.map +0 -1
- package/dist/lib/memory.js +0 -275
- package/dist/lib/memory.js.map +0 -1
- package/dist/lib/models.d.ts +0 -98
- package/dist/lib/models.d.ts.map +0 -1
- package/dist/lib/models.js +0 -728
- package/dist/lib/models.js.map +0 -1
- package/dist/lib/permissions.d.ts +0 -227
- package/dist/lib/permissions.d.ts.map +0 -1
- package/dist/lib/permissions.js +0 -1085
- package/dist/lib/permissions.js.map +0 -1
- package/dist/lib/picker.d.ts +0 -27
- package/dist/lib/picker.d.ts.map +0 -1
- package/dist/lib/picker.js +0 -110
- package/dist/lib/picker.js.map +0 -1
- package/dist/lib/plugins.d.ts +0 -80
- package/dist/lib/plugins.d.ts.map +0 -1
- package/dist/lib/plugins.js +0 -556
- package/dist/lib/plugins.js.map +0 -1
- package/dist/lib/profiles-keychain.d.ts +0 -11
- package/dist/lib/profiles-keychain.d.ts.map +0 -1
- package/dist/lib/profiles-keychain.js +0 -14
- package/dist/lib/profiles-keychain.js.map +0 -1
- package/dist/lib/profiles-presets.d.ts +0 -25
- package/dist/lib/profiles-presets.d.ts.map +0 -1
- package/dist/lib/profiles-presets.js +0 -104
- package/dist/lib/profiles-presets.js.map +0 -1
- package/dist/lib/profiles.d.ts +0 -70
- package/dist/lib/profiles.d.ts.map +0 -1
- package/dist/lib/profiles.js +0 -145
- package/dist/lib/profiles.js.map +0 -1
- package/dist/lib/pty-client.d.ts +0 -23
- package/dist/lib/pty-client.d.ts.map +0 -1
- package/dist/lib/pty-client.js +0 -181
- package/dist/lib/pty-client.js.map +0 -1
- package/dist/lib/pty-server.d.ts +0 -21
- package/dist/lib/pty-server.d.ts.map +0 -1
- package/dist/lib/pty-server.js +0 -427
- package/dist/lib/pty-server.js.map +0 -1
- package/dist/lib/registry.d.ts +0 -45
- package/dist/lib/registry.d.ts.map +0 -1
- package/dist/lib/registry.js +0 -220
- package/dist/lib/registry.js.map +0 -1
- package/dist/lib/resources.d.ts +0 -55
- package/dist/lib/resources.d.ts.map +0 -1
- package/dist/lib/resources.js +0 -103
- package/dist/lib/resources.js.map +0 -1
- package/dist/lib/rotate.d.ts +0 -58
- package/dist/lib/rotate.d.ts.map +0 -1
- package/dist/lib/rotate.js +0 -93
- package/dist/lib/rotate.js.map +0 -1
- package/dist/lib/routines.d.ts +0 -99
- package/dist/lib/routines.d.ts.map +0 -1
- package/dist/lib/routines.js +0 -352
- package/dist/lib/routines.js.map +0 -1
- package/dist/lib/runner.d.ts +0 -26
- package/dist/lib/runner.d.ts.map +0 -1
- package/dist/lib/runner.js +0 -325
- package/dist/lib/runner.js.map +0 -1
- package/dist/lib/sandbox.d.ts +0 -26
- package/dist/lib/sandbox.d.ts.map +0 -1
- package/dist/lib/sandbox.js +0 -218
- package/dist/lib/sandbox.js.map +0 -1
- package/dist/lib/scheduler.d.ts +0 -26
- package/dist/lib/scheduler.d.ts.map +0 -1
- package/dist/lib/scheduler.js +0 -77
- package/dist/lib/scheduler.js.map +0 -1
- package/dist/lib/secrets-bundles.d.ts +0 -38
- package/dist/lib/secrets-bundles.d.ts.map +0 -1
- package/dist/lib/secrets-bundles.js +0 -176
- package/dist/lib/secrets-bundles.js.map +0 -1
- package/dist/lib/secrets.d.ts +0 -53
- package/dist/lib/secrets.d.ts.map +0 -1
- package/dist/lib/secrets.js +0 -140
- package/dist/lib/secrets.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/active.d.ts +0 -44
- package/dist/lib/session/active.d.ts.map +0 -1
- package/dist/lib/session/active.js +0 -379
- package/dist/lib/session/active.js.map +0 -1
- package/dist/lib/session/artifacts.d.ts +0 -15
- package/dist/lib/session/artifacts.d.ts.map +0 -1
- package/dist/lib/session/artifacts.js +0 -86
- package/dist/lib/session/artifacts.js.map +0 -1
- package/dist/lib/session/db.d.ts +0 -140
- package/dist/lib/session/db.d.ts.map +0 -1
- package/dist/lib/session/db.js +0 -599
- package/dist/lib/session/db.js.map +0 -1
- package/dist/lib/session/discover.d.ts +0 -72
- package/dist/lib/session/discover.d.ts.map +0 -1
- package/dist/lib/session/discover.js +0 -1315
- package/dist/lib/session/discover.js.map +0 -1
- package/dist/lib/session/parse.d.ts +0 -34
- package/dist/lib/session/parse.d.ts.map +0 -1
- package/dist/lib/session/parse.js +0 -663
- package/dist/lib/session/parse.js.map +0 -1
- package/dist/lib/session/prompt.d.ts +0 -13
- package/dist/lib/session/prompt.d.ts.map +0 -1
- package/dist/lib/session/prompt.js +0 -79
- 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 +0 -103
- package/dist/lib/session/render.d.ts.map +0 -1
- package/dist/lib/session/render.js +0 -798
- package/dist/lib/session/render.js.map +0 -1
- package/dist/lib/session/team-filter.d.ts +0 -35
- package/dist/lib/session/team-filter.d.ts.map +0 -1
- package/dist/lib/session/team-filter.js +0 -75
- 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 +0 -84
- package/dist/lib/session/types.d.ts.map +0 -1
- package/dist/lib/session/types.js +0 -11
- package/dist/lib/session/types.js.map +0 -1
- package/dist/lib/shims.d.ts +0 -272
- package/dist/lib/shims.d.ts.map +0 -1
- package/dist/lib/shims.js +0 -1322
- package/dist/lib/shims.js.map +0 -1
- package/dist/lib/skills.d.ts +0 -142
- package/dist/lib/skills.d.ts.map +0 -1
- package/dist/lib/skills.js +0 -791
- package/dist/lib/skills.js.map +0 -1
- package/dist/lib/state.d.ts +0 -87
- package/dist/lib/state.d.ts.map +0 -1
- package/dist/lib/state.js +0 -333
- package/dist/lib/state.js.map +0 -1
- package/dist/lib/subagents.d.ts +0 -84
- package/dist/lib/subagents.d.ts.map +0 -1
- package/dist/lib/subagents.js +0 -410
- package/dist/lib/subagents.js.map +0 -1
- package/dist/lib/teams/__tests__/oracle.test.d.ts +0 -2
- package/dist/lib/teams/__tests__/oracle.test.d.ts.map +0 -1
- package/dist/lib/teams/__tests__/oracle.test.js +0 -89
- package/dist/lib/teams/__tests__/oracle.test.js.map +0 -1
- package/dist/lib/teams/__tests__/supervisor.test.d.ts +0 -2
- package/dist/lib/teams/__tests__/supervisor.test.d.ts.map +0 -1
- package/dist/lib/teams/__tests__/supervisor.test.js +0 -179
- package/dist/lib/teams/__tests__/supervisor.test.js.map +0 -1
- package/dist/lib/teams/agents.d.ts +0 -247
- package/dist/lib/teams/agents.d.ts.map +0 -1
- package/dist/lib/teams/agents.js +0 -1244
- package/dist/lib/teams/agents.js.map +0 -1
- package/dist/lib/teams/api.d.ts +0 -91
- package/dist/lib/teams/api.d.ts.map +0 -1
- package/dist/lib/teams/api.js +0 -239
- 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 +0 -8
- package/dist/lib/teams/debug.d.ts.map +0 -1
- package/dist/lib/teams/debug.js +0 -12
- package/dist/lib/teams/debug.js.map +0 -1
- package/dist/lib/teams/file_ops.d.ts +0 -13
- package/dist/lib/teams/file_ops.d.ts.map +0 -1
- package/dist/lib/teams/file_ops.js +0 -66
- package/dist/lib/teams/file_ops.js.map +0 -1
- package/dist/lib/teams/index.d.ts +0 -16
- package/dist/lib/teams/index.d.ts.map +0 -1
- package/dist/lib/teams/index.js +0 -15
- package/dist/lib/teams/index.js.map +0 -1
- package/dist/lib/teams/oracle.d.ts +0 -20
- package/dist/lib/teams/oracle.d.ts.map +0 -1
- package/dist/lib/teams/oracle.js +0 -59
- package/dist/lib/teams/oracle.js.map +0 -1
- package/dist/lib/teams/parsers.d.ts +0 -9
- package/dist/lib/teams/parsers.d.ts.map +0 -1
- package/dist/lib/teams/parsers.js +0 -837
- package/dist/lib/teams/parsers.js.map +0 -1
- package/dist/lib/teams/persistence.d.ts +0 -43
- package/dist/lib/teams/persistence.d.ts.map +0 -1
- package/dist/lib/teams/persistence.js +0 -299
- 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 +0 -18
- package/dist/lib/teams/registry.d.ts.map +0 -1
- package/dist/lib/teams/registry.js +0 -68
- package/dist/lib/teams/registry.js.map +0 -1
- package/dist/lib/teams/summarizer.d.ts +0 -73
- package/dist/lib/teams/summarizer.d.ts.map +0 -1
- package/dist/lib/teams/summarizer.js +0 -780
- package/dist/lib/teams/summarizer.js.map +0 -1
- package/dist/lib/teams/supervisor.d.ts +0 -49
- package/dist/lib/teams/supervisor.d.ts.map +0 -1
- package/dist/lib/teams/supervisor.js +0 -74
- package/dist/lib/teams/supervisor.js.map +0 -1
- package/dist/lib/template.d.ts +0 -27
- package/dist/lib/template.d.ts.map +0 -1
- package/dist/lib/template.js +0 -60
- package/dist/lib/template.js.map +0 -1
- package/dist/lib/types.d.ts +0 -331
- package/dist/lib/types.d.ts.map +0 -1
- package/dist/lib/types.js +0 -29
- package/dist/lib/types.js.map +0 -1
- package/dist/lib/usage.d.ts +0 -105
- package/dist/lib/usage.d.ts.map +0 -1
- package/dist/lib/usage.js +0 -686
- package/dist/lib/usage.js.map +0 -1
- package/dist/lib/versions.d.ts +0 -253
- package/dist/lib/versions.d.ts.map +0 -1
- package/dist/lib/versions.js +0 -1796
- package/dist/lib/versions.js.map +0 -1
- package/scripts/rebuild-sqlite.sh +0 -46
|
@@ -1,798 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Session rendering: summary, markdown conversation, and JSON output.
|
|
3
|
-
*
|
|
4
|
-
* Provides the display layer for `agents sessions <id>`. The summary renderer
|
|
5
|
-
* produces a chalk-formatted activity overview (modified files, commands,
|
|
6
|
-
* errors, final message). The markdown renderer emits a full conversation
|
|
7
|
-
* transcript. Filtering by role and turn slicing is handled here as well.
|
|
8
|
-
*/
|
|
9
|
-
import chalk from 'chalk';
|
|
10
|
-
import { summarizeToolUse } from './parse.js';
|
|
11
|
-
import { cleanSessionPrompt, extractSessionTopic } from './prompt.js';
|
|
12
|
-
import { renderMarkdown } from '../markdown.js';
|
|
13
|
-
// ── Path helpers ──────────────────────────────────────────────────────────────
|
|
14
|
-
/**
|
|
15
|
-
* Return absPath relative to cwd; fall back to ~/… then absolute.
|
|
16
|
-
*/
|
|
17
|
-
export function relativeToCwd(absPath, cwd) {
|
|
18
|
-
if (cwd && (absPath === cwd || absPath.startsWith(cwd + '/'))) {
|
|
19
|
-
const rel = absPath.slice(cwd.length + 1);
|
|
20
|
-
return rel || '.';
|
|
21
|
-
}
|
|
22
|
-
const home = process.env.HOME || '';
|
|
23
|
-
if (home && (absPath === home || absPath.startsWith(home + '/'))) {
|
|
24
|
-
return '~' + absPath.slice(home.length);
|
|
25
|
-
}
|
|
26
|
-
return absPath;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Wrap label in an OSC 8 hyperlink when the terminal supports it.
|
|
30
|
-
* Degrades to plain label otherwise.
|
|
31
|
-
*/
|
|
32
|
-
export function linkPath(absPath, label) {
|
|
33
|
-
if (process.stdout.isTTY &&
|
|
34
|
-
(process.env.TERM_PROGRAM ||
|
|
35
|
-
process.env.WT_SESSION ||
|
|
36
|
-
process.env.KITTY_WINDOW_ID ||
|
|
37
|
-
process.env.WEZTERM_PANE)) {
|
|
38
|
-
return `\x1b]8;;file://${absPath}\x1b\\${label}\x1b]8;;\x1b\\`;
|
|
39
|
-
}
|
|
40
|
-
return label;
|
|
41
|
-
}
|
|
42
|
-
// ── Command grouping ──────────────────────────────────────────────────────────
|
|
43
|
-
/**
|
|
44
|
-
* Unwrap wrapper prefixes to find the actual executable.
|
|
45
|
-
*/
|
|
46
|
-
export function unwrapCommand(cmd) {
|
|
47
|
-
const ssh = cmd.match(/^ssh\s+\S+\s+"(.+)"\s*(?:\|.*)?$/);
|
|
48
|
-
if (ssh)
|
|
49
|
-
return unwrapCommand(ssh[1]);
|
|
50
|
-
const lead = cmd.match(/^(?:sudo|env\s+\S+=\S+|time)\s+(.+)/);
|
|
51
|
-
if (lead)
|
|
52
|
-
return unwrapCommand(lead[1]);
|
|
53
|
-
// Strip shell-style leading env assignments: `PATH=/x CMD ...`, `FOO=bar BAR=baz CMD ...`
|
|
54
|
-
const shellEnv = cmd.match(/^(?:[A-Z_][A-Z0-9_]*=\S+\s+)+(\S.*)$/);
|
|
55
|
-
if (shellEnv)
|
|
56
|
-
return unwrapCommand(shellEnv[1]);
|
|
57
|
-
const cd = cmd.match(/^cd\s+\S+\s*&&\s*(.+)/);
|
|
58
|
-
if (cd)
|
|
59
|
-
return unwrapCommand(cd[1]);
|
|
60
|
-
const npx = cmd.match(/^npx\s+(.+)/);
|
|
61
|
-
if (npx)
|
|
62
|
-
return unwrapCommand(npx[1]);
|
|
63
|
-
return cmd;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Normalize a command so trivial flag/pipe variations collapse to the same key.
|
|
67
|
-
*/
|
|
68
|
-
export function normalizeForDedup(cmd) {
|
|
69
|
-
let s = cmd.trim();
|
|
70
|
-
s = s.replace(/\s+-[a-zA-Z]+/g, '');
|
|
71
|
-
s = s.replace(/\s+--[a-zA-Z][-a-zA-Z0-9]*(?:=\S+)?/g, '');
|
|
72
|
-
s = s.replace(/\s*\|\s*(head|tail|wc|less|more|cat)(\s+\S+)?.*$/, '');
|
|
73
|
-
s = s.replace(/\s*2>&1\s*$/, '');
|
|
74
|
-
s = s.replace(/\s*;\s*echo\b.*$/, '');
|
|
75
|
-
const home = process.env.HOME ?? '';
|
|
76
|
-
if (home) {
|
|
77
|
-
s = s.replace(new RegExp('^' + home.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')), '~');
|
|
78
|
-
}
|
|
79
|
-
return s.trim();
|
|
80
|
-
}
|
|
81
|
-
/** Command classification categories with signal levels for summary rendering. */
|
|
82
|
-
const CATEGORIES = [
|
|
83
|
-
{ name: 'Probes', match: t => ['ls', 'cat', 'head', 'tail', 'wc', 'stat', 'file', 'which', 'tree', 'pwd'].includes(t), signal: 'low' },
|
|
84
|
-
{ name: 'Search', match: t => ['grep', 'rg', 'ag', 'fd', 'find'].includes(t), signal: 'low' },
|
|
85
|
-
{ name: 'Build/test', match: t => ['make', 'cargo', 'pytest', 'go', 'bun', 'npm', 'pnpm', 'yarn', 'tsc', 'vitest', 'tsx', 'node', 'python', 'python3', 'jest'].includes(t), signal: 'high' },
|
|
86
|
-
{ name: 'Install', match: t => ['brew', 'pip', 'apt', 'apk'].includes(t), signal: 'high' },
|
|
87
|
-
{ name: 'VCS', match: t => ['git', 'gh'].includes(t), signal: 'mid' },
|
|
88
|
-
{ name: 'HTTP', match: t => ['curl', 'wget', 'rush', 'http'].includes(t), signal: 'mid' },
|
|
89
|
-
{ name: 'Remote', match: t => ['ssh', 'scp', 'rsync'].includes(t), signal: 'mid' },
|
|
90
|
-
{ name: 'Shell', match: t => ['rm', 'mv', 'cp', 'mkdir', 'touch', 'echo', 'printf', 'chmod', 'ln', 'awk', 'sed', 'tee', 'xargs', 'for'].includes(t), signal: 'low' },
|
|
91
|
-
{ name: 'Wait', match: t => ['sleep', 'wait'].includes(t), signal: 'low' },
|
|
92
|
-
];
|
|
93
|
-
/** CLI tools whose subcommand (second token) is included in the bucket key. */
|
|
94
|
-
const TWO_LEVEL_TOKENS = new Set([
|
|
95
|
-
'git', 'gh', 'bun', 'npm', 'cargo', 'docker', 'kubectl', 'rush', 'openclaw', 'pnpm', 'yarn',
|
|
96
|
-
]);
|
|
97
|
-
/**
|
|
98
|
-
* Return the bucket key for a command (used for grouping within a category).
|
|
99
|
-
*/
|
|
100
|
-
export function bucketKey(cmd) {
|
|
101
|
-
const unwrapped = unwrapCommand(cmd);
|
|
102
|
-
const tokens = unwrapped.trim().split(/\s+/);
|
|
103
|
-
const first = tokens[0] ?? 'other';
|
|
104
|
-
const isRemote = cmd.trim().startsWith('ssh ') || cmd.trim().startsWith('scp ');
|
|
105
|
-
if (TWO_LEVEL_TOKENS.has(first) && tokens[1]) {
|
|
106
|
-
const key = `${first} ${tokens[1]}`;
|
|
107
|
-
return isRemote ? `ssh\u2192${key}` : key;
|
|
108
|
-
}
|
|
109
|
-
return isRemote ? `ssh\u2192${first}` : first;
|
|
110
|
-
}
|
|
111
|
-
function categoryOf(cmd) {
|
|
112
|
-
const rawFirst = cmd.trim().split(/\s+/)[0]?.toLowerCase() ?? '';
|
|
113
|
-
// Remote wrappers: classify as Remote regardless of inner command.
|
|
114
|
-
if (['ssh', 'scp', 'rsync'].includes(rawFirst)) {
|
|
115
|
-
return CATEGORIES.find(c => c.name === 'Remote') ?? null;
|
|
116
|
-
}
|
|
117
|
-
const unwrapped = unwrapCommand(cmd);
|
|
118
|
-
const first = unwrapped.trim().split(/\s+/)[0]?.toLowerCase() ?? '';
|
|
119
|
-
return CATEGORIES.find(c => c.match(first)) ?? null;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Collapse consecutive same-normalized commands within a 60-second window
|
|
123
|
-
* when they appear 3+ times. Fewer than 3 stay as separate entries.
|
|
124
|
-
*/
|
|
125
|
-
export function collapseRetries(commands) {
|
|
126
|
-
const groups = [];
|
|
127
|
-
for (const { cmd, ts } of commands) {
|
|
128
|
-
const normalized = normalizeForDedup(unwrapCommand(cmd));
|
|
129
|
-
const last = groups[groups.length - 1];
|
|
130
|
-
if (last && last.normalized === normalized && ts - last.lastTs <= 60_000) {
|
|
131
|
-
last.count++;
|
|
132
|
-
last.lastTs = ts;
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
groups.push({ normalized, raw: cmd, firstTs: ts, lastTs: ts, count: 1 });
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
// Expand groups with count < 3 back to individual entries
|
|
139
|
-
const result = [];
|
|
140
|
-
for (const g of groups) {
|
|
141
|
-
if (g.count >= 3) {
|
|
142
|
-
result.push(g);
|
|
143
|
-
}
|
|
144
|
-
else {
|
|
145
|
-
for (let i = 0; i < g.count; i++) {
|
|
146
|
-
result.push({ normalized: g.normalized, raw: g.raw, firstTs: g.firstTs, lastTs: g.lastTs, count: 1 });
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
return result;
|
|
151
|
-
}
|
|
152
|
-
/** Compute aggregate statistics (turns, tools, tokens, duration) from session events. */
|
|
153
|
-
export function computeSummaryStats(events) {
|
|
154
|
-
const modelSet = new Set();
|
|
155
|
-
let userTurns = 0;
|
|
156
|
-
let assistantTurns = 0;
|
|
157
|
-
let toolCount = 0;
|
|
158
|
-
let errorCount = 0;
|
|
159
|
-
let outputTokens = 0;
|
|
160
|
-
let cacheReadTokens = 0;
|
|
161
|
-
let firstTs = Infinity;
|
|
162
|
-
let lastTs = -Infinity;
|
|
163
|
-
for (const e of events) {
|
|
164
|
-
const ts = new Date(e.timestamp).getTime();
|
|
165
|
-
if (!isNaN(ts)) {
|
|
166
|
-
if (ts < firstTs)
|
|
167
|
-
firstTs = ts;
|
|
168
|
-
if (ts > lastTs)
|
|
169
|
-
lastTs = ts;
|
|
170
|
-
}
|
|
171
|
-
if (e.type === 'message') {
|
|
172
|
-
if (e.role === 'user')
|
|
173
|
-
userTurns++;
|
|
174
|
-
else if (e.role === 'assistant')
|
|
175
|
-
assistantTurns++;
|
|
176
|
-
}
|
|
177
|
-
else if (e.type === 'tool_use' && !e._local) {
|
|
178
|
-
toolCount++;
|
|
179
|
-
}
|
|
180
|
-
else if (e.type === 'error') {
|
|
181
|
-
errorCount++;
|
|
182
|
-
}
|
|
183
|
-
else if (e.type === 'usage') {
|
|
184
|
-
if (e.model)
|
|
185
|
-
modelSet.add(shortenModel(e.model));
|
|
186
|
-
outputTokens += e.outputTokens ?? 0;
|
|
187
|
-
cacheReadTokens += e.cacheReadTokens ?? 0;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
return {
|
|
191
|
-
models: Array.from(modelSet),
|
|
192
|
-
userTurns,
|
|
193
|
-
assistantTurns,
|
|
194
|
-
toolCount,
|
|
195
|
-
errorCount,
|
|
196
|
-
outputTokens,
|
|
197
|
-
cacheReadTokens,
|
|
198
|
-
firstTs: firstTs === Infinity ? 0 : firstTs,
|
|
199
|
-
lastTs: lastTs === -Infinity ? 0 : lastTs,
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
|
-
/** Strip the 'claude-' prefix and date suffix from a model identifier. */
|
|
203
|
-
function shortenModel(model) {
|
|
204
|
-
return model.replace(/^claude-/, '').replace(/-\d{8}$/, '');
|
|
205
|
-
}
|
|
206
|
-
/** Format a token count as a human-readable string (e.g. 67.5K, 1.2M). */
|
|
207
|
-
function formatTokenCount(n) {
|
|
208
|
-
if (n === 0)
|
|
209
|
-
return '0';
|
|
210
|
-
if (n < 1000)
|
|
211
|
-
return String(n);
|
|
212
|
-
if (n < 1_000_000) {
|
|
213
|
-
const k = n / 1000;
|
|
214
|
-
return (k >= 100 ? Math.round(k) : parseFloat(k.toFixed(1))) + 'K';
|
|
215
|
-
}
|
|
216
|
-
const m = n / 1_000_000;
|
|
217
|
-
return (m >= 100 ? Math.round(m) : parseFloat(m.toFixed(1))) + 'M';
|
|
218
|
-
}
|
|
219
|
-
/** Format a duration in milliseconds as a human-readable string (e.g. '12 min', '2h 30min'). */
|
|
220
|
-
function formatDuration(ms) {
|
|
221
|
-
const totalMin = Math.round(ms / 60_000);
|
|
222
|
-
if (totalMin < 1)
|
|
223
|
-
return 'under 1 min';
|
|
224
|
-
if (totalMin < 60)
|
|
225
|
-
return `${totalMin} min`;
|
|
226
|
-
const hrs = Math.floor(totalMin / 60);
|
|
227
|
-
const mins = totalMin % 60;
|
|
228
|
-
return mins > 0 ? `${hrs}h ${mins}min` : `${hrs}h`;
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* Return the stats line for a session summary header.
|
|
232
|
-
* e.g. "221 turns · 198 tools (10 errors) · 67.5M cached / 361K out · 12 min"
|
|
233
|
-
*/
|
|
234
|
-
export function renderSummaryHeader(stats) {
|
|
235
|
-
const turns = stats.userTurns + stats.assistantTurns;
|
|
236
|
-
const parts = [];
|
|
237
|
-
parts.push(`${turns} turn${turns !== 1 ? 's' : ''}`);
|
|
238
|
-
if (stats.toolCount > 0) {
|
|
239
|
-
const toolPart = stats.errorCount > 0
|
|
240
|
-
? `${stats.toolCount} tools (${stats.errorCount} error${stats.errorCount !== 1 ? 's' : ''})`
|
|
241
|
-
: `${stats.toolCount} tools`;
|
|
242
|
-
parts.push(toolPart);
|
|
243
|
-
}
|
|
244
|
-
if (stats.cacheReadTokens > 0 || stats.outputTokens > 0) {
|
|
245
|
-
const tokenPart = stats.cacheReadTokens > 0
|
|
246
|
-
? `${formatTokenCount(stats.cacheReadTokens)} cached / ${formatTokenCount(stats.outputTokens)} out`
|
|
247
|
-
: `${formatTokenCount(stats.outputTokens)} out`;
|
|
248
|
-
parts.push(tokenPart);
|
|
249
|
-
}
|
|
250
|
-
if (stats.lastTs > stats.firstTs) {
|
|
251
|
-
parts.push(formatDuration(stats.lastTs - stats.firstTs));
|
|
252
|
-
}
|
|
253
|
-
return parts.join(' · ');
|
|
254
|
-
}
|
|
255
|
-
// ── Prompt reference extraction ───────────────────────────────────────────────
|
|
256
|
-
/** Extract @-mentions, slash paths, and ~/... references from a prompt string. */
|
|
257
|
-
function extractReferences(text) {
|
|
258
|
-
const refs = new Set();
|
|
259
|
-
for (const m of text.matchAll(/@[\w/.-]+/g))
|
|
260
|
-
refs.add(m[0]);
|
|
261
|
-
for (const m of text.matchAll(/(?:^|\s)(\/[\w/.-]{3,})/gm))
|
|
262
|
-
refs.add(m[1]);
|
|
263
|
-
for (const m of text.matchAll(/~\/[\w/.-]+/g))
|
|
264
|
-
refs.add(m[0]);
|
|
265
|
-
return Array.from(refs);
|
|
266
|
-
}
|
|
267
|
-
/** Render the Commands section of the summary, grouping by category and collapsing retries. */
|
|
268
|
-
function renderCommandsSection(cmds, lines) {
|
|
269
|
-
if (cmds.length === 0)
|
|
270
|
-
return;
|
|
271
|
-
const runs = collapseRetries(cmds);
|
|
272
|
-
// Group runs by category → key → {count, samples}
|
|
273
|
-
const catMap = new Map();
|
|
274
|
-
let otherCount = 0;
|
|
275
|
-
const otherKeys = new Map();
|
|
276
|
-
for (const run of runs) {
|
|
277
|
-
const cat = categoryOf(run.raw);
|
|
278
|
-
const key = bucketKey(run.raw);
|
|
279
|
-
if (cat) {
|
|
280
|
-
let catEntry = catMap.get(cat.name);
|
|
281
|
-
if (!catEntry) {
|
|
282
|
-
catEntry = { signal: cat.signal, keys: new Map() };
|
|
283
|
-
catMap.set(cat.name, catEntry);
|
|
284
|
-
}
|
|
285
|
-
const existing = catEntry.keys.get(key) ?? { count: 0, samples: [] };
|
|
286
|
-
existing.count += run.count;
|
|
287
|
-
if (existing.samples.length < 5 && !existing.samples.some(s => sharesPrefix(s, run.raw, 30))) {
|
|
288
|
-
existing.samples.push(run.raw);
|
|
289
|
-
}
|
|
290
|
-
catEntry.keys.set(key, existing);
|
|
291
|
-
}
|
|
292
|
-
else {
|
|
293
|
-
otherCount += run.count;
|
|
294
|
-
const existing = otherKeys.get(key) ?? { count: 0, samples: [] };
|
|
295
|
-
existing.count += run.count;
|
|
296
|
-
if (existing.samples.length < 3)
|
|
297
|
-
existing.samples.push(run.raw);
|
|
298
|
-
otherKeys.set(key, existing);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
// Total command count (sum of all run counts)
|
|
302
|
-
const total = runs.reduce((sum, r) => sum + r.count, 0);
|
|
303
|
-
lines.push(chalk.bold('Commands') + chalk.gray(` (${total})`));
|
|
304
|
-
// Sort categories: high-signal first, then mid, then low, by total count desc. Other last.
|
|
305
|
-
const SIGNAL_ORDER = { high: 0, mid: 1, low: 2 };
|
|
306
|
-
const sortedCats = Array.from(catMap.entries()).sort((a, b) => {
|
|
307
|
-
const sigA = SIGNAL_ORDER[a[1].signal] ?? 3;
|
|
308
|
-
const sigB = SIGNAL_ORDER[b[1].signal] ?? 3;
|
|
309
|
-
if (sigA !== sigB)
|
|
310
|
-
return sigA - sigB;
|
|
311
|
-
const countA = Array.from(a[1].keys.values()).reduce((s, v) => s + v.count, 0);
|
|
312
|
-
const countB = Array.from(b[1].keys.values()).reduce((s, v) => s + v.count, 0);
|
|
313
|
-
return countB - countA;
|
|
314
|
-
});
|
|
315
|
-
for (const [catName, catEntry] of sortedCats) {
|
|
316
|
-
const catTotal = Array.from(catEntry.keys.values()).reduce((s, v) => s + v.count, 0);
|
|
317
|
-
if (catEntry.signal === 'low') {
|
|
318
|
-
// Single inline line: category name + top 5 first tokens
|
|
319
|
-
const topTokens = Array.from(catEntry.keys.keys()).slice(0, 5).join(', ');
|
|
320
|
-
lines.push(` ${chalk.dim(catName)} ${chalk.gray(`(${catTotal})`)} ${chalk.gray('— ' + topTokens)}`);
|
|
321
|
-
}
|
|
322
|
-
else {
|
|
323
|
-
lines.push(` ${chalk.dim(catName)} ${chalk.gray(`(${catTotal})`)}`);
|
|
324
|
-
const keysSorted = Array.from(catEntry.keys.entries()).sort((a, b) => b[1].count - a[1].count);
|
|
325
|
-
const limit = catEntry.signal === 'high' ? Infinity : 3;
|
|
326
|
-
let shown = 0;
|
|
327
|
-
for (const [key, v] of keysSorted) {
|
|
328
|
-
if (shown >= limit)
|
|
329
|
-
break;
|
|
330
|
-
if (catEntry.signal === 'mid') {
|
|
331
|
-
// Mid signal: display the bucket key (e.g. ssh→openclaw browser) with aggregate count
|
|
332
|
-
const countSuffix = v.count > 1 ? chalk.gray(` × ${v.count}`) : '';
|
|
333
|
-
lines.push(` ${chalk.cyan(truncateCmd(key, 80))}${countSuffix}`);
|
|
334
|
-
}
|
|
335
|
-
else {
|
|
336
|
-
// High signal: display distinct raw sample commands
|
|
337
|
-
const distinctSamples = pickDistinct(v.samples, 3);
|
|
338
|
-
for (const sample of distinctSamples) {
|
|
339
|
-
const countSuffix = v.count > 1 ? chalk.gray(` × ${v.count}`) : '';
|
|
340
|
-
lines.push(` ${chalk.cyan(truncateCmd(sample, 80))}${countSuffix}`);
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
shown++;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
if (otherCount > 0) {
|
|
348
|
-
lines.push(` ${chalk.dim('Other')} ${chalk.gray(`(${otherCount})`)}`);
|
|
349
|
-
for (const [, v] of Array.from(otherKeys.entries()).slice(0, 5)) {
|
|
350
|
-
const countSuffix = v.count > 1 ? chalk.gray(` × ${v.count}`) : '';
|
|
351
|
-
lines.push(` ${chalk.cyan(truncateCmd(v.samples[0] ?? '', 80))}${countSuffix}`);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
lines.push('');
|
|
355
|
-
}
|
|
356
|
-
function sharesPrefix(a, b, len) {
|
|
357
|
-
return a.slice(0, len) === b.slice(0, len);
|
|
358
|
-
}
|
|
359
|
-
function pickDistinct(samples, max) {
|
|
360
|
-
const result = [];
|
|
361
|
-
for (const s of samples) {
|
|
362
|
-
if (result.length >= max)
|
|
363
|
-
break;
|
|
364
|
-
if (!result.some(r => sharesPrefix(r, s, 30)))
|
|
365
|
-
result.push(s);
|
|
366
|
-
}
|
|
367
|
-
return result.length > 0 ? result : samples.slice(0, max);
|
|
368
|
-
}
|
|
369
|
-
function truncateCmd(cmd, max) {
|
|
370
|
-
return cmd.length <= max ? cmd : cmd.slice(0, max - 1) + '…';
|
|
371
|
-
}
|
|
372
|
-
// ── File grouping ─────────────────────────────────────────────────────────────
|
|
373
|
-
/** Group file paths by their parent directory, relative to cwd. */
|
|
374
|
-
function groupByParentDir(paths, cwd) {
|
|
375
|
-
const groups = new Map();
|
|
376
|
-
for (const p of paths) {
|
|
377
|
-
const rel = relativeToCwd(p, cwd);
|
|
378
|
-
const slashIdx = rel.lastIndexOf('/');
|
|
379
|
-
const dir = slashIdx >= 0 ? rel.slice(0, slashIdx) : '.';
|
|
380
|
-
const base = slashIdx >= 0 ? rel.slice(slashIdx + 1) : rel;
|
|
381
|
-
const arr = groups.get(dir) ?? [];
|
|
382
|
-
arr.push(base);
|
|
383
|
-
groups.set(dir, arr);
|
|
384
|
-
}
|
|
385
|
-
return new Map(Array.from(groups.entries()).sort((a, b) => b[1].length - a[1].length));
|
|
386
|
-
}
|
|
387
|
-
/** Render grouped file paths as indented, clickable terminal lines. */
|
|
388
|
-
function renderFileGroup(lines, groups, absPathMap) {
|
|
389
|
-
if (groups.size === 1) {
|
|
390
|
-
const [dir, files] = Array.from(groups.entries())[0];
|
|
391
|
-
for (const f of files) {
|
|
392
|
-
const abs = absPathMap.get(dir === '.' ? f : `${dir}/${f}`) ?? '';
|
|
393
|
-
const label = dir === '.' ? f : `${dir}/${f}`;
|
|
394
|
-
lines.push(' ' + chalk.cyan(abs ? linkPath(abs, label) : label));
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
else {
|
|
398
|
-
for (const [dir, files] of groups) {
|
|
399
|
-
lines.push(` ${chalk.dim(dir + '/')}`);
|
|
400
|
-
for (const f of files) {
|
|
401
|
-
const abs = absPathMap.get(dir === '.' ? f : `${dir}/${f}`) ?? '';
|
|
402
|
-
const label = f;
|
|
403
|
-
lines.push(' ' + chalk.cyan(abs ? linkPath(abs, label) : label));
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
// ── Main summary renderer ─────────────────────────────────────────────────────
|
|
409
|
-
/**
|
|
410
|
-
* Render session as an activity summary.
|
|
411
|
-
* Returns a chalk-formatted string (not markdown) for direct terminal output.
|
|
412
|
-
*/
|
|
413
|
-
export function renderSummary(events, cwd) {
|
|
414
|
-
// ── Collect data in a single chronological pass ───────────────────────────
|
|
415
|
-
let firstUserMessage = '';
|
|
416
|
-
const attachments = [];
|
|
417
|
-
let lastAssistantMessage = '';
|
|
418
|
-
// File paths (absolute) for grouping — split by whether they're inside cwd
|
|
419
|
-
const filesModifiedAbs = new Set();
|
|
420
|
-
const filesReadAbs = new Set();
|
|
421
|
-
const filesModifiedExternal = new Set();
|
|
422
|
-
// Commands with timestamps
|
|
423
|
-
const cmdList = [];
|
|
424
|
-
// Plan items
|
|
425
|
-
const todoItems = [];
|
|
426
|
-
let exitPlanContent = null;
|
|
427
|
-
// Subagent spawns
|
|
428
|
-
const subagents = [];
|
|
429
|
-
// Errors
|
|
430
|
-
const errors = [];
|
|
431
|
-
// Assistant message count (used to decide whether the session produced any narration)
|
|
432
|
-
let assistantCount = 0;
|
|
433
|
-
const isInsideCwd = (p) => !!(cwd && p.startsWith(cwd + '/'));
|
|
434
|
-
for (const event of events) {
|
|
435
|
-
const ts = new Date(event.timestamp).getTime() || 0;
|
|
436
|
-
if (event.type === 'tool_use') {
|
|
437
|
-
if (event._local)
|
|
438
|
-
continue;
|
|
439
|
-
const tool = event.tool || '';
|
|
440
|
-
const args = event.args || {};
|
|
441
|
-
const p = event.path || args.file_path || args.path || '';
|
|
442
|
-
if (['Read', 'read_file', 'view_file', 'cat_file', 'get_file'].includes(tool)) {
|
|
443
|
-
if (p)
|
|
444
|
-
filesReadAbs.add(p);
|
|
445
|
-
}
|
|
446
|
-
else if (['Write', 'Edit', 'write_file', 'edit_file', 'create_file', 'replace', 'patch'].includes(tool)) {
|
|
447
|
-
if (p)
|
|
448
|
-
(isInsideCwd(p) || !cwd ? filesModifiedAbs : filesModifiedExternal).add(p);
|
|
449
|
-
}
|
|
450
|
-
if (event.command) {
|
|
451
|
-
const cmd = event.command.replace(/\n/g, ' ').trim();
|
|
452
|
-
if (cmd)
|
|
453
|
-
cmdList.push({ cmd, ts });
|
|
454
|
-
}
|
|
455
|
-
// Plan items: TodoWrite items + TaskCreate descriptions (project's task tracker)
|
|
456
|
-
if (tool === 'TodoWrite' && Array.isArray(args.todos)) {
|
|
457
|
-
for (const item of args.todos) {
|
|
458
|
-
const text = item.content || item.text || String(item);
|
|
459
|
-
if (text && !todoItems.includes(text))
|
|
460
|
-
todoItems.push(text);
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
if (tool === 'TaskCreate' && (args.description || args.prompt)) {
|
|
464
|
-
const text = String(args.description || args.prompt || '').slice(0, 140);
|
|
465
|
-
if (text && !todoItems.includes(text))
|
|
466
|
-
todoItems.push(text);
|
|
467
|
-
}
|
|
468
|
-
if (tool === 'ExitPlanMode') {
|
|
469
|
-
exitPlanContent = args.result || args.plan || args.content || null;
|
|
470
|
-
}
|
|
471
|
-
// Subagent spawns
|
|
472
|
-
if ((tool === 'Agent' || tool === 'Task') && (args.description || args.prompt)) {
|
|
473
|
-
subagents.push({
|
|
474
|
-
description: String(args.description || args.prompt || '').slice(0, 120),
|
|
475
|
-
subagentType: String(args.subagent_type || ''),
|
|
476
|
-
});
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
else if (event.type === 'error') {
|
|
480
|
-
errors.push({
|
|
481
|
-
tool: event.tool || 'unknown',
|
|
482
|
-
cmd: event.args?.command ? String(event.args.command).slice(0, 80) : undefined,
|
|
483
|
-
content: event.content?.slice(0, 120),
|
|
484
|
-
});
|
|
485
|
-
}
|
|
486
|
-
else if (event.type === 'message') {
|
|
487
|
-
if (event.role === 'user') {
|
|
488
|
-
if (!firstUserMessage) {
|
|
489
|
-
const content = event.content || '';
|
|
490
|
-
if (!/^\s*<local-command-caveat>/i.test(content)) {
|
|
491
|
-
const topic = extractSessionTopic(content);
|
|
492
|
-
if (topic)
|
|
493
|
-
firstUserMessage = content;
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
else if (event.role === 'assistant' && event.content) {
|
|
498
|
-
lastAssistantMessage = event.content;
|
|
499
|
-
assistantCount++;
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
else if (event.type === 'attachment') {
|
|
503
|
-
attachments.push({ mediaType: event.mediaType || 'image/png' });
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
// Dedupe: files in Modified should not appear in Read
|
|
507
|
-
for (const p of filesModifiedAbs)
|
|
508
|
-
filesReadAbs.delete(p);
|
|
509
|
-
for (const p of filesModifiedExternal)
|
|
510
|
-
filesReadAbs.delete(p);
|
|
511
|
-
// Build abs→rel mapping for linkPath
|
|
512
|
-
const buildAbsMap = (absSet) => {
|
|
513
|
-
const m = new Map();
|
|
514
|
-
for (const abs of absSet) {
|
|
515
|
-
const rel = relativeToCwd(abs, cwd);
|
|
516
|
-
m.set(rel, abs);
|
|
517
|
-
}
|
|
518
|
-
return m;
|
|
519
|
-
};
|
|
520
|
-
const modifiedAbsMap = buildAbsMap(filesModifiedAbs);
|
|
521
|
-
const readAbsMap = buildAbsMap(filesReadAbs);
|
|
522
|
-
// ── Render sections ───────────────────────────────────────────────────────
|
|
523
|
-
const lines = [''];
|
|
524
|
-
// 1. Prompt
|
|
525
|
-
if (firstUserMessage) {
|
|
526
|
-
const cleaned = cleanSessionPrompt(firstUserMessage);
|
|
527
|
-
if (cleaned) {
|
|
528
|
-
lines.push(chalk.bold('Prompt:') + ' ' + cleaned.split('\n')[0]);
|
|
529
|
-
const secondLine = cleaned.split('\n')[1]?.trim();
|
|
530
|
-
if (secondLine)
|
|
531
|
-
lines.push(' ' + secondLine);
|
|
532
|
-
const refs = extractReferences(cleaned);
|
|
533
|
-
if (refs.length > 0) {
|
|
534
|
-
lines.push(chalk.gray(' Referenced: ' + refs.join(', ')));
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
// Attachments (images/documents in the first user turn)
|
|
539
|
-
if (attachments.length > 0) {
|
|
540
|
-
const mediaTypes = [...new Set(attachments.map(a => a.mediaType))].join(', ');
|
|
541
|
-
lines.push(chalk.gray(` + ${attachments.length} screenshot${attachments.length !== 1 ? 's' : ''} (${mediaTypes})`));
|
|
542
|
-
}
|
|
543
|
-
if (firstUserMessage || attachments.length > 0)
|
|
544
|
-
lines.push('');
|
|
545
|
-
// 2. Plan
|
|
546
|
-
if (todoItems.length > 0 || exitPlanContent) {
|
|
547
|
-
lines.push(chalk.bold('Plan'));
|
|
548
|
-
if (exitPlanContent) {
|
|
549
|
-
const planLines = exitPlanContent.split('\n').slice(0, 10);
|
|
550
|
-
for (const l of planLines)
|
|
551
|
-
lines.push(' ' + l);
|
|
552
|
-
}
|
|
553
|
-
else {
|
|
554
|
-
for (const item of todoItems.slice(0, 20)) {
|
|
555
|
-
lines.push(' · ' + item);
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
lines.push('');
|
|
559
|
-
}
|
|
560
|
-
// 3. Subagents
|
|
561
|
-
if (subagents.length > 0) {
|
|
562
|
-
lines.push(chalk.bold('Subagents') + chalk.gray(` (${subagents.length})`));
|
|
563
|
-
for (const s of subagents) {
|
|
564
|
-
const typeSuffix = s.subagentType ? chalk.gray(` (${s.subagentType})`) : '';
|
|
565
|
-
lines.push(' Task: ' + s.description + typeSuffix);
|
|
566
|
-
}
|
|
567
|
-
lines.push('');
|
|
568
|
-
}
|
|
569
|
-
// 4. Modified files
|
|
570
|
-
if (filesModifiedAbs.size > 0) {
|
|
571
|
-
lines.push(chalk.bold('Modified') + chalk.gray(` (${filesModifiedAbs.size})`));
|
|
572
|
-
const groups = groupByParentDir(filesModifiedAbs, cwd);
|
|
573
|
-
renderFileGroup(lines, groups, modifiedAbsMap);
|
|
574
|
-
lines.push('');
|
|
575
|
-
}
|
|
576
|
-
// 4b. External edits (files edited outside the project root — typically /tmp)
|
|
577
|
-
if (filesModifiedExternal.size > 0) {
|
|
578
|
-
const externalList = [...filesModifiedExternal].sort();
|
|
579
|
-
const home = process.env.HOME ?? '';
|
|
580
|
-
const display = externalList.slice(0, 3).map(p => home && p.startsWith(home) ? p.replace(home, '~') : p);
|
|
581
|
-
const more = externalList.length > 3 ? chalk.gray(` +${externalList.length - 3} more`) : '';
|
|
582
|
-
lines.push(chalk.gray(`External edits (${filesModifiedExternal.size}): ${display.join(', ')}${more}`));
|
|
583
|
-
lines.push('');
|
|
584
|
-
}
|
|
585
|
-
// 5. Read files
|
|
586
|
-
if (filesReadAbs.size > 0) {
|
|
587
|
-
if (filesReadAbs.size <= 5) {
|
|
588
|
-
lines.push(chalk.bold('Read') + chalk.gray(` (${filesReadAbs.size})`));
|
|
589
|
-
const groups = groupByParentDir(filesReadAbs, cwd);
|
|
590
|
-
renderFileGroup(lines, groups, readAbsMap);
|
|
591
|
-
}
|
|
592
|
-
else {
|
|
593
|
-
lines.push(chalk.bold('Read') + chalk.gray(` ${filesReadAbs.size} other files`));
|
|
594
|
-
}
|
|
595
|
-
lines.push('');
|
|
596
|
-
}
|
|
597
|
-
// 6. Commands
|
|
598
|
-
renderCommandsSection(cmdList, lines);
|
|
599
|
-
// 7. Errors
|
|
600
|
-
if (errors.length > 0) {
|
|
601
|
-
const first = errors[0];
|
|
602
|
-
const firstDesc = first.cmd
|
|
603
|
-
? `${first.tool} "${first.cmd.slice(0, 60)}"`
|
|
604
|
-
: first.content
|
|
605
|
-
? `${first.tool}: ${first.content.slice(0, 60)}`
|
|
606
|
-
: first.tool;
|
|
607
|
-
lines.push(chalk.red(chalk.bold('Errors')) +
|
|
608
|
-
chalk.gray(`: ${errors.length} failure${errors.length !== 1 ? 's' : ''} — first: ${firstDesc}`));
|
|
609
|
-
lines.push('');
|
|
610
|
-
}
|
|
611
|
-
// 9. Final message
|
|
612
|
-
if (lastAssistantMessage) {
|
|
613
|
-
const hasActivity = filesModifiedAbs.size > 0 || filesReadAbs.size > 0 || cmdList.length > 0;
|
|
614
|
-
if (hasActivity || errors.length > 0)
|
|
615
|
-
lines.push(chalk.gray('─'.repeat(60)));
|
|
616
|
-
lines.push('');
|
|
617
|
-
const truncated = lastAssistantMessage.length > 3000
|
|
618
|
-
? lastAssistantMessage.slice(0, 2997) + '...'
|
|
619
|
-
: lastAssistantMessage;
|
|
620
|
-
lines.push(renderMarkdown(truncated).trimEnd());
|
|
621
|
-
lines.push('');
|
|
622
|
-
}
|
|
623
|
-
else if (filesModifiedAbs.size === 0 &&
|
|
624
|
-
filesReadAbs.size === 0 &&
|
|
625
|
-
cmdList.length === 0 &&
|
|
626
|
-
assistantCount === 0) {
|
|
627
|
-
lines.push(chalk.gray('No activity recorded in this session.'));
|
|
628
|
-
lines.push('');
|
|
629
|
-
}
|
|
630
|
-
return lines.join('\n');
|
|
631
|
-
}
|
|
632
|
-
// ── Event filters ─────────────────────────────────────────────────────────────
|
|
633
|
-
/** Allowed values for --include/--exclude role filters. */
|
|
634
|
-
export const VALID_ROLE_VALUES = ['user', 'assistant', 'thinking', 'tools'];
|
|
635
|
-
/**
|
|
636
|
-
* Parse a comma-separated role list (e.g. "user,assistant") into typed values.
|
|
637
|
-
* Throws with a clear message listing valid values on any unknown entry.
|
|
638
|
-
*/
|
|
639
|
-
export function parseRoleList(raw, flag) {
|
|
640
|
-
const parts = raw.split(',').map(s => s.trim()).filter(Boolean);
|
|
641
|
-
if (parts.length === 0) {
|
|
642
|
-
throw new Error(`${flag} requires at least one role. Valid values: ${VALID_ROLE_VALUES.join(', ')}`);
|
|
643
|
-
}
|
|
644
|
-
for (const p of parts) {
|
|
645
|
-
if (!VALID_ROLE_VALUES.includes(p)) {
|
|
646
|
-
throw new Error(`Invalid value "${p}" for ${flag}. Valid values: ${VALID_ROLE_VALUES.join(', ')}`);
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
return parts;
|
|
650
|
-
}
|
|
651
|
-
function roleOfEvent(e) {
|
|
652
|
-
if (e.type === 'message' && e.role === 'user')
|
|
653
|
-
return 'user';
|
|
654
|
-
if (e.type === 'message' && e.role === 'assistant')
|
|
655
|
-
return 'assistant';
|
|
656
|
-
if (e.type === 'thinking')
|
|
657
|
-
return 'thinking';
|
|
658
|
-
if (e.type === 'tool_use' || e.type === 'tool_result')
|
|
659
|
-
return 'tools';
|
|
660
|
-
return null;
|
|
661
|
-
}
|
|
662
|
-
/**
|
|
663
|
-
* Keep events whose role is in `include` (whitelist) or whose role is not in
|
|
664
|
-
* `exclude` (blacklist). Non-role events (errors, usage, attachments, init,
|
|
665
|
-
* result) are preserved unless explicitly constrained by `include` — that
|
|
666
|
-
* matches the user model: "include user" means "only user".
|
|
667
|
-
*/
|
|
668
|
-
function applyRoleFilter(events, opts) {
|
|
669
|
-
if (opts.include && opts.include.length > 0) {
|
|
670
|
-
const set = new Set(opts.include);
|
|
671
|
-
return events.filter(e => {
|
|
672
|
-
const role = roleOfEvent(e);
|
|
673
|
-
return role !== null && set.has(role);
|
|
674
|
-
});
|
|
675
|
-
}
|
|
676
|
-
if (opts.exclude && opts.exclude.length > 0) {
|
|
677
|
-
const set = new Set(opts.exclude);
|
|
678
|
-
return events.filter(e => {
|
|
679
|
-
const role = roleOfEvent(e);
|
|
680
|
-
return role === null || !set.has(role);
|
|
681
|
-
});
|
|
682
|
-
}
|
|
683
|
-
return events;
|
|
684
|
-
}
|
|
685
|
-
/**
|
|
686
|
-
* A "turn" starts at each user message. `--first N` keeps events through the
|
|
687
|
-
* end of the Nth user turn; `--last N` keeps events from the start of the
|
|
688
|
-
* (M-N+1)th user turn to the end. If the session has no user messages, every
|
|
689
|
-
* assistant message counts as a turn instead.
|
|
690
|
-
*/
|
|
691
|
-
function applyTurnSlice(events, opts) {
|
|
692
|
-
if (opts.first === undefined && opts.last === undefined)
|
|
693
|
-
return events;
|
|
694
|
-
if (opts.first !== undefined && opts.last !== undefined) {
|
|
695
|
-
throw new Error('--first and --last are mutually exclusive');
|
|
696
|
-
}
|
|
697
|
-
const n = (opts.first ?? opts.last);
|
|
698
|
-
if (!Number.isFinite(n) || n <= 0) {
|
|
699
|
-
throw new Error(`Turn count must be a positive integer, got ${n}`);
|
|
700
|
-
}
|
|
701
|
-
const isTurnStart = (e) => e.type === 'message' && e.role === 'user';
|
|
702
|
-
const turnStartIdx = [];
|
|
703
|
-
for (let i = 0; i < events.length; i++)
|
|
704
|
-
if (isTurnStart(events[i]))
|
|
705
|
-
turnStartIdx.push(i);
|
|
706
|
-
// Fallback: no user messages — treat assistant messages as turn boundaries.
|
|
707
|
-
if (turnStartIdx.length === 0) {
|
|
708
|
-
for (let i = 0; i < events.length; i++) {
|
|
709
|
-
if (events[i].type === 'message' && events[i].role === 'assistant')
|
|
710
|
-
turnStartIdx.push(i);
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
if (turnStartIdx.length === 0)
|
|
714
|
-
return events;
|
|
715
|
-
if (opts.first !== undefined) {
|
|
716
|
-
if (n >= turnStartIdx.length)
|
|
717
|
-
return events;
|
|
718
|
-
const endIdx = turnStartIdx[n]; // exclusive
|
|
719
|
-
return events.slice(0, endIdx);
|
|
720
|
-
}
|
|
721
|
-
// --last
|
|
722
|
-
if (n >= turnStartIdx.length)
|
|
723
|
-
return events;
|
|
724
|
-
const startIdx = turnStartIdx[turnStartIdx.length - n];
|
|
725
|
-
return events.slice(startIdx);
|
|
726
|
-
}
|
|
727
|
-
/**
|
|
728
|
-
* Apply include/exclude/first/last. Turn slicing runs first so role filters
|
|
729
|
-
* operate on the sliced window (natural semantics: "last 3 turns, user only").
|
|
730
|
-
*/
|
|
731
|
-
export function filterEvents(events, opts) {
|
|
732
|
-
if (opts.include && opts.include.length > 0 && opts.exclude && opts.exclude.length > 0) {
|
|
733
|
-
throw new Error('--include and --exclude are mutually exclusive');
|
|
734
|
-
}
|
|
735
|
-
const sliced = applyTurnSlice(events, opts);
|
|
736
|
-
return applyRoleFilter(sliced, opts);
|
|
737
|
-
}
|
|
738
|
-
// ── Conversation renderers ────────────────────────────────────────────────────
|
|
739
|
-
/**
|
|
740
|
-
* Build the conversation as a single markdown string: user / assistant
|
|
741
|
-
* messages, inline thinking blocks, tool calls, and errors. Emitted in event
|
|
742
|
-
* order so reasoning sits where it actually occurred relative to the assistant
|
|
743
|
-
* reply.
|
|
744
|
-
*/
|
|
745
|
-
export function renderConversationMarkdown(events) {
|
|
746
|
-
const parts = [];
|
|
747
|
-
for (const event of events) {
|
|
748
|
-
if (event.type === 'message') {
|
|
749
|
-
if (event.role === 'user') {
|
|
750
|
-
parts.push(`## User\n\n${event.content ?? ''}`);
|
|
751
|
-
}
|
|
752
|
-
else if (event.role === 'assistant') {
|
|
753
|
-
parts.push(`## Assistant\n\n${event.content ?? ''}`);
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
else if (event.type === 'thinking') {
|
|
757
|
-
if (event.content)
|
|
758
|
-
parts.push(`### Thinking\n\n${event.content}`);
|
|
759
|
-
}
|
|
760
|
-
else if (event.type === 'tool_use') {
|
|
761
|
-
const tool = event.tool || 'unknown';
|
|
762
|
-
if (event.command) {
|
|
763
|
-
parts.push(`### Tool: ${tool}\n\n\`\`\`bash\n${event.command}\n\`\`\``);
|
|
764
|
-
}
|
|
765
|
-
else if (event.path) {
|
|
766
|
-
parts.push(`### Tool: ${tool}\n\n\`${shortenPathTrace(event.path)}\``);
|
|
767
|
-
}
|
|
768
|
-
else {
|
|
769
|
-
const summary = summarizeToolUse(tool, event.args);
|
|
770
|
-
parts.push(`### Tool: ${tool}\n\n${summary}`);
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
else if (event.type === 'tool_result') {
|
|
774
|
-
if (event.content) {
|
|
775
|
-
const body = event.content.length > 2000 ? event.content.slice(0, 2000) + '\n…' : event.content;
|
|
776
|
-
parts.push(`### Tool Result\n\n\`\`\`\n${body}\n\`\`\``);
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
else if (event.type === 'error') {
|
|
780
|
-
parts.push(`### Error\n\n${event.content || event.tool || 'Unknown error'}`);
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
return parts.join('\n\n');
|
|
784
|
-
}
|
|
785
|
-
/**
|
|
786
|
-
* Render session as JSON (normalized events).
|
|
787
|
-
*/
|
|
788
|
-
export function renderJson(events) {
|
|
789
|
-
return JSON.stringify(events, null, 2);
|
|
790
|
-
}
|
|
791
|
-
/** Replace the home directory prefix with ~ for trace display. */
|
|
792
|
-
function shortenPathTrace(p) {
|
|
793
|
-
const home = process.env.HOME || '';
|
|
794
|
-
if (home && p.startsWith(home))
|
|
795
|
-
return '~' + p.slice(home.length);
|
|
796
|
-
return p;
|
|
797
|
-
}
|
|
798
|
-
//# sourceMappingURL=render.js.map
|