@compilr-dev/cli 0.5.0 → 0.5.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/LICENSE +108 -0
- package/README.md +237 -69
- package/dist/.tsbuildinfo.app +1 -0
- package/dist/.tsbuildinfo.data +1 -0
- package/dist/.tsbuildinfo.domain +1 -0
- package/dist/.tsbuildinfo.foundation +1 -0
- package/dist/agent.d.ts +61 -4
- package/dist/agent.js +241 -245
- package/dist/anchors/index.d.ts +1 -1
- package/dist/anchors/index.js +1 -1
- package/dist/anchors/project-anchors.d.ts +2 -2
- package/dist/anchors/project-anchors.js +1 -1
- package/dist/auth/api-client.d.ts +124 -0
- package/dist/auth/api-client.js +261 -0
- package/dist/auth/index.d.ts +172 -0
- package/dist/auth/index.js +545 -0
- package/dist/auth/storage.d.ts +52 -0
- package/dist/auth/storage.js +118 -0
- package/dist/changelog/index.d.ts +16 -0
- package/dist/changelog/index.js +24 -0
- package/dist/changelog/releases.d.ts +17 -0
- package/dist/changelog/releases.js +63 -0
- package/dist/commands-v2/handlers/auth.d.ts +10 -0
- package/dist/commands-v2/handlers/auth.js +118 -0
- package/dist/commands-v2/handlers/background.d.ts +14 -0
- package/dist/commands-v2/handlers/background.js +276 -0
- package/dist/commands-v2/handlers/context.js +286 -81
- package/dist/commands-v2/handlers/core.d.ts +1 -0
- package/dist/commands-v2/handlers/core.js +133 -8
- package/dist/commands-v2/handlers/debug.js +18 -0
- package/dist/commands-v2/handlers/delegations.d.ts +8 -0
- package/dist/commands-v2/handlers/delegations.js +29 -0
- package/dist/commands-v2/handlers/files.d.ts +8 -0
- package/dist/commands-v2/handlers/files.js +162 -0
- package/dist/commands-v2/handlers/filter.d.ts +9 -0
- package/dist/commands-v2/handlers/filter.js +130 -0
- package/dist/commands-v2/handlers/games.d.ts +7 -0
- package/dist/commands-v2/handlers/games.js +57 -0
- package/dist/commands-v2/handlers/index.d.ts +13 -0
- package/dist/commands-v2/handlers/index.js +39 -0
- package/dist/commands-v2/handlers/mcp.d.ts +8 -0
- package/dist/commands-v2/handlers/mcp.js +39 -0
- package/dist/commands-v2/handlers/notifications.d.ts +9 -0
- package/dist/commands-v2/handlers/notifications.js +34 -0
- package/dist/commands-v2/handlers/project.js +295 -31
- package/dist/commands-v2/handlers/reset.d.ts +11 -0
- package/dist/commands-v2/handlers/reset.js +118 -0
- package/dist/commands-v2/handlers/session.d.ts +161 -0
- package/dist/commands-v2/handlers/session.js +805 -0
- package/dist/commands-v2/handlers/settings.d.ts +2 -0
- package/dist/commands-v2/handlers/settings.js +217 -35
- package/dist/commands-v2/handlers/tasks.d.ts +5 -0
- package/dist/commands-v2/handlers/tasks.js +36 -0
- package/dist/commands-v2/handlers/team.d.ts +9 -0
- package/dist/commands-v2/handlers/team.js +549 -0
- package/dist/commands-v2/handlers/terminals.d.ts +9 -0
- package/dist/commands-v2/handlers/terminals.js +34 -0
- package/dist/commands-v2/index.d.ts +3 -2
- package/dist/commands-v2/index.js +4 -1
- package/dist/commands-v2/registry.d.ts +15 -0
- package/dist/commands-v2/registry.js +34 -0
- package/dist/commands-v2/types.d.ts +81 -3
- package/dist/commands.js +13 -0
- package/dist/compilr-diff-companion.vsix +0 -0
- package/dist/db/index.js +98 -4
- package/dist/db/repositories/document-repository.d.ts +2 -0
- package/dist/db/repositories/document-repository.js +6 -1
- package/dist/db/repositories/index.d.ts +2 -0
- package/dist/db/repositories/index.js +1 -0
- package/dist/db/repositories/plan-repository.d.ts +101 -0
- package/dist/db/repositories/plan-repository.js +275 -0
- package/dist/db/repositories/project-repository.d.ts +6 -0
- package/dist/db/repositories/project-repository.js +41 -0
- package/dist/db/repositories/work-item-repository.d.ts +15 -0
- package/dist/db/repositories/work-item-repository.js +69 -4
- package/dist/db/schema.d.ts +40 -3
- package/dist/db/schema.js +66 -3
- package/dist/episodes/index.d.ts +20 -0
- package/dist/episodes/index.js +27 -0
- package/dist/episodes/recorder.d.ts +51 -0
- package/dist/episodes/recorder.js +195 -0
- package/dist/episodes/significant-work.d.ts +21 -0
- package/dist/episodes/significant-work.js +56 -0
- package/dist/episodes/store.d.ts +38 -0
- package/dist/episodes/store.js +199 -0
- package/dist/episodes/types.d.ts +35 -0
- package/dist/episodes/types.js +6 -0
- package/dist/episodes/work-at-risk.d.ts +12 -0
- package/dist/episodes/work-at-risk.js +38 -0
- package/dist/episodes/work-summary-anchor.d.ts +23 -0
- package/dist/episodes/work-summary-anchor.js +73 -0
- package/dist/games/coins.d.ts +66 -0
- package/dist/games/coins.js +165 -0
- package/dist/games/game-base.d.ts +84 -0
- package/dist/games/game-base.js +204 -0
- package/dist/games/index.d.ts +16 -0
- package/dist/games/index.js +49 -0
- package/dist/games/scores.d.ts +69 -0
- package/dist/games/scores.js +191 -0
- package/dist/games/tetris/board.d.ts +59 -0
- package/dist/games/tetris/board.js +170 -0
- package/dist/games/tetris/index.d.ts +109 -0
- package/dist/games/tetris/index.js +610 -0
- package/dist/games/tetris/pieces.d.ts +44 -0
- package/dist/games/tetris/pieces.js +271 -0
- package/dist/games/tetris/renderer.d.ts +26 -0
- package/dist/games/tetris/renderer.js +77 -0
- package/dist/guide/guide-content.d.ts +23 -0
- package/dist/guide/guide-content.js +196 -0
- package/dist/guide/index.d.ts +8 -0
- package/dist/guide/index.js +7 -0
- package/dist/guide/shared-content.d.ts +37 -0
- package/dist/guide/shared-content.js +1272 -0
- package/dist/guide/tutorial-helpers.d.ts +57 -0
- package/dist/guide/tutorial-helpers.js +147 -0
- package/dist/handlers/ask-user-handlers.d.ts +32 -0
- package/dist/handlers/ask-user-handlers.js +104 -0
- package/dist/handlers/delegation-handlers.d.ts +34 -0
- package/dist/handlers/delegation-handlers.js +291 -0
- package/dist/handlers/permission-handler.d.ts +30 -0
- package/dist/handlers/permission-handler.js +205 -0
- package/dist/index.d.ts +11 -1
- package/dist/index.js +448 -271
- package/dist/input-handlers/memory-handler.d.ts +1 -1
- package/dist/input-handlers/memory-handler.js +2 -1
- package/dist/models/index.d.ts +10 -0
- package/dist/models/index.js +12 -0
- package/dist/models/model-registry.d.ts +38 -0
- package/dist/models/model-registry.js +69 -0
- package/dist/models/model-tiers.d.ts +28 -0
- package/dist/models/model-tiers.js +71 -0
- package/dist/models/model-validation.d.ts +25 -0
- package/dist/models/model-validation.js +291 -0
- package/dist/models/ollama-models.d.ts +73 -0
- package/dist/models/ollama-models.js +178 -0
- package/dist/models/provider-types.d.ts +6 -0
- package/dist/models/provider-types.js +1 -0
- package/dist/models/providers.d.ts +35 -0
- package/dist/models/providers.js +58 -0
- package/dist/models/types.d.ts +4 -0
- package/dist/models/types.js +4 -0
- package/dist/multi-agent/activity.d.ts +21 -0
- package/dist/multi-agent/activity.js +34 -0
- package/dist/multi-agent/agent-selection.d.ts +55 -0
- package/dist/multi-agent/agent-selection.js +90 -0
- package/dist/multi-agent/artifacts.d.ts +197 -0
- package/dist/multi-agent/artifacts.js +379 -0
- package/dist/multi-agent/checkpointer.d.ts +138 -0
- package/dist/multi-agent/checkpointer.js +471 -0
- package/dist/multi-agent/collision-utils.d.ts +16 -0
- package/dist/multi-agent/collision-utils.js +28 -0
- package/dist/multi-agent/context-resolver.d.ts +97 -0
- package/dist/multi-agent/context-resolver.js +316 -0
- package/dist/multi-agent/custom-agents.d.ts +83 -0
- package/dist/multi-agent/custom-agents.js +227 -0
- package/dist/multi-agent/delegation-tracker.d.ts +157 -0
- package/dist/multi-agent/delegation-tracker.js +243 -0
- package/dist/multi-agent/file-lock-hook.d.ts +29 -0
- package/dist/multi-agent/file-lock-hook.js +97 -0
- package/dist/multi-agent/file-locks.d.ts +58 -0
- package/dist/multi-agent/file-locks.js +194 -0
- package/dist/multi-agent/index.d.ts +24 -0
- package/dist/multi-agent/index.js +30 -0
- package/dist/multi-agent/mention-parser.d.ts +64 -0
- package/dist/multi-agent/mention-parser.js +146 -0
- package/dist/multi-agent/notification-manager.d.ts +84 -0
- package/dist/multi-agent/notification-manager.js +224 -0
- package/dist/multi-agent/pending-requests.d.ts +122 -0
- package/dist/multi-agent/pending-requests.js +155 -0
- package/dist/multi-agent/session-registry.d.ts +139 -0
- package/dist/multi-agent/session-registry.js +514 -0
- package/dist/multi-agent/shared-context.d.ts +293 -0
- package/dist/multi-agent/shared-context.js +671 -0
- package/dist/multi-agent/skill-requirements.d.ts +66 -0
- package/dist/multi-agent/skill-requirements.js +178 -0
- package/dist/multi-agent/task-assignment.d.ts +69 -0
- package/dist/multi-agent/task-assignment.js +123 -0
- package/dist/multi-agent/task-suggestion.d.ts +31 -0
- package/dist/multi-agent/task-suggestion.js +72 -0
- package/dist/multi-agent/team-agent.d.ts +201 -0
- package/dist/multi-agent/team-agent.js +488 -0
- package/dist/multi-agent/team.d.ts +286 -0
- package/dist/multi-agent/team.js +610 -0
- package/dist/multi-agent/tool-config.d.ts +110 -0
- package/dist/multi-agent/tool-config.js +661 -0
- package/dist/multi-agent/types.d.ts +211 -0
- package/dist/multi-agent/types.js +617 -0
- package/dist/prompts/plan-mode-prompt.d.ts +11 -0
- package/dist/prompts/plan-mode-prompt.js +95 -0
- package/dist/repl-helpers.js +5 -2
- package/dist/repl-v2.d.ts +401 -2
- package/dist/repl-v2.js +2588 -65
- package/dist/session/index.d.ts +6 -0
- package/dist/session/index.js +6 -0
- package/dist/session/project-session-manager.d.ts +158 -0
- package/dist/session/project-session-manager.js +650 -0
- package/dist/settings/index.d.ts +133 -13
- package/dist/settings/index.js +329 -24
- package/dist/settings/mcp-config.d.ts +76 -0
- package/dist/settings/mcp-config.js +143 -0
- package/dist/settings/paths.d.ts +4 -0
- package/dist/settings/paths.js +6 -0
- package/dist/shared-handlers.d.ts +62 -0
- package/dist/shared-handlers.js +48 -0
- package/dist/system-prompt/builder.d.ts +5 -0
- package/dist/system-prompt/builder.js +4 -0
- package/dist/system-prompt/index.d.ts +18 -0
- package/dist/system-prompt/index.js +18 -0
- package/dist/system-prompt/modules.d.ts +5 -0
- package/dist/system-prompt/modules.js +4 -0
- package/dist/tabbed-menu.js +2 -1
- package/dist/templates/compilr-md-import.d.ts +16 -0
- package/dist/templates/compilr-md-import.js +241 -0
- package/dist/templates/compilr-md.js +10 -61
- package/dist/templates/config-json.d.ts +1 -25
- package/dist/templates/index.d.ts +2 -0
- package/dist/templates/index.js +34 -73
- package/dist/tool-names.d.ts +113 -0
- package/dist/tool-names.js +239 -0
- package/dist/tools/ask-user-simple.d.ts +1 -1
- package/dist/tools/ask-user-simple.js +2 -1
- package/dist/tools/ask-user.d.ts +1 -1
- package/dist/tools/ask-user.js +2 -1
- package/dist/tools/backlog.d.ts +2 -2
- package/dist/tools/backlog.js +1 -1
- package/dist/tools/db-tools.d.ts +13 -61
- package/dist/tools/db-tools.js +12 -13
- package/dist/tools/delegate-background.d.ts +27 -0
- package/dist/tools/delegate-background.js +115 -0
- package/dist/tools/delegate.d.ts +22 -0
- package/dist/tools/delegate.js +97 -0
- package/dist/tools/delegation-status.d.ts +16 -0
- package/dist/tools/delegation-status.js +128 -0
- package/dist/tools/guide-tool.d.ts +12 -0
- package/dist/tools/guide-tool.js +59 -0
- package/dist/tools/handoff.d.ts +25 -0
- package/dist/tools/handoff.js +99 -0
- package/dist/tools/meta-tools.d.ts +26 -0
- package/dist/tools/meta-tools.js +47 -0
- package/dist/tools/platform-adapter.d.ts +35 -0
- package/dist/tools/platform-adapter.js +404 -0
- package/dist/tools/project-db.d.ts +5 -73
- package/dist/tools/project-db.js +5 -336
- package/dist/tools.d.ts +67 -2
- package/dist/tools.js +240 -48
- package/dist/ui/autocomplete-controller.d.ts +42 -0
- package/dist/ui/autocomplete-controller.js +384 -0
- package/dist/ui/base/index.d.ts +1 -1
- package/dist/ui/base/index.js +1 -1
- package/dist/ui/base/overlay-base-v2.d.ts +10 -0
- package/dist/ui/base/overlay-base-v2.js +14 -0
- package/dist/ui/base/render-utils.d.ts +19 -0
- package/dist/ui/base/render-utils.js +25 -0
- package/dist/ui/base/tabbed-list-overlay-v2.d.ts +16 -1
- package/dist/ui/base/tabbed-list-overlay-v2.js +19 -1
- package/dist/ui/constants/labels.d.ts +14 -0
- package/dist/ui/constants/labels.js +52 -0
- package/dist/ui/conversation-store.d.ts +55 -0
- package/dist/ui/conversation-store.js +107 -0
- package/dist/ui/conversation.js +11 -13
- package/dist/ui/diff.d.ts +7 -1
- package/dist/ui/diff.js +85 -48
- package/dist/ui/ephemeral.js +3 -9
- package/dist/ui/file-autocomplete.d.ts +24 -0
- package/dist/ui/file-autocomplete.js +56 -0
- package/dist/ui/footer-renderer.d.ts +69 -0
- package/dist/ui/footer-renderer.js +431 -0
- package/dist/ui/footer.d.ts +74 -7
- package/dist/ui/footer.js +173 -16
- package/dist/ui/input-controller.d.ts +51 -0
- package/dist/ui/input-controller.js +176 -0
- package/dist/ui/input-prompt.d.ts +19 -0
- package/dist/ui/input-prompt.js +206 -14
- package/dist/ui/keyboard-handler.d.ts +57 -0
- package/dist/ui/keyboard-handler.js +557 -0
- package/dist/ui/live-region-facade.d.ts +42 -0
- package/dist/ui/live-region-facade.js +205 -0
- package/dist/ui/live-region.d.ts +0 -4
- package/dist/ui/live-region.js +6 -14
- package/dist/ui/mascot/renderer.d.ts +1 -1
- package/dist/ui/mascot/renderer.js +37 -2
- package/dist/ui/overlay/data/tutorial-content.d.ts +9 -0
- package/dist/ui/overlay/data/tutorial-content.js +9 -0
- package/dist/ui/overlay/data/tutorial-registry.d.ts +12 -0
- package/dist/ui/overlay/data/tutorial-registry.js +116 -0
- package/dist/ui/overlay/data/tutorial-types.d.ts +35 -0
- package/dist/ui/overlay/data/tutorial-types.js +6 -0
- package/dist/ui/overlay/data/tutorials/basics/first-conversation.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/basics/first-conversation.js +220 -0
- package/dist/ui/overlay/data/tutorials/basics/first-project.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/basics/first-project.js +284 -0
- package/dist/ui/overlay/data/tutorials/basics/navigation.d.ts +8 -0
- package/dist/ui/overlay/data/tutorials/basics/navigation.js +22 -0
- package/dist/ui/overlay/data/tutorials/basics/welcome.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/basics/welcome.js +174 -0
- package/dist/ui/overlay/data/tutorials/config/context-management.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/config/context-management.js +158 -0
- package/dist/ui/overlay/data/tutorials/config/mcp-servers.d.ts +8 -0
- package/dist/ui/overlay/data/tutorials/config/mcp-servers.js +155 -0
- package/dist/ui/overlay/data/tutorials/config/model-selection.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/config/model-selection.js +162 -0
- package/dist/ui/overlay/data/tutorials/config/permissions-safety.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/config/permissions-safety.js +163 -0
- package/dist/ui/overlay/data/tutorials/config/settings-config.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/config/settings-config.js +166 -0
- package/dist/ui/overlay/data/tutorials/planning/arch.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/planning/arch.js +168 -0
- package/dist/ui/overlay/data/tutorials/planning/backlog.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/planning/backlog.js +103 -0
- package/dist/ui/overlay/data/tutorials/planning/build.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/planning/build.js +173 -0
- package/dist/ui/overlay/data/tutorials/planning/design.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/planning/design.js +205 -0
- package/dist/ui/overlay/data/tutorials/planning/docs.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/planning/docs.js +143 -0
- package/dist/ui/overlay/data/tutorials/planning/prd.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/planning/prd.js +173 -0
- package/dist/ui/overlay/data/tutorials/planning/scaffold.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/planning/scaffold.js +164 -0
- package/dist/ui/overlay/data/tutorials/planning/sketch.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/planning/sketch.js +58 -0
- package/dist/ui/overlay/data/tutorials/projects/anchors.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/projects/anchors.js +248 -0
- package/dist/ui/overlay/data/tutorials/projects/import-project.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/projects/import-project.js +172 -0
- package/dist/ui/overlay/data/tutorials/projects/managing-projects.d.ts +8 -0
- package/dist/ui/overlay/data/tutorials/projects/managing-projects.js +212 -0
- package/dist/ui/overlay/data/tutorials/projects/new-project.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/projects/new-project.js +251 -0
- package/dist/ui/overlay/data/tutorials/projects/session-management.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/projects/session-management.js +169 -0
- package/dist/ui/overlay/data/tutorials/teams/background-execution.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/teams/background-execution.js +171 -0
- package/dist/ui/overlay/data/tutorials/teams/multi-terminal.d.ts +8 -0
- package/dist/ui/overlay/data/tutorials/teams/multi-terminal.js +147 -0
- package/dist/ui/overlay/data/tutorials/teams/task-assignment.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/teams/task-assignment.js +204 -0
- package/dist/ui/overlay/data/tutorials/teams/team-overview.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/teams/team-overview.js +165 -0
- package/dist/ui/overlay/data/tutorials/teams/working-with-agents.d.ts +7 -0
- package/dist/ui/overlay/data/tutorials/teams/working-with-agents.js +172 -0
- package/dist/ui/overlay/impl/agents-overlay-v2.js +6 -17
- package/dist/ui/overlay/impl/anchors-overlay-v2.js +30 -64
- package/dist/ui/overlay/impl/artifact-detail-overlay-v2.d.ts +43 -0
- package/dist/ui/overlay/impl/artifact-detail-overlay-v2.js +232 -0
- package/dist/ui/overlay/impl/artifact-overlay-v2.d.ts +40 -0
- package/dist/ui/overlay/impl/artifact-overlay-v2.js +115 -0
- package/dist/ui/overlay/impl/ask-user-overlay-v2.js +2 -5
- package/dist/ui/overlay/impl/background-overlay-v2.d.ts +40 -0
- package/dist/ui/overlay/impl/background-overlay-v2.js +147 -0
- package/dist/ui/overlay/impl/backlog-overlay-v2.d.ts +4 -1
- package/dist/ui/overlay/impl/backlog-overlay-v2.js +55 -16
- package/dist/ui/overlay/impl/changelog-overlay-v2.d.ts +44 -0
- package/dist/ui/overlay/impl/changelog-overlay-v2.js +165 -0
- package/dist/ui/overlay/impl/commands-overlay-v2.js +4 -6
- package/dist/ui/overlay/impl/config-overlay-v2.d.ts +12 -1
- package/dist/ui/overlay/impl/config-overlay-v2.js +164 -100
- package/dist/ui/overlay/impl/custom-agent-form-overlay-v2.d.ts +83 -0
- package/dist/ui/overlay/impl/custom-agent-form-overlay-v2.js +711 -0
- package/dist/ui/overlay/impl/dashboard-overlay-v2.d.ts +2 -0
- package/dist/ui/overlay/impl/dashboard-overlay-v2.js +26 -3
- package/dist/ui/overlay/impl/delegations-overlay-v2.d.ts +28 -0
- package/dist/ui/overlay/impl/delegations-overlay-v2.js +279 -0
- package/dist/ui/overlay/impl/docs-overlay-v2.js +12 -9
- package/dist/ui/overlay/impl/document-detail-overlay-v2.d.ts +7 -0
- package/dist/ui/overlay/impl/document-detail-overlay-v2.js +119 -78
- package/dist/ui/overlay/impl/filter-overlay-v2.d.ts +41 -0
- package/dist/ui/overlay/impl/filter-overlay-v2.js +110 -0
- package/dist/ui/overlay/impl/games-overlay-v2.d.ts +31 -0
- package/dist/ui/overlay/impl/games-overlay-v2.js +135 -0
- package/dist/ui/overlay/impl/help-overlay-v2.d.ts +26 -3
- package/dist/ui/overlay/impl/help-overlay-v2.js +20 -42
- package/dist/ui/overlay/impl/login-overlay-v2.d.ts +49 -0
- package/dist/ui/overlay/impl/login-overlay-v2.js +277 -0
- package/dist/ui/overlay/impl/mcp-overlay-v2.d.ts +63 -0
- package/dist/ui/overlay/impl/mcp-overlay-v2.js +907 -0
- package/dist/ui/overlay/impl/model-overlay-v2.d.ts +57 -13
- package/dist/ui/overlay/impl/model-overlay-v2.js +1086 -61
- package/dist/ui/overlay/impl/new-overlay-v2.d.ts +37 -6
- package/dist/ui/overlay/impl/new-overlay-v2.js +715 -65
- package/dist/ui/overlay/impl/notifications-overlay-v2.d.ts +20 -0
- package/dist/ui/overlay/impl/notifications-overlay-v2.js +116 -0
- package/dist/ui/overlay/impl/onboarding-wizard-overlay-v2.d.ts +76 -0
- package/dist/ui/overlay/impl/onboarding-wizard-overlay-v2.js +728 -0
- package/dist/ui/overlay/impl/pending-overlay-v2.d.ts +51 -0
- package/dist/ui/overlay/impl/pending-overlay-v2.js +445 -0
- package/dist/ui/overlay/impl/permission-overlay-v2.js +5 -5
- package/dist/ui/overlay/impl/permissions-overlay-v2.d.ts +85 -0
- package/dist/ui/overlay/impl/permissions-overlay-v2.js +820 -0
- package/dist/ui/overlay/impl/plan-approval-overlay-v2.d.ts +35 -0
- package/dist/ui/overlay/impl/plan-approval-overlay-v2.js +181 -0
- package/dist/ui/overlay/impl/project-edit-overlay-v2.d.ts +36 -0
- package/dist/ui/overlay/impl/project-edit-overlay-v2.js +195 -0
- package/dist/ui/overlay/impl/projects-overlay-v2.d.ts +1 -0
- package/dist/ui/overlay/impl/projects-overlay-v2.js +278 -44
- package/dist/ui/overlay/impl/reset-overlay-v2.d.ts +39 -0
- package/dist/ui/overlay/impl/reset-overlay-v2.js +107 -0
- package/dist/ui/overlay/impl/resume-overlay-v2.d.ts +60 -0
- package/dist/ui/overlay/impl/resume-overlay-v2.js +414 -0
- package/dist/ui/overlay/impl/session-mode-overlay-v2.d.ts +43 -0
- package/dist/ui/overlay/impl/session-mode-overlay-v2.js +124 -0
- package/dist/ui/overlay/impl/tasks-overlay-v2.d.ts +28 -0
- package/dist/ui/overlay/impl/tasks-overlay-v2.js +283 -0
- package/dist/ui/overlay/impl/team-overlay-v2.d.ts +86 -0
- package/dist/ui/overlay/impl/team-overlay-v2.js +692 -0
- package/dist/ui/overlay/impl/terminals-overlay-v2.d.ts +26 -0
- package/dist/ui/overlay/impl/terminals-overlay-v2.js +217 -0
- package/dist/ui/overlay/impl/tools-overlay-v2.js +3 -7
- package/dist/ui/overlay/impl/tutorial-overlay-v2.d.ts +30 -16
- package/dist/ui/overlay/impl/tutorial-overlay-v2.js +133 -956
- package/dist/ui/overlay/impl/workflow-overlay-v2.d.ts +1 -0
- package/dist/ui/overlay/impl/workflow-overlay-v2.js +10 -4
- package/dist/ui/overlay/index.d.ts +20 -1
- package/dist/ui/overlay/index.js +19 -0
- package/dist/ui/overlay/types.d.ts +5 -0
- package/dist/ui/overlay-manager.d.ts +43 -0
- package/dist/ui/overlay-manager.js +238 -0
- package/dist/ui/overlays.js +4 -16
- package/dist/ui/permission-overlay.js +6 -5
- package/dist/ui/status-bar-controller.d.ts +33 -0
- package/dist/ui/status-bar-controller.js +99 -0
- package/dist/ui/subagent-renderer.js +3 -19
- package/dist/ui/terminal-autocomplete-utils.d.ts +23 -0
- package/dist/ui/terminal-autocomplete-utils.js +83 -0
- package/dist/ui/terminal-line-builders.d.ts +17 -0
- package/dist/ui/terminal-line-builders.js +42 -0
- package/dist/ui/terminal-render-item.d.ts +16 -0
- package/dist/ui/terminal-render-item.js +267 -0
- package/dist/ui/terminal-renderer.d.ts +7 -8
- package/dist/ui/terminal-renderer.js +7 -8
- package/dist/ui/terminal-types.d.ts +179 -0
- package/dist/ui/terminal-types.js +34 -0
- package/dist/ui/terminal-ui.d.ts +144 -276
- package/dist/ui/terminal-ui.js +384 -1861
- package/dist/ui/todo-zone.d.ts +19 -1
- package/dist/ui/todo-zone.js +71 -13
- package/dist/ui/tool-formatters.js +696 -1
- package/dist/ui/turn-metrics.d.ts +56 -0
- package/dist/ui/turn-metrics.js +75 -0
- package/dist/ui/types.d.ts +28 -0
- package/dist/ui/types.js +1 -0
- package/dist/ui/vscode-diff-ipc.d.ts +102 -0
- package/dist/ui/vscode-diff-ipc.js +385 -0
- package/dist/utils/credentials.d.ts +24 -5
- package/dist/utils/credentials.js +123 -9
- package/dist/utils/format-tokens.d.ts +13 -0
- package/dist/utils/format-tokens.js +18 -0
- package/dist/utils/git-config.d.ts +26 -0
- package/dist/utils/git-config.js +54 -0
- package/dist/utils/message-utils.d.ts +61 -0
- package/dist/utils/message-utils.js +72 -0
- package/dist/utils/model-tiers.d.ts +8 -1
- package/dist/utils/model-tiers.js +38 -16
- package/dist/utils/open-browser.d.ts +5 -0
- package/dist/utils/open-browser.js +32 -0
- package/dist/utils/path-safety.js +3 -2
- package/dist/utils/project-detection.d.ts +58 -0
- package/dist/utils/project-detection.js +424 -0
- package/dist/utils/project-memory.js +2 -1
- package/dist/utils/project-status.d.ts +2 -2
- package/dist/utils/startup-perf.d.ts +18 -0
- package/dist/utils/startup-perf.js +60 -0
- package/dist/utils/token-tracker.d.ts +62 -0
- package/dist/utils/token-tracker.js +150 -0
- package/dist/utils/token-types.d.ts +23 -0
- package/dist/utils/token-types.js +18 -0
- package/dist/utils/types/config-types.d.ts +32 -0
- package/dist/utils/types/config-types.js +8 -0
- package/dist/utils/update-checker.d.ts +28 -0
- package/dist/utils/update-checker.js +106 -0
- package/dist/utils/version.d.ts +7 -0
- package/dist/utils/version.js +10 -0
- package/dist/utils/vscode-detect.d.ts +39 -0
- package/dist/utils/vscode-detect.js +137 -0
- package/package.json +27 -13
- package/dist/commands/handler-types.d.ts +0 -68
- package/dist/commands/handler-types.js +0 -8
- package/dist/commands/handlers/agent-commands.d.ts +0 -13
- package/dist/commands/handlers/agent-commands.js +0 -305
- package/dist/commands/handlers/design-commands.d.ts +0 -15
- package/dist/commands/handlers/design-commands.js +0 -334
- package/dist/commands/handlers/index.d.ts +0 -20
- package/dist/commands/handlers/index.js +0 -43
- package/dist/commands/handlers/overlay-commands.d.ts +0 -21
- package/dist/commands/handlers/overlay-commands.js +0 -287
- package/dist/commands/handlers/project-commands.d.ts +0 -11
- package/dist/commands/handlers/project-commands.js +0 -167
- package/dist/commands/handlers/simple-commands.d.ts +0 -19
- package/dist/commands/handlers/simple-commands.js +0 -144
- package/dist/commands/registry.d.ts +0 -50
- package/dist/commands/registry.js +0 -75
- package/dist/index.old.d.ts +0 -7
- package/dist/index.old.js +0 -1014
- package/dist/repl.d.ts +0 -149
- package/dist/repl.js +0 -1151
- package/dist/templates/claude-md.d.ts +0 -7
- package/dist/templates/claude-md.js +0 -189
- package/dist/test-autocomplete.d.ts +0 -7
- package/dist/test-autocomplete.js +0 -85
- package/dist/test-tabbed-menu.d.ts +0 -7
- package/dist/test-tabbed-menu.js +0 -25
- package/dist/tool-selector.d.ts +0 -71
- package/dist/tool-selector.js +0 -184
- package/dist/tools/anchor-tools.d.ts +0 -31
- package/dist/tools/anchor-tools.js +0 -255
- package/dist/tools/backlog-wrappers.d.ts +0 -54
- package/dist/tools/backlog-wrappers.js +0 -338
- package/dist/tools/document-db.d.ts +0 -43
- package/dist/tools/document-db.js +0 -220
- package/dist/tools/workitem-db.d.ts +0 -103
- package/dist/tools/workitem-db.js +0 -549
- package/dist/ui/agents-overlay-v2.d.ts +0 -43
- package/dist/ui/agents-overlay-v2.js +0 -809
- package/dist/ui/agents-overlay.d.ts +0 -12
- package/dist/ui/agents-overlay.js +0 -863
- package/dist/ui/anchors-overlay.d.ts +0 -12
- package/dist/ui/anchors-overlay.js +0 -775
- package/dist/ui/arch-type-overlay.d.ts +0 -15
- package/dist/ui/arch-type-overlay.js +0 -201
- package/dist/ui/ask-user-overlay-v2.d.ts +0 -26
- package/dist/ui/ask-user-overlay-v2.js +0 -555
- package/dist/ui/ask-user-simple-overlay-v2.d.ts +0 -25
- package/dist/ui/ask-user-simple-overlay-v2.js +0 -215
- package/dist/ui/backlog-overlay.d.ts +0 -32
- package/dist/ui/backlog-overlay.js +0 -652
- package/dist/ui/commands-overlay-v2.d.ts +0 -33
- package/dist/ui/commands-overlay-v2.js +0 -441
- package/dist/ui/commands-overlay.d.ts +0 -16
- package/dist/ui/commands-overlay.js +0 -439
- package/dist/ui/config-overlay.d.ts +0 -35
- package/dist/ui/config-overlay.js +0 -707
- package/dist/ui/docs-overlay.d.ts +0 -17
- package/dist/ui/docs-overlay.js +0 -303
- package/dist/ui/footer-v2.d.ts +0 -222
- package/dist/ui/footer-v2.js +0 -1349
- package/dist/ui/help-overlay-v2.d.ts +0 -34
- package/dist/ui/help-overlay-v2.js +0 -309
- package/dist/ui/help-overlay.d.ts +0 -16
- package/dist/ui/help-overlay.js +0 -316
- package/dist/ui/init-overlay-v2.d.ts +0 -34
- package/dist/ui/init-overlay-v2.js +0 -600
- package/dist/ui/init-overlay.d.ts +0 -34
- package/dist/ui/init-overlay.js +0 -604
- package/dist/ui/input-prompt-v2.d.ts +0 -180
- package/dist/ui/input-prompt-v2.js +0 -999
- package/dist/ui/iteration-limit-overlay-v2.d.ts +0 -21
- package/dist/ui/iteration-limit-overlay-v2.js +0 -114
- package/dist/ui/keys-overlay-v2.d.ts +0 -41
- package/dist/ui/keys-overlay-v2.js +0 -248
- package/dist/ui/mascot-overlay-v2.d.ts +0 -41
- package/dist/ui/mascot-overlay-v2.js +0 -138
- package/dist/ui/mascot-overlay.d.ts +0 -21
- package/dist/ui/mascot-overlay.js +0 -146
- package/dist/ui/model-overlay-v2.d.ts +0 -49
- package/dist/ui/model-overlay-v2.js +0 -118
- package/dist/ui/model-overlay.d.ts +0 -27
- package/dist/ui/model-overlay.js +0 -221
- package/dist/ui/model-warning-overlay.d.ts +0 -30
- package/dist/ui/model-warning-overlay.js +0 -169
- package/dist/ui/new-overlay.d.ts +0 -34
- package/dist/ui/new-overlay.js +0 -604
- package/dist/ui/overlay/impl/init-overlay-v2.d.ts +0 -77
- package/dist/ui/overlay/impl/init-overlay-v2.js +0 -593
- package/dist/ui/overlay/overlay-types.d.ts +0 -128
- package/dist/ui/overlay/overlay-types.js +0 -22
- package/dist/ui/overlays/help-overlay-v2.d.ts +0 -28
- package/dist/ui/overlays/help-overlay-v2.js +0 -198
- package/dist/ui/overlays/index.d.ts +0 -11
- package/dist/ui/overlays/index.js +0 -11
- package/dist/ui/permission-overlay-v2.d.ts +0 -36
- package/dist/ui/permission-overlay-v2.js +0 -380
- package/dist/ui/projects-overlay.d.ts +0 -19
- package/dist/ui/projects-overlay.js +0 -484
- package/dist/ui/theme-overlay-v2.d.ts +0 -42
- package/dist/ui/theme-overlay-v2.js +0 -135
- package/dist/ui/theme-overlay.d.ts +0 -24
- package/dist/ui/theme-overlay.js +0 -127
- package/dist/ui/tools-overlay-v2.d.ts +0 -47
- package/dist/ui/tools-overlay-v2.js +0 -218
- package/dist/ui/tools-overlay.d.ts +0 -34
- package/dist/ui/tools-overlay.js +0 -230
- package/dist/ui/tutorial-overlay-v2.d.ts +0 -31
- package/dist/ui/tutorial-overlay-v2.js +0 -1035
- package/dist/ui/tutorial-overlay.d.ts +0 -11
- package/dist/ui/tutorial-overlay.js +0 -1034
- package/dist/ui/workflow-overlay.d.ts +0 -22
- package/dist/ui/workflow-overlay.js +0 -636
|
@@ -0,0 +1,805 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Commands for REPL V2
|
|
3
|
+
*
|
|
4
|
+
* Commands for managing session persistence and resumption.
|
|
5
|
+
* Sessions are now bound to projects - each project has its own session.
|
|
6
|
+
*/
|
|
7
|
+
import { ResumeOverlayV2, } from '../../ui/overlay/index.js';
|
|
8
|
+
import { getProjectSessionManager, } from '../../session/index.js';
|
|
9
|
+
import { getCurrentProject } from '../../tools/project-db.js';
|
|
10
|
+
import { projectRepository } from '../../db/repositories/index.js';
|
|
11
|
+
import { getTeamCheckpointer, setActiveSharedContext } from '../../multi-agent/index.js';
|
|
12
|
+
import { getSessionRegistry, getActiveTerminalSessionId } from '../../multi-agent/session-registry.js';
|
|
13
|
+
import { getFileLockManager } from '../../multi-agent/file-locks.js';
|
|
14
|
+
import { stripThinkingBlocks } from '../../utils/message-utils.js';
|
|
15
|
+
import { truncate } from '../../ui/base/index.js';
|
|
16
|
+
// =============================================================================
|
|
17
|
+
// Message → PrintableItem Conversion
|
|
18
|
+
// =============================================================================
|
|
19
|
+
/**
|
|
20
|
+
* Convert restored messages to PrintableItems for Ctrl+R history view.
|
|
21
|
+
* Filters out noise (thinking blocks, pure tool_result messages) and
|
|
22
|
+
* maps each message to the appropriate PrintableItem type.
|
|
23
|
+
*/
|
|
24
|
+
export function convertMessagesToItems(messages) {
|
|
25
|
+
const items = [];
|
|
26
|
+
for (const msg of messages) {
|
|
27
|
+
if (msg.role === 'user') {
|
|
28
|
+
if (typeof msg.content === 'string') {
|
|
29
|
+
items.push({ type: 'user-message', text: msg.content });
|
|
30
|
+
}
|
|
31
|
+
else if (Array.isArray(msg.content)) {
|
|
32
|
+
// Extract text blocks only — skip pure tool_result messages
|
|
33
|
+
const textBlocks = msg.content.filter((b) => b.type === 'text');
|
|
34
|
+
if (textBlocks.length > 0) {
|
|
35
|
+
const text = textBlocks.map(b => b.text).join('\n');
|
|
36
|
+
items.push({ type: 'user-message', text });
|
|
37
|
+
}
|
|
38
|
+
// Skip messages that are purely tool_result blocks (no human text)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
else if (msg.role === 'assistant') {
|
|
42
|
+
if (typeof msg.content === 'string') {
|
|
43
|
+
items.push({ type: 'agent-text', text: msg.content });
|
|
44
|
+
}
|
|
45
|
+
else if (Array.isArray(msg.content)) {
|
|
46
|
+
for (const block of msg.content) {
|
|
47
|
+
if (block.type === 'text') {
|
|
48
|
+
items.push({ type: 'agent-text', text: block.text });
|
|
49
|
+
}
|
|
50
|
+
else if (block.type === 'tool_use') {
|
|
51
|
+
// Brief summary of tool params
|
|
52
|
+
const params = summarizeToolParams(block.input);
|
|
53
|
+
items.push({ type: 'tool-start', name: block.name, params });
|
|
54
|
+
}
|
|
55
|
+
// Skip thinking blocks — noise in history review
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return items;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Create a brief summary of tool parameters for history display.
|
|
64
|
+
*/
|
|
65
|
+
function summarizeToolParams(input) {
|
|
66
|
+
const keys = Object.keys(input);
|
|
67
|
+
if (keys.length === 0)
|
|
68
|
+
return '';
|
|
69
|
+
const parts = [];
|
|
70
|
+
for (const key of keys.slice(0, 3)) {
|
|
71
|
+
const val = input[key];
|
|
72
|
+
if (typeof val === 'string') {
|
|
73
|
+
const display = truncate(val, 50);
|
|
74
|
+
parts.push(`${key}: ${display}`);
|
|
75
|
+
}
|
|
76
|
+
else if (typeof val === 'number' || typeof val === 'boolean') {
|
|
77
|
+
parts.push(`${key}: ${String(val)}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (keys.length > 3) {
|
|
81
|
+
parts.push(`+${String(keys.length - 3)} more`);
|
|
82
|
+
}
|
|
83
|
+
return parts.join(', ');
|
|
84
|
+
}
|
|
85
|
+
// =============================================================================
|
|
86
|
+
// Session Management Helpers
|
|
87
|
+
// =============================================================================
|
|
88
|
+
/**
|
|
89
|
+
* Save the current agent state to the current project's session.
|
|
90
|
+
* Called after each successful agent response.
|
|
91
|
+
*/
|
|
92
|
+
export async function saveCurrentSession(state) {
|
|
93
|
+
const psm = getProjectSessionManager();
|
|
94
|
+
const currentProject = getCurrentProject();
|
|
95
|
+
const projectId = currentProject?.id ?? null;
|
|
96
|
+
const projectName = currentProject?.displayName ?? null;
|
|
97
|
+
// Get workflow state from project if available
|
|
98
|
+
let workflowState;
|
|
99
|
+
if (currentProject) {
|
|
100
|
+
const project = projectRepository.getById(currentProject.id);
|
|
101
|
+
if (project) {
|
|
102
|
+
workflowState = {
|
|
103
|
+
mode: project.workflowMode,
|
|
104
|
+
currentItemId: project.currentItemId ?? undefined,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
await psm.saveProjectSession(projectId, projectName, state, workflowState);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Load the session for the current or specified project.
|
|
112
|
+
* Returns null if no session exists.
|
|
113
|
+
*/
|
|
114
|
+
export async function loadProjectSession(projectId) {
|
|
115
|
+
const psm = getProjectSessionManager();
|
|
116
|
+
return psm.loadProjectSession(projectId);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Check if the current project has a saved session.
|
|
120
|
+
*/
|
|
121
|
+
export function hasCurrentProjectSession() {
|
|
122
|
+
const psm = getProjectSessionManager();
|
|
123
|
+
const currentProject = getCurrentProject();
|
|
124
|
+
return psm.hasProjectSession(currentProject?.id ?? null);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Archive the current session before starting fresh.
|
|
128
|
+
*/
|
|
129
|
+
export async function archiveCurrentSession() {
|
|
130
|
+
const psm = getProjectSessionManager();
|
|
131
|
+
const currentProject = getCurrentProject();
|
|
132
|
+
return psm.archiveCurrentSession(currentProject?.id ?? null);
|
|
133
|
+
}
|
|
134
|
+
// =============================================================================
|
|
135
|
+
// Team Persistence Helpers
|
|
136
|
+
// =============================================================================
|
|
137
|
+
/**
|
|
138
|
+
* Save the current team state to the current project.
|
|
139
|
+
* Called after each successful agent response (alongside session save).
|
|
140
|
+
* Also saves shared context and artifact store.
|
|
141
|
+
*/
|
|
142
|
+
export function saveCurrentTeam(team) {
|
|
143
|
+
const currentProject = getCurrentProject();
|
|
144
|
+
const projectId = currentProject?.id ?? null;
|
|
145
|
+
const checkpointer = getTeamCheckpointer();
|
|
146
|
+
// Save team metadata and agent states
|
|
147
|
+
checkpointer.saveTeam(projectId, team);
|
|
148
|
+
// Save shared context
|
|
149
|
+
checkpointer.saveSharedContext(projectId, team.sharedContext);
|
|
150
|
+
// Save artifacts
|
|
151
|
+
team.artifactStore.save();
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Load the team for the current project.
|
|
155
|
+
* Returns null if no team exists.
|
|
156
|
+
* The checkpointer automatically loads shared context and artifact store.
|
|
157
|
+
*/
|
|
158
|
+
export function loadCurrentTeam(agentFactory, onEvent) {
|
|
159
|
+
const currentProject = getCurrentProject();
|
|
160
|
+
const projectId = currentProject?.id ?? null;
|
|
161
|
+
const checkpointer = getTeamCheckpointer();
|
|
162
|
+
return checkpointer.loadTeam(projectId, agentFactory, onEvent);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Check if the current project has a saved team.
|
|
166
|
+
*/
|
|
167
|
+
export function hasCurrentTeam() {
|
|
168
|
+
const currentProject = getCurrentProject();
|
|
169
|
+
const projectId = currentProject?.id ?? null;
|
|
170
|
+
const checkpointer = getTeamCheckpointer();
|
|
171
|
+
return checkpointer.hasTeam(projectId);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Delete the team for the current project.
|
|
175
|
+
*/
|
|
176
|
+
export function deleteCurrentTeam() {
|
|
177
|
+
const currentProject = getCurrentProject();
|
|
178
|
+
const projectId = currentProject?.id ?? null;
|
|
179
|
+
const checkpointer = getTeamCheckpointer();
|
|
180
|
+
return checkpointer.deleteTeam(projectId);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* List all saved sessions for display in the resume overlay.
|
|
184
|
+
* Ordering priority:
|
|
185
|
+
* 1. This terminal's current session (if exists)
|
|
186
|
+
* 2. Other terminals' current sessions for the same project
|
|
187
|
+
* 3. History sessions for the same project
|
|
188
|
+
* 4. Other projects' sessions (sorted by most recent)
|
|
189
|
+
*/
|
|
190
|
+
async function listSessionsForResume() {
|
|
191
|
+
const psm = getProjectSessionManager();
|
|
192
|
+
const currentProject = getCurrentProject();
|
|
193
|
+
const allSessions = await psm.listAllSessions();
|
|
194
|
+
const currentProjectId = currentProject?.id ?? null;
|
|
195
|
+
const ownPrefix = getActiveTerminalSessionId()?.slice(0, 8) ?? null;
|
|
196
|
+
// Get current project's sessions
|
|
197
|
+
const currentProjectSessions = allSessions.get(currentProjectId) ?? [];
|
|
198
|
+
allSessions.delete(currentProjectId);
|
|
199
|
+
// Split current project sessions into tiers
|
|
200
|
+
const ownSession = [];
|
|
201
|
+
const otherTerminalSessions = [];
|
|
202
|
+
const historySessions = [];
|
|
203
|
+
for (const session of currentProjectSessions) {
|
|
204
|
+
if (session.terminalPrefix && ownPrefix && session.terminalPrefix === ownPrefix) {
|
|
205
|
+
ownSession.push(session);
|
|
206
|
+
}
|
|
207
|
+
else if (session.terminalPrefix) {
|
|
208
|
+
otherTerminalSessions.push(session);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
historySessions.push(session);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
// Sort each tier by updatedAt descending
|
|
215
|
+
const byRecent = (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();
|
|
216
|
+
otherTerminalSessions.sort(byRecent);
|
|
217
|
+
historySessions.sort(byRecent);
|
|
218
|
+
// Build result with priority ordering
|
|
219
|
+
const result = [
|
|
220
|
+
...ownSession,
|
|
221
|
+
...otherTerminalSessions,
|
|
222
|
+
...historySessions,
|
|
223
|
+
];
|
|
224
|
+
// Add other projects' sessions (sorted by most recent)
|
|
225
|
+
const otherProjectSessions = [];
|
|
226
|
+
for (const sessions of allSessions.values()) {
|
|
227
|
+
otherProjectSessions.push(...sessions);
|
|
228
|
+
}
|
|
229
|
+
otherProjectSessions.sort(byRecent);
|
|
230
|
+
result.push(...otherProjectSessions);
|
|
231
|
+
return result;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Parse a session ID into its components.
|
|
235
|
+
* Handles both new format "current-{8hex}-{projectId}" and legacy "current-{projectId}".
|
|
236
|
+
*/
|
|
237
|
+
function parseCurrentSessionId(sessionId) {
|
|
238
|
+
if (!sessionId.startsWith('current-'))
|
|
239
|
+
return null;
|
|
240
|
+
const rest = sessionId.slice('current-'.length);
|
|
241
|
+
// New format: "{8hex}-{projectId}" or "{8hex}-global"
|
|
242
|
+
const hexMatch = /^([a-f0-9]{8})-(.+)$/.exec(rest);
|
|
243
|
+
if (hexMatch) {
|
|
244
|
+
const terminalPrefix = hexMatch[1];
|
|
245
|
+
const projectIdStr = hexMatch[2];
|
|
246
|
+
const projectId = projectIdStr === 'global' ? null : parseInt(projectIdStr, 10);
|
|
247
|
+
return { terminalPrefix, projectId };
|
|
248
|
+
}
|
|
249
|
+
// Legacy format: "{projectId}" or "global"
|
|
250
|
+
const projectId = rest === 'global' ? null : parseInt(rest, 10);
|
|
251
|
+
return { terminalPrefix: null, projectId };
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Delete a session by ID.
|
|
255
|
+
* Handles both current and historical sessions.
|
|
256
|
+
*/
|
|
257
|
+
async function deleteSession(sessionId) {
|
|
258
|
+
const psm = getProjectSessionManager();
|
|
259
|
+
// Parse session ID to determine project and terminal prefix
|
|
260
|
+
const parsed = parseCurrentSessionId(sessionId);
|
|
261
|
+
if (parsed) {
|
|
262
|
+
if (parsed.terminalPrefix) {
|
|
263
|
+
return psm.deleteSessionByPrefix(parsed.projectId, parsed.terminalPrefix);
|
|
264
|
+
}
|
|
265
|
+
return psm.deleteCurrentSession(parsed.projectId);
|
|
266
|
+
}
|
|
267
|
+
// For historical sessions, we need to search all projects
|
|
268
|
+
// This is less common, so a simple search is acceptable
|
|
269
|
+
const allSessions = await psm.listAllSessions();
|
|
270
|
+
for (const [_projectId, sessions] of allSessions) {
|
|
271
|
+
const session = sessions.find((s) => s.sessionId === sessionId);
|
|
272
|
+
if (session) {
|
|
273
|
+
// TODO: Delete historical session from history folder
|
|
274
|
+
// For now, only current sessions are deletable
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Check if there are any recent sessions (within last 24 hours).
|
|
282
|
+
*/
|
|
283
|
+
export async function hasRecentSession() {
|
|
284
|
+
const sessions = await listSessionsForResume();
|
|
285
|
+
if (sessions.length === 0)
|
|
286
|
+
return false;
|
|
287
|
+
const twentyFourHoursAgo = Date.now() - 24 * 60 * 60 * 1000;
|
|
288
|
+
const mostRecent = new Date(sessions[0].updatedAt).getTime();
|
|
289
|
+
return mostRecent > twentyFourHoursAgo;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Get the most recent session info.
|
|
293
|
+
*/
|
|
294
|
+
export async function getMostRecentSession() {
|
|
295
|
+
const sessions = await listSessionsForResume();
|
|
296
|
+
return sessions.length > 0 ? sessions[0] : null;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Checkpoint the current project's session before switching.
|
|
300
|
+
* Returns the old project ID if a checkpoint was made.
|
|
301
|
+
*/
|
|
302
|
+
export async function checkpointBeforeSwitch(agent) {
|
|
303
|
+
const currentProject = getCurrentProject();
|
|
304
|
+
const oldProjectId = currentProject?.id ?? null;
|
|
305
|
+
// Only checkpoint if we have an agent and messages to save
|
|
306
|
+
if (agent) {
|
|
307
|
+
try {
|
|
308
|
+
const state = agent.serialize();
|
|
309
|
+
if (state.messages.length > 0) {
|
|
310
|
+
await saveCurrentSession(state);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
// Silently fail - checkpoint is best-effort
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return oldProjectId;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Load and restore a session for a project.
|
|
321
|
+
* Returns the session if restored, null if no session or fresh start.
|
|
322
|
+
*/
|
|
323
|
+
export async function loadAndRestoreSession(projectId, agent, mode = 'auto') {
|
|
324
|
+
// Fresh mode = never load existing session
|
|
325
|
+
if (mode === 'fresh') {
|
|
326
|
+
return null;
|
|
327
|
+
}
|
|
328
|
+
const psm = getProjectSessionManager();
|
|
329
|
+
const session = await psm.loadProjectSession(projectId);
|
|
330
|
+
if (!session) {
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
// Auto mode = restore immediately
|
|
334
|
+
if (mode === 'auto' && agent) {
|
|
335
|
+
try {
|
|
336
|
+
// Strip thinking blocks - they contain provider-specific signatures
|
|
337
|
+
// that don't transfer between sessions (uses shared utility)
|
|
338
|
+
const messagesWithoutThinking = stripThinkingBlocks(session.messages);
|
|
339
|
+
await agent.setHistory(messagesWithoutThinking, { turnCount: session.turnCount });
|
|
340
|
+
return session;
|
|
341
|
+
}
|
|
342
|
+
catch {
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
// Ask mode - return the session but don't restore (caller decides)
|
|
347
|
+
return session;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Handle project context switch after an overlay that may have changed projects.
|
|
351
|
+
* Checkpoints the old session, loads the new one, and refreshes context.
|
|
352
|
+
* Also handles team switching - saves old team and loads new project's team.
|
|
353
|
+
*
|
|
354
|
+
* @param oldProjectId - The project ID before the overlay was shown
|
|
355
|
+
* @param agent - The agent instance (for checkpoint/restore/anchors)
|
|
356
|
+
* @param teamOptions - Optional team switching options
|
|
357
|
+
* @returns Object with switch info, or null if no switch occurred
|
|
358
|
+
*/
|
|
359
|
+
export async function handleProjectSwitch(oldProjectId, agent, teamOptions) {
|
|
360
|
+
const newProject = getCurrentProject();
|
|
361
|
+
const newProjectId = newProject?.id ?? null;
|
|
362
|
+
// No switch occurred
|
|
363
|
+
if (oldProjectId === newProjectId) {
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
// Update session registry with new project + release old locks
|
|
367
|
+
const registry = getSessionRegistry();
|
|
368
|
+
if (registry) {
|
|
369
|
+
registry.updateProjectId(newProjectId);
|
|
370
|
+
}
|
|
371
|
+
const lockManager = getFileLockManager();
|
|
372
|
+
const sessionId = getActiveTerminalSessionId();
|
|
373
|
+
if (lockManager && sessionId) {
|
|
374
|
+
lockManager.releaseSessionLocks(sessionId);
|
|
375
|
+
}
|
|
376
|
+
// Switch occurred - checkpoint old session
|
|
377
|
+
if (agent && oldProjectId !== null) {
|
|
378
|
+
try {
|
|
379
|
+
const state = agent.serialize();
|
|
380
|
+
if (state.messages.length > 0) {
|
|
381
|
+
// Temporarily set back to old project for saving
|
|
382
|
+
const psm = getProjectSessionManager();
|
|
383
|
+
await psm.saveProjectSession(oldProjectId, null, // We don't have the old project name here
|
|
384
|
+
state);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
catch {
|
|
388
|
+
// Best effort - continue even if checkpoint fails
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
// Load the new project's session
|
|
392
|
+
let sessionRestored = false;
|
|
393
|
+
let messageCount = 0;
|
|
394
|
+
let messages = [];
|
|
395
|
+
if (agent) {
|
|
396
|
+
try {
|
|
397
|
+
const psm = getProjectSessionManager();
|
|
398
|
+
const session = await psm.loadProjectSession(newProjectId);
|
|
399
|
+
if (session && session.messages.length > 0) {
|
|
400
|
+
// Strip thinking blocks from messages (uses shared utility)
|
|
401
|
+
messages = stripThinkingBlocks(session.messages);
|
|
402
|
+
messageCount = messages.length;
|
|
403
|
+
sessionRestored = true;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
catch {
|
|
407
|
+
// If restore fails, start fresh
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
// Refresh project context (COMPILR.md, guided context, anchors)
|
|
411
|
+
let contextRefreshed = false;
|
|
412
|
+
let contextMessage;
|
|
413
|
+
try {
|
|
414
|
+
const contextResult = await refreshProjectContext(newProjectId, newProject?.path ?? null);
|
|
415
|
+
if (contextResult.memoryLoaded || contextResult.guidedContextGenerated) {
|
|
416
|
+
contextRefreshed = true;
|
|
417
|
+
contextMessage = contextResult.contextMessage;
|
|
418
|
+
// Append context refresh as a system message to the conversation
|
|
419
|
+
if (contextMessage && messages.length > 0) {
|
|
420
|
+
messages = [
|
|
421
|
+
...messages,
|
|
422
|
+
{
|
|
423
|
+
role: 'user',
|
|
424
|
+
content: contextMessage,
|
|
425
|
+
},
|
|
426
|
+
];
|
|
427
|
+
messageCount = messages.length;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
// Update agent's anchors for the new project
|
|
431
|
+
if (agent?.clearAnchors && agent.addAnchor) {
|
|
432
|
+
// Clear existing persistent anchors
|
|
433
|
+
agent.clearAnchors({ scope: 'persistent' });
|
|
434
|
+
// Add new project's anchors
|
|
435
|
+
const newAnchors = await getProjectAnchors(newProjectId);
|
|
436
|
+
for (const anchor of newAnchors) {
|
|
437
|
+
agent.addAnchor({
|
|
438
|
+
id: anchor.id,
|
|
439
|
+
content: anchor.content,
|
|
440
|
+
priority: anchor.priority,
|
|
441
|
+
scope: anchor.scope,
|
|
442
|
+
tags: anchor.tags,
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
catch {
|
|
448
|
+
// Context refresh is best-effort
|
|
449
|
+
}
|
|
450
|
+
// Set the updated history (with context message if any)
|
|
451
|
+
if (agent) {
|
|
452
|
+
if (messages.length > 0) {
|
|
453
|
+
await agent.setHistory(messages, { turnCount: messageCount });
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
agent.clearHistory();
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
// Handle team switching if team options provided
|
|
460
|
+
let newTeam;
|
|
461
|
+
if (teamOptions) {
|
|
462
|
+
const checkpointer = getTeamCheckpointer();
|
|
463
|
+
// Save the old team to the old project
|
|
464
|
+
if (teamOptions.team && oldProjectId !== null) {
|
|
465
|
+
try {
|
|
466
|
+
checkpointer.saveTeam(oldProjectId, teamOptions.team);
|
|
467
|
+
checkpointer.saveSharedContext(oldProjectId, teamOptions.team.sharedContext);
|
|
468
|
+
teamOptions.team.artifactStore.save();
|
|
469
|
+
}
|
|
470
|
+
catch {
|
|
471
|
+
// Best effort - continue even if save fails
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
// Load or create the new project's team
|
|
475
|
+
const loadedTeam = checkpointer.loadTeam(newProjectId, teamOptions.agentFactory, teamOptions.onEvent);
|
|
476
|
+
if (loadedTeam) {
|
|
477
|
+
newTeam = loadedTeam;
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
// Create fresh team for the new project
|
|
481
|
+
const { AgentTeam } = await import('../../multi-agent/index.js');
|
|
482
|
+
newTeam = new AgentTeam({
|
|
483
|
+
name: newProject?.displayName ?? 'Team',
|
|
484
|
+
agentFactory: teamOptions.agentFactory,
|
|
485
|
+
onEvent: teamOptions.onEvent,
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
return {
|
|
490
|
+
switched: true,
|
|
491
|
+
oldProjectId,
|
|
492
|
+
newProjectId,
|
|
493
|
+
sessionRestored,
|
|
494
|
+
messageCount,
|
|
495
|
+
restoredMessages: sessionRestored ? messages : undefined,
|
|
496
|
+
contextRefreshed,
|
|
497
|
+
contextMessage,
|
|
498
|
+
newTeam,
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Get the current project ID for tracking before overlay.
|
|
503
|
+
* Use with handleProjectSwitch after overlay closes.
|
|
504
|
+
*/
|
|
505
|
+
export function getCurrentProjectIdForTracking() {
|
|
506
|
+
const currentProject = getCurrentProject();
|
|
507
|
+
return currentProject?.id ?? null;
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Refresh project context after switching projects.
|
|
511
|
+
* Loads COMPILR.md, generates guided context, and prepares anchor updates.
|
|
512
|
+
*
|
|
513
|
+
* @param projectId - The new project's ID (null for global)
|
|
514
|
+
* @param projectPath - The new project's path (for loading COMPILR.md)
|
|
515
|
+
* @returns Context refresh result with message to inject
|
|
516
|
+
*/
|
|
517
|
+
export async function refreshProjectContext(projectId, projectPath) {
|
|
518
|
+
// Lazy imports to avoid circular dependencies
|
|
519
|
+
const { loadProjectMemory } = await import('../../utils/project-memory.js');
|
|
520
|
+
const { getFullGuidedPrompt, shouldInjectGuidedContext } = await import('../../workflow/index.js');
|
|
521
|
+
const { workItemRepository } = await import('../../db/repositories/index.js');
|
|
522
|
+
const { getGlobalAnchorManager, getAnchorManager } = await import('../../anchors/index.js');
|
|
523
|
+
const result = {
|
|
524
|
+
memoryLoaded: false,
|
|
525
|
+
guidedContextGenerated: false,
|
|
526
|
+
anchorsLoaded: 0,
|
|
527
|
+
contextMessage: '',
|
|
528
|
+
};
|
|
529
|
+
const contextParts = [];
|
|
530
|
+
const project = projectId ? projectRepository.getById(projectId) : null;
|
|
531
|
+
// 1. Load COMPILR.md from the new project's directory
|
|
532
|
+
if (projectPath) {
|
|
533
|
+
const memory = loadProjectMemory({ cwd: projectPath });
|
|
534
|
+
if (memory.found && memory.content) {
|
|
535
|
+
result.memoryLoaded = true;
|
|
536
|
+
result.memoryContent = memory.content;
|
|
537
|
+
result.memoryPath = memory.filePath ?? undefined;
|
|
538
|
+
// Add to context message
|
|
539
|
+
const filename = memory.filePath?.split('/').pop() ?? 'COMPILR.md';
|
|
540
|
+
contextParts.push(`## Project Instructions (${filename})\n\n${memory.content}`);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
// 2. Generate guided mode context if applicable
|
|
544
|
+
if (project && shouldInjectGuidedContext(project)) {
|
|
545
|
+
const statusCounts = workItemRepository.getStatusCounts(project.id);
|
|
546
|
+
let currentItem = null;
|
|
547
|
+
if (project.currentItemId) {
|
|
548
|
+
currentItem = workItemRepository.getByItemId(project.id, project.currentItemId);
|
|
549
|
+
}
|
|
550
|
+
else {
|
|
551
|
+
const inProgressItems = workItemRepository.query({
|
|
552
|
+
project_id: project.id,
|
|
553
|
+
status: 'in_progress',
|
|
554
|
+
limit: 1,
|
|
555
|
+
});
|
|
556
|
+
if (inProgressItems.items.length > 0) {
|
|
557
|
+
currentItem = inProgressItems.items[0];
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
const contextOptions = {
|
|
561
|
+
project,
|
|
562
|
+
currentItem,
|
|
563
|
+
backlogCount: statusCounts.backlog,
|
|
564
|
+
inProgressCount: statusCounts.in_progress,
|
|
565
|
+
completedCount: statusCounts.completed,
|
|
566
|
+
};
|
|
567
|
+
result.guidedContext = getFullGuidedPrompt(contextOptions);
|
|
568
|
+
result.guidedContextGenerated = true;
|
|
569
|
+
// Add to context message
|
|
570
|
+
contextParts.push(`## Current Workflow\n\n${result.guidedContext}`);
|
|
571
|
+
}
|
|
572
|
+
// 3. Collect anchors for the new project
|
|
573
|
+
const globalAnchors = getGlobalAnchorManager().getAll({ scope: 'persistent' });
|
|
574
|
+
const projectAnchors = projectId
|
|
575
|
+
? getAnchorManager(String(projectId)).getAll({ scope: 'persistent' })
|
|
576
|
+
: [];
|
|
577
|
+
result.anchorsLoaded = globalAnchors.length + projectAnchors.length;
|
|
578
|
+
if (projectAnchors.length > 0) {
|
|
579
|
+
const anchorSummary = projectAnchors
|
|
580
|
+
.slice(0, 3)
|
|
581
|
+
.map(a => `- ${truncate(a.content, 50)}`)
|
|
582
|
+
.join('\n');
|
|
583
|
+
contextParts.push(`## Project Anchors (${String(projectAnchors.length)} items)\n\n${anchorSummary}`);
|
|
584
|
+
}
|
|
585
|
+
// Build final context message
|
|
586
|
+
if (contextParts.length > 0) {
|
|
587
|
+
result.contextMessage = `[Project context updated - now working on: ${project?.displayName ?? 'Global'}]\n\n${contextParts.join('\n\n---\n\n')}`;
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
590
|
+
result.contextMessage = `[Project context updated - now working on: ${project?.displayName ?? 'Global'}]`;
|
|
591
|
+
}
|
|
592
|
+
return result;
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* Get anchor data for the new project (to update agent's anchor manager).
|
|
596
|
+
*/
|
|
597
|
+
export async function getProjectAnchors(projectId) {
|
|
598
|
+
const { getGlobalAnchorManager, getAnchorManager } = await import('../../anchors/index.js');
|
|
599
|
+
const globalAnchors = getGlobalAnchorManager().getAll({ scope: 'persistent' });
|
|
600
|
+
const projectAnchors = projectId
|
|
601
|
+
? getAnchorManager(String(projectId)).getAll({ scope: 'persistent' })
|
|
602
|
+
: [];
|
|
603
|
+
return [
|
|
604
|
+
...globalAnchors.map((a) => ({
|
|
605
|
+
id: a.id,
|
|
606
|
+
content: a.content,
|
|
607
|
+
priority: a.priority,
|
|
608
|
+
scope: a.scope,
|
|
609
|
+
tags: a.tags ?? [],
|
|
610
|
+
})),
|
|
611
|
+
...projectAnchors.map((a) => ({
|
|
612
|
+
id: a.id,
|
|
613
|
+
content: a.content,
|
|
614
|
+
priority: a.priority,
|
|
615
|
+
scope: a.scope,
|
|
616
|
+
tags: a.tags ?? [],
|
|
617
|
+
projectId: String(projectId),
|
|
618
|
+
})),
|
|
619
|
+
];
|
|
620
|
+
}
|
|
621
|
+
// =============================================================================
|
|
622
|
+
// Resume Command
|
|
623
|
+
// =============================================================================
|
|
624
|
+
export const resumeCommand = {
|
|
625
|
+
name: 'resume',
|
|
626
|
+
aliases: ['sessions'],
|
|
627
|
+
description: 'Resume a previous session',
|
|
628
|
+
details: 'View and resume saved sessions. Sessions are now bound to projects - each project maintains its own conversation context. Use this to continue a previous conversation or switch between ongoing tasks.',
|
|
629
|
+
examples: [{ code: '/resume' }],
|
|
630
|
+
interactions: [
|
|
631
|
+
'↑/↓ to navigate sessions',
|
|
632
|
+
'Enter to resume selected session',
|
|
633
|
+
'd to delete a session',
|
|
634
|
+
'/ to search sessions',
|
|
635
|
+
'Esc to close',
|
|
636
|
+
],
|
|
637
|
+
async execute(_args, ctx) {
|
|
638
|
+
// Load sessions
|
|
639
|
+
const sessions = await listSessionsForResume();
|
|
640
|
+
if (sessions.length === 0) {
|
|
641
|
+
ctx.ui.print({ type: 'info', message: 'No saved sessions found.' });
|
|
642
|
+
ctx.ui.print({ type: 'info', message: 'Sessions are automatically saved after each agent response.' });
|
|
643
|
+
return true;
|
|
644
|
+
}
|
|
645
|
+
// Show the resume overlay with current project context
|
|
646
|
+
const currentProject = getCurrentProject();
|
|
647
|
+
const overlay = new ResumeOverlayV2({
|
|
648
|
+
sessions,
|
|
649
|
+
currentProjectId: currentProject?.id ?? null,
|
|
650
|
+
onDelete: deleteSession,
|
|
651
|
+
});
|
|
652
|
+
const result = await ctx.ui.showOverlay(overlay);
|
|
653
|
+
// Handle result
|
|
654
|
+
if (result?.deleted) {
|
|
655
|
+
ctx.ui.print({ type: 'success', message: `Session deleted.` });
|
|
656
|
+
return true;
|
|
657
|
+
}
|
|
658
|
+
if (result?.sessionId) {
|
|
659
|
+
// Determine which project/terminal's session to load
|
|
660
|
+
let projectId = null;
|
|
661
|
+
let terminalPrefix = null;
|
|
662
|
+
const parsed = parseCurrentSessionId(result.sessionId);
|
|
663
|
+
if (parsed) {
|
|
664
|
+
projectId = parsed.projectId;
|
|
665
|
+
terminalPrefix = parsed.terminalPrefix;
|
|
666
|
+
}
|
|
667
|
+
else {
|
|
668
|
+
// For historical sessions, we'd need to parse from metadata
|
|
669
|
+
// For now, assume it's the current project
|
|
670
|
+
const currentProject = getCurrentProject();
|
|
671
|
+
projectId = currentProject?.id ?? null;
|
|
672
|
+
}
|
|
673
|
+
// Restore team roster (bound to the session's terminal prefix)
|
|
674
|
+
let teamRestored = false;
|
|
675
|
+
let teamAgentCount = 0;
|
|
676
|
+
if (terminalPrefix && ctx.team && ctx.agentFactory && ctx.setTeam) {
|
|
677
|
+
const checkpointer = getTeamCheckpointer();
|
|
678
|
+
const persistedTeam = checkpointer.loadTeamByPrefix(projectId, terminalPrefix, ctx.agentFactory);
|
|
679
|
+
if (persistedTeam && persistedTeam.size > 1) {
|
|
680
|
+
// Wire up the current agent as default
|
|
681
|
+
if (ctx.agent) {
|
|
682
|
+
persistedTeam.setDefaultAgent(ctx.agent);
|
|
683
|
+
}
|
|
684
|
+
// Replace the team via ctx.setTeam (updates UI callbacks)
|
|
685
|
+
ctx.setTeam(persistedTeam);
|
|
686
|
+
setActiveSharedContext(persistedTeam.sharedContext);
|
|
687
|
+
// Populate project info in shared context
|
|
688
|
+
const activeProject = getCurrentProject();
|
|
689
|
+
if (activeProject) {
|
|
690
|
+
persistedTeam.sharedContext.setProject({
|
|
691
|
+
id: activeProject.id,
|
|
692
|
+
name: activeProject.displayName,
|
|
693
|
+
path: activeProject.path,
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
// Set team roster anchor
|
|
697
|
+
if (persistedTeam.sharedContext.hasTeamRoster() && ctx.agent?.hasAnchors()) {
|
|
698
|
+
ctx.agent.addAnchor({
|
|
699
|
+
id: 'team-roster',
|
|
700
|
+
content: persistedTeam.sharedContext.formatTeamRoster(),
|
|
701
|
+
priority: 'info',
|
|
702
|
+
scope: 'session',
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
// Sync roster to session registry
|
|
706
|
+
const registry = getSessionRegistry();
|
|
707
|
+
if (registry) {
|
|
708
|
+
const agents = persistedTeam.getAll();
|
|
709
|
+
registry.updateAgents(agents.map(a => ({
|
|
710
|
+
id: a.id,
|
|
711
|
+
displayName: a.displayName,
|
|
712
|
+
mascot: a.mascot,
|
|
713
|
+
})));
|
|
714
|
+
}
|
|
715
|
+
teamRestored = true;
|
|
716
|
+
teamAgentCount = persistedTeam.size;
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
// Load the session state (specific terminal or default)
|
|
720
|
+
const psm = getProjectSessionManager();
|
|
721
|
+
const session = terminalPrefix
|
|
722
|
+
? await psm.loadProjectSessionByPrefix(projectId, terminalPrefix)
|
|
723
|
+
: await loadProjectSession(projectId);
|
|
724
|
+
// Claim: rename files from old prefix to this terminal's prefix
|
|
725
|
+
const ownPrefix = getActiveTerminalSessionId()?.slice(0, 8) ?? null;
|
|
726
|
+
if (terminalPrefix && ownPrefix && terminalPrefix !== ownPrefix) {
|
|
727
|
+
psm.claimSession(projectId, terminalPrefix, ownPrefix);
|
|
728
|
+
getTeamCheckpointer().claimTeamFiles(projectId, terminalPrefix, ownPrefix);
|
|
729
|
+
}
|
|
730
|
+
// Handle 0-message sessions (team-only restore)
|
|
731
|
+
if (!session || session.messages.length === 0) {
|
|
732
|
+
if (teamRestored) {
|
|
733
|
+
ctx.ui.print({ type: 'success', message: `Team restored (${String(teamAgentCount)} agents).` });
|
|
734
|
+
}
|
|
735
|
+
else if (!session) {
|
|
736
|
+
ctx.ui.print({ type: 'error', message: 'Failed to load session. It may have been corrupted or deleted.' });
|
|
737
|
+
}
|
|
738
|
+
else {
|
|
739
|
+
ctx.ui.print({ type: 'info', message: 'Session has no conversation history.' });
|
|
740
|
+
}
|
|
741
|
+
return true;
|
|
742
|
+
}
|
|
743
|
+
// Restore the agent's conversation history
|
|
744
|
+
if (ctx.agent) {
|
|
745
|
+
try {
|
|
746
|
+
// Strip thinking blocks (uses shared utility)
|
|
747
|
+
const filteredMessages = stripThinkingBlocks(session.messages);
|
|
748
|
+
// Use setHistory to restore the conversation
|
|
749
|
+
// Pass turnCount to ensure compaction works correctly after resume
|
|
750
|
+
await ctx.agent.setHistory(filteredMessages, {
|
|
751
|
+
turnCount: session.turnCount,
|
|
752
|
+
});
|
|
753
|
+
// Show project info if session belongs to a different project
|
|
754
|
+
const currentProject = getCurrentProject();
|
|
755
|
+
if (session.projectId !== null && session.projectId !== currentProject?.id) {
|
|
756
|
+
ctx.ui.print({ type: 'info', message: `Session from project: ${session.projectName ?? `ID ${String(session.projectId)}`}` });
|
|
757
|
+
}
|
|
758
|
+
// Build success message with team info
|
|
759
|
+
const parts = [`${String(session.messages.length)} messages`];
|
|
760
|
+
if (teamRestored) {
|
|
761
|
+
parts.push(`${String(teamAgentCount)} agents`);
|
|
762
|
+
}
|
|
763
|
+
ctx.ui.print({ type: 'success', message: `Session restored (${parts.join(', ')}).` });
|
|
764
|
+
// Populate restored history for Ctrl+R view
|
|
765
|
+
const historyItems = convertMessagesToItems(filteredMessages);
|
|
766
|
+
ctx.ui.setRestoredHistory(historyItems);
|
|
767
|
+
// Show a summary of what was restored
|
|
768
|
+
const lastUserMsg = session.messages.filter(m => m.role === 'user').pop();
|
|
769
|
+
if (lastUserMsg) {
|
|
770
|
+
let content = '';
|
|
771
|
+
if (typeof lastUserMsg.content === 'string') {
|
|
772
|
+
content = lastUserMsg.content;
|
|
773
|
+
}
|
|
774
|
+
else if (Array.isArray(lastUserMsg.content)) {
|
|
775
|
+
const textBlock = lastUserMsg.content.find((b) => b.type === 'text');
|
|
776
|
+
if (textBlock?.type === 'text') {
|
|
777
|
+
content = textBlock.text;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
const preview = truncate(content, 60);
|
|
781
|
+
if (preview) {
|
|
782
|
+
ctx.ui.print({ type: 'info', message: `Last message: "${preview}"` });
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
ctx.ui.print({ type: 'info', message: 'Tip: Use Ctrl+R to view conversation history.' });
|
|
786
|
+
}
|
|
787
|
+
catch (error) {
|
|
788
|
+
ctx.ui.print({ type: 'error', message: `Failed to restore session: ${String(error)}` });
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
else {
|
|
792
|
+
ctx.ui.print({ type: 'warning', message: 'Cannot restore session - no agent connected.' });
|
|
793
|
+
}
|
|
794
|
+
return true;
|
|
795
|
+
}
|
|
796
|
+
// User cancelled
|
|
797
|
+
return true;
|
|
798
|
+
},
|
|
799
|
+
};
|
|
800
|
+
// =============================================================================
|
|
801
|
+
// Export All Session Commands
|
|
802
|
+
// =============================================================================
|
|
803
|
+
export const sessionCommands = [
|
|
804
|
+
resumeCommand,
|
|
805
|
+
];
|